diff options
author | Kalle Valo <kvalo@codeaurora.org> | 2015-11-18 09:27:32 +0200 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-11-18 14:28:30 +0200 |
commit | 6948300c79dba2b6c7b54af43d1924f51e47e017 (patch) | |
tree | 0660a79871b03cceb14fe31ac58c90452302e5fb /drivers/net/wireless/zd1211rw | |
parent | ed0ad06f5c8e5b8fc3c6d7c0e3d2dc546638c18c (diff) | |
download | op-kernel-dev-6948300c79dba2b6c7b54af43d1924f51e47e017.zip op-kernel-dev-6948300c79dba2b6c7b54af43d1924f51e47e017.tar.gz |
zd1211rw: move under zydas vendor directory
Part of reorganising wireless drivers directory and Kconfig.
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/Kconfig | 19 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/Makefile | 9 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 1560 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.h | 983 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_def.h | 69 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 1550 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.h | 327 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf.c | 181 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf.h | 110 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf_al2230.c | 443 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf_al7230b.c | 494 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf_rf2959.c | 281 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_rf_uw2453.c | 539 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 2060 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.h | 292 |
15 files changed, 0 insertions, 8917 deletions
diff --git a/drivers/net/wireless/zd1211rw/Kconfig b/drivers/net/wireless/zd1211rw/Kconfig deleted file mode 100644 index 95920581..0000000 --- a/drivers/net/wireless/zd1211rw/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -config ZD1211RW - tristate "ZyDAS ZD1211/ZD1211B USB-wireless support" - depends on USB && MAC80211 - select FW_LOADER - ---help--- - This is a driver for the ZyDAS ZD1211/ZD1211B wireless - chip, present in many USB-wireless adapters. - - Device firmware is required alongside this driver. You can download - the firmware distribution from http://sf.net/projects/zd1211/files/ - -config ZD1211RW_DEBUG - bool "ZyDAS ZD1211 debugging" - depends on ZD1211RW - ---help--- - ZD1211 debugging messages. Choosing Y will result in additional debug - messages being saved to your kernel logs, which may help debug any - problems. - diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile deleted file mode 100644 index 5728a91..0000000 --- a/drivers/net/wireless/zd1211rw/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -obj-$(CONFIG_ZD1211RW) += zd1211rw.o - -zd1211rw-objs := zd_chip.o zd_mac.o \ - zd_rf_al2230.o zd_rf_rf2959.o \ - zd_rf_al7230b.o zd_rf_uw2453.o \ - zd_rf.o zd_usb.o - -ccflags-$(CONFIG_ZD1211RW_DEBUG) := -DDEBUG - diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c deleted file mode 100644 index 07b94ed..0000000 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ /dev/null @@ -1,1560 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* This file implements all the hardware specific functions for the ZD1211 - * and ZD1211B chips. Support for the ZD1211B was possible after Timothy - * Legge sent me a ZD1211B device. Thank you Tim. -- Uli - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/slab.h> - -#include "zd_def.h" -#include "zd_chip.h" -#include "zd_mac.h" -#include "zd_rf.h" - -void zd_chip_init(struct zd_chip *chip, - struct ieee80211_hw *hw, - struct usb_interface *intf) -{ - memset(chip, 0, sizeof(*chip)); - mutex_init(&chip->mutex); - zd_usb_init(&chip->usb, hw, intf); - zd_rf_init(&chip->rf); -} - -void zd_chip_clear(struct zd_chip *chip) -{ - ZD_ASSERT(!mutex_is_locked(&chip->mutex)); - zd_usb_clear(&chip->usb); - zd_rf_clear(&chip->rf); - mutex_destroy(&chip->mutex); - ZD_MEMCLEAR(chip, sizeof(*chip)); -} - -static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size) -{ - u8 *addr = zd_mac_get_perm_addr(zd_chip_to_mac(chip)); - return scnprintf(buffer, size, "%02x-%02x-%02x", - addr[0], addr[1], addr[2]); -} - -/* Prints an identifier line, which will support debugging. */ -static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size) -{ - int i = 0; - - i = scnprintf(buffer, size, "zd1211%s chip ", - zd_chip_is_zd1211b(chip) ? "b" : ""); - i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i); - i += scnprintf(buffer+i, size-i, " "); - i += scnprint_mac_oui(chip, buffer+i, size-i); - i += scnprintf(buffer+i, size-i, " "); - i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i); - i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type, - chip->patch_cck_gain ? 'g' : '-', - chip->patch_cr157 ? '7' : '-', - chip->patch_6m_band_edge ? '6' : '-', - chip->new_phy_layout ? 'N' : '-', - chip->al2230s_bit ? 'S' : '-'); - return i; -} - -static void print_id(struct zd_chip *chip) -{ - char buffer[80]; - - scnprint_id(chip, buffer, sizeof(buffer)); - buffer[sizeof(buffer)-1] = 0; - dev_info(zd_chip_dev(chip), "%s\n", buffer); -} - -static zd_addr_t inc_addr(zd_addr_t addr) -{ - u16 a = (u16)addr; - /* Control registers use byte addressing, but everything else uses word - * addressing. */ - if ((a & 0xf000) == CR_START) - a += 2; - else - a += 1; - return (zd_addr_t)a; -} - -/* Read a variable number of 32-bit values. Parameter count is not allowed to - * exceed USB_MAX_IOREAD32_COUNT. - */ -int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr, - unsigned int count) -{ - int r; - int i; - zd_addr_t a16[USB_MAX_IOREAD32_COUNT * 2]; - u16 v16[USB_MAX_IOREAD32_COUNT * 2]; - unsigned int count16; - - if (count > USB_MAX_IOREAD32_COUNT) - return -EINVAL; - - /* Use stack for values and addresses. */ - count16 = 2 * count; - BUG_ON(count16 * sizeof(zd_addr_t) > sizeof(a16)); - BUG_ON(count16 * sizeof(u16) > sizeof(v16)); - - for (i = 0; i < count; i++) { - int j = 2*i; - /* We read the high word always first. */ - a16[j] = inc_addr(addr[i]); - a16[j+1] = addr[i]; - } - - r = zd_ioread16v_locked(chip, v16, a16, count16); - if (r) { - dev_dbg_f(zd_chip_dev(chip), - "error: %s. Error number %d\n", __func__, r); - return r; - } - - for (i = 0; i < count; i++) { - int j = 2*i; - values[i] = (v16[j] << 16) | v16[j+1]; - } - - return 0; -} - -static int _zd_iowrite32v_async_locked(struct zd_chip *chip, - const struct zd_ioreq32 *ioreqs, - unsigned int count) -{ - int i, j, r; - struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; - unsigned int count16; - - /* Use stack for values and addresses. */ - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - - if (count == 0) - return 0; - if (count > USB_MAX_IOWRITE32_COUNT) - return -EINVAL; - - count16 = 2 * count; - BUG_ON(count16 * sizeof(struct zd_ioreq16) > sizeof(ioreqs16)); - - for (i = 0; i < count; i++) { - j = 2*i; - /* We write the high word always first. */ - ioreqs16[j].value = ioreqs[i].value >> 16; - ioreqs16[j].addr = inc_addr(ioreqs[i].addr); - ioreqs16[j+1].value = ioreqs[i].value; - ioreqs16[j+1].addr = ioreqs[i].addr; - } - - r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16); -#ifdef DEBUG - if (r) { - dev_dbg_f(zd_chip_dev(chip), - "error %d in zd_usb_write16v\n", r); - } -#endif /* DEBUG */ - return r; -} - -int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, - unsigned int count) -{ - int r; - - zd_usb_iowrite16v_async_start(&chip->usb); - r = _zd_iowrite32v_async_locked(chip, ioreqs, count); - if (r) { - zd_usb_iowrite16v_async_end(&chip->usb, 0); - return r; - } - return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); -} - -int zd_iowrite16a_locked(struct zd_chip *chip, - const struct zd_ioreq16 *ioreqs, unsigned int count) -{ - int r; - unsigned int i, j, t, max; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - zd_usb_iowrite16v_async_start(&chip->usb); - - for (i = 0; i < count; i += j + t) { - t = 0; - max = count-i; - if (max > USB_MAX_IOWRITE16_COUNT) - max = USB_MAX_IOWRITE16_COUNT; - for (j = 0; j < max; j++) { - if (!ioreqs[i+j].addr) { - t = 1; - break; - } - } - - r = zd_usb_iowrite16v_async(&chip->usb, &ioreqs[i], j); - if (r) { - zd_usb_iowrite16v_async_end(&chip->usb, 0); - dev_dbg_f(zd_chip_dev(chip), - "error zd_usb_iowrite16v. Error number %d\n", - r); - return r; - } - } - - return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); -} - -/* Writes a variable number of 32 bit registers. The functions will split - * that in several USB requests. A split can be forced by inserting an IO - * request with an zero address field. - */ -int zd_iowrite32a_locked(struct zd_chip *chip, - const struct zd_ioreq32 *ioreqs, unsigned int count) -{ - int r; - unsigned int i, j, t, max; - - zd_usb_iowrite16v_async_start(&chip->usb); - - for (i = 0; i < count; i += j + t) { - t = 0; - max = count-i; - if (max > USB_MAX_IOWRITE32_COUNT) - max = USB_MAX_IOWRITE32_COUNT; - for (j = 0; j < max; j++) { - if (!ioreqs[i+j].addr) { - t = 1; - break; - } - } - - r = _zd_iowrite32v_async_locked(chip, &ioreqs[i], j); - if (r) { - zd_usb_iowrite16v_async_end(&chip->usb, 0); - dev_dbg_f(zd_chip_dev(chip), - "error _%s. Error number %d\n", __func__, - r); - return r; - } - } - - return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); -} - -int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_ioread16_locked(chip, value, addr); - mutex_unlock(&chip->mutex); - return r; -} - -int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_ioread32_locked(chip, value, addr); - mutex_unlock(&chip->mutex); - return r; -} - -int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_iowrite16_locked(chip, value, addr); - mutex_unlock(&chip->mutex); - return r; -} - -int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_iowrite32_locked(chip, value, addr); - mutex_unlock(&chip->mutex); - return r; -} - -int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses, - u32 *values, unsigned int count) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_ioread32v_locked(chip, values, addresses, count); - mutex_unlock(&chip->mutex); - return r; -} - -int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, - unsigned int count) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_iowrite32a_locked(chip, ioreqs, count); - mutex_unlock(&chip->mutex); - return r; -} - -static int read_pod(struct zd_chip *chip, u8 *rf_type) -{ - int r; - u32 value; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_ioread32_locked(chip, &value, E2P_POD); - if (r) - goto error; - dev_dbg_f(zd_chip_dev(chip), "E2P_POD %#010x\n", value); - - /* FIXME: AL2230 handling (Bit 7 in POD) */ - *rf_type = value & 0x0f; - chip->pa_type = (value >> 16) & 0x0f; - chip->patch_cck_gain = (value >> 8) & 0x1; - chip->patch_cr157 = (value >> 13) & 0x1; - chip->patch_6m_band_edge = (value >> 21) & 0x1; - chip->new_phy_layout = (value >> 31) & 0x1; - chip->al2230s_bit = (value >> 7) & 0x1; - chip->link_led = ((value >> 4) & 1) ? LED1 : LED2; - chip->supports_tx_led = 1; - if (value & (1 << 24)) { /* LED scenario */ - if (value & (1 << 29)) - chip->supports_tx_led = 0; - } - - dev_dbg_f(zd_chip_dev(chip), - "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d " - "patch 6M %d new PHY %d link LED%d tx led %d\n", - zd_rf_name(*rf_type), *rf_type, - chip->pa_type, chip->patch_cck_gain, - chip->patch_cr157, chip->patch_6m_band_edge, - chip->new_phy_layout, - chip->link_led == LED1 ? 1 : 2, - chip->supports_tx_led); - return 0; -error: - *rf_type = 0; - chip->pa_type = 0; - chip->patch_cck_gain = 0; - chip->patch_cr157 = 0; - chip->patch_6m_band_edge = 0; - chip->new_phy_layout = 0; - return r; -} - -static int zd_write_mac_addr_common(struct zd_chip *chip, const u8 *mac_addr, - const struct zd_ioreq32 *in_reqs, - const char *type) -{ - int r; - struct zd_ioreq32 reqs[2] = {in_reqs[0], in_reqs[1]}; - - if (mac_addr) { - reqs[0].value = (mac_addr[3] << 24) - | (mac_addr[2] << 16) - | (mac_addr[1] << 8) - | mac_addr[0]; - reqs[1].value = (mac_addr[5] << 8) - | mac_addr[4]; - dev_dbg_f(zd_chip_dev(chip), "%s addr %pM\n", type, mac_addr); - } else { - dev_dbg_f(zd_chip_dev(chip), "set NULL %s\n", type); - } - - mutex_lock(&chip->mutex); - r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); - mutex_unlock(&chip->mutex); - return r; -} - -/* MAC address: if custom mac addresses are to be used CR_MAC_ADDR_P1 and - * CR_MAC_ADDR_P2 must be overwritten - */ -int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) -{ - static const struct zd_ioreq32 reqs[2] = { - [0] = { .addr = CR_MAC_ADDR_P1 }, - [1] = { .addr = CR_MAC_ADDR_P2 }, - }; - - return zd_write_mac_addr_common(chip, mac_addr, reqs, "mac"); -} - -int zd_write_bssid(struct zd_chip *chip, const u8 *bssid) -{ - static const struct zd_ioreq32 reqs[2] = { - [0] = { .addr = CR_BSSID_P1 }, - [1] = { .addr = CR_BSSID_P2 }, - }; - - return zd_write_mac_addr_common(chip, bssid, reqs, "bssid"); -} - -int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain) -{ - int r; - u32 value; - - mutex_lock(&chip->mutex); - r = zd_ioread32_locked(chip, &value, E2P_SUBID); - mutex_unlock(&chip->mutex); - if (r) - return r; - - *regdomain = value >> 16; - dev_dbg_f(zd_chip_dev(chip), "regdomain: %#04x\n", *regdomain); - - return 0; -} - -static int read_values(struct zd_chip *chip, u8 *values, size_t count, - zd_addr_t e2p_addr, u32 guard) -{ - int r; - int i; - u32 v; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - for (i = 0;;) { - r = zd_ioread32_locked(chip, &v, - (zd_addr_t)((u16)e2p_addr+i/2)); - if (r) - return r; - v -= guard; - if (i+4 < count) { - values[i++] = v; - values[i++] = v >> 8; - values[i++] = v >> 16; - values[i++] = v >> 24; - continue; - } - for (;i < count; i++) - values[i] = v >> (8*(i%3)); - return 0; - } -} - -static int read_pwr_cal_values(struct zd_chip *chip) -{ - return read_values(chip, chip->pwr_cal_values, - E2P_CHANNEL_COUNT, E2P_PWR_CAL_VALUE1, - 0); -} - -static int read_pwr_int_values(struct zd_chip *chip) -{ - return read_values(chip, chip->pwr_int_values, - E2P_CHANNEL_COUNT, E2P_PWR_INT_VALUE1, - E2P_PWR_INT_GUARD); -} - -static int read_ofdm_cal_values(struct zd_chip *chip) -{ - int r; - int i; - static const zd_addr_t addresses[] = { - E2P_36M_CAL_VALUE1, - E2P_48M_CAL_VALUE1, - E2P_54M_CAL_VALUE1, - }; - - for (i = 0; i < 3; i++) { - r = read_values(chip, chip->ofdm_cal_values[i], - E2P_CHANNEL_COUNT, addresses[i], 0); - if (r) - return r; - } - return 0; -} - -static int read_cal_int_tables(struct zd_chip *chip) -{ - int r; - - r = read_pwr_cal_values(chip); - if (r) - return r; - r = read_pwr_int_values(chip); - if (r) - return r; - r = read_ofdm_cal_values(chip); - if (r) - return r; - return 0; -} - -/* phy means physical registers */ -int zd_chip_lock_phy_regs(struct zd_chip *chip) -{ - int r; - u32 tmp; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_ioread32_locked(chip, &tmp, CR_REG1); - if (r) { - dev_err(zd_chip_dev(chip), "error ioread32(CR_REG1): %d\n", r); - return r; - } - - tmp &= ~UNLOCK_PHY_REGS; - - r = zd_iowrite32_locked(chip, tmp, CR_REG1); - if (r) - dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r); - return r; -} - -int zd_chip_unlock_phy_regs(struct zd_chip *chip) -{ - int r; - u32 tmp; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_ioread32_locked(chip, &tmp, CR_REG1); - if (r) { - dev_err(zd_chip_dev(chip), - "error ioread32(CR_REG1): %d\n", r); - return r; - } - - tmp |= UNLOCK_PHY_REGS; - - r = zd_iowrite32_locked(chip, tmp, CR_REG1); - if (r) - dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r); - return r; -} - -/* ZD_CR157 can be optionally patched by the EEPROM for original ZD1211 */ -static int patch_cr157(struct zd_chip *chip) -{ - int r; - u16 value; - - if (!chip->patch_cr157) - return 0; - - r = zd_ioread16_locked(chip, &value, E2P_PHY_REG); - if (r) - return r; - - dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8); - return zd_iowrite32_locked(chip, value >> 8, ZD_CR157); -} - -/* - * 6M band edge can be optionally overwritten for certain RF's - * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge - * bit (for AL2230, AL2230S) - */ -static int patch_6m_band_edge(struct zd_chip *chip, u8 channel) -{ - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - if (!chip->patch_6m_band_edge) - return 0; - - return zd_rf_patch_6m_band_edge(&chip->rf, channel); -} - -/* Generic implementation of 6M band edge patching, used by most RFs via - * zd_rf_generic_patch_6m() */ -int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel) -{ - struct zd_ioreq16 ioreqs[] = { - { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, - { ZD_CR47, 0x1e }, - }; - - /* FIXME: Channel 11 is not the edge for all regulatory domains. */ - if (channel == 1 || channel == 11) - ioreqs[0].value = 0x12; - - dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel); - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int zd1211_hw_reset_phy(struct zd_chip *chip) -{ - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR0, 0x0a }, { ZD_CR1, 0x06 }, { ZD_CR2, 0x26 }, - { ZD_CR3, 0x38 }, { ZD_CR4, 0x80 }, { ZD_CR9, 0xa0 }, - { ZD_CR10, 0x81 }, { ZD_CR11, 0x00 }, { ZD_CR12, 0x7f }, - { ZD_CR13, 0x8c }, { ZD_CR14, 0x80 }, { ZD_CR15, 0x3d }, - { ZD_CR16, 0x20 }, { ZD_CR17, 0x1e }, { ZD_CR18, 0x0a }, - { ZD_CR19, 0x48 }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0c }, - { ZD_CR22, 0x23 }, { ZD_CR23, 0x90 }, { ZD_CR24, 0x14 }, - { ZD_CR25, 0x40 }, { ZD_CR26, 0x10 }, { ZD_CR27, 0x19 }, - { ZD_CR28, 0x7f }, { ZD_CR29, 0x80 }, { ZD_CR30, 0x4b }, - { ZD_CR31, 0x60 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x08 }, - { ZD_CR34, 0x06 }, { ZD_CR35, 0x0a }, { ZD_CR36, 0x00 }, - { ZD_CR37, 0x00 }, { ZD_CR38, 0x38 }, { ZD_CR39, 0x0c }, - { ZD_CR40, 0x84 }, { ZD_CR41, 0x2a }, { ZD_CR42, 0x80 }, - { ZD_CR43, 0x10 }, { ZD_CR44, 0x12 }, { ZD_CR46, 0xff }, - { ZD_CR47, 0x1E }, { ZD_CR48, 0x26 }, { ZD_CR49, 0x5b }, - { ZD_CR64, 0xd0 }, { ZD_CR65, 0x04 }, { ZD_CR66, 0x58 }, - { ZD_CR67, 0xc9 }, { ZD_CR68, 0x88 }, { ZD_CR69, 0x41 }, - { ZD_CR70, 0x23 }, { ZD_CR71, 0x10 }, { ZD_CR72, 0xff }, - { ZD_CR73, 0x32 }, { ZD_CR74, 0x30 }, { ZD_CR75, 0x65 }, - { ZD_CR76, 0x41 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x30 }, - { ZD_CR79, 0x68 }, { ZD_CR80, 0x64 }, { ZD_CR81, 0x64 }, - { ZD_CR82, 0x00 }, { ZD_CR83, 0x00 }, { ZD_CR84, 0x00 }, - { ZD_CR85, 0x02 }, { ZD_CR86, 0x00 }, { ZD_CR87, 0x00 }, - { ZD_CR88, 0xff }, { ZD_CR89, 0xfc }, { ZD_CR90, 0x00 }, - { ZD_CR91, 0x00 }, { ZD_CR92, 0x00 }, { ZD_CR93, 0x08 }, - { ZD_CR94, 0x00 }, { ZD_CR95, 0x00 }, { ZD_CR96, 0xff }, - { ZD_CR97, 0xe7 }, { ZD_CR98, 0x00 }, { ZD_CR99, 0x00 }, - { ZD_CR100, 0x00 }, { ZD_CR101, 0xae }, { ZD_CR102, 0x02 }, - { ZD_CR103, 0x00 }, { ZD_CR104, 0x03 }, { ZD_CR105, 0x65 }, - { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 }, { ZD_CR108, 0x0a }, - { ZD_CR109, 0xaa }, { ZD_CR110, 0xaa }, { ZD_CR111, 0x25 }, - { ZD_CR112, 0x25 }, { ZD_CR113, 0x00 }, { ZD_CR119, 0x1e }, - { ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 }, - { }, - { ZD_CR5, 0x00 }, { ZD_CR6, 0x00 }, { ZD_CR7, 0x00 }, - { ZD_CR8, 0x00 }, { ZD_CR9, 0x20 }, { ZD_CR12, 0xf0 }, - { ZD_CR20, 0x0e }, { ZD_CR21, 0x0e }, { ZD_CR27, 0x10 }, - { ZD_CR44, 0x33 }, { ZD_CR47, 0x1E }, { ZD_CR83, 0x24 }, - { ZD_CR84, 0x04 }, { ZD_CR85, 0x00 }, { ZD_CR86, 0x0C }, - { ZD_CR87, 0x12 }, { ZD_CR88, 0x0C }, { ZD_CR89, 0x00 }, - { ZD_CR90, 0x10 }, { ZD_CR91, 0x08 }, { ZD_CR93, 0x00 }, - { ZD_CR94, 0x01 }, { ZD_CR95, 0x00 }, { ZD_CR96, 0x50 }, - { ZD_CR97, 0x37 }, { ZD_CR98, 0x35 }, { ZD_CR101, 0x13 }, - { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 }, - { ZD_CR105, 0x12 }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 }, - { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 }, - { ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 }, - { ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR120, 0x4f }, - { ZD_CR125, 0xaa }, { ZD_CR127, 0x03 }, { ZD_CR128, 0x14 }, - { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, { ZD_CR131, 0x0C }, - { ZD_CR136, 0xdf }, { ZD_CR137, 0x40 }, { ZD_CR138, 0xa0 }, - { ZD_CR139, 0xb0 }, { ZD_CR140, 0x99 }, { ZD_CR141, 0x82 }, - { ZD_CR142, 0x54 }, { ZD_CR143, 0x1c }, { ZD_CR144, 0x6c }, - { ZD_CR147, 0x07 }, { ZD_CR148, 0x4c }, { ZD_CR149, 0x50 }, - { ZD_CR150, 0x0e }, { ZD_CR151, 0x18 }, { ZD_CR160, 0xfe }, - { ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa }, - { ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe }, - { ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba }, - { ZD_CR170, 0xba }, { ZD_CR171, 0xba }, - /* Note: ZD_CR204 must lead the ZD_CR203 */ - { ZD_CR204, 0x7d }, - { }, - { ZD_CR203, 0x30 }, - }; - - int r, t; - - dev_dbg_f(zd_chip_dev(chip), "\n"); - - r = zd_chip_lock_phy_regs(chip); - if (r) - goto out; - - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - goto unlock; - - r = patch_cr157(chip); -unlock: - t = zd_chip_unlock_phy_regs(chip); - if (t && !r) - r = t; -out: - return r; -} - -static int zd1211b_hw_reset_phy(struct zd_chip *chip) -{ - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR0, 0x14 }, { ZD_CR1, 0x06 }, { ZD_CR2, 0x26 }, - { ZD_CR3, 0x38 }, { ZD_CR4, 0x80 }, { ZD_CR9, 0xe0 }, - { ZD_CR10, 0x81 }, - /* power control { { ZD_CR11, 1 << 6 }, */ - { ZD_CR11, 0x00 }, - { ZD_CR12, 0xf0 }, { ZD_CR13, 0x8c }, { ZD_CR14, 0x80 }, - { ZD_CR15, 0x3d }, { ZD_CR16, 0x20 }, { ZD_CR17, 0x1e }, - { ZD_CR18, 0x0a }, { ZD_CR19, 0x48 }, - { ZD_CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */ - { ZD_CR21, 0x0e }, { ZD_CR22, 0x23 }, { ZD_CR23, 0x90 }, - { ZD_CR24, 0x14 }, { ZD_CR25, 0x40 }, { ZD_CR26, 0x10 }, - { ZD_CR27, 0x10 }, { ZD_CR28, 0x7f }, { ZD_CR29, 0x80 }, - { ZD_CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */ - { ZD_CR31, 0x60 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x08 }, - { ZD_CR34, 0x06 }, { ZD_CR35, 0x0a }, { ZD_CR36, 0x00 }, - { ZD_CR37, 0x00 }, { ZD_CR38, 0x38 }, { ZD_CR39, 0x0c }, - { ZD_CR40, 0x84 }, { ZD_CR41, 0x2a }, { ZD_CR42, 0x80 }, - { ZD_CR43, 0x10 }, { ZD_CR44, 0x33 }, { ZD_CR46, 0xff }, - { ZD_CR47, 0x1E }, { ZD_CR48, 0x26 }, { ZD_CR49, 0x5b }, - { ZD_CR64, 0xd0 }, { ZD_CR65, 0x04 }, { ZD_CR66, 0x58 }, - { ZD_CR67, 0xc9 }, { ZD_CR68, 0x88 }, { ZD_CR69, 0x41 }, - { ZD_CR70, 0x23 }, { ZD_CR71, 0x10 }, { ZD_CR72, 0xff }, - { ZD_CR73, 0x32 }, { ZD_CR74, 0x30 }, { ZD_CR75, 0x65 }, - { ZD_CR76, 0x41 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x30 }, - { ZD_CR79, 0xf0 }, { ZD_CR80, 0x64 }, { ZD_CR81, 0x64 }, - { ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 }, - { ZD_CR85, 0x00 }, { ZD_CR86, 0x0c }, { ZD_CR87, 0x12 }, - { ZD_CR88, 0x0c }, { ZD_CR89, 0x00 }, { ZD_CR90, 0x58 }, - { ZD_CR91, 0x04 }, { ZD_CR92, 0x00 }, { ZD_CR93, 0x00 }, - { ZD_CR94, 0x01 }, - { ZD_CR95, 0x20 }, /* ZD1211B */ - { ZD_CR96, 0x50 }, { ZD_CR97, 0x37 }, { ZD_CR98, 0x35 }, - { ZD_CR99, 0x00 }, { ZD_CR100, 0x01 }, { ZD_CR101, 0x13 }, - { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 }, - { ZD_CR105, 0x12 }, { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 }, - { ZD_CR108, 0x0a }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 }, - { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 }, - { ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 }, - { ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x1e }, - { ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 }, - { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, - { ZD_CR131, 0x0c }, { ZD_CR136, 0xdf }, { ZD_CR137, 0xa0 }, - { ZD_CR138, 0xa8 }, { ZD_CR139, 0xb4 }, { ZD_CR140, 0x98 }, - { ZD_CR141, 0x82 }, { ZD_CR142, 0x53 }, { ZD_CR143, 0x1c }, - { ZD_CR144, 0x6c }, { ZD_CR147, 0x07 }, { ZD_CR148, 0x40 }, - { ZD_CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */ - { ZD_CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */ - { ZD_CR151, 0x18 }, { ZD_CR159, 0x70 }, { ZD_CR160, 0xfe }, - { ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa }, - { ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe }, - { ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba }, - { ZD_CR170, 0xba }, { ZD_CR171, 0xba }, - /* Note: ZD_CR204 must lead the ZD_CR203 */ - { ZD_CR204, 0x7d }, - {}, - { ZD_CR203, 0x30 }, - }; - - int r, t; - - dev_dbg_f(zd_chip_dev(chip), "\n"); - - r = zd_chip_lock_phy_regs(chip); - if (r) - goto out; - - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - t = zd_chip_unlock_phy_regs(chip); - if (t && !r) - r = t; -out: - return r; -} - -static int hw_reset_phy(struct zd_chip *chip) -{ - return zd_chip_is_zd1211b(chip) ? zd1211b_hw_reset_phy(chip) : - zd1211_hw_reset_phy(chip); -} - -static int zd1211_hw_init_hmac(struct zd_chip *chip) -{ - static const struct zd_ioreq32 ioreqs[] = { - { CR_ZD1211_RETRY_MAX, ZD1211_RETRY_COUNT }, - { CR_RX_THRESHOLD, 0x000c0640 }, - }; - - dev_dbg_f(zd_chip_dev(chip), "\n"); - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int zd1211b_hw_init_hmac(struct zd_chip *chip) -{ - static const struct zd_ioreq32 ioreqs[] = { - { CR_ZD1211B_RETRY_MAX, ZD1211B_RETRY_COUNT }, - { CR_ZD1211B_CWIN_MAX_MIN_AC0, 0x007f003f }, - { CR_ZD1211B_CWIN_MAX_MIN_AC1, 0x007f003f }, - { CR_ZD1211B_CWIN_MAX_MIN_AC2, 0x003f001f }, - { CR_ZD1211B_CWIN_MAX_MIN_AC3, 0x001f000f }, - { CR_ZD1211B_AIFS_CTL1, 0x00280028 }, - { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, - { CR_ZD1211B_TXOP, 0x01800824 }, - { CR_RX_THRESHOLD, 0x000c0eff, }, - }; - - dev_dbg_f(zd_chip_dev(chip), "\n"); - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int hw_init_hmac(struct zd_chip *chip) -{ - int r; - static const struct zd_ioreq32 ioreqs[] = { - { CR_ACK_TIMEOUT_EXT, 0x20 }, - { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, - { CR_SNIFFER_ON, 0 }, - { CR_RX_FILTER, STA_RX_FILTER }, - { CR_GROUP_HASH_P1, 0x00 }, - { CR_GROUP_HASH_P2, 0x80000000 }, - { CR_REG1, 0xa4 }, - { CR_ADDA_PWR_DWN, 0x7f }, - { CR_BCN_PLCP_CFG, 0x00f00401 }, - { CR_PHY_DELAY, 0x00 }, - { CR_ACK_TIMEOUT_EXT, 0x80 }, - { CR_ADDA_PWR_DWN, 0x00 }, - { CR_ACK_TIME_80211, 0x100 }, - { CR_RX_PE_DELAY, 0x70 }, - { CR_PS_CTRL, 0x10000000 }, - { CR_RTS_CTS_RATE, 0x02030203 }, - { CR_AFTER_PNP, 0x1 }, - { CR_WEP_PROTECT, 0x114 }, - { CR_IFS_VALUE, IFS_VALUE_DEFAULT }, - { CR_CAM_MODE, MODE_AP_WDS}, - }; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - return r; - - return zd_chip_is_zd1211b(chip) ? - zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip); -} - -struct aw_pt_bi { - u32 atim_wnd_period; - u32 pre_tbtt; - u32 beacon_interval; -}; - -static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) -{ - int r; - static const zd_addr_t aw_pt_bi_addr[] = - { CR_ATIM_WND_PERIOD, CR_PRE_TBTT, CR_BCN_INTERVAL }; - u32 values[3]; - - r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr, - ARRAY_SIZE(aw_pt_bi_addr)); - if (r) { - memset(s, 0, sizeof(*s)); - return r; - } - - s->atim_wnd_period = values[0]; - s->pre_tbtt = values[1]; - s->beacon_interval = values[2]; - return 0; -} - -static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) -{ - struct zd_ioreq32 reqs[3]; - u16 b_interval = s->beacon_interval & 0xffff; - - if (b_interval <= 5) - b_interval = 5; - if (s->pre_tbtt < 4 || s->pre_tbtt >= b_interval) - s->pre_tbtt = b_interval - 1; - if (s->atim_wnd_period >= s->pre_tbtt) - s->atim_wnd_period = s->pre_tbtt - 1; - - reqs[0].addr = CR_ATIM_WND_PERIOD; - reqs[0].value = s->atim_wnd_period; - reqs[1].addr = CR_PRE_TBTT; - reqs[1].value = s->pre_tbtt; - reqs[2].addr = CR_BCN_INTERVAL; - reqs[2].value = (s->beacon_interval & ~0xffff) | b_interval; - - return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); -} - - -static int set_beacon_interval(struct zd_chip *chip, u16 interval, - u8 dtim_period, int type) -{ - int r; - struct aw_pt_bi s; - u32 b_interval, mode_flag; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - - if (interval > 0) { - switch (type) { - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_MESH_POINT: - mode_flag = BCN_MODE_IBSS; - break; - case NL80211_IFTYPE_AP: - mode_flag = BCN_MODE_AP; - break; - default: - mode_flag = 0; - break; - } - } else { - dtim_period = 0; - mode_flag = 0; - } - - b_interval = mode_flag | (dtim_period << 16) | interval; - - r = zd_iowrite32_locked(chip, b_interval, CR_BCN_INTERVAL); - if (r) - return r; - r = get_aw_pt_bi(chip, &s); - if (r) - return r; - return set_aw_pt_bi(chip, &s); -} - -int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period, - int type) -{ - int r; - - mutex_lock(&chip->mutex); - r = set_beacon_interval(chip, interval, dtim_period, type); - mutex_unlock(&chip->mutex); - return r; -} - -static int hw_init(struct zd_chip *chip) -{ - int r; - - dev_dbg_f(zd_chip_dev(chip), "\n"); - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = hw_reset_phy(chip); - if (r) - return r; - - r = hw_init_hmac(chip); - if (r) - return r; - - return set_beacon_interval(chip, 100, 0, NL80211_IFTYPE_UNSPECIFIED); -} - -static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset) -{ - return (zd_addr_t)((u16)chip->fw_regs_base + offset); -} - -#ifdef DEBUG -static int dump_cr(struct zd_chip *chip, const zd_addr_t addr, - const char *addr_string) -{ - int r; - u32 value; - - r = zd_ioread32_locked(chip, &value, addr); - if (r) { - dev_dbg_f(zd_chip_dev(chip), - "error reading %s. Error number %d\n", addr_string, r); - return r; - } - - dev_dbg_f(zd_chip_dev(chip), "%s %#010x\n", - addr_string, (unsigned int)value); - return 0; -} - -static int test_init(struct zd_chip *chip) -{ - int r; - - r = dump_cr(chip, CR_AFTER_PNP, "CR_AFTER_PNP"); - if (r) - return r; - r = dump_cr(chip, CR_GPI_EN, "CR_GPI_EN"); - if (r) - return r; - return dump_cr(chip, CR_INTERRUPT, "CR_INTERRUPT"); -} - -static void dump_fw_registers(struct zd_chip *chip) -{ - const zd_addr_t addr[4] = { - fw_reg_addr(chip, FW_REG_FIRMWARE_VER), - fw_reg_addr(chip, FW_REG_USB_SPEED), - fw_reg_addr(chip, FW_REG_FIX_TX_RATE), - fw_reg_addr(chip, FW_REG_LED_LINK_STATUS), - }; - - int r; - u16 values[4]; - - r = zd_ioread16v_locked(chip, values, (const zd_addr_t*)addr, - ARRAY_SIZE(addr)); - if (r) { - dev_dbg_f(zd_chip_dev(chip), "error %d zd_ioread16v_locked\n", - r); - return; - } - - dev_dbg_f(zd_chip_dev(chip), "FW_FIRMWARE_VER %#06hx\n", values[0]); - dev_dbg_f(zd_chip_dev(chip), "FW_USB_SPEED %#06hx\n", values[1]); - dev_dbg_f(zd_chip_dev(chip), "FW_FIX_TX_RATE %#06hx\n", values[2]); - dev_dbg_f(zd_chip_dev(chip), "FW_LINK_STATUS %#06hx\n", values[3]); -} -#endif /* DEBUG */ - -static int print_fw_version(struct zd_chip *chip) -{ - struct wiphy *wiphy = zd_chip_to_mac(chip)->hw->wiphy; - int r; - u16 version; - - r = zd_ioread16_locked(chip, &version, - fw_reg_addr(chip, FW_REG_FIRMWARE_VER)); - if (r) - return r; - - dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version); - - snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), - "%04hx", version); - - return 0; -} - -static int set_mandatory_rates(struct zd_chip *chip, int gmode) -{ - u32 rates; - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - /* This sets the mandatory rates, which only depend from the standard - * that the device is supporting. Until further notice we should try - * to support 802.11g also for full speed USB. - */ - if (!gmode) - rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; - else - rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| - CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; - - return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); -} - -int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, - int preamble) -{ - u32 value = 0; - - dev_dbg_f(zd_chip_dev(chip), "preamble=%x\n", preamble); - value |= preamble << RTSCTS_SH_RTS_PMB_TYPE; - value |= preamble << RTSCTS_SH_CTS_PMB_TYPE; - - /* We always send 11M RTS/self-CTS messages, like the vendor driver. */ - value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_RTS_RATE; - value |= ZD_RX_CCK << RTSCTS_SH_RTS_MOD_TYPE; - value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE; - value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE; - - return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE); -} - -int zd_chip_enable_hwint(struct zd_chip *chip) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_iowrite32_locked(chip, HWINT_ENABLED, CR_INTERRUPT); - mutex_unlock(&chip->mutex); - return r; -} - -static int disable_hwint(struct zd_chip *chip) -{ - return zd_iowrite32_locked(chip, HWINT_DISABLED, CR_INTERRUPT); -} - -int zd_chip_disable_hwint(struct zd_chip *chip) -{ - int r; - - mutex_lock(&chip->mutex); - r = disable_hwint(chip); - mutex_unlock(&chip->mutex); - return r; -} - -static int read_fw_regs_offset(struct zd_chip *chip) -{ - int r; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_ioread16_locked(chip, (u16*)&chip->fw_regs_base, - FWRAW_REGS_ADDR); - if (r) - return r; - dev_dbg_f(zd_chip_dev(chip), "fw_regs_base: %#06hx\n", - (u16)chip->fw_regs_base); - - return 0; -} - -/* Read mac address using pre-firmware interface */ -int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr) -{ - dev_dbg_f(zd_chip_dev(chip), "\n"); - return zd_usb_read_fw(&chip->usb, E2P_MAC_ADDR_P1, addr, - ETH_ALEN); -} - -int zd_chip_init_hw(struct zd_chip *chip) -{ - int r; - u8 rf_type; - - dev_dbg_f(zd_chip_dev(chip), "\n"); - - mutex_lock(&chip->mutex); - -#ifdef DEBUG - r = test_init(chip); - if (r) - goto out; -#endif - r = zd_iowrite32_locked(chip, 1, CR_AFTER_PNP); - if (r) - goto out; - - r = read_fw_regs_offset(chip); - if (r) - goto out; - - /* GPI is always disabled, also in the other driver. - */ - r = zd_iowrite32_locked(chip, 0, CR_GPI_EN); - if (r) - goto out; - r = zd_iowrite32_locked(chip, CWIN_SIZE, CR_CWMIN_CWMAX); - if (r) - goto out; - /* Currently we support IEEE 802.11g for full and high speed USB. - * It might be discussed, whether we should support pure b mode for - * full speed USB. - */ - r = set_mandatory_rates(chip, 1); - if (r) - goto out; - /* Disabling interrupts is certainly a smart thing here. - */ - r = disable_hwint(chip); - if (r) - goto out; - r = read_pod(chip, &rf_type); - if (r) - goto out; - r = hw_init(chip); - if (r) - goto out; - r = zd_rf_init_hw(&chip->rf, rf_type); - if (r) - goto out; - - r = print_fw_version(chip); - if (r) - goto out; - -#ifdef DEBUG - dump_fw_registers(chip); - r = test_init(chip); - if (r) - goto out; -#endif /* DEBUG */ - - r = read_cal_int_tables(chip); - if (r) - goto out; - - print_id(chip); -out: - mutex_unlock(&chip->mutex); - return r; -} - -static int update_pwr_int(struct zd_chip *chip, u8 channel) -{ - u8 value = chip->pwr_int_values[channel - 1]; - return zd_iowrite16_locked(chip, value, ZD_CR31); -} - -static int update_pwr_cal(struct zd_chip *chip, u8 channel) -{ - u8 value = chip->pwr_cal_values[channel-1]; - return zd_iowrite16_locked(chip, value, ZD_CR68); -} - -static int update_ofdm_cal(struct zd_chip *chip, u8 channel) -{ - struct zd_ioreq16 ioreqs[3]; - - ioreqs[0].addr = ZD_CR67; - ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1]; - ioreqs[1].addr = ZD_CR66; - ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1]; - ioreqs[2].addr = ZD_CR65; - ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1]; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int update_channel_integration_and_calibration(struct zd_chip *chip, - u8 channel) -{ - int r; - - if (!zd_rf_should_update_pwr_int(&chip->rf)) - return 0; - - r = update_pwr_int(chip, channel); - if (r) - return r; - if (zd_chip_is_zd1211b(chip)) { - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR69, 0x28 }, - {}, - { ZD_CR69, 0x2a }, - }; - - r = update_ofdm_cal(chip, channel); - if (r) - return r; - r = update_pwr_cal(chip, channel); - if (r) - return r; - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - return r; - } - - return 0; -} - -/* The CCK baseband gain can be optionally patched by the EEPROM */ -static int patch_cck_gain(struct zd_chip *chip) -{ - int r; - u32 value; - - if (!chip->patch_cck_gain || !zd_rf_should_patch_cck_gain(&chip->rf)) - return 0; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_ioread32_locked(chip, &value, E2P_PHY_REG); - if (r) - return r; - dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff); - return zd_iowrite16_locked(chip, value & 0xff, ZD_CR47); -} - -int zd_chip_set_channel(struct zd_chip *chip, u8 channel) -{ - int r, t; - - mutex_lock(&chip->mutex); - r = zd_chip_lock_phy_regs(chip); - if (r) - goto out; - r = zd_rf_set_channel(&chip->rf, channel); - if (r) - goto unlock; - r = update_channel_integration_and_calibration(chip, channel); - if (r) - goto unlock; - r = patch_cck_gain(chip); - if (r) - goto unlock; - r = patch_6m_band_edge(chip, channel); - if (r) - goto unlock; - r = zd_iowrite32_locked(chip, 0, CR_CONFIG_PHILIPS); -unlock: - t = zd_chip_unlock_phy_regs(chip); - if (t && !r) - r = t; -out: - mutex_unlock(&chip->mutex); - return r; -} - -u8 zd_chip_get_channel(struct zd_chip *chip) -{ - u8 channel; - - mutex_lock(&chip->mutex); - channel = chip->rf.channel; - mutex_unlock(&chip->mutex); - return channel; -} - -int zd_chip_control_leds(struct zd_chip *chip, enum led_status status) -{ - const zd_addr_t a[] = { - fw_reg_addr(chip, FW_REG_LED_LINK_STATUS), - CR_LED, - }; - - int r; - u16 v[ARRAY_SIZE(a)]; - struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = { - [0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) }, - [1] = { CR_LED }, - }; - u16 other_led; - - mutex_lock(&chip->mutex); - r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a)); - if (r) - goto out; - - other_led = chip->link_led == LED1 ? LED2 : LED1; - - switch (status) { - case ZD_LED_OFF: - ioreqs[0].value = FW_LINK_OFF; - ioreqs[1].value = v[1] & ~(LED1|LED2); - break; - case ZD_LED_SCANNING: - ioreqs[0].value = FW_LINK_OFF; - ioreqs[1].value = v[1] & ~other_led; - if (get_seconds() % 3 == 0) { - ioreqs[1].value &= ~chip->link_led; - } else { - ioreqs[1].value |= chip->link_led; - } - break; - case ZD_LED_ASSOCIATED: - ioreqs[0].value = FW_LINK_TX; - ioreqs[1].value = v[1] & ~other_led; - ioreqs[1].value |= chip->link_led; - break; - default: - r = -EINVAL; - goto out; - } - - if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) { - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - goto out; - } - r = 0; -out: - mutex_unlock(&chip->mutex); - return r; -} - -int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) -{ - int r; - - if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G)) - return -EINVAL; - - mutex_lock(&chip->mutex); - r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL); - mutex_unlock(&chip->mutex); - return r; -} - -static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame) -{ - return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame); -} - -/** - * zd_rx_rate - report zd-rate - * @rx_frame - received frame - * @rx_status - rx_status as given by the device - * - * This function converts the rate as encoded in the received packet to the - * zd-rate, we are using on other places in the driver. - */ -u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status) -{ - u8 zd_rate; - if (status->frame_status & ZD_RX_OFDM) { - zd_rate = zd_rate_from_ofdm_plcp_header(rx_frame); - } else { - switch (zd_cck_plcp_header_signal(rx_frame)) { - case ZD_CCK_PLCP_SIGNAL_1M: - zd_rate = ZD_CCK_RATE_1M; - break; - case ZD_CCK_PLCP_SIGNAL_2M: - zd_rate = ZD_CCK_RATE_2M; - break; - case ZD_CCK_PLCP_SIGNAL_5M5: - zd_rate = ZD_CCK_RATE_5_5M; - break; - case ZD_CCK_PLCP_SIGNAL_11M: - zd_rate = ZD_CCK_RATE_11M; - break; - default: - zd_rate = 0; - } - } - - return zd_rate; -} - -int zd_chip_switch_radio_on(struct zd_chip *chip) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_switch_radio_on(&chip->rf); - mutex_unlock(&chip->mutex); - return r; -} - -int zd_chip_switch_radio_off(struct zd_chip *chip) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_switch_radio_off(&chip->rf); - mutex_unlock(&chip->mutex); - return r; -} - -int zd_chip_enable_int(struct zd_chip *chip) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_usb_enable_int(&chip->usb); - mutex_unlock(&chip->mutex); - return r; -} - -void zd_chip_disable_int(struct zd_chip *chip) -{ - mutex_lock(&chip->mutex); - zd_usb_disable_int(&chip->usb); - mutex_unlock(&chip->mutex); - - /* cancel pending interrupt work */ - cancel_work_sync(&zd_chip_to_mac(chip)->process_intr); -} - -int zd_chip_enable_rxtx(struct zd_chip *chip) -{ - int r; - - mutex_lock(&chip->mutex); - zd_usb_enable_tx(&chip->usb); - r = zd_usb_enable_rx(&chip->usb); - zd_tx_watchdog_enable(&chip->usb); - mutex_unlock(&chip->mutex); - return r; -} - -void zd_chip_disable_rxtx(struct zd_chip *chip) -{ - mutex_lock(&chip->mutex); - zd_tx_watchdog_disable(&chip->usb); - zd_usb_disable_rx(&chip->usb); - zd_usb_disable_tx(&chip->usb); - mutex_unlock(&chip->mutex); -} - -int zd_rfwritev_locked(struct zd_chip *chip, - const u32* values, unsigned int count, u8 bits) -{ - int r; - unsigned int i; - - for (i = 0; i < count; i++) { - r = zd_rfwrite_locked(chip, values[i], bits); - if (r) - return r; - } - - return 0; -} - -/* - * We can optionally program the RF directly through CR regs, if supported by - * the hardware. This is much faster than the older method. - */ -int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value) -{ - const struct zd_ioreq16 ioreqs[] = { - { ZD_CR244, (value >> 16) & 0xff }, - { ZD_CR243, (value >> 8) & 0xff }, - { ZD_CR242, value & 0xff }, - }; - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -int zd_rfwritev_cr_locked(struct zd_chip *chip, - const u32 *values, unsigned int count) -{ - int r; - unsigned int i; - - for (i = 0; i < count; i++) { - r = zd_rfwrite_cr_locked(chip, values[i]); - if (r) - return r; - } - - return 0; -} - -int zd_chip_set_multicast_hash(struct zd_chip *chip, - struct zd_mc_hash *hash) -{ - const struct zd_ioreq32 ioreqs[] = { - { CR_GROUP_HASH_P1, hash->low }, - { CR_GROUP_HASH_P2, hash->high }, - }; - - return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -u64 zd_chip_get_tsf(struct zd_chip *chip) -{ - int r; - static const zd_addr_t aw_pt_bi_addr[] = - { CR_TSF_LOW_PART, CR_TSF_HIGH_PART }; - u32 values[2]; - u64 tsf; - - mutex_lock(&chip->mutex); - r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr, - ARRAY_SIZE(aw_pt_bi_addr)); - mutex_unlock(&chip->mutex); - if (r) - return 0; - - tsf = values[1]; - tsf = (tsf << 32) | values[0]; - - return tsf; -} diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h deleted file mode 100644 index b03786c..0000000 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ /dev/null @@ -1,983 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _ZD_CHIP_H -#define _ZD_CHIP_H - -#include <net/mac80211.h> - -#include "zd_rf.h" -#include "zd_usb.h" - -/* Header for the Media Access Controller (MAC) and the Baseband Processor - * (BBP). It appears that the ZD1211 wraps the old ZD1205 with USB glue and - * adds a processor for handling the USB protocol. - */ - -/* Address space */ -enum { - /* CONTROL REGISTERS */ - CR_START = 0x9000, - - - /* FIRMWARE */ - FW_START = 0xee00, - - - /* EEPROM */ - E2P_START = 0xf800, - E2P_LEN = 0x800, - - /* EEPROM layout */ - E2P_LOAD_CODE_LEN = 0xe, /* base 0xf800 */ - E2P_LOAD_VECT_LEN = 0x9, /* base 0xf80e */ - /* E2P_DATA indexes into this */ - E2P_DATA_LEN = 0x7e, /* base 0xf817 */ - E2P_BOOT_CODE_LEN = 0x760, /* base 0xf895 */ - E2P_INTR_VECT_LEN = 0xb, /* base 0xfff5 */ - - /* Some precomputed offsets into the EEPROM */ - E2P_DATA_OFFSET = E2P_LOAD_CODE_LEN + E2P_LOAD_VECT_LEN, - E2P_BOOT_CODE_OFFSET = E2P_DATA_OFFSET + E2P_DATA_LEN, -}; - -#define CTL_REG(offset) ((zd_addr_t)(CR_START + (offset))) -#define E2P_DATA(offset) ((zd_addr_t)(E2P_START + E2P_DATA_OFFSET + (offset))) -#define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset))) - -/* 8-bit hardware registers */ -#define ZD_CR0 CTL_REG(0x0000) -#define ZD_CR1 CTL_REG(0x0004) -#define ZD_CR2 CTL_REG(0x0008) -#define ZD_CR3 CTL_REG(0x000C) - -#define ZD_CR5 CTL_REG(0x0010) -/* bit 5: if set short preamble used - * bit 6: filter band - Japan channel 14 on, else off - */ -#define ZD_CR6 CTL_REG(0x0014) -#define ZD_CR7 CTL_REG(0x0018) -#define ZD_CR8 CTL_REG(0x001C) - -#define ZD_CR4 CTL_REG(0x0020) - -#define ZD_CR9 CTL_REG(0x0024) -/* bit 2: antenna switch (together with ZD_CR10) */ -#define ZD_CR10 CTL_REG(0x0028) -/* bit 1: antenna switch (together with ZD_CR9) - * RF2959 controls with ZD_CR11 radion on and off - */ -#define ZD_CR11 CTL_REG(0x002C) -/* bit 6: TX power control for OFDM - * RF2959 controls with ZD_CR10 radio on and off - */ -#define ZD_CR12 CTL_REG(0x0030) -#define ZD_CR13 CTL_REG(0x0034) -#define ZD_CR14 CTL_REG(0x0038) -#define ZD_CR15 CTL_REG(0x003C) -#define ZD_CR16 CTL_REG(0x0040) -#define ZD_CR17 CTL_REG(0x0044) -#define ZD_CR18 CTL_REG(0x0048) -#define ZD_CR19 CTL_REG(0x004C) -#define ZD_CR20 CTL_REG(0x0050) -#define ZD_CR21 CTL_REG(0x0054) -#define ZD_CR22 CTL_REG(0x0058) -#define ZD_CR23 CTL_REG(0x005C) -#define ZD_CR24 CTL_REG(0x0060) /* CCA threshold */ -#define ZD_CR25 CTL_REG(0x0064) -#define ZD_CR26 CTL_REG(0x0068) -#define ZD_CR27 CTL_REG(0x006C) -#define ZD_CR28 CTL_REG(0x0070) -#define ZD_CR29 CTL_REG(0x0074) -#define ZD_CR30 CTL_REG(0x0078) -#define ZD_CR31 CTL_REG(0x007C) /* TX power control for RF in - * CCK mode - */ -#define ZD_CR32 CTL_REG(0x0080) -#define ZD_CR33 CTL_REG(0x0084) -#define ZD_CR34 CTL_REG(0x0088) -#define ZD_CR35 CTL_REG(0x008C) -#define ZD_CR36 CTL_REG(0x0090) -#define ZD_CR37 CTL_REG(0x0094) -#define ZD_CR38 CTL_REG(0x0098) -#define ZD_CR39 CTL_REG(0x009C) -#define ZD_CR40 CTL_REG(0x00A0) -#define ZD_CR41 CTL_REG(0x00A4) -#define ZD_CR42 CTL_REG(0x00A8) -#define ZD_CR43 CTL_REG(0x00AC) -#define ZD_CR44 CTL_REG(0x00B0) -#define ZD_CR45 CTL_REG(0x00B4) -#define ZD_CR46 CTL_REG(0x00B8) -#define ZD_CR47 CTL_REG(0x00BC) /* CCK baseband gain - * (patch value might be in EEPROM) - */ -#define ZD_CR48 CTL_REG(0x00C0) -#define ZD_CR49 CTL_REG(0x00C4) -#define ZD_CR50 CTL_REG(0x00C8) -#define ZD_CR51 CTL_REG(0x00CC) /* TX power control for RF in - * 6-36M modes - */ -#define ZD_CR52 CTL_REG(0x00D0) /* TX power control for RF in - * 48M mode - */ -#define ZD_CR53 CTL_REG(0x00D4) /* TX power control for RF in - * 54M mode - */ -#define ZD_CR54 CTL_REG(0x00D8) -#define ZD_CR55 CTL_REG(0x00DC) -#define ZD_CR56 CTL_REG(0x00E0) -#define ZD_CR57 CTL_REG(0x00E4) -#define ZD_CR58 CTL_REG(0x00E8) -#define ZD_CR59 CTL_REG(0x00EC) -#define ZD_CR60 CTL_REG(0x00F0) -#define ZD_CR61 CTL_REG(0x00F4) -#define ZD_CR62 CTL_REG(0x00F8) -#define ZD_CR63 CTL_REG(0x00FC) -#define ZD_CR64 CTL_REG(0x0100) -#define ZD_CR65 CTL_REG(0x0104) /* OFDM 54M calibration */ -#define ZD_CR66 CTL_REG(0x0108) /* OFDM 48M calibration */ -#define ZD_CR67 CTL_REG(0x010C) /* OFDM 36M calibration */ -#define ZD_CR68 CTL_REG(0x0110) /* CCK calibration */ -#define ZD_CR69 CTL_REG(0x0114) -#define ZD_CR70 CTL_REG(0x0118) -#define ZD_CR71 CTL_REG(0x011C) -#define ZD_CR72 CTL_REG(0x0120) -#define ZD_CR73 CTL_REG(0x0124) -#define ZD_CR74 CTL_REG(0x0128) -#define ZD_CR75 CTL_REG(0x012C) -#define ZD_CR76 CTL_REG(0x0130) -#define ZD_CR77 CTL_REG(0x0134) -#define ZD_CR78 CTL_REG(0x0138) -#define ZD_CR79 CTL_REG(0x013C) -#define ZD_CR80 CTL_REG(0x0140) -#define ZD_CR81 CTL_REG(0x0144) -#define ZD_CR82 CTL_REG(0x0148) -#define ZD_CR83 CTL_REG(0x014C) -#define ZD_CR84 CTL_REG(0x0150) -#define ZD_CR85 CTL_REG(0x0154) -#define ZD_CR86 CTL_REG(0x0158) -#define ZD_CR87 CTL_REG(0x015C) -#define ZD_CR88 CTL_REG(0x0160) -#define ZD_CR89 CTL_REG(0x0164) -#define ZD_CR90 CTL_REG(0x0168) -#define ZD_CR91 CTL_REG(0x016C) -#define ZD_CR92 CTL_REG(0x0170) -#define ZD_CR93 CTL_REG(0x0174) -#define ZD_CR94 CTL_REG(0x0178) -#define ZD_CR95 CTL_REG(0x017C) -#define ZD_CR96 CTL_REG(0x0180) -#define ZD_CR97 CTL_REG(0x0184) -#define ZD_CR98 CTL_REG(0x0188) -#define ZD_CR99 CTL_REG(0x018C) -#define ZD_CR100 CTL_REG(0x0190) -#define ZD_CR101 CTL_REG(0x0194) -#define ZD_CR102 CTL_REG(0x0198) -#define ZD_CR103 CTL_REG(0x019C) -#define ZD_CR104 CTL_REG(0x01A0) -#define ZD_CR105 CTL_REG(0x01A4) -#define ZD_CR106 CTL_REG(0x01A8) -#define ZD_CR107 CTL_REG(0x01AC) -#define ZD_CR108 CTL_REG(0x01B0) -#define ZD_CR109 CTL_REG(0x01B4) -#define ZD_CR110 CTL_REG(0x01B8) -#define ZD_CR111 CTL_REG(0x01BC) -#define ZD_CR112 CTL_REG(0x01C0) -#define ZD_CR113 CTL_REG(0x01C4) -#define ZD_CR114 CTL_REG(0x01C8) -#define ZD_CR115 CTL_REG(0x01CC) -#define ZD_CR116 CTL_REG(0x01D0) -#define ZD_CR117 CTL_REG(0x01D4) -#define ZD_CR118 CTL_REG(0x01D8) -#define ZD_CR119 CTL_REG(0x01DC) -#define ZD_CR120 CTL_REG(0x01E0) -#define ZD_CR121 CTL_REG(0x01E4) -#define ZD_CR122 CTL_REG(0x01E8) -#define ZD_CR123 CTL_REG(0x01EC) -#define ZD_CR124 CTL_REG(0x01F0) -#define ZD_CR125 CTL_REG(0x01F4) -#define ZD_CR126 CTL_REG(0x01F8) -#define ZD_CR127 CTL_REG(0x01FC) -#define ZD_CR128 CTL_REG(0x0200) -#define ZD_CR129 CTL_REG(0x0204) -#define ZD_CR130 CTL_REG(0x0208) -#define ZD_CR131 CTL_REG(0x020C) -#define ZD_CR132 CTL_REG(0x0210) -#define ZD_CR133 CTL_REG(0x0214) -#define ZD_CR134 CTL_REG(0x0218) -#define ZD_CR135 CTL_REG(0x021C) -#define ZD_CR136 CTL_REG(0x0220) -#define ZD_CR137 CTL_REG(0x0224) -#define ZD_CR138 CTL_REG(0x0228) -#define ZD_CR139 CTL_REG(0x022C) -#define ZD_CR140 CTL_REG(0x0230) -#define ZD_CR141 CTL_REG(0x0234) -#define ZD_CR142 CTL_REG(0x0238) -#define ZD_CR143 CTL_REG(0x023C) -#define ZD_CR144 CTL_REG(0x0240) -#define ZD_CR145 CTL_REG(0x0244) -#define ZD_CR146 CTL_REG(0x0248) -#define ZD_CR147 CTL_REG(0x024C) -#define ZD_CR148 CTL_REG(0x0250) -#define ZD_CR149 CTL_REG(0x0254) -#define ZD_CR150 CTL_REG(0x0258) -#define ZD_CR151 CTL_REG(0x025C) -#define ZD_CR152 CTL_REG(0x0260) -#define ZD_CR153 CTL_REG(0x0264) -#define ZD_CR154 CTL_REG(0x0268) -#define ZD_CR155 CTL_REG(0x026C) -#define ZD_CR156 CTL_REG(0x0270) -#define ZD_CR157 CTL_REG(0x0274) -#define ZD_CR158 CTL_REG(0x0278) -#define ZD_CR159 CTL_REG(0x027C) -#define ZD_CR160 CTL_REG(0x0280) -#define ZD_CR161 CTL_REG(0x0284) -#define ZD_CR162 CTL_REG(0x0288) -#define ZD_CR163 CTL_REG(0x028C) -#define ZD_CR164 CTL_REG(0x0290) -#define ZD_CR165 CTL_REG(0x0294) -#define ZD_CR166 CTL_REG(0x0298) -#define ZD_CR167 CTL_REG(0x029C) -#define ZD_CR168 CTL_REG(0x02A0) -#define ZD_CR169 CTL_REG(0x02A4) -#define ZD_CR170 CTL_REG(0x02A8) -#define ZD_CR171 CTL_REG(0x02AC) -#define ZD_CR172 CTL_REG(0x02B0) -#define ZD_CR173 CTL_REG(0x02B4) -#define ZD_CR174 CTL_REG(0x02B8) -#define ZD_CR175 CTL_REG(0x02BC) -#define ZD_CR176 CTL_REG(0x02C0) -#define ZD_CR177 CTL_REG(0x02C4) -#define ZD_CR178 CTL_REG(0x02C8) -#define ZD_CR179 CTL_REG(0x02CC) -#define ZD_CR180 CTL_REG(0x02D0) -#define ZD_CR181 CTL_REG(0x02D4) -#define ZD_CR182 CTL_REG(0x02D8) -#define ZD_CR183 CTL_REG(0x02DC) -#define ZD_CR184 CTL_REG(0x02E0) -#define ZD_CR185 CTL_REG(0x02E4) -#define ZD_CR186 CTL_REG(0x02E8) -#define ZD_CR187 CTL_REG(0x02EC) -#define ZD_CR188 CTL_REG(0x02F0) -#define ZD_CR189 CTL_REG(0x02F4) -#define ZD_CR190 CTL_REG(0x02F8) -#define ZD_CR191 CTL_REG(0x02FC) -#define ZD_CR192 CTL_REG(0x0300) -#define ZD_CR193 CTL_REG(0x0304) -#define ZD_CR194 CTL_REG(0x0308) -#define ZD_CR195 CTL_REG(0x030C) -#define ZD_CR196 CTL_REG(0x0310) -#define ZD_CR197 CTL_REG(0x0314) -#define ZD_CR198 CTL_REG(0x0318) -#define ZD_CR199 CTL_REG(0x031C) -#define ZD_CR200 CTL_REG(0x0320) -#define ZD_CR201 CTL_REG(0x0324) -#define ZD_CR202 CTL_REG(0x0328) -#define ZD_CR203 CTL_REG(0x032C) /* I2C bus template value & flash - * control - */ -#define ZD_CR204 CTL_REG(0x0330) -#define ZD_CR205 CTL_REG(0x0334) -#define ZD_CR206 CTL_REG(0x0338) -#define ZD_CR207 CTL_REG(0x033C) -#define ZD_CR208 CTL_REG(0x0340) -#define ZD_CR209 CTL_REG(0x0344) -#define ZD_CR210 CTL_REG(0x0348) -#define ZD_CR211 CTL_REG(0x034C) -#define ZD_CR212 CTL_REG(0x0350) -#define ZD_CR213 CTL_REG(0x0354) -#define ZD_CR214 CTL_REG(0x0358) -#define ZD_CR215 CTL_REG(0x035C) -#define ZD_CR216 CTL_REG(0x0360) -#define ZD_CR217 CTL_REG(0x0364) -#define ZD_CR218 CTL_REG(0x0368) -#define ZD_CR219 CTL_REG(0x036C) -#define ZD_CR220 CTL_REG(0x0370) -#define ZD_CR221 CTL_REG(0x0374) -#define ZD_CR222 CTL_REG(0x0378) -#define ZD_CR223 CTL_REG(0x037C) -#define ZD_CR224 CTL_REG(0x0380) -#define ZD_CR225 CTL_REG(0x0384) -#define ZD_CR226 CTL_REG(0x0388) -#define ZD_CR227 CTL_REG(0x038C) -#define ZD_CR228 CTL_REG(0x0390) -#define ZD_CR229 CTL_REG(0x0394) -#define ZD_CR230 CTL_REG(0x0398) -#define ZD_CR231 CTL_REG(0x039C) -#define ZD_CR232 CTL_REG(0x03A0) -#define ZD_CR233 CTL_REG(0x03A4) -#define ZD_CR234 CTL_REG(0x03A8) -#define ZD_CR235 CTL_REG(0x03AC) -#define ZD_CR236 CTL_REG(0x03B0) - -#define ZD_CR240 CTL_REG(0x03C0) -/* bit 7: host-controlled RF register writes - * ZD_CR241-ZD_CR245: for hardware controlled writing of RF bits, not needed for - * USB - */ -#define ZD_CR241 CTL_REG(0x03C4) -#define ZD_CR242 CTL_REG(0x03C8) -#define ZD_CR243 CTL_REG(0x03CC) -#define ZD_CR244 CTL_REG(0x03D0) -#define ZD_CR245 CTL_REG(0x03D4) - -#define ZD_CR251 CTL_REG(0x03EC) /* only used for activation and - * deactivation of Airoha RFs AL2230 - * and AL7230B - */ -#define ZD_CR252 CTL_REG(0x03F0) -#define ZD_CR253 CTL_REG(0x03F4) -#define ZD_CR254 CTL_REG(0x03F8) -#define ZD_CR255 CTL_REG(0x03FC) - -#define CR_MAX_PHY_REG 255 - -/* Taken from the ZYDAS driver, not all of them are relevant for the ZD1211 - * driver. - */ - -#define CR_RF_IF_CLK CTL_REG(0x0400) -#define CR_RF_IF_DATA CTL_REG(0x0404) -#define CR_PE1_PE2 CTL_REG(0x0408) -#define CR_PE2_DLY CTL_REG(0x040C) -#define CR_LE1 CTL_REG(0x0410) -#define CR_LE2 CTL_REG(0x0414) -/* Seems to enable/disable GPI (General Purpose IO?) */ -#define CR_GPI_EN CTL_REG(0x0418) -#define CR_RADIO_PD CTL_REG(0x042C) -#define CR_RF2948_PD CTL_REG(0x042C) -#define CR_ENABLE_PS_MANUAL_AGC CTL_REG(0x043C) -#define CR_CONFIG_PHILIPS CTL_REG(0x0440) -#define CR_SA2400_SER_AP CTL_REG(0x0444) -#define CR_I2C_WRITE CTL_REG(0x0444) -#define CR_SA2400_SER_RP CTL_REG(0x0448) -#define CR_RADIO_PE CTL_REG(0x0458) -#define CR_RST_BUS_MASTER CTL_REG(0x045C) -#define CR_RFCFG CTL_REG(0x0464) -#define CR_HSTSCHG CTL_REG(0x046C) -#define CR_PHY_ON CTL_REG(0x0474) -#define CR_RX_DELAY CTL_REG(0x0478) -#define CR_RX_PE_DELAY CTL_REG(0x047C) -#define CR_GPIO_1 CTL_REG(0x0490) -#define CR_GPIO_2 CTL_REG(0x0494) -#define CR_EncryBufMux CTL_REG(0x04A8) -#define CR_PS_CTRL CTL_REG(0x0500) -#define CR_ADDA_PWR_DWN CTL_REG(0x0504) -#define CR_ADDA_MBIAS_WARMTIME CTL_REG(0x0508) -#define CR_MAC_PS_STATE CTL_REG(0x050C) - -#define CR_INTERRUPT CTL_REG(0x0510) -#define INT_TX_COMPLETE (1 << 0) -#define INT_RX_COMPLETE (1 << 1) -#define INT_RETRY_FAIL (1 << 2) -#define INT_WAKEUP (1 << 3) -#define INT_DTIM_NOTIFY (1 << 5) -#define INT_CFG_NEXT_BCN (1 << 6) -#define INT_BUS_ABORT (1 << 7) -#define INT_TX_FIFO_READY (1 << 8) -#define INT_UART (1 << 9) -#define INT_TX_COMPLETE_EN (1 << 16) -#define INT_RX_COMPLETE_EN (1 << 17) -#define INT_RETRY_FAIL_EN (1 << 18) -#define INT_WAKEUP_EN (1 << 19) -#define INT_DTIM_NOTIFY_EN (1 << 21) -#define INT_CFG_NEXT_BCN_EN (1 << 22) -#define INT_BUS_ABORT_EN (1 << 23) -#define INT_TX_FIFO_READY_EN (1 << 24) -#define INT_UART_EN (1 << 25) - -#define CR_TSF_LOW_PART CTL_REG(0x0514) -#define CR_TSF_HIGH_PART CTL_REG(0x0518) - -/* Following three values are in time units (1024us) - * Following condition must be met: - * atim < tbtt < bcn - */ -#define CR_ATIM_WND_PERIOD CTL_REG(0x051C) -#define CR_BCN_INTERVAL CTL_REG(0x0520) -#define CR_PRE_TBTT CTL_REG(0x0524) -/* in units of TU(1024us) */ - -/* for UART support */ -#define CR_UART_RBR_THR_DLL CTL_REG(0x0540) -#define CR_UART_DLM_IER CTL_REG(0x0544) -#define CR_UART_IIR_FCR CTL_REG(0x0548) -#define CR_UART_LCR CTL_REG(0x054c) -#define CR_UART_MCR CTL_REG(0x0550) -#define CR_UART_LSR CTL_REG(0x0554) -#define CR_UART_MSR CTL_REG(0x0558) -#define CR_UART_ECR CTL_REG(0x055c) -#define CR_UART_STATUS CTL_REG(0x0560) - -#define CR_PCI_TX_ADDR_P1 CTL_REG(0x0600) -#define CR_PCI_TX_AddR_P2 CTL_REG(0x0604) -#define CR_PCI_RX_AddR_P1 CTL_REG(0x0608) -#define CR_PCI_RX_AddR_P2 CTL_REG(0x060C) - -/* must be overwritten if custom MAC address will be used */ -#define CR_MAC_ADDR_P1 CTL_REG(0x0610) -#define CR_MAC_ADDR_P2 CTL_REG(0x0614) -#define CR_BSSID_P1 CTL_REG(0x0618) -#define CR_BSSID_P2 CTL_REG(0x061C) -#define CR_BCN_PLCP_CFG CTL_REG(0x0620) - -/* Group hash table for filtering incoming packets. - * - * The group hash table is 64 bit large and split over two parts. The first - * part is the lower part. The upper 6 bits of the last byte of the target - * address are used as index. Packets are received if the hash table bit is - * set. This is used for multicast handling, but for broadcasts (address - * ff:ff:ff:ff:ff:ff) the highest bit in the second table must also be set. - */ -#define CR_GROUP_HASH_P1 CTL_REG(0x0624) -#define CR_GROUP_HASH_P2 CTL_REG(0x0628) - -#define CR_RX_TIMEOUT CTL_REG(0x062C) - -/* Basic rates supported by the BSS. When producing ACK or CTS messages, the - * device will use a rate in this table that is less than or equal to the rate - * of the incoming frame which prompted the response. */ -#define CR_BASIC_RATE_TBL CTL_REG(0x0630) -#define CR_RATE_1M (1 << 0) /* 802.11b */ -#define CR_RATE_2M (1 << 1) /* 802.11b */ -#define CR_RATE_5_5M (1 << 2) /* 802.11b */ -#define CR_RATE_11M (1 << 3) /* 802.11b */ -#define CR_RATE_6M (1 << 8) /* 802.11g */ -#define CR_RATE_9M (1 << 9) /* 802.11g */ -#define CR_RATE_12M (1 << 10) /* 802.11g */ -#define CR_RATE_18M (1 << 11) /* 802.11g */ -#define CR_RATE_24M (1 << 12) /* 802.11g */ -#define CR_RATE_36M (1 << 13) /* 802.11g */ -#define CR_RATE_48M (1 << 14) /* 802.11g */ -#define CR_RATE_54M (1 << 15) /* 802.11g */ -#define CR_RATES_80211G 0xff00 -#define CR_RATES_80211B 0x000f - -/* Mandatory rates required in the BSS. When producing ACK or CTS messages, if - * the device could not find an appropriate rate in CR_BASIC_RATE_TBL, it will - * look for a rate in this table that is less than or equal to the rate of - * the incoming frame. */ -#define CR_MANDATORY_RATE_TBL CTL_REG(0x0634) -#define CR_RTS_CTS_RATE CTL_REG(0x0638) - -/* These are all bit indexes in CR_RTS_CTS_RATE, so remember to shift. */ -#define RTSCTS_SH_RTS_RATE 0 -#define RTSCTS_SH_EXP_CTS_RATE 4 -#define RTSCTS_SH_RTS_MOD_TYPE 8 -#define RTSCTS_SH_RTS_PMB_TYPE 9 -#define RTSCTS_SH_CTS_RATE 16 -#define RTSCTS_SH_CTS_MOD_TYPE 24 -#define RTSCTS_SH_CTS_PMB_TYPE 25 - -#define CR_WEP_PROTECT CTL_REG(0x063C) -#define CR_RX_THRESHOLD CTL_REG(0x0640) - -/* register for controlling the LEDS */ -#define CR_LED CTL_REG(0x0644) -/* masks for controlling LEDs */ -#define LED1 (1 << 8) -#define LED2 (1 << 9) -#define LED_SW (1 << 10) - -/* Seems to indicate that the configuration is over. - */ -#define CR_AFTER_PNP CTL_REG(0x0648) -#define CR_ACK_TIME_80211 CTL_REG(0x0658) - -#define CR_RX_OFFSET CTL_REG(0x065c) - -#define CR_BCN_LENGTH CTL_REG(0x0664) -#define CR_PHY_DELAY CTL_REG(0x066C) -#define CR_BCN_FIFO CTL_REG(0x0670) -#define CR_SNIFFER_ON CTL_REG(0x0674) - -#define CR_ENCRYPTION_TYPE CTL_REG(0x0678) -#define NO_WEP 0 -#define WEP64 1 -#define WEP128 5 -#define WEP256 6 -#define ENC_SNIFFER 8 - -#define CR_ZD1211_RETRY_MAX CTL_REG(0x067C) - -#define CR_REG1 CTL_REG(0x0680) -/* Setting the bit UNLOCK_PHY_REGS disallows the write access to physical - * registers, so one could argue it is a LOCK bit. But calling it - * LOCK_PHY_REGS makes it confusing. - */ -#define UNLOCK_PHY_REGS (1 << 7) - -#define CR_DEVICE_STATE CTL_REG(0x0684) -#define CR_UNDERRUN_CNT CTL_REG(0x0688) - -#define CR_RX_FILTER CTL_REG(0x068c) -#define RX_FILTER_ASSOC_REQUEST (1 << 0) -#define RX_FILTER_ASSOC_RESPONSE (1 << 1) -#define RX_FILTER_REASSOC_REQUEST (1 << 2) -#define RX_FILTER_REASSOC_RESPONSE (1 << 3) -#define RX_FILTER_PROBE_REQUEST (1 << 4) -#define RX_FILTER_PROBE_RESPONSE (1 << 5) -/* bits 6 and 7 reserved */ -#define RX_FILTER_BEACON (1 << 8) -#define RX_FILTER_ATIM (1 << 9) -#define RX_FILTER_DISASSOC (1 << 10) -#define RX_FILTER_AUTH (1 << 11) -#define RX_FILTER_DEAUTH (1 << 12) -#define RX_FILTER_PSPOLL (1 << 26) -#define RX_FILTER_RTS (1 << 27) -#define RX_FILTER_CTS (1 << 28) -#define RX_FILTER_ACK (1 << 29) -#define RX_FILTER_CFEND (1 << 30) -#define RX_FILTER_CFACK (1 << 31) - -/* Enable bits for all frames you are interested in. */ -#define STA_RX_FILTER (RX_FILTER_ASSOC_REQUEST | RX_FILTER_ASSOC_RESPONSE | \ - RX_FILTER_REASSOC_REQUEST | RX_FILTER_REASSOC_RESPONSE | \ - RX_FILTER_PROBE_REQUEST | RX_FILTER_PROBE_RESPONSE | \ - (0x3 << 6) /* vendor driver sets these reserved bits */ | \ - RX_FILTER_BEACON | RX_FILTER_ATIM | RX_FILTER_DISASSOC | \ - RX_FILTER_AUTH | RX_FILTER_DEAUTH | \ - (0x7 << 13) /* vendor driver sets these reserved bits */ | \ - RX_FILTER_PSPOLL | RX_FILTER_ACK) /* 0x2400ffff */ - -#define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \ - RX_FILTER_CFEND | RX_FILTER_CFACK) - -#define BCN_MODE_AP 0x1000000 -#define BCN_MODE_IBSS 0x2000000 - -/* Monitor mode sets filter to 0xfffff */ - -#define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690) -#define CR_BCN_FIFO_SEMAPHORE CTL_REG(0x0694) - -#define CR_IFS_VALUE CTL_REG(0x0698) -#define IFS_VALUE_DIFS_SH 0 -#define IFS_VALUE_EIFS_SH 12 -#define IFS_VALUE_SIFS_SH 24 -#define IFS_VALUE_DEFAULT (( 50 << IFS_VALUE_DIFS_SH) | \ - (1148 << IFS_VALUE_EIFS_SH) | \ - ( 10 << IFS_VALUE_SIFS_SH)) - -#define CR_RX_TIME_OUT CTL_REG(0x069C) -#define CR_TOTAL_RX_FRM CTL_REG(0x06A0) -#define CR_CRC32_CNT CTL_REG(0x06A4) -#define CR_CRC16_CNT CTL_REG(0x06A8) -#define CR_DECRYPTION_ERR_UNI CTL_REG(0x06AC) -#define CR_RX_FIFO_OVERRUN CTL_REG(0x06B0) - -#define CR_DECRYPTION_ERR_MUL CTL_REG(0x06BC) - -#define CR_NAV_CNT CTL_REG(0x06C4) -#define CR_NAV_CCA CTL_REG(0x06C8) -#define CR_RETRY_CNT CTL_REG(0x06CC) - -#define CR_READ_TCB_ADDR CTL_REG(0x06E8) -#define CR_READ_RFD_ADDR CTL_REG(0x06EC) -#define CR_CWMIN_CWMAX CTL_REG(0x06F0) -#define CR_TOTAL_TX_FRM CTL_REG(0x06F4) - -/* CAM: Continuous Access Mode (power management) */ -#define CR_CAM_MODE CTL_REG(0x0700) -#define MODE_IBSS 0x0 -#define MODE_AP 0x1 -#define MODE_STA 0x2 -#define MODE_AP_WDS 0x3 - -#define CR_CAM_ROLL_TB_LOW CTL_REG(0x0704) -#define CR_CAM_ROLL_TB_HIGH CTL_REG(0x0708) -#define CR_CAM_ADDRESS CTL_REG(0x070C) -#define CR_CAM_DATA CTL_REG(0x0710) - -#define CR_ROMDIR CTL_REG(0x0714) - -#define CR_DECRY_ERR_FLG_LOW CTL_REG(0x0714) -#define CR_DECRY_ERR_FLG_HIGH CTL_REG(0x0718) - -#define CR_WEPKEY0 CTL_REG(0x0720) -#define CR_WEPKEY1 CTL_REG(0x0724) -#define CR_WEPKEY2 CTL_REG(0x0728) -#define CR_WEPKEY3 CTL_REG(0x072C) -#define CR_WEPKEY4 CTL_REG(0x0730) -#define CR_WEPKEY5 CTL_REG(0x0734) -#define CR_WEPKEY6 CTL_REG(0x0738) -#define CR_WEPKEY7 CTL_REG(0x073C) -#define CR_WEPKEY8 CTL_REG(0x0740) -#define CR_WEPKEY9 CTL_REG(0x0744) -#define CR_WEPKEY10 CTL_REG(0x0748) -#define CR_WEPKEY11 CTL_REG(0x074C) -#define CR_WEPKEY12 CTL_REG(0x0750) -#define CR_WEPKEY13 CTL_REG(0x0754) -#define CR_WEPKEY14 CTL_REG(0x0758) -#define CR_WEPKEY15 CTL_REG(0x075c) -#define CR_TKIP_MODE CTL_REG(0x0760) - -#define CR_EEPROM_PROTECT0 CTL_REG(0x0758) -#define CR_EEPROM_PROTECT1 CTL_REG(0x075C) - -#define CR_DBG_FIFO_RD CTL_REG(0x0800) -#define CR_DBG_SELECT CTL_REG(0x0804) -#define CR_FIFO_Length CTL_REG(0x0808) - - -#define CR_RSSI_MGC CTL_REG(0x0810) - -#define CR_PON CTL_REG(0x0818) -#define CR_RX_ON CTL_REG(0x081C) -#define CR_TX_ON CTL_REG(0x0820) -#define CR_CHIP_EN CTL_REG(0x0824) -#define CR_LO_SW CTL_REG(0x0828) -#define CR_TXRX_SW CTL_REG(0x082C) -#define CR_S_MD CTL_REG(0x0830) - -#define CR_USB_DEBUG_PORT CTL_REG(0x0888) -#define CR_ZD1211B_CWIN_MAX_MIN_AC0 CTL_REG(0x0b00) -#define CR_ZD1211B_CWIN_MAX_MIN_AC1 CTL_REG(0x0b04) -#define CR_ZD1211B_CWIN_MAX_MIN_AC2 CTL_REG(0x0b08) -#define CR_ZD1211B_CWIN_MAX_MIN_AC3 CTL_REG(0x0b0c) -#define CR_ZD1211B_AIFS_CTL1 CTL_REG(0x0b10) -#define CR_ZD1211B_AIFS_CTL2 CTL_REG(0x0b14) -#define CR_ZD1211B_TXOP CTL_REG(0x0b20) -#define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28) - -/* Value for CR_ZD1211_RETRY_MAX & CR_ZD1211B_RETRY_MAX. Vendor driver uses 2, - * we use 0. The first rate is tried (count+2), then all next rates are tried - * twice, until 1 Mbits is tried. */ -#define ZD1211_RETRY_COUNT 0 -#define ZD1211B_RETRY_COUNT \ - (ZD1211_RETRY_COUNT << 0)| \ - (ZD1211_RETRY_COUNT << 8)| \ - (ZD1211_RETRY_COUNT << 16)| \ - (ZD1211_RETRY_COUNT << 24) - -/* Used to detect PLL lock */ -#define UW2453_INTR_REG ((zd_addr_t)0x85c1) - -#define CWIN_SIZE 0x007f043f - - -#define HWINT_ENABLED \ - (INT_TX_COMPLETE_EN| \ - INT_RX_COMPLETE_EN| \ - INT_RETRY_FAIL_EN| \ - INT_WAKEUP_EN| \ - INT_CFG_NEXT_BCN_EN) - -#define HWINT_DISABLED 0 - -#define E2P_PWR_INT_GUARD 8 -#define E2P_CHANNEL_COUNT 14 - -/* If you compare this addresses with the ZYDAS orignal driver, please notify - * that we use word mapping for the EEPROM. - */ - -/* - * Upper 16 bit contains the regulatory domain. - */ -#define E2P_SUBID E2P_DATA(0x00) -#define E2P_POD E2P_DATA(0x02) -#define E2P_MAC_ADDR_P1 E2P_DATA(0x04) -#define E2P_MAC_ADDR_P2 E2P_DATA(0x06) -#define E2P_PWR_CAL_VALUE1 E2P_DATA(0x08) -#define E2P_PWR_CAL_VALUE2 E2P_DATA(0x0a) -#define E2P_PWR_CAL_VALUE3 E2P_DATA(0x0c) -#define E2P_PWR_CAL_VALUE4 E2P_DATA(0x0e) -#define E2P_PWR_INT_VALUE1 E2P_DATA(0x10) -#define E2P_PWR_INT_VALUE2 E2P_DATA(0x12) -#define E2P_PWR_INT_VALUE3 E2P_DATA(0x14) -#define E2P_PWR_INT_VALUE4 E2P_DATA(0x16) - -/* Contains a bit for each allowed channel. It gives for Europe (ETSI 0x30) - * also only 11 channels. */ -#define E2P_ALLOWED_CHANNEL E2P_DATA(0x18) - -#define E2P_DEVICE_VER E2P_DATA(0x20) -#define E2P_PHY_REG E2P_DATA(0x25) -#define E2P_36M_CAL_VALUE1 E2P_DATA(0x28) -#define E2P_36M_CAL_VALUE2 E2P_DATA(0x2a) -#define E2P_36M_CAL_VALUE3 E2P_DATA(0x2c) -#define E2P_36M_CAL_VALUE4 E2P_DATA(0x2e) -#define E2P_11A_INT_VALUE1 E2P_DATA(0x30) -#define E2P_11A_INT_VALUE2 E2P_DATA(0x32) -#define E2P_11A_INT_VALUE3 E2P_DATA(0x34) -#define E2P_11A_INT_VALUE4 E2P_DATA(0x36) -#define E2P_48M_CAL_VALUE1 E2P_DATA(0x38) -#define E2P_48M_CAL_VALUE2 E2P_DATA(0x3a) -#define E2P_48M_CAL_VALUE3 E2P_DATA(0x3c) -#define E2P_48M_CAL_VALUE4 E2P_DATA(0x3e) -#define E2P_48M_INT_VALUE1 E2P_DATA(0x40) -#define E2P_48M_INT_VALUE2 E2P_DATA(0x42) -#define E2P_48M_INT_VALUE3 E2P_DATA(0x44) -#define E2P_48M_INT_VALUE4 E2P_DATA(0x46) -#define E2P_54M_CAL_VALUE1 E2P_DATA(0x48) /* ??? */ -#define E2P_54M_CAL_VALUE2 E2P_DATA(0x4a) -#define E2P_54M_CAL_VALUE3 E2P_DATA(0x4c) -#define E2P_54M_CAL_VALUE4 E2P_DATA(0x4e) -#define E2P_54M_INT_VALUE1 E2P_DATA(0x50) -#define E2P_54M_INT_VALUE2 E2P_DATA(0x52) -#define E2P_54M_INT_VALUE3 E2P_DATA(0x54) -#define E2P_54M_INT_VALUE4 E2P_DATA(0x56) - -/* This word contains the base address of the FW_REG_ registers below */ -#define FWRAW_REGS_ADDR FWRAW_DATA(0x1d) - -/* All 16 bit values, offset from the address in FWRAW_REGS_ADDR */ -enum { - FW_REG_FIRMWARE_VER = 0, - /* non-zero if USB high speed connection */ - FW_REG_USB_SPEED = 1, - FW_REG_FIX_TX_RATE = 2, - /* Seems to be able to control LEDs over the firmware */ - FW_REG_LED_LINK_STATUS = 3, - FW_REG_SOFT_RESET = 4, - FW_REG_FLASH_CHK = 5, -}; - -/* Values for FW_LINK_STATUS */ -#define FW_LINK_OFF 0x0 -#define FW_LINK_TX 0x1 -/* 0x2 - link led on? */ - -enum { - /* indices for ofdm_cal_values */ - OFDM_36M_INDEX = 0, - OFDM_48M_INDEX = 1, - OFDM_54M_INDEX = 2, -}; - -struct zd_chip { - struct zd_usb usb; - struct zd_rf rf; - struct mutex mutex; - /* Base address of FW_REG_ registers */ - zd_addr_t fw_regs_base; - /* EepSetPoint in the vendor driver */ - u8 pwr_cal_values[E2P_CHANNEL_COUNT]; - /* integration values in the vendor driver */ - u8 pwr_int_values[E2P_CHANNEL_COUNT]; - /* SetPointOFDM in the vendor driver */ - u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT]; - u16 link_led; - unsigned int pa_type:4, - patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1, - new_phy_layout:1, al2230s_bit:1, - supports_tx_led:1; -}; - -static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb) -{ - return container_of(usb, struct zd_chip, usb); -} - -static inline struct zd_chip *zd_rf_to_chip(struct zd_rf *rf) -{ - return container_of(rf, struct zd_chip, rf); -} - -#define zd_chip_dev(chip) (&(chip)->usb.intf->dev) - -void zd_chip_init(struct zd_chip *chip, - struct ieee80211_hw *hw, - struct usb_interface *intf); -void zd_chip_clear(struct zd_chip *chip); -int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr); -int zd_chip_init_hw(struct zd_chip *chip); -int zd_chip_reset(struct zd_chip *chip); - -static inline int zd_chip_is_zd1211b(struct zd_chip *chip) -{ - return chip->usb.is_zd1211b; -} - -static inline int zd_ioread16v_locked(struct zd_chip *chip, u16 *values, - const zd_addr_t *addresses, - unsigned int count) -{ - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_usb_ioread16v(&chip->usb, values, addresses, count); -} - -static inline int zd_ioread16_locked(struct zd_chip *chip, u16 *value, - const zd_addr_t addr) -{ - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_usb_ioread16(&chip->usb, value, addr); -} - -int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, - const zd_addr_t *addresses, unsigned int count); - -static inline int zd_ioread32_locked(struct zd_chip *chip, u32 *value, - const zd_addr_t addr) -{ - return zd_ioread32v_locked(chip, value, &addr, 1); -} - -static inline int zd_iowrite16_locked(struct zd_chip *chip, u16 value, - zd_addr_t addr) -{ - struct zd_ioreq16 ioreq; - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - ioreq.addr = addr; - ioreq.value = value; - - return zd_usb_iowrite16v(&chip->usb, &ioreq, 1); -} - -int zd_iowrite16a_locked(struct zd_chip *chip, - const struct zd_ioreq16 *ioreqs, unsigned int count); - -int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, - unsigned int count); - -static inline int zd_iowrite32_locked(struct zd_chip *chip, u32 value, - zd_addr_t addr) -{ - struct zd_ioreq32 ioreq; - - ioreq.addr = addr; - ioreq.value = value; - - return _zd_iowrite32v_locked(chip, &ioreq, 1); -} - -int zd_iowrite32a_locked(struct zd_chip *chip, - const struct zd_ioreq32 *ioreqs, unsigned int count); - -static inline int zd_rfwrite_locked(struct zd_chip *chip, u32 value, u8 bits) -{ - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_usb_rfwrite(&chip->usb, value, bits); -} - -int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value); - -int zd_rfwritev_locked(struct zd_chip *chip, - const u32* values, unsigned int count, u8 bits); -int zd_rfwritev_cr_locked(struct zd_chip *chip, - const u32* values, unsigned int count); - -/* Locking functions for reading and writing registers. - * The different parameters are intentional. - */ -int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value); -int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value); -int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value); -int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value); -int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses, - u32 *values, unsigned int count); -int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, - unsigned int count); - -int zd_chip_set_channel(struct zd_chip *chip, u8 channel); -static inline u8 _zd_chip_get_channel(struct zd_chip *chip) -{ - return chip->rf.channel; -} -u8 zd_chip_get_channel(struct zd_chip *chip); -int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain); -int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr); -int zd_write_bssid(struct zd_chip *chip, const u8 *bssid); -int zd_chip_switch_radio_on(struct zd_chip *chip); -int zd_chip_switch_radio_off(struct zd_chip *chip); -int zd_chip_enable_int(struct zd_chip *chip); -void zd_chip_disable_int(struct zd_chip *chip); -int zd_chip_enable_rxtx(struct zd_chip *chip); -void zd_chip_disable_rxtx(struct zd_chip *chip); -int zd_chip_enable_hwint(struct zd_chip *chip); -int zd_chip_disable_hwint(struct zd_chip *chip); -int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel); -int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, int preamble); - -static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type) -{ - return zd_ioread32(chip, CR_ENCRYPTION_TYPE, type); -} - -static inline int zd_set_encryption_type(struct zd_chip *chip, u32 type) -{ - return zd_iowrite32(chip, CR_ENCRYPTION_TYPE, type); -} - -static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates) -{ - return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates); -} - -int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates); - -int zd_chip_lock_phy_regs(struct zd_chip *chip); -int zd_chip_unlock_phy_regs(struct zd_chip *chip); - -enum led_status { - ZD_LED_OFF = 0, - ZD_LED_SCANNING = 1, - ZD_LED_ASSOCIATED = 2, -}; - -int zd_chip_control_leds(struct zd_chip *chip, enum led_status status); - -int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period, - int type); - -static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) -{ - return zd_ioread32(chip, CR_BCN_INTERVAL, interval); -} - -struct rx_status; - -u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status); - -struct zd_mc_hash { - u32 low; - u32 high; -}; - -static inline void zd_mc_clear(struct zd_mc_hash *hash) -{ - hash->low = 0; - /* The interfaces must always received broadcasts. - * The hash of the broadcast address ff:ff:ff:ff:ff:ff is 63. - */ - hash->high = 0x80000000; -} - -static inline void zd_mc_add_all(struct zd_mc_hash *hash) -{ - hash->low = hash->high = 0xffffffff; -} - -static inline void zd_mc_add_addr(struct zd_mc_hash *hash, u8 *addr) -{ - unsigned int i = addr[5] >> 2; - if (i < 32) { - hash->low |= 1 << i; - } else { - hash->high |= 1 << (i-32); - } -} - -int zd_chip_set_multicast_hash(struct zd_chip *chip, - struct zd_mc_hash *hash); - -u64 zd_chip_get_tsf(struct zd_chip *chip); - -#endif /* _ZD_CHIP_H */ diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h deleted file mode 100644 index 41bd755..0000000 --- a/drivers/net/wireless/zd1211rw/zd_def.h +++ /dev/null @@ -1,69 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _ZD_DEF_H -#define _ZD_DEF_H - -#include <linux/kernel.h> -#include <linux/stringify.h> -#include <linux/device.h> - -typedef u16 __nocast zd_addr_t; - -#define dev_printk_f(level, dev, fmt, args...) \ - dev_printk(level, dev, "%s() " fmt, __func__, ##args) - -#ifdef DEBUG -# define dev_dbg_f(dev, fmt, args...) \ - dev_printk_f(KERN_DEBUG, dev, fmt, ## args) -# define dev_dbg_f_limit(dev, fmt, args...) do { \ - if (net_ratelimit()) \ - dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \ -} while (0) -# define dev_dbg_f_cond(dev, cond, fmt, args...) ({ \ - bool __cond = !!(cond); \ - if (unlikely(__cond)) \ - dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \ -}) -#else -# define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0) -# define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0) -# define dev_dbg_f_cond(dev, cond, fmt, args...) do { (void)(dev); } while (0) -#endif /* DEBUG */ - -#ifdef DEBUG -# define ZD_ASSERT(x) \ -do { \ - if (unlikely(!(x))) { \ - pr_debug("%s:%d ASSERT %s VIOLATED!\n", \ - __FILE__, __LINE__, __stringify(x)); \ - dump_stack(); \ - } \ -} while (0) -#else -# define ZD_ASSERT(x) do { } while (0) -#endif - -#ifdef DEBUG -# define ZD_MEMCLEAR(pointer, size) memset((pointer), 0xff, (size)) -#else -# define ZD_MEMCLEAR(pointer, size) do { } while (0) -#endif - -#endif /* _ZD_DEF_H */ diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c deleted file mode 100644 index e539d9b..0000000 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ /dev/null @@ -1,1550 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.net> - * Copyright (C) 2007-2008 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/slab.h> -#include <linux/usb.h> -#include <linux/jiffies.h> -#include <net/ieee80211_radiotap.h> - -#include "zd_def.h" -#include "zd_chip.h" -#include "zd_mac.h" -#include "zd_rf.h" - -struct zd_reg_alpha2_map { - u32 reg; - char alpha2[2]; -}; - -static struct zd_reg_alpha2_map reg_alpha2_map[] = { - { ZD_REGDOMAIN_FCC, "US" }, - { ZD_REGDOMAIN_IC, "CA" }, - { ZD_REGDOMAIN_ETSI, "DE" }, /* Generic ETSI, use most restrictive */ - { ZD_REGDOMAIN_JAPAN, "JP" }, - { ZD_REGDOMAIN_JAPAN_2, "JP" }, - { ZD_REGDOMAIN_JAPAN_3, "JP" }, - { ZD_REGDOMAIN_SPAIN, "ES" }, - { ZD_REGDOMAIN_FRANCE, "FR" }, -}; - -/* This table contains the hardware specific values for the modulation rates. */ -static const struct ieee80211_rate zd_rates[] = { - { .bitrate = 10, - .hw_value = ZD_CCK_RATE_1M, }, - { .bitrate = 20, - .hw_value = ZD_CCK_RATE_2M, - .hw_value_short = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 55, - .hw_value = ZD_CCK_RATE_5_5M, - .hw_value_short = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 110, - .hw_value = ZD_CCK_RATE_11M, - .hw_value_short = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 60, - .hw_value = ZD_OFDM_RATE_6M, - .flags = 0 }, - { .bitrate = 90, - .hw_value = ZD_OFDM_RATE_9M, - .flags = 0 }, - { .bitrate = 120, - .hw_value = ZD_OFDM_RATE_12M, - .flags = 0 }, - { .bitrate = 180, - .hw_value = ZD_OFDM_RATE_18M, - .flags = 0 }, - { .bitrate = 240, - .hw_value = ZD_OFDM_RATE_24M, - .flags = 0 }, - { .bitrate = 360, - .hw_value = ZD_OFDM_RATE_36M, - .flags = 0 }, - { .bitrate = 480, - .hw_value = ZD_OFDM_RATE_48M, - .flags = 0 }, - { .bitrate = 540, - .hw_value = ZD_OFDM_RATE_54M, - .flags = 0 }, -}; - -/* - * Zydas retry rates table. Each line is listed in the same order as - * in zd_rates[] and contains all the rate used when a packet is sent - * starting with a given rates. Let's consider an example : - * - * "11 Mbits : 4, 3, 2, 1, 0" means : - * - packet is sent using 4 different rates - * - 1st rate is index 3 (ie 11 Mbits) - * - 2nd rate is index 2 (ie 5.5 Mbits) - * - 3rd rate is index 1 (ie 2 Mbits) - * - 4th rate is index 0 (ie 1 Mbits) - */ - -static const struct tx_retry_rate zd_retry_rates[] = { - { /* 1 Mbits */ 1, { 0 }}, - { /* 2 Mbits */ 2, { 1, 0 }}, - { /* 5.5 Mbits */ 3, { 2, 1, 0 }}, - { /* 11 Mbits */ 4, { 3, 2, 1, 0 }}, - { /* 6 Mbits */ 5, { 4, 3, 2, 1, 0 }}, - { /* 9 Mbits */ 6, { 5, 4, 3, 2, 1, 0}}, - { /* 12 Mbits */ 5, { 6, 3, 2, 1, 0 }}, - { /* 18 Mbits */ 6, { 7, 6, 3, 2, 1, 0 }}, - { /* 24 Mbits */ 6, { 8, 6, 3, 2, 1, 0 }}, - { /* 36 Mbits */ 7, { 9, 8, 6, 3, 2, 1, 0 }}, - { /* 48 Mbits */ 8, {10, 9, 8, 6, 3, 2, 1, 0 }}, - { /* 54 Mbits */ 9, {11, 10, 9, 8, 6, 3, 2, 1, 0 }} -}; - -static const struct ieee80211_channel zd_channels[] = { - { .center_freq = 2412, .hw_value = 1 }, - { .center_freq = 2417, .hw_value = 2 }, - { .center_freq = 2422, .hw_value = 3 }, - { .center_freq = 2427, .hw_value = 4 }, - { .center_freq = 2432, .hw_value = 5 }, - { .center_freq = 2437, .hw_value = 6 }, - { .center_freq = 2442, .hw_value = 7 }, - { .center_freq = 2447, .hw_value = 8 }, - { .center_freq = 2452, .hw_value = 9 }, - { .center_freq = 2457, .hw_value = 10 }, - { .center_freq = 2462, .hw_value = 11 }, - { .center_freq = 2467, .hw_value = 12 }, - { .center_freq = 2472, .hw_value = 13 }, - { .center_freq = 2484, .hw_value = 14 }, -}; - -static void housekeeping_init(struct zd_mac *mac); -static void housekeeping_enable(struct zd_mac *mac); -static void housekeeping_disable(struct zd_mac *mac); -static void beacon_init(struct zd_mac *mac); -static void beacon_enable(struct zd_mac *mac); -static void beacon_disable(struct zd_mac *mac); -static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble); -static int zd_mac_config_beacon(struct ieee80211_hw *hw, - struct sk_buff *beacon, bool in_intr); - -static int zd_reg2alpha2(u8 regdomain, char *alpha2) -{ - unsigned int i; - struct zd_reg_alpha2_map *reg_map; - for (i = 0; i < ARRAY_SIZE(reg_alpha2_map); i++) { - reg_map = ®_alpha2_map[i]; - if (regdomain == reg_map->reg) { - alpha2[0] = reg_map->alpha2[0]; - alpha2[1] = reg_map->alpha2[1]; - return 0; - } - } - return 1; -} - -static int zd_check_signal(struct ieee80211_hw *hw, int signal) -{ - struct zd_mac *mac = zd_hw_mac(hw); - - dev_dbg_f_cond(zd_mac_dev(mac), signal < 0 || signal > 100, - "%s: signal value from device not in range 0..100, " - "but %d.\n", __func__, signal); - - if (signal < 0) - signal = 0; - else if (signal > 100) - signal = 100; - - return signal; -} - -int zd_mac_preinit_hw(struct ieee80211_hw *hw) -{ - int r; - u8 addr[ETH_ALEN]; - struct zd_mac *mac = zd_hw_mac(hw); - - r = zd_chip_read_mac_addr_fw(&mac->chip, addr); - if (r) - return r; - - SET_IEEE80211_PERM_ADDR(hw, addr); - - return 0; -} - -int zd_mac_init_hw(struct ieee80211_hw *hw) -{ - int r; - struct zd_mac *mac = zd_hw_mac(hw); - struct zd_chip *chip = &mac->chip; - char alpha2[2]; - u8 default_regdomain; - - r = zd_chip_enable_int(chip); - if (r) - goto out; - r = zd_chip_init_hw(chip); - if (r) - goto disable_int; - - ZD_ASSERT(!irqs_disabled()); - - r = zd_read_regdomain(chip, &default_regdomain); - if (r) - goto disable_int; - spin_lock_irq(&mac->lock); - mac->regdomain = mac->default_regdomain = default_regdomain; - spin_unlock_irq(&mac->lock); - - /* We must inform the device that we are doing encryption/decryption in - * software at the moment. */ - r = zd_set_encryption_type(chip, ENC_SNIFFER); - if (r) - goto disable_int; - - r = zd_reg2alpha2(mac->regdomain, alpha2); - if (r) - goto disable_int; - - r = regulatory_hint(hw->wiphy, alpha2); -disable_int: - zd_chip_disable_int(chip); -out: - return r; -} - -void zd_mac_clear(struct zd_mac *mac) -{ - flush_workqueue(zd_workqueue); - zd_chip_clear(&mac->chip); - ZD_ASSERT(!spin_is_locked(&mac->lock)); - ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); -} - -static int set_rx_filter(struct zd_mac *mac) -{ - unsigned long flags; - u32 filter = STA_RX_FILTER; - - spin_lock_irqsave(&mac->lock, flags); - if (mac->pass_ctrl) - filter |= RX_FILTER_CTRL; - spin_unlock_irqrestore(&mac->lock, flags); - - return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); -} - -static int set_mac_and_bssid(struct zd_mac *mac) -{ - int r; - - if (!mac->vif) - return -1; - - r = zd_write_mac_addr(&mac->chip, mac->vif->addr); - if (r) - return r; - - /* Vendor driver after setting MAC either sets BSSID for AP or - * filter for other modes. - */ - if (mac->type != NL80211_IFTYPE_AP) - return set_rx_filter(mac); - else - return zd_write_bssid(&mac->chip, mac->vif->addr); -} - -static int set_mc_hash(struct zd_mac *mac) -{ - struct zd_mc_hash hash; - zd_mc_clear(&hash); - return zd_chip_set_multicast_hash(&mac->chip, &hash); -} - -int zd_op_start(struct ieee80211_hw *hw) -{ - struct zd_mac *mac = zd_hw_mac(hw); - struct zd_chip *chip = &mac->chip; - struct zd_usb *usb = &chip->usb; - int r; - - if (!usb->initialized) { - r = zd_usb_init_hw(usb); - if (r) - goto out; - } - - r = zd_chip_enable_int(chip); - if (r < 0) - goto out; - - r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); - if (r < 0) - goto disable_int; - r = set_rx_filter(mac); - if (r) - goto disable_int; - r = set_mc_hash(mac); - if (r) - goto disable_int; - - /* Wait after setting the multicast hash table and powering on - * the radio otherwise interface bring up will fail. This matches - * what the vendor driver did. - */ - msleep(10); - - r = zd_chip_switch_radio_on(chip); - if (r < 0) { - dev_err(zd_chip_dev(chip), - "%s: failed to set radio on\n", __func__); - goto disable_int; - } - r = zd_chip_enable_rxtx(chip); - if (r < 0) - goto disable_radio; - r = zd_chip_enable_hwint(chip); - if (r < 0) - goto disable_rxtx; - - housekeeping_enable(mac); - beacon_enable(mac); - set_bit(ZD_DEVICE_RUNNING, &mac->flags); - return 0; -disable_rxtx: - zd_chip_disable_rxtx(chip); -disable_radio: - zd_chip_switch_radio_off(chip); -disable_int: - zd_chip_disable_int(chip); -out: - return r; -} - -void zd_op_stop(struct ieee80211_hw *hw) -{ - struct zd_mac *mac = zd_hw_mac(hw); - struct zd_chip *chip = &mac->chip; - struct sk_buff *skb; - struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue; - - clear_bit(ZD_DEVICE_RUNNING, &mac->flags); - - /* The order here deliberately is a little different from the open() - * method, since we need to make sure there is no opportunity for RX - * frames to be processed by mac80211 after we have stopped it. - */ - - zd_chip_disable_rxtx(chip); - beacon_disable(mac); - housekeeping_disable(mac); - flush_workqueue(zd_workqueue); - - zd_chip_disable_hwint(chip); - zd_chip_switch_radio_off(chip); - zd_chip_disable_int(chip); - - - while ((skb = skb_dequeue(ack_wait_queue))) - dev_kfree_skb_any(skb); -} - -int zd_restore_settings(struct zd_mac *mac) -{ - struct sk_buff *beacon; - struct zd_mc_hash multicast_hash; - unsigned int short_preamble; - int r, beacon_interval, beacon_period; - u8 channel; - - dev_dbg_f(zd_mac_dev(mac), "\n"); - - spin_lock_irq(&mac->lock); - multicast_hash = mac->multicast_hash; - short_preamble = mac->short_preamble; - beacon_interval = mac->beacon.interval; - beacon_period = mac->beacon.period; - channel = mac->channel; - spin_unlock_irq(&mac->lock); - - r = set_mac_and_bssid(mac); - if (r < 0) { - dev_dbg_f(zd_mac_dev(mac), "set_mac_and_bssid failed, %d\n", r); - return r; - } - - r = zd_chip_set_channel(&mac->chip, channel); - if (r < 0) { - dev_dbg_f(zd_mac_dev(mac), "zd_chip_set_channel failed, %d\n", - r); - return r; - } - - set_rts_cts(mac, short_preamble); - - r = zd_chip_set_multicast_hash(&mac->chip, &multicast_hash); - if (r < 0) { - dev_dbg_f(zd_mac_dev(mac), - "zd_chip_set_multicast_hash failed, %d\n", r); - return r; - } - - if (mac->type == NL80211_IFTYPE_MESH_POINT || - mac->type == NL80211_IFTYPE_ADHOC || - mac->type == NL80211_IFTYPE_AP) { - if (mac->vif != NULL) { - beacon = ieee80211_beacon_get(mac->hw, mac->vif); - if (beacon) - zd_mac_config_beacon(mac->hw, beacon, false); - } - - zd_set_beacon_interval(&mac->chip, beacon_interval, - beacon_period, mac->type); - - spin_lock_irq(&mac->lock); - mac->beacon.last_update = jiffies; - spin_unlock_irq(&mac->lock); - } - - return 0; -} - -/** - * zd_mac_tx_status - reports tx status of a packet if required - * @hw - a &struct ieee80211_hw pointer - * @skb - a sk-buffer - * @flags: extra flags to set in the TX status info - * @ackssi: ACK signal strength - * @success - True for successful transmission of the frame - * - * This information calls ieee80211_tx_status_irqsafe() if required by the - * control information. It copies the control information into the status - * information. - * - * If no status information has been requested, the skb is freed. - */ -static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, - int ackssi, struct tx_status *tx_status) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - int i; - int success = 1, retry = 1; - int first_idx; - const struct tx_retry_rate *retries; - - ieee80211_tx_info_clear_status(info); - - if (tx_status) { - success = !tx_status->failure; - retry = tx_status->retry + success; - } - - if (success) { - /* success */ - info->flags |= IEEE80211_TX_STAT_ACK; - } else { - /* failure */ - info->flags &= ~IEEE80211_TX_STAT_ACK; - } - - first_idx = info->status.rates[0].idx; - ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); - retries = &zd_retry_rates[first_idx]; - ZD_ASSERT(1 <= retry && retry <= retries->count); - - info->status.rates[0].idx = retries->rate[0]; - info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1); - - for (i=1; i<IEEE80211_TX_MAX_RATES-1 && i<retry; i++) { - info->status.rates[i].idx = retries->rate[i]; - info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2); - } - for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) { - info->status.rates[i].idx = retries->rate[retry - 1]; - info->status.rates[i].count = 1; // (success ? 1:2); - } - if (i<IEEE80211_TX_MAX_RATES) - info->status.rates[i].idx = -1; /* terminate */ - - info->status.ack_signal = zd_check_signal(hw, ackssi); - ieee80211_tx_status_irqsafe(hw, skb); -} - -/** - * zd_mac_tx_failed - callback for failed frames - * @dev: the mac80211 wireless device - * - * This function is called if a frame couldn't be successfully - * transferred. The first frame from the tx queue, will be selected and - * reported as error to the upper layers. - */ -void zd_mac_tx_failed(struct urb *urb) -{ - struct ieee80211_hw * hw = zd_usb_to_hw(urb->context); - struct zd_mac *mac = zd_hw_mac(hw); - struct sk_buff_head *q = &mac->ack_wait_queue; - struct sk_buff *skb; - struct tx_status *tx_status = (struct tx_status *)urb->transfer_buffer; - unsigned long flags; - int success = !tx_status->failure; - int retry = tx_status->retry + success; - int found = 0; - int i, position = 0; - - q = &mac->ack_wait_queue; - spin_lock_irqsave(&q->lock, flags); - - skb_queue_walk(q, skb) { - struct ieee80211_hdr *tx_hdr; - struct ieee80211_tx_info *info; - int first_idx, final_idx; - const struct tx_retry_rate *retries; - u8 final_rate; - - position ++; - - /* if the hardware reports a failure and we had a 802.11 ACK - * pending, then we skip the first skb when searching for a - * matching frame */ - if (tx_status->failure && mac->ack_pending && - skb_queue_is_first(q, skb)) { - continue; - } - - tx_hdr = (struct ieee80211_hdr *)skb->data; - - /* we skip all frames not matching the reported destination */ - if (unlikely(!ether_addr_equal(tx_hdr->addr1, tx_status->mac))) - continue; - - /* we skip all frames not matching the reported final rate */ - - info = IEEE80211_SKB_CB(skb); - first_idx = info->status.rates[0].idx; - ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates)); - retries = &zd_retry_rates[first_idx]; - if (retry <= 0 || retry > retries->count) - continue; - - final_idx = retries->rate[retry - 1]; - final_rate = zd_rates[final_idx].hw_value; - - if (final_rate != tx_status->rate) { - continue; - } - - found = 1; - break; - } - - if (found) { - for (i=1; i<=position; i++) { - skb = __skb_dequeue(q); - zd_mac_tx_status(hw, skb, - mac->ack_pending ? mac->ack_signal : 0, - i == position ? tx_status : NULL); - mac->ack_pending = 0; - } - } - - spin_unlock_irqrestore(&q->lock, flags); -} - -/** - * zd_mac_tx_to_dev - callback for USB layer - * @skb: a &sk_buff pointer - * @error: error value, 0 if transmission successful - * - * Informs the MAC layer that the frame has successfully transferred to the - * device. If an ACK is required and the transfer to the device has been - * successful, the packets are put on the @ack_wait_queue with - * the control set removed. - */ -void zd_mac_tx_to_dev(struct sk_buff *skb, int error) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_hw *hw = info->rate_driver_data[0]; - struct zd_mac *mac = zd_hw_mac(hw); - - ieee80211_tx_info_clear_status(info); - - skb_pull(skb, sizeof(struct zd_ctrlset)); - if (unlikely(error || - (info->flags & IEEE80211_TX_CTL_NO_ACK))) { - /* - * FIXME : do we need to fill in anything ? - */ - ieee80211_tx_status_irqsafe(hw, skb); - } else { - struct sk_buff_head *q = &mac->ack_wait_queue; - - skb_queue_tail(q, skb); - while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) { - zd_mac_tx_status(hw, skb_dequeue(q), - mac->ack_pending ? mac->ack_signal : 0, - NULL); - mac->ack_pending = 0; - } - } -} - -static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) -{ - /* ZD_PURE_RATE() must be used to remove the modulation type flag of - * the zd-rate values. - */ - static const u8 rate_divisor[] = { - [ZD_PURE_RATE(ZD_CCK_RATE_1M)] = 1, - [ZD_PURE_RATE(ZD_CCK_RATE_2M)] = 2, - /* Bits must be doubled. */ - [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11, - [ZD_PURE_RATE(ZD_CCK_RATE_11M)] = 11, - [ZD_PURE_RATE(ZD_OFDM_RATE_6M)] = 6, - [ZD_PURE_RATE(ZD_OFDM_RATE_9M)] = 9, - [ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12, - [ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18, - [ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24, - [ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36, - [ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48, - [ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54, - }; - - u32 bits = (u32)tx_length * 8; - u32 divisor; - - divisor = rate_divisor[ZD_PURE_RATE(zd_rate)]; - if (divisor == 0) - return -EINVAL; - - switch (zd_rate) { - case ZD_CCK_RATE_5_5M: - bits = (2*bits) + 10; /* round up to the next integer */ - break; - case ZD_CCK_RATE_11M: - if (service) { - u32 t = bits % 11; - *service &= ~ZD_PLCP_SERVICE_LENGTH_EXTENSION; - if (0 < t && t <= 3) { - *service |= ZD_PLCP_SERVICE_LENGTH_EXTENSION; - } - } - bits += 10; /* round up to the next integer */ - break; - } - - return bits/divisor; -} - -static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, - struct ieee80211_hdr *header, - struct ieee80211_tx_info *info) -{ - /* - * CONTROL TODO: - * - if backoff needed, enable bit 0 - * - if burst (backoff not needed) disable bit 0 - */ - - cs->control = 0; - - /* First fragment */ - if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) - cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; - - /* No ACK expected (multicast, etc.) */ - if (info->flags & IEEE80211_TX_CTL_NO_ACK) - cs->control |= ZD_CS_NO_ACK; - - /* PS-POLL */ - if (ieee80211_is_pspoll(header->frame_control)) - cs->control |= ZD_CS_PS_POLL_FRAME; - - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) - cs->control |= ZD_CS_RTS; - - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) - cs->control |= ZD_CS_SELF_CTS; - - /* FIXME: Management frame? */ -} - -static bool zd_mac_match_cur_beacon(struct zd_mac *mac, struct sk_buff *beacon) -{ - if (!mac->beacon.cur_beacon) - return false; - - if (mac->beacon.cur_beacon->len != beacon->len) - return false; - - return !memcmp(beacon->data, mac->beacon.cur_beacon->data, beacon->len); -} - -static void zd_mac_free_cur_beacon_locked(struct zd_mac *mac) -{ - ZD_ASSERT(mutex_is_locked(&mac->chip.mutex)); - - kfree_skb(mac->beacon.cur_beacon); - mac->beacon.cur_beacon = NULL; -} - -static void zd_mac_free_cur_beacon(struct zd_mac *mac) -{ - mutex_lock(&mac->chip.mutex); - zd_mac_free_cur_beacon_locked(mac); - mutex_unlock(&mac->chip.mutex); -} - -static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon, - bool in_intr) -{ - struct zd_mac *mac = zd_hw_mac(hw); - int r, ret, num_cmds, req_pos = 0; - u32 tmp, j = 0; - /* 4 more bytes for tail CRC */ - u32 full_len = beacon->len + 4; - unsigned long end_jiffies, message_jiffies; - struct zd_ioreq32 *ioreqs; - - mutex_lock(&mac->chip.mutex); - - /* Check if hw already has this beacon. */ - if (zd_mac_match_cur_beacon(mac, beacon)) { - r = 0; - goto out_nofree; - } - - /* Alloc memory for full beacon write at once. */ - num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len; - ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL); - if (!ioreqs) { - r = -ENOMEM; - goto out_nofree; - } - - r = zd_iowrite32_locked(&mac->chip, 0, CR_BCN_FIFO_SEMAPHORE); - if (r < 0) - goto out; - r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE); - if (r < 0) - goto release_sema; - if (in_intr && tmp & 0x2) { - r = -EBUSY; - goto release_sema; - } - - end_jiffies = jiffies + HZ / 2; /*~500ms*/ - message_jiffies = jiffies + HZ / 10; /*~100ms*/ - while (tmp & 0x2) { - r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE); - if (r < 0) - goto release_sema; - if (time_is_before_eq_jiffies(message_jiffies)) { - message_jiffies = jiffies + HZ / 10; - dev_err(zd_mac_dev(mac), - "CR_BCN_FIFO_SEMAPHORE not ready\n"); - if (time_is_before_eq_jiffies(end_jiffies)) { - dev_err(zd_mac_dev(mac), - "Giving up beacon config.\n"); - r = -ETIMEDOUT; - goto reset_device; - } - } - msleep(20); - } - - ioreqs[req_pos].addr = CR_BCN_FIFO; - ioreqs[req_pos].value = full_len - 1; - req_pos++; - if (zd_chip_is_zd1211b(&mac->chip)) { - ioreqs[req_pos].addr = CR_BCN_LENGTH; - ioreqs[req_pos].value = full_len - 1; - req_pos++; - } - - for (j = 0 ; j < beacon->len; j++) { - ioreqs[req_pos].addr = CR_BCN_FIFO; - ioreqs[req_pos].value = *((u8 *)(beacon->data + j)); - req_pos++; - } - - for (j = 0; j < 4; j++) { - ioreqs[req_pos].addr = CR_BCN_FIFO; - ioreqs[req_pos].value = 0x0; - req_pos++; - } - - BUG_ON(req_pos != num_cmds); - - r = zd_iowrite32a_locked(&mac->chip, ioreqs, num_cmds); - -release_sema: - /* - * Try very hard to release device beacon semaphore, as otherwise - * device/driver can be left in unusable state. - */ - end_jiffies = jiffies + HZ / 2; /*~500ms*/ - ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE); - while (ret < 0) { - if (in_intr || time_is_before_eq_jiffies(end_jiffies)) { - ret = -ETIMEDOUT; - break; - } - - msleep(20); - ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE); - } - - if (ret < 0) - dev_err(zd_mac_dev(mac), "Could not release " - "CR_BCN_FIFO_SEMAPHORE!\n"); - if (r < 0 || ret < 0) { - if (r >= 0) - r = ret; - - /* We don't know if beacon was written successfully or not, - * so clear current. */ - zd_mac_free_cur_beacon_locked(mac); - - goto out; - } - - /* Beacon has now been written successfully, update current. */ - zd_mac_free_cur_beacon_locked(mac); - mac->beacon.cur_beacon = beacon; - beacon = NULL; - - /* 802.11b/g 2.4G CCK 1Mb - * 802.11a, not yet implemented, uses different values (see GPL vendor - * driver) - */ - r = zd_iowrite32_locked(&mac->chip, 0x00000400 | (full_len << 19), - CR_BCN_PLCP_CFG); -out: - kfree(ioreqs); -out_nofree: - kfree_skb(beacon); - mutex_unlock(&mac->chip.mutex); - - return r; - -reset_device: - zd_mac_free_cur_beacon_locked(mac); - kfree_skb(beacon); - - mutex_unlock(&mac->chip.mutex); - kfree(ioreqs); - - /* semaphore stuck, reset device to avoid fw freeze later */ - dev_warn(zd_mac_dev(mac), "CR_BCN_FIFO_SEMAPHORE stuck, " - "resetting device..."); - usb_queue_reset_device(mac->chip.usb.intf); - - return r; -} - -static int fill_ctrlset(struct zd_mac *mac, - struct sk_buff *skb) -{ - int r; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - unsigned int frag_len = skb->len + FCS_LEN; - unsigned int packet_length; - struct ieee80211_rate *txrate; - struct zd_ctrlset *cs = (struct zd_ctrlset *) - skb_push(skb, sizeof(struct zd_ctrlset)); - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - ZD_ASSERT(frag_len <= 0xffff); - - /* - * Firmware computes the duration itself (for all frames except PSPoll) - * and needs the field set to 0 at input, otherwise firmware messes up - * duration_id and sets bits 14 and 15 on. - */ - if (!ieee80211_is_pspoll(hdr->frame_control)) - hdr->duration_id = 0; - - txrate = ieee80211_get_tx_rate(mac->hw, info); - - cs->modulation = txrate->hw_value; - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - cs->modulation = txrate->hw_value_short; - - cs->tx_length = cpu_to_le16(frag_len); - - cs_set_control(mac, cs, hdr, info); - - packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; - ZD_ASSERT(packet_length <= 0xffff); - /* ZD1211B: Computing the length difference this way, gives us - * flexibility to compute the packet length. - */ - cs->packet_length = cpu_to_le16(zd_chip_is_zd1211b(&mac->chip) ? - packet_length - frag_len : packet_length); - - /* - * CURRENT LENGTH: - * - transmit frame length in microseconds - * - seems to be derived from frame length - * - see Cal_Us_Service() in zdinlinef.h - * - if macp->bTxBurstEnable is enabled, then multiply by 4 - * - bTxBurstEnable is never set in the vendor driver - * - * SERVICE: - * - "for PLCP configuration" - * - always 0 except in some situations at 802.11b 11M - * - see line 53 of zdinlinef.h - */ - cs->service = 0; - r = zd_calc_tx_length_us(&cs->service, ZD_RATE(cs->modulation), - le16_to_cpu(cs->tx_length)); - if (r < 0) - return r; - cs->current_length = cpu_to_le16(r); - cs->next_frame_length = 0; - - return 0; -} - -/** - * zd_op_tx - transmits a network frame to the device - * - * @dev: mac80211 hardware device - * @skb: socket buffer - * @control: the control structure - * - * This function transmit an IEEE 802.11 network frame to the device. The - * control block of the skbuff will be initialized. If necessary the incoming - * mac80211 queues will be stopped. - */ -static void zd_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) -{ - struct zd_mac *mac = zd_hw_mac(hw); - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - int r; - - r = fill_ctrlset(mac, skb); - if (r) - goto fail; - - info->rate_driver_data[0] = hw; - - r = zd_usb_tx(&mac->chip.usb, skb); - if (r) - goto fail; - return; - -fail: - dev_kfree_skb(skb); -} - -/** - * filter_ack - filters incoming packets for acknowledgements - * @dev: the mac80211 device - * @rx_hdr: received header - * @stats: the status for the received packet - * - * This functions looks for ACK packets and tries to match them with the - * frames in the tx queue. If a match is found the frame will be dequeued and - * the upper layers is informed about the successful transmission. If - * mac80211 queues have been stopped and the number of frames still to be - * transmitted is low the queues will be opened again. - * - * Returns 1 if the frame was an ACK, 0 if it was ignored. - */ -static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, - struct ieee80211_rx_status *stats) -{ - struct zd_mac *mac = zd_hw_mac(hw); - struct sk_buff *skb; - struct sk_buff_head *q; - unsigned long flags; - int found = 0; - int i, position = 0; - - if (!ieee80211_is_ack(rx_hdr->frame_control)) - return 0; - - q = &mac->ack_wait_queue; - spin_lock_irqsave(&q->lock, flags); - skb_queue_walk(q, skb) { - struct ieee80211_hdr *tx_hdr; - - position ++; - - if (mac->ack_pending && skb_queue_is_first(q, skb)) - continue; - - tx_hdr = (struct ieee80211_hdr *)skb->data; - if (likely(ether_addr_equal(tx_hdr->addr2, rx_hdr->addr1))) - { - found = 1; - break; - } - } - - if (found) { - for (i=1; i<position; i++) { - skb = __skb_dequeue(q); - zd_mac_tx_status(hw, skb, - mac->ack_pending ? mac->ack_signal : 0, - NULL); - mac->ack_pending = 0; - } - - mac->ack_pending = 1; - mac->ack_signal = stats->signal; - - /* Prevent pending tx-packet on AP-mode */ - if (mac->type == NL80211_IFTYPE_AP) { - skb = __skb_dequeue(q); - zd_mac_tx_status(hw, skb, mac->ack_signal, NULL); - mac->ack_pending = 0; - } - } - - spin_unlock_irqrestore(&q->lock, flags); - return 1; -} - -int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) -{ - struct zd_mac *mac = zd_hw_mac(hw); - struct ieee80211_rx_status stats; - const struct rx_status *status; - struct sk_buff *skb; - int bad_frame = 0; - __le16 fc; - int need_padding; - int i; - u8 rate; - - if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ + - FCS_LEN + sizeof(struct rx_status)) - return -EINVAL; - - memset(&stats, 0, sizeof(stats)); - - /* Note about pass_failed_fcs and pass_ctrl access below: - * mac locking intentionally omitted here, as this is the only unlocked - * reader and the only writer is configure_filter. Plus, if there were - * any races accessing these variables, it wouldn't really matter. - * If mac80211 ever provides a way for us to access filter flags - * from outside configure_filter, we could improve on this. Also, this - * situation may change once we implement some kind of DMA-into-skb - * RX path. */ - - /* Caller has to ensure that length >= sizeof(struct rx_status). */ - status = (struct rx_status *) - (buffer + (length - sizeof(struct rx_status))); - if (status->frame_status & ZD_RX_ERROR) { - if (mac->pass_failed_fcs && - (status->frame_status & ZD_RX_CRC32_ERROR)) { - stats.flag |= RX_FLAG_FAILED_FCS_CRC; - bad_frame = 1; - } else { - return -EINVAL; - } - } - - stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; - stats.band = IEEE80211_BAND_2GHZ; - stats.signal = zd_check_signal(hw, status->signal_strength); - - rate = zd_rx_rate(buffer, status); - - /* todo: return index in the big switches in zd_rx_rate instead */ - for (i = 0; i < mac->band.n_bitrates; i++) - if (rate == mac->band.bitrates[i].hw_value) - stats.rate_idx = i; - - length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status); - buffer += ZD_PLCP_HEADER_SIZE; - - /* Except for bad frames, filter each frame to see if it is an ACK, in - * which case our internal TX tracking is updated. Normally we then - * bail here as there's no need to pass ACKs on up to the stack, but - * there is also the case where the stack has requested us to pass - * control frames on up (pass_ctrl) which we must consider. */ - if (!bad_frame && - filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats) - && !mac->pass_ctrl) - return 0; - - fc = get_unaligned((__le16*)buffer); - need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc); - - skb = dev_alloc_skb(length + (need_padding ? 2 : 0)); - if (skb == NULL) - return -ENOMEM; - if (need_padding) { - /* Make sure the payload data is 4 byte aligned. */ - skb_reserve(skb, 2); - } - - /* FIXME : could we avoid this big memcpy ? */ - memcpy(skb_put(skb, length), buffer, length); - - memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats)); - ieee80211_rx_irqsafe(hw, skb); - return 0; -} - -static int zd_op_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct zd_mac *mac = zd_hw_mac(hw); - - /* using NL80211_IFTYPE_UNSPECIFIED to indicate no mode selected */ - if (mac->type != NL80211_IFTYPE_UNSPECIFIED) - return -EOPNOTSUPP; - - switch (vif->type) { - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP: - mac->type = vif->type; - break; - default: - return -EOPNOTSUPP; - } - - mac->vif = vif; - - return set_mac_and_bssid(mac); -} - -static void zd_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct zd_mac *mac = zd_hw_mac(hw); - mac->type = NL80211_IFTYPE_UNSPECIFIED; - mac->vif = NULL; - zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED); - zd_write_mac_addr(&mac->chip, NULL); - - zd_mac_free_cur_beacon(mac); -} - -static int zd_op_config(struct ieee80211_hw *hw, u32 changed) -{ - struct zd_mac *mac = zd_hw_mac(hw); - struct ieee80211_conf *conf = &hw->conf; - - spin_lock_irq(&mac->lock); - mac->channel = conf->chandef.chan->hw_value; - spin_unlock_irq(&mac->lock); - - return zd_chip_set_channel(&mac->chip, conf->chandef.chan->hw_value); -} - -static void zd_beacon_done(struct zd_mac *mac) -{ - struct sk_buff *skb, *beacon; - - if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags)) - return; - if (!mac->vif || mac->vif->type != NL80211_IFTYPE_AP) - return; - - /* - * Send out buffered broad- and multicast frames. - */ - while (!ieee80211_queue_stopped(mac->hw, 0)) { - skb = ieee80211_get_buffered_bc(mac->hw, mac->vif); - if (!skb) - break; - zd_op_tx(mac->hw, NULL, skb); - } - - /* - * Fetch next beacon so that tim_count is updated. - */ - beacon = ieee80211_beacon_get(mac->hw, mac->vif); - if (beacon) - zd_mac_config_beacon(mac->hw, beacon, true); - - spin_lock_irq(&mac->lock); - mac->beacon.last_update = jiffies; - spin_unlock_irq(&mac->lock); -} - -static void zd_process_intr(struct work_struct *work) -{ - u16 int_status; - unsigned long flags; - struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); - - spin_lock_irqsave(&mac->lock, flags); - int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer + 4)); - spin_unlock_irqrestore(&mac->lock, flags); - - if (int_status & INT_CFG_NEXT_BCN) { - /*dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");*/ - zd_beacon_done(mac); - } else { - dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n"); - } - - zd_chip_enable_hwint(&mac->chip); -} - - -static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - struct zd_mac *mac = zd_hw_mac(hw); - struct zd_mc_hash hash; - struct netdev_hw_addr *ha; - - zd_mc_clear(&hash); - - netdev_hw_addr_list_for_each(ha, mc_list) { - dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n", ha->addr); - zd_mc_add_addr(&hash, ha->addr); - } - - return hash.low | ((u64)hash.high << 32); -} - -#define SUPPORTED_FIF_FLAGS \ - (FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ - FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC) -static void zd_op_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *new_flags, - u64 multicast) -{ - struct zd_mc_hash hash = { - .low = multicast, - .high = multicast >> 32, - }; - struct zd_mac *mac = zd_hw_mac(hw); - unsigned long flags; - int r; - - /* Only deal with supported flags */ - changed_flags &= SUPPORTED_FIF_FLAGS; - *new_flags &= SUPPORTED_FIF_FLAGS; - - /* - * If multicast parameter (as returned by zd_op_prepare_multicast) - * has changed, no bit in changed_flags is set. To handle this - * situation, we do not return if changed_flags is 0. If we do so, - * we will have some issue with IPv6 which uses multicast for link - * layer address resolution. - */ - if (*new_flags & FIF_ALLMULTI) - zd_mc_add_all(&hash); - - spin_lock_irqsave(&mac->lock, flags); - mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL); - mac->pass_ctrl = !!(*new_flags & FIF_CONTROL); - mac->multicast_hash = hash; - spin_unlock_irqrestore(&mac->lock, flags); - - zd_chip_set_multicast_hash(&mac->chip, &hash); - - if (changed_flags & FIF_CONTROL) { - r = set_rx_filter(mac); - if (r) - dev_err(zd_mac_dev(mac), "set_rx_filter error %d\n", r); - } - - /* no handling required for FIF_OTHER_BSS as we don't currently - * do BSSID filtering */ - /* FIXME: in future it would be nice to enable the probe response - * filter (so that the driver doesn't see them) until - * FIF_BCN_PRBRESP_PROMISC is set. however due to atomicity here, we'd - * have to schedule work to enable prbresp reception, which might - * happen too late. For now we'll just listen and forward them all the - * time. */ -} - -static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble) -{ - mutex_lock(&mac->chip.mutex); - zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble); - mutex_unlock(&mac->chip.mutex); -} - -static void zd_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct zd_mac *mac = zd_hw_mac(hw); - int associated; - - dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); - - if (mac->type == NL80211_IFTYPE_MESH_POINT || - mac->type == NL80211_IFTYPE_ADHOC || - mac->type == NL80211_IFTYPE_AP) { - associated = true; - if (changes & BSS_CHANGED_BEACON) { - struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); - - if (beacon) { - zd_chip_disable_hwint(&mac->chip); - zd_mac_config_beacon(hw, beacon, false); - zd_chip_enable_hwint(&mac->chip); - } - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) { - u16 interval = 0; - u8 period = 0; - - if (bss_conf->enable_beacon) { - period = bss_conf->dtim_period; - interval = bss_conf->beacon_int; - } - - spin_lock_irq(&mac->lock); - mac->beacon.period = period; - mac->beacon.interval = interval; - mac->beacon.last_update = jiffies; - spin_unlock_irq(&mac->lock); - - zd_set_beacon_interval(&mac->chip, interval, period, - mac->type); - } - } else - associated = is_valid_ether_addr(bss_conf->bssid); - - spin_lock_irq(&mac->lock); - mac->associated = associated; - spin_unlock_irq(&mac->lock); - - /* TODO: do hardware bssid filtering */ - - if (changes & BSS_CHANGED_ERP_PREAMBLE) { - spin_lock_irq(&mac->lock); - mac->short_preamble = bss_conf->use_short_preamble; - spin_unlock_irq(&mac->lock); - - set_rts_cts(mac, bss_conf->use_short_preamble); - } -} - -static u64 zd_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct zd_mac *mac = zd_hw_mac(hw); - return zd_chip_get_tsf(&mac->chip); -} - -static const struct ieee80211_ops zd_ops = { - .tx = zd_op_tx, - .start = zd_op_start, - .stop = zd_op_stop, - .add_interface = zd_op_add_interface, - .remove_interface = zd_op_remove_interface, - .config = zd_op_config, - .prepare_multicast = zd_op_prepare_multicast, - .configure_filter = zd_op_configure_filter, - .bss_info_changed = zd_op_bss_info_changed, - .get_tsf = zd_op_get_tsf, -}; - -struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) -{ - struct zd_mac *mac; - struct ieee80211_hw *hw; - - hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); - if (!hw) { - dev_dbg_f(&intf->dev, "out of memory\n"); - return NULL; - } - - mac = zd_hw_mac(hw); - - memset(mac, 0, sizeof(*mac)); - spin_lock_init(&mac->lock); - mac->hw = hw; - - mac->type = NL80211_IFTYPE_UNSPECIFIED; - - memcpy(mac->channels, zd_channels, sizeof(zd_channels)); - memcpy(mac->rates, zd_rates, sizeof(zd_rates)); - mac->band.n_bitrates = ARRAY_SIZE(zd_rates); - mac->band.bitrates = mac->rates; - mac->band.n_channels = ARRAY_SIZE(zd_channels); - mac->band.channels = mac->channels; - - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; - - ieee80211_hw_set(hw, MFP_CAPABLE); - ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING); - ieee80211_hw_set(hw, RX_INCLUDES_FCS); - ieee80211_hw_set(hw, SIGNAL_UNSPEC); - - hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_MESH_POINT) | - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP); - - hw->max_signal = 100; - hw->queues = 1; - hw->extra_tx_headroom = sizeof(struct zd_ctrlset); - - /* - * Tell mac80211 that we support multi rate retries - */ - hw->max_rates = IEEE80211_TX_MAX_RATES; - hw->max_rate_tries = 18; /* 9 rates * 2 retries/rate */ - - skb_queue_head_init(&mac->ack_wait_queue); - mac->ack_pending = 0; - - zd_chip_init(&mac->chip, hw, intf); - housekeeping_init(mac); - beacon_init(mac); - INIT_WORK(&mac->process_intr, zd_process_intr); - - SET_IEEE80211_DEV(hw, &intf->dev); - return hw; -} - -#define BEACON_WATCHDOG_DELAY round_jiffies_relative(HZ) - -static void beacon_watchdog_handler(struct work_struct *work) -{ - struct zd_mac *mac = - container_of(work, struct zd_mac, beacon.watchdog_work.work); - struct sk_buff *beacon; - unsigned long timeout; - int interval, period; - - if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags)) - goto rearm; - if (mac->type != NL80211_IFTYPE_AP || !mac->vif) - goto rearm; - - spin_lock_irq(&mac->lock); - interval = mac->beacon.interval; - period = mac->beacon.period; - timeout = mac->beacon.last_update + - msecs_to_jiffies(interval * 1024 / 1000) * 3; - spin_unlock_irq(&mac->lock); - - if (interval > 0 && time_is_before_jiffies(timeout)) { - dev_dbg_f(zd_mac_dev(mac), "beacon interrupt stalled, " - "restarting. " - "(interval: %d, dtim: %d)\n", - interval, period); - - zd_chip_disable_hwint(&mac->chip); - - beacon = ieee80211_beacon_get(mac->hw, mac->vif); - if (beacon) { - zd_mac_free_cur_beacon(mac); - - zd_mac_config_beacon(mac->hw, beacon, false); - } - - zd_set_beacon_interval(&mac->chip, interval, period, mac->type); - - zd_chip_enable_hwint(&mac->chip); - - spin_lock_irq(&mac->lock); - mac->beacon.last_update = jiffies; - spin_unlock_irq(&mac->lock); - } - -rearm: - queue_delayed_work(zd_workqueue, &mac->beacon.watchdog_work, - BEACON_WATCHDOG_DELAY); -} - -static void beacon_init(struct zd_mac *mac) -{ - INIT_DELAYED_WORK(&mac->beacon.watchdog_work, beacon_watchdog_handler); -} - -static void beacon_enable(struct zd_mac *mac) -{ - dev_dbg_f(zd_mac_dev(mac), "\n"); - - mac->beacon.last_update = jiffies; - queue_delayed_work(zd_workqueue, &mac->beacon.watchdog_work, - BEACON_WATCHDOG_DELAY); -} - -static void beacon_disable(struct zd_mac *mac) -{ - dev_dbg_f(zd_mac_dev(mac), "\n"); - cancel_delayed_work_sync(&mac->beacon.watchdog_work); - - zd_mac_free_cur_beacon(mac); -} - -#define LINK_LED_WORK_DELAY HZ - -static void link_led_handler(struct work_struct *work) -{ - struct zd_mac *mac = - container_of(work, struct zd_mac, housekeeping.link_led_work.work); - struct zd_chip *chip = &mac->chip; - int is_associated; - int r; - - if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags)) - goto requeue; - - spin_lock_irq(&mac->lock); - is_associated = mac->associated; - spin_unlock_irq(&mac->lock); - - r = zd_chip_control_leds(chip, - is_associated ? ZD_LED_ASSOCIATED : ZD_LED_SCANNING); - if (r) - dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); - -requeue: - queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, - LINK_LED_WORK_DELAY); -} - -static void housekeeping_init(struct zd_mac *mac) -{ - INIT_DELAYED_WORK(&mac->housekeeping.link_led_work, link_led_handler); -} - -static void housekeeping_enable(struct zd_mac *mac) -{ - dev_dbg_f(zd_mac_dev(mac), "\n"); - queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, - 0); -} - -static void housekeeping_disable(struct zd_mac *mac) -{ - dev_dbg_f(zd_mac_dev(mac), "\n"); - cancel_delayed_work_sync(&mac->housekeeping.link_led_work); - zd_chip_control_leds(&mac->chip, ZD_LED_OFF); -} diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h deleted file mode 100644 index 5a48423..0000000 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ /dev/null @@ -1,327 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _ZD_MAC_H -#define _ZD_MAC_H - -#include <linux/kernel.h> -#include <net/mac80211.h> - -#include "zd_chip.h" - -struct zd_ctrlset { - u8 modulation; - __le16 tx_length; - u8 control; - /* stores only the difference to tx_length on ZD1211B */ - __le16 packet_length; - __le16 current_length; - u8 service; - __le16 next_frame_length; -} __packed; - -#define ZD_CS_RESERVED_SIZE 25 - -/* The field modulation of struct zd_ctrlset controls the bit rate, the use - * of short or long preambles in 802.11b (CCK mode) or the use of 802.11a or - * 802.11g in OFDM mode. - * - * The term zd-rate is used for the combination of the modulation type flag - * and the "pure" rate value. - */ -#define ZD_PURE_RATE_MASK 0x0f -#define ZD_MODULATION_TYPE_MASK 0x10 -#define ZD_RATE_MASK (ZD_PURE_RATE_MASK|ZD_MODULATION_TYPE_MASK) -#define ZD_PURE_RATE(modulation) ((modulation) & ZD_PURE_RATE_MASK) -#define ZD_MODULATION_TYPE(modulation) ((modulation) & ZD_MODULATION_TYPE_MASK) -#define ZD_RATE(modulation) ((modulation) & ZD_RATE_MASK) - -/* The two possible modulation types. Notify that 802.11b doesn't use the CCK - * codeing for the 1 and 2 MBit/s rate. We stay with the term here to remain - * consistent with uses the term at other places. - */ -#define ZD_CCK 0x00 -#define ZD_OFDM 0x10 - -/* The ZD1211 firmware uses proprietary encodings of the 802.11b (CCK) rates. - * For OFDM the PLCP rate encodings are used. We combine these "pure" rates - * with the modulation type flag and call the resulting values zd-rates. - */ -#define ZD_CCK_RATE_1M (ZD_CCK|0x00) -#define ZD_CCK_RATE_2M (ZD_CCK|0x01) -#define ZD_CCK_RATE_5_5M (ZD_CCK|0x02) -#define ZD_CCK_RATE_11M (ZD_CCK|0x03) -#define ZD_OFDM_RATE_6M (ZD_OFDM|ZD_OFDM_PLCP_RATE_6M) -#define ZD_OFDM_RATE_9M (ZD_OFDM|ZD_OFDM_PLCP_RATE_9M) -#define ZD_OFDM_RATE_12M (ZD_OFDM|ZD_OFDM_PLCP_RATE_12M) -#define ZD_OFDM_RATE_18M (ZD_OFDM|ZD_OFDM_PLCP_RATE_18M) -#define ZD_OFDM_RATE_24M (ZD_OFDM|ZD_OFDM_PLCP_RATE_24M) -#define ZD_OFDM_RATE_36M (ZD_OFDM|ZD_OFDM_PLCP_RATE_36M) -#define ZD_OFDM_RATE_48M (ZD_OFDM|ZD_OFDM_PLCP_RATE_48M) -#define ZD_OFDM_RATE_54M (ZD_OFDM|ZD_OFDM_PLCP_RATE_54M) - -/* The bit 5 of the zd_ctrlset modulation field controls the preamble in CCK - * mode or the 802.11a/802.11g selection in OFDM mode. - */ -#define ZD_CCK_PREA_LONG 0x00 -#define ZD_CCK_PREA_SHORT 0x20 -#define ZD_OFDM_MODE_11G 0x00 -#define ZD_OFDM_MODE_11A 0x20 - -/* zd_ctrlset control field */ -#define ZD_CS_NEED_RANDOM_BACKOFF 0x01 -#define ZD_CS_NO_ACK 0x02 - -#define ZD_CS_FRAME_TYPE_MASK 0x0c -#define ZD_CS_DATA_FRAME 0x00 -#define ZD_CS_PS_POLL_FRAME 0x04 -#define ZD_CS_MANAGEMENT_FRAME 0x08 -#define ZD_CS_NO_SEQUENCE_CTL_FRAME 0x0c - -#define ZD_CS_WAKE_DESTINATION 0x10 -#define ZD_CS_RTS 0x20 -#define ZD_CS_ENCRYPT 0x40 -#define ZD_CS_SELF_CTS 0x80 - -/* Incoming frames are prepended by a PLCP header */ -#define ZD_PLCP_HEADER_SIZE 5 - -struct rx_length_info { - __le16 length[3]; - __le16 tag; -} __packed; - -#define RX_LENGTH_INFO_TAG 0x697e - -struct rx_status { - u8 signal_quality_cck; - /* rssi */ - u8 signal_strength; - u8 signal_quality_ofdm; - u8 decryption_type; - u8 frame_status; -} __packed; - -/* rx_status field decryption_type */ -#define ZD_RX_NO_WEP 0 -#define ZD_RX_WEP64 1 -#define ZD_RX_TKIP 2 -#define ZD_RX_AES 4 -#define ZD_RX_WEP128 5 -#define ZD_RX_WEP256 6 - -/* rx_status field frame_status */ -#define ZD_RX_FRAME_MODULATION_MASK 0x01 -#define ZD_RX_CCK 0x00 -#define ZD_RX_OFDM 0x01 - -#define ZD_RX_TIMEOUT_ERROR 0x02 -#define ZD_RX_FIFO_OVERRUN_ERROR 0x04 -#define ZD_RX_DECRYPTION_ERROR 0x08 -#define ZD_RX_CRC32_ERROR 0x10 -#define ZD_RX_NO_ADDR1_MATCH_ERROR 0x20 -#define ZD_RX_CRC16_ERROR 0x40 -#define ZD_RX_ERROR 0x80 - -struct tx_retry_rate { - int count; /* number of valid element in rate[] array */ - int rate[10]; /* retry rates, described by an index in zd_rates[] */ -}; - -struct tx_status { - u8 type; /* must always be 0x01 : USB_INT_TYPE */ - u8 id; /* must always be 0xa0 : USB_INT_ID_RETRY_FAILED */ - u8 rate; - u8 pad; - u8 mac[ETH_ALEN]; - u8 retry; - u8 failure; -} __packed; - -enum mac_flags { - MAC_FIXED_CHANNEL = 0x01, -}; - -struct housekeeping { - struct delayed_work link_led_work; -}; - -struct beacon { - struct delayed_work watchdog_work; - struct sk_buff *cur_beacon; - unsigned long last_update; - u16 interval; - u8 period; -}; - -enum zd_device_flags { - ZD_DEVICE_RUNNING, -}; - -#define ZD_MAC_STATS_BUFFER_SIZE 16 - -#define ZD_MAC_MAX_ACK_WAITERS 50 - -struct zd_mac { - struct zd_chip chip; - spinlock_t lock; - spinlock_t intr_lock; - struct ieee80211_hw *hw; - struct ieee80211_vif *vif; - struct housekeeping housekeeping; - struct beacon beacon; - struct work_struct set_rts_cts_work; - struct work_struct process_intr; - struct zd_mc_hash multicast_hash; - u8 intr_buffer[USB_MAX_EP_INT_BUFFER]; - u8 regdomain; - u8 default_regdomain; - u8 channel; - int type; - int associated; - unsigned long flags; - struct sk_buff_head ack_wait_queue; - struct ieee80211_channel channels[14]; - struct ieee80211_rate rates[12]; - struct ieee80211_supported_band band; - - /* Short preamble (used for RTS/CTS) */ - unsigned int short_preamble:1; - - /* whether to pass frames with CRC errors to stack */ - unsigned int pass_failed_fcs:1; - - /* whether to pass control frames to stack */ - unsigned int pass_ctrl:1; - - /* whether we have received a 802.11 ACK that is pending */ - unsigned int ack_pending:1; - - /* signal strength of the last 802.11 ACK received */ - int ack_signal; -}; - -#define ZD_REGDOMAIN_FCC 0x10 -#define ZD_REGDOMAIN_IC 0x20 -#define ZD_REGDOMAIN_ETSI 0x30 -#define ZD_REGDOMAIN_SPAIN 0x31 -#define ZD_REGDOMAIN_FRANCE 0x32 -#define ZD_REGDOMAIN_JAPAN_2 0x40 -#define ZD_REGDOMAIN_JAPAN 0x41 -#define ZD_REGDOMAIN_JAPAN_3 0x49 - -enum { - MIN_CHANNEL24 = 1, - MAX_CHANNEL24 = 14, -}; - -#define ZD_PLCP_SERVICE_LENGTH_EXTENSION 0x80 - -struct ofdm_plcp_header { - u8 prefix[3]; - __le16 service; -} __packed; - -static inline u8 zd_ofdm_plcp_header_rate(const struct ofdm_plcp_header *header) -{ - return header->prefix[0] & 0xf; -} - -/* The following defines give the encoding of the 4-bit rate field in the - * OFDM (802.11a/802.11g) PLCP header. Notify that these values are used to - * define the zd-rate values for OFDM. - * - * See the struct zd_ctrlset definition in zd_mac.h. - */ -#define ZD_OFDM_PLCP_RATE_6M 0xb -#define ZD_OFDM_PLCP_RATE_9M 0xf -#define ZD_OFDM_PLCP_RATE_12M 0xa -#define ZD_OFDM_PLCP_RATE_18M 0xe -#define ZD_OFDM_PLCP_RATE_24M 0x9 -#define ZD_OFDM_PLCP_RATE_36M 0xd -#define ZD_OFDM_PLCP_RATE_48M 0x8 -#define ZD_OFDM_PLCP_RATE_54M 0xc - -struct cck_plcp_header { - u8 signal; - u8 service; - __le16 length; - __le16 crc16; -} __packed; - -static inline u8 zd_cck_plcp_header_signal(const struct cck_plcp_header *header) -{ - return header->signal; -} - -/* These defines give the encodings of the signal field in the 802.11b PLCP - * header. The signal field gives the bit rate of the following packet. Even - * if technically wrong we use CCK here also for the 1 MBit/s and 2 MBit/s - * rate to stay consistent with Zydas and our use of the term. - * - * Notify that these values are *not* used in the zd-rates. - */ -#define ZD_CCK_PLCP_SIGNAL_1M 0x0a -#define ZD_CCK_PLCP_SIGNAL_2M 0x14 -#define ZD_CCK_PLCP_SIGNAL_5M5 0x37 -#define ZD_CCK_PLCP_SIGNAL_11M 0x6e - -static inline struct zd_mac *zd_hw_mac(struct ieee80211_hw *hw) -{ - return hw->priv; -} - -static inline struct zd_mac *zd_chip_to_mac(struct zd_chip *chip) -{ - return container_of(chip, struct zd_mac, chip); -} - -static inline struct zd_mac *zd_usb_to_mac(struct zd_usb *usb) -{ - return zd_chip_to_mac(zd_usb_to_chip(usb)); -} - -static inline u8 *zd_mac_get_perm_addr(struct zd_mac *mac) -{ - return mac->hw->wiphy->perm_addr; -} - -#define zd_mac_dev(mac) (zd_chip_dev(&(mac)->chip)) - -struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf); -void zd_mac_clear(struct zd_mac *mac); - -int zd_mac_preinit_hw(struct ieee80211_hw *hw); -int zd_mac_init_hw(struct ieee80211_hw *hw); - -int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length); -void zd_mac_tx_failed(struct urb *urb); -void zd_mac_tx_to_dev(struct sk_buff *skb, int error); - -int zd_op_start(struct ieee80211_hw *hw); -void zd_op_stop(struct ieee80211_hw *hw); -int zd_restore_settings(struct zd_mac *mac); - -#ifdef DEBUG -void zd_dump_rx_status(const struct rx_status *status); -#else -#define zd_dump_rx_status(status) -#endif /* DEBUG */ - -#endif /* _ZD_MAC_H */ diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c deleted file mode 100644 index dc179c4..0000000 --- a/drivers/net/wireless/zd1211rw/zd_rf.c +++ /dev/null @@ -1,181 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/errno.h> -#include <linux/string.h> - -#include "zd_def.h" -#include "zd_rf.h" -#include "zd_mac.h" -#include "zd_chip.h" - -static const char * const rfs[] = { - [0] = "unknown RF0", - [1] = "unknown RF1", - [UW2451_RF] = "UW2451_RF", - [UCHIP_RF] = "UCHIP_RF", - [AL2230_RF] = "AL2230_RF", - [AL7230B_RF] = "AL7230B_RF", - [THETA_RF] = "THETA_RF", - [AL2210_RF] = "AL2210_RF", - [MAXIM_NEW_RF] = "MAXIM_NEW_RF", - [UW2453_RF] = "UW2453_RF", - [AL2230S_RF] = "AL2230S_RF", - [RALINK_RF] = "RALINK_RF", - [INTERSIL_RF] = "INTERSIL_RF", - [RF2959_RF] = "RF2959_RF", - [MAXIM_NEW2_RF] = "MAXIM_NEW2_RF", - [PHILIPS_RF] = "PHILIPS_RF", -}; - -const char *zd_rf_name(u8 type) -{ - if (type & 0xf0) - type = 0; - return rfs[type]; -} - -void zd_rf_init(struct zd_rf *rf) -{ - memset(rf, 0, sizeof(*rf)); - - /* default to update channel integration, as almost all RF's do want - * this */ - rf->update_channel_int = 1; -} - -void zd_rf_clear(struct zd_rf *rf) -{ - if (rf->clear) - rf->clear(rf); - ZD_MEMCLEAR(rf, sizeof(*rf)); -} - -int zd_rf_init_hw(struct zd_rf *rf, u8 type) -{ - int r = 0; - int t; - struct zd_chip *chip = zd_rf_to_chip(rf); - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - switch (type) { - case RF2959_RF: - r = zd_rf_init_rf2959(rf); - break; - case AL2230_RF: - case AL2230S_RF: - r = zd_rf_init_al2230(rf); - break; - case AL7230B_RF: - r = zd_rf_init_al7230b(rf); - break; - case MAXIM_NEW_RF: - case UW2453_RF: - r = zd_rf_init_uw2453(rf); - break; - default: - dev_err(zd_chip_dev(chip), - "RF %s %#x is not supported\n", zd_rf_name(type), type); - rf->type = 0; - return -ENODEV; - } - - if (r) - return r; - - rf->type = type; - - r = zd_chip_lock_phy_regs(chip); - if (r) - return r; - t = rf->init_hw(rf); - r = zd_chip_unlock_phy_regs(chip); - if (t) - r = t; - return r; -} - -int zd_rf_scnprint_id(struct zd_rf *rf, char *buffer, size_t size) -{ - return scnprintf(buffer, size, "%s", zd_rf_name(rf->type)); -} - -int zd_rf_set_channel(struct zd_rf *rf, u8 channel) -{ - int r; - - ZD_ASSERT(mutex_is_locked(&zd_rf_to_chip(rf)->mutex)); - if (channel < MIN_CHANNEL24) - return -EINVAL; - if (channel > MAX_CHANNEL24) - return -EINVAL; - dev_dbg_f(zd_chip_dev(zd_rf_to_chip(rf)), "channel: %d\n", channel); - - r = rf->set_channel(rf, channel); - if (r >= 0) - rf->channel = channel; - return r; -} - -int zd_switch_radio_on(struct zd_rf *rf) -{ - int r, t; - struct zd_chip *chip = zd_rf_to_chip(rf); - - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_chip_lock_phy_regs(chip); - if (r) - return r; - t = rf->switch_radio_on(rf); - r = zd_chip_unlock_phy_regs(chip); - if (t) - r = t; - return r; -} - -int zd_switch_radio_off(struct zd_rf *rf) -{ - int r, t; - struct zd_chip *chip = zd_rf_to_chip(rf); - - /* TODO: move phy regs handling to zd_chip */ - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_chip_lock_phy_regs(chip); - if (r) - return r; - t = rf->switch_radio_off(rf); - r = zd_chip_unlock_phy_regs(chip); - if (t) - r = t; - return r; -} - -int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel) -{ - if (!rf->patch_6m_band_edge) - return 0; - - return rf->patch_6m_band_edge(rf, channel); -} - -int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel) -{ - return zd_chip_generic_patch_6m_band(zd_rf_to_chip(rf), channel); -} - diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h deleted file mode 100644 index 8f14e25..0000000 --- a/drivers/net/wireless/zd1211rw/zd_rf.h +++ /dev/null @@ -1,110 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _ZD_RF_H -#define _ZD_RF_H - -#define UW2451_RF 0x2 -#define UCHIP_RF 0x3 -#define AL2230_RF 0x4 -#define AL7230B_RF 0x5 /* a,b,g */ -#define THETA_RF 0x6 -#define AL2210_RF 0x7 -#define MAXIM_NEW_RF 0x8 -#define UW2453_RF 0x9 -#define AL2230S_RF 0xa -#define RALINK_RF 0xb -#define INTERSIL_RF 0xc -#define RF2959_RF 0xd -#define MAXIM_NEW2_RF 0xe -#define PHILIPS_RF 0xf - -#define RF_CHANNEL(ch) [(ch)-1] - -/* Provides functions of the RF transceiver. */ - -enum { - RF_REG_BITS = 6, - RF_VALUE_BITS = 18, - RF_RV_BITS = RF_REG_BITS + RF_VALUE_BITS, -}; - -struct zd_rf { - u8 type; - - u8 channel; - - /* whether channel integration and calibration should be updated - * defaults to 1 (yes) */ - u8 update_channel_int:1; - - /* whether ZD_CR47 should be patched from the EEPROM, if the appropriate - * flag is set in the POD. The vendor driver suggests that this should - * be done for all RF's, but a bug in their code prevents but their - * HW_OverWritePhyRegFromE2P() routine from ever taking effect. */ - u8 patch_cck_gain:1; - - /* private RF driver data */ - void *priv; - - /* RF-specific functions */ - int (*init_hw)(struct zd_rf *rf); - int (*set_channel)(struct zd_rf *rf, u8 channel); - int (*switch_radio_on)(struct zd_rf *rf); - int (*switch_radio_off)(struct zd_rf *rf); - int (*patch_6m_band_edge)(struct zd_rf *rf, u8 channel); - void (*clear)(struct zd_rf *rf); -}; - -const char *zd_rf_name(u8 type); -void zd_rf_init(struct zd_rf *rf); -void zd_rf_clear(struct zd_rf *rf); -int zd_rf_init_hw(struct zd_rf *rf, u8 type); - -int zd_rf_scnprint_id(struct zd_rf *rf, char *buffer, size_t size); - -int zd_rf_set_channel(struct zd_rf *rf, u8 channel); - -int zd_switch_radio_on(struct zd_rf *rf); -int zd_switch_radio_off(struct zd_rf *rf); - -int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel); -int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel); - -static inline int zd_rf_should_update_pwr_int(struct zd_rf *rf) -{ - return rf->update_channel_int; -} - -static inline int zd_rf_should_patch_cck_gain(struct zd_rf *rf) -{ - return rf->patch_cck_gain; -} - -int zd_rf_patch_6m_band_edge(struct zd_rf *rf, u8 channel); -int zd_rf_generic_patch_6m(struct zd_rf *rf, u8 channel); - -/* Functions for individual RF chips */ - -int zd_rf_init_rf2959(struct zd_rf *rf); -int zd_rf_init_al2230(struct zd_rf *rf); -int zd_rf_init_al7230b(struct zd_rf *rf); -int zd_rf_init_uw2453(struct zd_rf *rf); - -#endif /* _ZD_RF_H */ diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c deleted file mode 100644 index 99aed7d..0000000 --- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c +++ /dev/null @@ -1,443 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> - -#include "zd_rf.h" -#include "zd_usb.h" -#include "zd_chip.h" - -#define IS_AL2230S(chip) ((chip)->al2230s_bit || (chip)->rf.type == AL2230S_RF) - -static const u32 zd1211_al2230_table[][3] = { - RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, }, - RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, }, - RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, }, - RF_CHANNEL( 4) = { 0x03e790, 0x0b3331, 0x00000d, }, - RF_CHANNEL( 5) = { 0x03f7a0, 0x033331, 0x00000d, }, - RF_CHANNEL( 6) = { 0x03f7a0, 0x0b3331, 0x00000d, }, - RF_CHANNEL( 7) = { 0x03e7a0, 0x033331, 0x00000d, }, - RF_CHANNEL( 8) = { 0x03e7a0, 0x0b3331, 0x00000d, }, - RF_CHANNEL( 9) = { 0x03f7b0, 0x033331, 0x00000d, }, - RF_CHANNEL(10) = { 0x03f7b0, 0x0b3331, 0x00000d, }, - RF_CHANNEL(11) = { 0x03e7b0, 0x033331, 0x00000d, }, - RF_CHANNEL(12) = { 0x03e7b0, 0x0b3331, 0x00000d, }, - RF_CHANNEL(13) = { 0x03f7c0, 0x033331, 0x00000d, }, - RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, }, -}; - -static const u32 zd1211b_al2230_table[][3] = { - RF_CHANNEL( 1) = { 0x09efc0, 0x8cccc0, 0xb00000, }, - RF_CHANNEL( 2) = { 0x09efc0, 0x8cccd0, 0xb00000, }, - RF_CHANNEL( 3) = { 0x09e7c0, 0x8cccc0, 0xb00000, }, - RF_CHANNEL( 4) = { 0x09e7c0, 0x8cccd0, 0xb00000, }, - RF_CHANNEL( 5) = { 0x05efc0, 0x8cccc0, 0xb00000, }, - RF_CHANNEL( 6) = { 0x05efc0, 0x8cccd0, 0xb00000, }, - RF_CHANNEL( 7) = { 0x05e7c0, 0x8cccc0, 0xb00000, }, - RF_CHANNEL( 8) = { 0x05e7c0, 0x8cccd0, 0xb00000, }, - RF_CHANNEL( 9) = { 0x0defc0, 0x8cccc0, 0xb00000, }, - RF_CHANNEL(10) = { 0x0defc0, 0x8cccd0, 0xb00000, }, - RF_CHANNEL(11) = { 0x0de7c0, 0x8cccc0, 0xb00000, }, - RF_CHANNEL(12) = { 0x0de7c0, 0x8cccd0, 0xb00000, }, - RF_CHANNEL(13) = { 0x03efc0, 0x8cccc0, 0xb00000, }, - RF_CHANNEL(14) = { 0x03e7c0, 0x866660, 0xb00000, }, -}; - -static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = { - { ZD_CR240, 0x57 }, { ZD_CR9, 0xe0 }, -}; - -static const struct zd_ioreq16 ioreqs_init_al2230s[] = { - { ZD_CR47, 0x1e }, /* MARK_002 */ - { ZD_CR106, 0x22 }, - { ZD_CR107, 0x2a }, /* MARK_002 */ - { ZD_CR109, 0x13 }, /* MARK_002 */ - { ZD_CR118, 0xf8 }, /* MARK_002 */ - { ZD_CR119, 0x12 }, { ZD_CR122, 0xe0 }, - { ZD_CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */ - { ZD_CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */ - { ZD_CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */ -}; - -static int zd1211b_al2230_finalize_rf(struct zd_chip *chip) -{ - int r; - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 }, - { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 }, - { ZD_CR203, 0x06 }, - { }, - - { ZD_CR240, 0x80 }, - }; - - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - return r; - - /* related to antenna selection? */ - if (chip->new_phy_layout) { - r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9); - if (r) - return r; - } - - return zd_iowrite16_locked(chip, 0x06, ZD_CR203); -} - -static int zd1211_al2230_init_hw(struct zd_rf *rf) -{ - int r; - struct zd_chip *chip = zd_rf_to_chip(rf); - - static const struct zd_ioreq16 ioreqs_init[] = { - { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, - { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, - { ZD_CR44, 0x33 }, { ZD_CR106, 0x2a }, { ZD_CR107, 0x1a }, - { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 }, { ZD_CR111, 0x2b }, - { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a }, { ZD_CR10, 0x89 }, - /* for newest (3rd cut) AL2300 */ - { ZD_CR17, 0x28 }, - { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 }, - /* for newest (3rd cut) AL2300 */ - { ZD_CR35, 0x3e }, - { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, - /* for newest (3rd cut) AL2300 */ - { ZD_CR46, 0x96 }, - { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, - { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, - { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 }, - { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR106, 0x24 }, - { ZD_CR107, 0x2a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x13 }, - { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, - { ZD_CR114, 0x27 }, - /* for newest (3rd cut) AL2300 */ - { ZD_CR115, 0x24 }, - { ZD_CR116, 0x24 }, { ZD_CR117, 0xf4 }, { ZD_CR118, 0xfc }, - { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f }, { ZD_CR121, 0x77 }, - { ZD_CR122, 0xe0 }, { ZD_CR137, 0x88 }, { ZD_CR252, 0xff }, - { ZD_CR253, 0xff }, - }; - - static const struct zd_ioreq16 ioreqs_pll[] = { - /* shdnb(PLL_ON)=0 */ - { ZD_CR251, 0x2f }, - /* shdnb(PLL_ON)=1 */ - { ZD_CR251, 0x3f }, - { ZD_CR138, 0x28 }, { ZD_CR203, 0x06 }, - }; - - static const u32 rv1[] = { - /* Channel 1 */ - 0x03f790, - 0x033331, - 0x00000d, - - 0x0b3331, - 0x03b812, - 0x00fff3, - }; - - static const u32 rv2[] = { - 0x000da4, - 0x0f4dc5, /* fix freq shift, 0x04edc5 */ - 0x0805b6, - 0x011687, - 0x000688, - 0x0403b9, /* external control TX power (ZD_CR31) */ - 0x00dbba, - 0x00099b, - 0x0bdffc, - 0x00000d, - 0x00500f, - }; - - static const u32 rv3[] = { - 0x00d00f, - 0x004c0f, - 0x00540f, - 0x00700f, - 0x00500f, - }; - - r = zd_iowrite16a_locked(chip, ioreqs_init, ARRAY_SIZE(ioreqs_init)); - if (r) - return r; - - if (IS_AL2230S(chip)) { - r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s, - ARRAY_SIZE(ioreqs_init_al2230s)); - if (r) - return r; - } - - r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS); - if (r) - return r; - - /* improve band edge for AL2230S */ - if (IS_AL2230S(chip)) - r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS); - else - r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS); - if (r) - return r; - - r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS); - if (r) - return r; - - r = zd_iowrite16a_locked(chip, ioreqs_pll, ARRAY_SIZE(ioreqs_pll)); - if (r) - return r; - - r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS); - if (r) - return r; - - return 0; -} - -static int zd1211b_al2230_init_hw(struct zd_rf *rf) -{ - int r; - struct zd_chip *chip = zd_rf_to_chip(rf); - - static const struct zd_ioreq16 ioreqs1[] = { - { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 }, - { ZD_CR17, 0x2B }, /* for newest(3rd cut) AL2230 */ - { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 }, - { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, - { ZD_CR33, 0x28 }, /* 5621 */ - { ZD_CR34, 0x30 }, - { ZD_CR35, 0x3e }, /* for newest(3rd cut) AL2230 */ - { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, - { ZD_CR46, 0x99 }, /* for newest(3rd cut) AL2230 */ - { ZD_CR47, 0x1e }, - - /* ZD1211B 05.06.10 */ - { ZD_CR48, 0x06 }, { ZD_CR49, 0xf9 }, { ZD_CR51, 0x01 }, - { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 }, - { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 }, - { ZD_CR69, 0x28 }, - - { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, - { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, - { ZD_CR91, 0x00 }, /* 5621 */ - { ZD_CR92, 0x0a }, - { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */ - { ZD_CR99, 0x00 }, /* 5621 */ - { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, - { ZD_CR106, 0x24 }, /* for newest(3rd cut) AL2230 */ - { ZD_CR107, 0x2a }, - { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */ - { ZD_CR110, 0x1f }, /* 4804, for 1212 new algorithm */ - { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, - { ZD_CR114, 0x27 }, - { ZD_CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) - * AL2230 - */ - { ZD_CR116, 0x24 }, - { ZD_CR117, 0xfa }, /* for 1211b */ - { ZD_CR118, 0xfa }, /* for 1211b */ - { ZD_CR119, 0x10 }, - { ZD_CR120, 0x4f }, - { ZD_CR121, 0x6c }, /* for 1211b */ - { ZD_CR122, 0xfc }, /* E0->FC at 4902 */ - { ZD_CR123, 0x57 }, /* 5623 */ - { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */ - { ZD_CR126, 0x6c }, /* 5614 */ - { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */ - { ZD_CR137, 0x50 }, /* 5614 */ - { ZD_CR138, 0xa8 }, - { ZD_CR144, 0xac }, /* 5621 */ - { ZD_CR150, 0x0d }, { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 }, - }; - - static const u32 rv1[] = { - 0x8cccd0, - 0x481dc0, - 0xcfff00, - 0x25a000, - }; - - static const u32 rv2[] = { - /* To improve AL2230 yield, improve phase noise, 4713 */ - 0x25a000, - 0xa3b2f0, - - 0x6da010, /* Reg6 update for MP versio */ - 0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */ - 0x116000, - 0x9dc020, /* External control TX power (ZD_CR31) */ - 0x5ddb00, /* RegA update for MP version */ - 0xd99000, /* RegB update for MP version */ - 0x3ffbd0, /* RegC update for MP version */ - 0xb00000, /* RegD update for MP version */ - - /* improve phase noise and remove phase calibration,4713 */ - 0xf01a00, - }; - - static const struct zd_ioreq16 ioreqs2[] = { - { ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */ - { ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */ - }; - - static const u32 rv3[] = { - /* To improve AL2230 yield, 4713 */ - 0xf01b00, - 0xf01e00, - 0xf01a00, - }; - - static const struct zd_ioreq16 ioreqs3[] = { - /* related to 6M band edge patching, happens unconditionally */ - { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, - }; - - r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1, - ARRAY_SIZE(zd1211b_ioreqs_shared_1)); - if (r) - return r; - r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1)); - if (r) - return r; - - if (IS_AL2230S(chip)) { - r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s, - ARRAY_SIZE(ioreqs_init_al2230s)); - if (r) - return r; - } - - r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3); - if (r) - return r; - r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1)); - if (r) - return r; - - if (IS_AL2230S(chip)) - r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS); - else - r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2)); - if (r) - return r; - r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2)); - if (r) - return r; - r = zd_rfwritev_cr_locked(chip, rv3, ARRAY_SIZE(rv3)); - if (r) - return r; - r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3)); - if (r) - return r; - return zd1211b_al2230_finalize_rf(chip); -} - -static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel) -{ - int r; - const u32 *rv = zd1211_al2230_table[channel-1]; - struct zd_chip *chip = zd_rf_to_chip(rf); - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR138, 0x28 }, - { ZD_CR203, 0x06 }, - }; - - r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS); - if (r) - return r; - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int zd1211b_al2230_set_channel(struct zd_rf *rf, u8 channel) -{ - int r; - const u32 *rv = zd1211b_al2230_table[channel-1]; - struct zd_chip *chip = zd_rf_to_chip(rf); - - r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1, - ARRAY_SIZE(zd1211b_ioreqs_shared_1)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, rv, 3); - if (r) - return r; - - return zd1211b_al2230_finalize_rf(chip); -} - -static int zd1211_al2230_switch_radio_on(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR11, 0x00 }, - { ZD_CR251, 0x3f }, - }; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int zd1211b_al2230_switch_radio_on(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR11, 0x00 }, - { ZD_CR251, 0x7f }, - }; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int al2230_switch_radio_off(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR11, 0x04 }, - { ZD_CR251, 0x2f }, - }; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -int zd_rf_init_al2230(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - - rf->switch_radio_off = al2230_switch_radio_off; - if (zd_chip_is_zd1211b(chip)) { - rf->init_hw = zd1211b_al2230_init_hw; - rf->set_channel = zd1211b_al2230_set_channel; - rf->switch_radio_on = zd1211b_al2230_switch_radio_on; - } else { - rf->init_hw = zd1211_al2230_init_hw; - rf->set_channel = zd1211_al2230_set_channel; - rf->switch_radio_on = zd1211_al2230_switch_radio_on; - } - rf->patch_6m_band_edge = zd_rf_generic_patch_6m; - rf->patch_cck_gain = 1; - return 0; -} diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c deleted file mode 100644 index 5fea485..0000000 --- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c +++ /dev/null @@ -1,494 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> - -#include "zd_rf.h" -#include "zd_usb.h" -#include "zd_chip.h" - -static const u32 chan_rv[][2] = { - RF_CHANNEL( 1) = { 0x09ec00, 0x8cccc8 }, - RF_CHANNEL( 2) = { 0x09ec00, 0x8cccd8 }, - RF_CHANNEL( 3) = { 0x09ec00, 0x8cccc0 }, - RF_CHANNEL( 4) = { 0x09ec00, 0x8cccd0 }, - RF_CHANNEL( 5) = { 0x05ec00, 0x8cccc8 }, - RF_CHANNEL( 6) = { 0x05ec00, 0x8cccd8 }, - RF_CHANNEL( 7) = { 0x05ec00, 0x8cccc0 }, - RF_CHANNEL( 8) = { 0x05ec00, 0x8cccd0 }, - RF_CHANNEL( 9) = { 0x0dec00, 0x8cccc8 }, - RF_CHANNEL(10) = { 0x0dec00, 0x8cccd8 }, - RF_CHANNEL(11) = { 0x0dec00, 0x8cccc0 }, - RF_CHANNEL(12) = { 0x0dec00, 0x8cccd0 }, - RF_CHANNEL(13) = { 0x03ec00, 0x8cccc8 }, - RF_CHANNEL(14) = { 0x03ec00, 0x866660 }, -}; - -static const u32 std_rv[] = { - 0x4ff821, - 0xc5fbfc, - 0x21ebfe, - 0xafd401, /* freq shift 0xaad401 */ - 0x6cf56a, - 0xe04073, - 0x193d76, - 0x9dd844, - 0x500007, - 0xd8c010, -}; - -static const u32 rv_init1[] = { - 0x3c9000, - 0xbfffff, - 0x700000, - 0xf15d58, -}; - -static const u32 rv_init2[] = { - 0xf15d59, - 0xf15d5c, - 0xf15d58, -}; - -static const struct zd_ioreq16 ioreqs_sw[] = { - { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, - { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf }, -}; - -static int zd1211b_al7230b_finalize(struct zd_chip *chip) -{ - int r; - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 }, - { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 }, - { ZD_CR203, 0x04 }, - { }, - { ZD_CR240, 0x80 }, - }; - - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - return r; - - if (chip->new_phy_layout) { - /* antenna selection? */ - r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9); - if (r) - return r; - } - - return zd_iowrite16_locked(chip, 0x04, ZD_CR203); -} - -static int zd1211_al7230b_init_hw(struct zd_rf *rf) -{ - int r; - struct zd_chip *chip = zd_rf_to_chip(rf); - - /* All of these writes are identical to AL2230 unless otherwise - * specified */ - static const struct zd_ioreq16 ioreqs_1[] = { - /* This one is 7230-specific, and happens before the rest */ - { ZD_CR240, 0x57 }, - { }, - - { ZD_CR15, 0x20 }, { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, - { ZD_CR26, 0x11 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, - { ZD_CR44, 0x33 }, - /* This value is different for 7230 (was: 0x2a) */ - { ZD_CR106, 0x22 }, - { ZD_CR107, 0x1a }, { ZD_CR109, 0x09 }, { ZD_CR110, 0x27 }, - { ZD_CR111, 0x2b }, { ZD_CR112, 0x2b }, { ZD_CR119, 0x0a }, - /* This happened further down in AL2230, - * and the value changed (was: 0xe0) */ - { ZD_CR122, 0xfc }, - { ZD_CR10, 0x89 }, - /* for newest (3rd cut) AL2300 */ - { ZD_CR17, 0x28 }, - { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 }, - /* for newest (3rd cut) AL2300 */ - { ZD_CR35, 0x3e }, - { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, - /* for newest (3rd cut) AL2300 */ - { ZD_CR46, 0x96 }, - { ZD_CR47, 0x1e }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, - { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, - { ZD_CR92, 0x0a }, { ZD_CR99, 0x28 }, - /* This value is different for 7230 (was: 0x00) */ - { ZD_CR100, 0x02 }, - { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, - /* This value is different for 7230 (was: 0x24) */ - { ZD_CR106, 0x22 }, - /* This value is different for 7230 (was: 0x2a) */ - { ZD_CR107, 0x3f }, - { ZD_CR109, 0x09 }, - /* This value is different for 7230 (was: 0x13) */ - { ZD_CR110, 0x1f }, - { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, - { ZD_CR114, 0x27 }, - /* for newest (3rd cut) AL2300 */ - { ZD_CR115, 0x24 }, - /* This value is different for 7230 (was: 0x24) */ - { ZD_CR116, 0x3f }, - /* This value is different for 7230 (was: 0xf4) */ - { ZD_CR117, 0xfa }, - { ZD_CR118, 0xfc }, { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f }, - { ZD_CR121, 0x77 }, { ZD_CR137, 0x88 }, - /* This one is 7230-specific */ - { ZD_CR138, 0xa8 }, - /* This value is different for 7230 (was: 0xff) */ - { ZD_CR252, 0x34 }, - /* This value is different for 7230 (was: 0xff) */ - { ZD_CR253, 0x34 }, - - /* PLL_OFF */ - { ZD_CR251, 0x2f }, - }; - - static const struct zd_ioreq16 ioreqs_2[] = { - { ZD_CR251, 0x3f }, /* PLL_ON */ - { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, - { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf }, - }; - - r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0])); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1)); - if (r) - return r; - - r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2)); - if (r) - return r; - - r = zd_iowrite16_locked(chip, 0x06, ZD_CR203); - if (r) - return r; - r = zd_iowrite16_locked(chip, 0x80, ZD_CR240); - if (r) - return r; - - return 0; -} - -static int zd1211b_al7230b_init_hw(struct zd_rf *rf) -{ - int r; - struct zd_chip *chip = zd_rf_to_chip(rf); - - static const struct zd_ioreq16 ioreqs_1[] = { - { ZD_CR240, 0x57 }, { ZD_CR9, 0x9 }, - { }, - { ZD_CR10, 0x8b }, { ZD_CR15, 0x20 }, - { ZD_CR17, 0x2B }, /* for newest (3rd cut) AL2230 */ - { ZD_CR20, 0x10 }, /* 4N25->Stone Request */ - { ZD_CR23, 0x40 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 }, - { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, - { ZD_CR33, 0x28 }, /* 5613 */ - { ZD_CR34, 0x30 }, - { ZD_CR35, 0x3e }, /* for newest (3rd cut) AL2230 */ - { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, - { ZD_CR46, 0x99 }, /* for newest (3rd cut) AL2230 */ - { ZD_CR47, 0x1e }, - - /* ZD1215 5610 */ - { ZD_CR48, 0x00 }, { ZD_CR49, 0x00 }, { ZD_CR51, 0x01 }, - { ZD_CR52, 0x80 }, { ZD_CR53, 0x7e }, { ZD_CR65, 0x00 }, - { ZD_CR66, 0x00 }, { ZD_CR67, 0x00 }, { ZD_CR68, 0x00 }, - { ZD_CR69, 0x28 }, - - { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, - { ZD_CR87, 0x0A }, { ZD_CR89, 0x04 }, - { ZD_CR90, 0x58 }, /* 5112 */ - { ZD_CR91, 0x00 }, /* 5613 */ - { ZD_CR92, 0x0a }, - { ZD_CR98, 0x8d }, /* 4804, for 1212 new algorithm */ - { ZD_CR99, 0x00 }, { ZD_CR100, 0x02 }, { ZD_CR101, 0x13 }, - { ZD_CR102, 0x27 }, - { ZD_CR106, 0x20 }, /* change to 0x24 for AL7230B */ - { ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */ - { ZD_CR112, 0x1f }, - }; - - static const struct zd_ioreq16 ioreqs_new_phy[] = { - { ZD_CR107, 0x28 }, - { ZD_CR110, 0x1f }, /* 5127, 0x13->0x1f */ - { ZD_CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */ - { ZD_CR116, 0x2a }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x12 }, - { ZD_CR121, 0x6c }, /* 5613 */ - }; - - static const struct zd_ioreq16 ioreqs_old_phy[] = { - { ZD_CR107, 0x24 }, - { ZD_CR110, 0x13 }, /* 5127, 0x13->0x1f */ - { ZD_CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */ - { ZD_CR116, 0x24 }, { ZD_CR118, 0xfc }, { ZD_CR119, 0x11 }, - { ZD_CR121, 0x6a }, /* 5613 */ - }; - - static const struct zd_ioreq16 ioreqs_2[] = { - { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x24 }, - { ZD_CR117, 0xfa }, { ZD_CR120, 0x4f }, - { ZD_CR122, 0xfc }, /* E0->FCh at 4901 */ - { ZD_CR123, 0x57 }, /* 5613 */ - { ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */ - { ZD_CR126, 0x6c }, /* 5613 */ - { ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */ - { ZD_CR130, 0x10 }, - { ZD_CR131, 0x00 }, /* 5112 */ - { ZD_CR137, 0x50 }, /* 5613 */ - { ZD_CR138, 0xa8 }, /* 5112 */ - { ZD_CR144, 0xac }, /* 5613 */ - { ZD_CR148, 0x40 }, /* 5112 */ - { ZD_CR149, 0x40 }, /* 4O07, 50->40 */ - { ZD_CR150, 0x1a }, /* 5112, 0C->1A */ - { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 }, - { ZD_CR251, 0x2f }, /* PLL_OFF */ - }; - - static const struct zd_ioreq16 ioreqs_3[] = { - { ZD_CR251, 0x7f }, /* PLL_ON */ - { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, - { ZD_CR38, 0x38 }, { ZD_CR136, 0xdf }, - }; - - r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1)); - if (r) - return r; - - if (chip->new_phy_layout) - r = zd_iowrite16a_locked(chip, ioreqs_new_phy, - ARRAY_SIZE(ioreqs_new_phy)); - else - r = zd_iowrite16a_locked(chip, ioreqs_old_phy, - ARRAY_SIZE(ioreqs_old_phy)); - if (r) - return r; - - r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, chan_rv[0], ARRAY_SIZE(chan_rv[0])); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, rv_init1, ARRAY_SIZE(rv_init1)); - if (r) - return r; - - r = zd_iowrite16a_locked(chip, ioreqs_3, ARRAY_SIZE(ioreqs_3)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, rv_init2, ARRAY_SIZE(rv_init2)); - if (r) - return r; - - return zd1211b_al7230b_finalize(chip); -} - -static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel) -{ - int r; - const u32 *rv = chan_rv[channel-1]; - struct zd_chip *chip = zd_rf_to_chip(rf); - - static const struct zd_ioreq16 ioreqs[] = { - /* PLL_ON */ - { ZD_CR251, 0x3f }, - { ZD_CR203, 0x06 }, { ZD_CR240, 0x08 }, - }; - - r = zd_iowrite16_locked(chip, 0x57, ZD_CR240); - if (r) - return r; - - /* PLL_OFF */ - r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv)); - if (r) - return r; - - r = zd_rfwrite_cr_locked(chip, 0x3c9000); - if (r) - return r; - r = zd_rfwrite_cr_locked(chip, 0xf15d58); - if (r) - return r; - - r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, rv, 2); - if (r) - return r; - - r = zd_rfwrite_cr_locked(chip, 0x3c9000); - if (r) - return r; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel) -{ - int r; - const u32 *rv = chan_rv[channel-1]; - struct zd_chip *chip = zd_rf_to_chip(rf); - - r = zd_iowrite16_locked(chip, 0x57, ZD_CR240); - if (r) - return r; - r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9); - if (r) - return r; - - /* PLL_OFF */ - r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251); - if (r) - return r; - r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv)); - if (r) - return r; - - r = zd_rfwrite_cr_locked(chip, 0x3c9000); - if (r) - return r; - r = zd_rfwrite_cr_locked(chip, 0xf15d58); - if (r) - return r; - - r = zd_iowrite16a_locked(chip, ioreqs_sw, ARRAY_SIZE(ioreqs_sw)); - if (r) - return r; - - r = zd_rfwritev_cr_locked(chip, rv, 2); - if (r) - return r; - - r = zd_rfwrite_cr_locked(chip, 0x3c9000); - if (r) - return r; - - r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251); - if (r) - return r; - - return zd1211b_al7230b_finalize(chip); -} - -static int zd1211_al7230b_switch_radio_on(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR11, 0x00 }, - { ZD_CR251, 0x3f }, - }; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int zd1211b_al7230b_switch_radio_on(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR11, 0x00 }, - { ZD_CR251, 0x7f }, - }; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int al7230b_switch_radio_off(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR11, 0x04 }, - { ZD_CR251, 0x2f }, - }; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -/* ZD1211B+AL7230B 6m band edge patching differs slightly from other - * configurations */ -static int zd1211b_al7230b_patch_6m(struct zd_rf *rf, u8 channel) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - struct zd_ioreq16 ioreqs[] = { - { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, - }; - - /* FIXME: Channel 11 is not the edge for all regulatory domains. */ - if (channel == 1) { - ioreqs[0].value = 0x0e; - ioreqs[1].value = 0x10; - } else if (channel == 11) { - ioreqs[0].value = 0x10; - ioreqs[1].value = 0x10; - } - - dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel); - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -int zd_rf_init_al7230b(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - - if (zd_chip_is_zd1211b(chip)) { - rf->init_hw = zd1211b_al7230b_init_hw; - rf->switch_radio_on = zd1211b_al7230b_switch_radio_on; - rf->set_channel = zd1211b_al7230b_set_channel; - rf->patch_6m_band_edge = zd1211b_al7230b_patch_6m; - } else { - rf->init_hw = zd1211_al7230b_init_hw; - rf->switch_radio_on = zd1211_al7230b_switch_radio_on; - rf->set_channel = zd1211_al7230b_set_channel; - rf->patch_6m_band_edge = zd_rf_generic_patch_6m; - rf->patch_cck_gain = 1; - } - - rf->switch_radio_off = al7230b_switch_radio_off; - - return 0; -} diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c deleted file mode 100644 index a93f657..0000000 --- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c +++ /dev/null @@ -1,281 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> - -#include "zd_rf.h" -#include "zd_usb.h" -#include "zd_chip.h" - -static const u32 rf2959_table[][2] = { - RF_CHANNEL( 1) = { 0x181979, 0x1e6666 }, - RF_CHANNEL( 2) = { 0x181989, 0x1e6666 }, - RF_CHANNEL( 3) = { 0x181999, 0x1e6666 }, - RF_CHANNEL( 4) = { 0x1819a9, 0x1e6666 }, - RF_CHANNEL( 5) = { 0x1819b9, 0x1e6666 }, - RF_CHANNEL( 6) = { 0x1819c9, 0x1e6666 }, - RF_CHANNEL( 7) = { 0x1819d9, 0x1e6666 }, - RF_CHANNEL( 8) = { 0x1819e9, 0x1e6666 }, - RF_CHANNEL( 9) = { 0x1819f9, 0x1e6666 }, - RF_CHANNEL(10) = { 0x181a09, 0x1e6666 }, - RF_CHANNEL(11) = { 0x181a19, 0x1e6666 }, - RF_CHANNEL(12) = { 0x181a29, 0x1e6666 }, - RF_CHANNEL(13) = { 0x181a39, 0x1e6666 }, - RF_CHANNEL(14) = { 0x181a60, 0x1c0000 }, -}; - -#if 0 -static int bits(u32 rw, int from, int to) -{ - rw &= ~(0xffffffffU << (to+1)); - rw >>= from; - return rw; -} - -static int bit(u32 rw, int bit) -{ - return bits(rw, bit, bit); -} - -static void dump_regwrite(u32 rw) -{ - int reg = bits(rw, 18, 22); - int rw_flag = bits(rw, 23, 23); - PDEBUG("rf2959 %#010x reg %d rw %d", rw, reg, rw_flag); - - switch (reg) { - case 0: - PDEBUG("reg0 CFG1 ref_sel %d hybernate %d rf_vco_reg_en %d" - " if_vco_reg_en %d if_vga_en %d", - bits(rw, 14, 15), bit(rw, 3), bit(rw, 2), bit(rw, 1), - bit(rw, 0)); - break; - case 1: - PDEBUG("reg1 IFPLL1 pll_en1 %d kv_en1 %d vtc_en1 %d lpf1 %d" - " cpl1 %d pdp1 %d autocal_en1 %d ld_en1 %d ifloopr %d" - " ifloopc %d dac1 %d", - bit(rw, 17), bit(rw, 16), bit(rw, 15), bit(rw, 14), - bit(rw, 13), bit(rw, 12), bit(rw, 11), bit(rw, 10), - bits(rw, 7, 9), bits(rw, 4, 6), bits(rw, 0, 3)); - break; - case 2: - PDEBUG("reg2 IFPLL2 n1 %d num1 %d", - bits(rw, 6, 17), bits(rw, 0, 5)); - break; - case 3: - PDEBUG("reg3 IFPLL3 num %d", bits(rw, 0, 17)); - break; - case 4: - PDEBUG("reg4 IFPLL4 dn1 %#04x ct_def1 %d kv_def1 %d", - bits(rw, 8, 16), bits(rw, 4, 7), bits(rw, 0, 3)); - break; - case 5: - PDEBUG("reg5 RFPLL1 pll_en %d kv_en %d vtc_en %d lpf %d cpl %d" - " pdp %d autocal_en %d ld_en %d rfloopr %d rfloopc %d" - " dac %d", - bit(rw, 17), bit(rw, 16), bit(rw, 15), bit(rw, 14), - bit(rw, 13), bit(rw, 12), bit(rw, 11), bit(rw, 10), - bits(rw, 7, 9), bits(rw, 4, 6), bits(rw, 0,3)); - break; - case 6: - PDEBUG("reg6 RFPLL2 n %d num %d", - bits(rw, 6, 17), bits(rw, 0, 5)); - break; - case 7: - PDEBUG("reg7 RFPLL3 num2 %d", bits(rw, 0, 17)); - break; - case 8: - PDEBUG("reg8 RFPLL4 dn %#06x ct_def %d kv_def %d", - bits(rw, 8, 16), bits(rw, 4, 7), bits(rw, 0, 3)); - break; - case 9: - PDEBUG("reg9 CAL1 tvco %d tlock %d m_ct_value %d ld_window %d", - bits(rw, 13, 17), bits(rw, 8, 12), bits(rw, 3, 7), - bits(rw, 0, 2)); - break; - case 10: - PDEBUG("reg10 TXRX1 rxdcfbbyps %d pcontrol %d txvgc %d" - " rxlpfbw %d txlpfbw %d txdiffmode %d txenmode %d" - " intbiasen %d tybypass %d", - bit(rw, 17), bits(rw, 15, 16), bits(rw, 10, 14), - bits(rw, 7, 9), bits(rw, 4, 6), bit(rw, 3), bit(rw, 2), - bit(rw, 1), bit(rw, 0)); - break; - case 11: - PDEBUG("reg11 PCNT1 mid_bias %d p_desired %d pc_offset %d" - " tx_delay %d", - bits(rw, 15, 17), bits(rw, 9, 14), bits(rw, 3, 8), - bits(rw, 0, 2)); - break; - case 12: - PDEBUG("reg12 PCNT2 max_power %d mid_power %d min_power %d", - bits(rw, 12, 17), bits(rw, 6, 11), bits(rw, 0, 5)); - break; - case 13: - PDEBUG("reg13 VCOT1 rfpll vco comp %d ifpll vco comp %d" - " lobias %d if_biasbuf %d if_biasvco %d rf_biasbuf %d" - " rf_biasvco %d", - bit(rw, 17), bit(rw, 16), bit(rw, 15), - bits(rw, 8, 9), bits(rw, 5, 7), bits(rw, 3, 4), - bits(rw, 0, 2)); - break; - case 14: - PDEBUG("reg14 IQCAL rx_acal %d rx_pcal %d" - " tx_acal %d tx_pcal %d", - bits(rw, 13, 17), bits(rw, 9, 12), bits(rw, 4, 8), - bits(rw, 0, 3)); - break; - } -} -#endif /* 0 */ - -static int rf2959_init_hw(struct zd_rf *rf) -{ - int r; - struct zd_chip *chip = zd_rf_to_chip(rf); - - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR2, 0x1E }, { ZD_CR9, 0x20 }, { ZD_CR10, 0x89 }, - { ZD_CR11, 0x00 }, { ZD_CR15, 0xD0 }, { ZD_CR17, 0x68 }, - { ZD_CR19, 0x4a }, { ZD_CR20, 0x0c }, { ZD_CR21, 0x0E }, - { ZD_CR23, 0x48 }, - /* normal size for cca threshold */ - { ZD_CR24, 0x14 }, - /* { ZD_CR24, 0x20 }, */ - { ZD_CR26, 0x90 }, { ZD_CR27, 0x30 }, { ZD_CR29, 0x20 }, - { ZD_CR31, 0xb2 }, { ZD_CR32, 0x43 }, { ZD_CR33, 0x28 }, - { ZD_CR38, 0x30 }, { ZD_CR34, 0x0f }, { ZD_CR35, 0xF0 }, - { ZD_CR41, 0x2a }, { ZD_CR46, 0x7F }, { ZD_CR47, 0x1E }, - { ZD_CR51, 0xc5 }, { ZD_CR52, 0xc5 }, { ZD_CR53, 0xc5 }, - { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, - { ZD_CR82, 0x00 }, { ZD_CR83, 0x24 }, { ZD_CR84, 0x04 }, - { ZD_CR85, 0x00 }, { ZD_CR86, 0x10 }, { ZD_CR87, 0x2A }, - { ZD_CR88, 0x10 }, { ZD_CR89, 0x24 }, { ZD_CR90, 0x18 }, - /* { ZD_CR91, 0x18 }, */ - /* should solve continuous CTS frame problems */ - { ZD_CR91, 0x00 }, - { ZD_CR92, 0x0a }, { ZD_CR93, 0x00 }, { ZD_CR94, 0x01 }, - { ZD_CR95, 0x00 }, { ZD_CR96, 0x40 }, { ZD_CR97, 0x37 }, - { ZD_CR98, 0x05 }, { ZD_CR99, 0x28 }, { ZD_CR100, 0x00 }, - { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, - { ZD_CR104, 0x18 }, { ZD_CR105, 0x12 }, - /* normal size */ - { ZD_CR106, 0x1a }, - /* { ZD_CR106, 0x22 }, */ - { ZD_CR107, 0x24 }, { ZD_CR108, 0x0a }, { ZD_CR109, 0x13 }, - { ZD_CR110, 0x2F }, { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, - { ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x40 }, - { ZD_CR116, 0x40 }, { ZD_CR117, 0xF0 }, { ZD_CR118, 0xF0 }, - { ZD_CR119, 0x16 }, - /* no TX continuation */ - { ZD_CR122, 0x00 }, - /* { ZD_CR122, 0xff }, */ - { ZD_CR127, 0x03 }, { ZD_CR131, 0x08 }, { ZD_CR138, 0x28 }, - { ZD_CR148, 0x44 }, { ZD_CR150, 0x10 }, { ZD_CR169, 0xBB }, - { ZD_CR170, 0xBB }, - }; - - static const u32 rv[] = { - 0x000007, /* REG0(CFG1) */ - 0x07dd43, /* REG1(IFPLL1) */ - 0x080959, /* REG2(IFPLL2) */ - 0x0e6666, - 0x116a57, /* REG4 */ - 0x17dd43, /* REG5 */ - 0x1819f9, /* REG6 */ - 0x1e6666, - 0x214554, - 0x25e7fa, - 0x27fffa, - /* The Zydas driver somehow forgets to set this value. It's - * only set for Japan. We are using internal power control - * for now. - */ - 0x294128, /* internal power */ - /* 0x28252c, */ /* External control TX power */ - /* ZD_CR31_CCK, ZD_CR51_6-36M, ZD_CR52_48M, ZD_CR53_54M */ - 0x2c0000, - 0x300000, - 0x340000, /* REG13(0xD) */ - 0x381e0f, /* REG14(0xE) */ - /* Bogus, RF2959's data sheet doesn't know register 27, which is - * actually referenced here. The commented 0x11 is 17. - */ - 0x6c180f, /* REG27(0x11) */ - }; - - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - return r; - - return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS); -} - -static int rf2959_set_channel(struct zd_rf *rf, u8 channel) -{ - int i, r; - const u32 *rv = rf2959_table[channel-1]; - struct zd_chip *chip = zd_rf_to_chip(rf); - - for (i = 0; i < 2; i++) { - r = zd_rfwrite_locked(chip, rv[i], RF_RV_BITS); - if (r) - return r; - } - return 0; -} - -static int rf2959_switch_radio_on(struct zd_rf *rf) -{ - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR10, 0x89 }, - { ZD_CR11, 0x00 }, - }; - struct zd_chip *chip = zd_rf_to_chip(rf); - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int rf2959_switch_radio_off(struct zd_rf *rf) -{ - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR10, 0x15 }, - { ZD_CR11, 0x81 }, - }; - struct zd_chip *chip = zd_rf_to_chip(rf); - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -int zd_rf_init_rf2959(struct zd_rf *rf) -{ - struct zd_chip *chip = zd_rf_to_chip(rf); - - if (zd_chip_is_zd1211b(chip)) { - dev_err(zd_chip_dev(chip), - "RF2959 is currently not supported for ZD1211B" - " devices\n"); - return -ENODEV; - } - rf->init_hw = rf2959_init_hw; - rf->set_channel = rf2959_set_channel; - rf->switch_radio_on = rf2959_switch_radio_on; - rf->switch_radio_off = rf2959_switch_radio_off; - return 0; -} diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c deleted file mode 100644 index 61b9240..0000000 --- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c +++ /dev/null @@ -1,539 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> - -#include "zd_rf.h" -#include "zd_usb.h" -#include "zd_chip.h" - -/* This RF programming code is based upon the code found in v2.16.0.0 of the - * ZyDAS vendor driver. Unlike other RF's, Ubec publish full technical specs - * for this RF on their website, so we're able to understand more than - * usual as to what is going on. Thumbs up for Ubec for doing that. */ - -/* The 3-wire serial interface provides access to 8 write-only registers. - * The data format is a 4 bit register address followed by a 20 bit value. */ -#define UW2453_REGWRITE(reg, val) ((((reg) & 0xf) << 20) | ((val) & 0xfffff)) - -/* For channel tuning, we have to configure registers 1 (synthesizer), 2 (synth - * fractional divide ratio) and 3 (VCO config). - * - * We configure the RF to produce an interrupt when the PLL is locked onto - * the configured frequency. During initialization, we run through a variety - * of different VCO configurations on channel 1 until we detect a PLL lock. - * When this happens, we remember which VCO configuration produced the lock - * and use it later. Actually, we use the configuration *after* the one that - * produced the lock, which seems odd, but it works. - * - * If we do not see a PLL lock on any standard VCO config, we fall back on an - * autocal configuration, which has a fixed (as opposed to per-channel) VCO - * config and different synth values from the standard set (divide ratio - * is still shared with the standard set). */ - -/* The per-channel synth values for all standard VCO configurations. These get - * written to register 1. */ -static const u8 uw2453_std_synth[] = { - RF_CHANNEL( 1) = 0x47, - RF_CHANNEL( 2) = 0x47, - RF_CHANNEL( 3) = 0x67, - RF_CHANNEL( 4) = 0x67, - RF_CHANNEL( 5) = 0x67, - RF_CHANNEL( 6) = 0x67, - RF_CHANNEL( 7) = 0x57, - RF_CHANNEL( 8) = 0x57, - RF_CHANNEL( 9) = 0x57, - RF_CHANNEL(10) = 0x57, - RF_CHANNEL(11) = 0x77, - RF_CHANNEL(12) = 0x77, - RF_CHANNEL(13) = 0x77, - RF_CHANNEL(14) = 0x4f, -}; - -/* This table stores the synthesizer fractional divide ratio for *all* VCO - * configurations (both standard and autocal). These get written to register 2. - */ -static const u16 uw2453_synth_divide[] = { - RF_CHANNEL( 1) = 0x999, - RF_CHANNEL( 2) = 0x99b, - RF_CHANNEL( 3) = 0x998, - RF_CHANNEL( 4) = 0x99a, - RF_CHANNEL( 5) = 0x999, - RF_CHANNEL( 6) = 0x99b, - RF_CHANNEL( 7) = 0x998, - RF_CHANNEL( 8) = 0x99a, - RF_CHANNEL( 9) = 0x999, - RF_CHANNEL(10) = 0x99b, - RF_CHANNEL(11) = 0x998, - RF_CHANNEL(12) = 0x99a, - RF_CHANNEL(13) = 0x999, - RF_CHANNEL(14) = 0xccc, -}; - -/* Here is the data for all the standard VCO configurations. We shrink our - * table a little by observing that both channels in a consecutive pair share - * the same value. We also observe that the high 4 bits ([0:3] in the specs) - * are all 'Reserved' and are always set to 0x4 - we chop them off in the data - * below. */ -#define CHAN_TO_PAIRIDX(a) ((a - 1) / 2) -#define RF_CHANPAIR(a,b) [CHAN_TO_PAIRIDX(a)] -static const u16 uw2453_std_vco_cfg[][7] = { - { /* table 1 */ - RF_CHANPAIR( 1, 2) = 0x664d, - RF_CHANPAIR( 3, 4) = 0x604d, - RF_CHANPAIR( 5, 6) = 0x6675, - RF_CHANPAIR( 7, 8) = 0x6475, - RF_CHANPAIR( 9, 10) = 0x6655, - RF_CHANPAIR(11, 12) = 0x6455, - RF_CHANPAIR(13, 14) = 0x6665, - }, - { /* table 2 */ - RF_CHANPAIR( 1, 2) = 0x666d, - RF_CHANPAIR( 3, 4) = 0x606d, - RF_CHANPAIR( 5, 6) = 0x664d, - RF_CHANPAIR( 7, 8) = 0x644d, - RF_CHANPAIR( 9, 10) = 0x6675, - RF_CHANPAIR(11, 12) = 0x6475, - RF_CHANPAIR(13, 14) = 0x6655, - }, - { /* table 3 */ - RF_CHANPAIR( 1, 2) = 0x665d, - RF_CHANPAIR( 3, 4) = 0x605d, - RF_CHANPAIR( 5, 6) = 0x666d, - RF_CHANPAIR( 7, 8) = 0x646d, - RF_CHANPAIR( 9, 10) = 0x664d, - RF_CHANPAIR(11, 12) = 0x644d, - RF_CHANPAIR(13, 14) = 0x6675, - }, - { /* table 4 */ - RF_CHANPAIR( 1, 2) = 0x667d, - RF_CHANPAIR( 3, 4) = 0x607d, - RF_CHANPAIR( 5, 6) = 0x665d, - RF_CHANPAIR( 7, 8) = 0x645d, - RF_CHANPAIR( 9, 10) = 0x666d, - RF_CHANPAIR(11, 12) = 0x646d, - RF_CHANPAIR(13, 14) = 0x664d, - }, - { /* table 5 */ - RF_CHANPAIR( 1, 2) = 0x6643, - RF_CHANPAIR( 3, 4) = 0x6043, - RF_CHANPAIR( 5, 6) = 0x667d, - RF_CHANPAIR( 7, 8) = 0x647d, - RF_CHANPAIR( 9, 10) = 0x665d, - RF_CHANPAIR(11, 12) = 0x645d, - RF_CHANPAIR(13, 14) = 0x666d, - }, - { /* table 6 */ - RF_CHANPAIR( 1, 2) = 0x6663, - RF_CHANPAIR( 3, 4) = 0x6063, - RF_CHANPAIR( 5, 6) = 0x6643, - RF_CHANPAIR( 7, 8) = 0x6443, - RF_CHANPAIR( 9, 10) = 0x667d, - RF_CHANPAIR(11, 12) = 0x647d, - RF_CHANPAIR(13, 14) = 0x665d, - }, - { /* table 7 */ - RF_CHANPAIR( 1, 2) = 0x6653, - RF_CHANPAIR( 3, 4) = 0x6053, - RF_CHANPAIR( 5, 6) = 0x6663, - RF_CHANPAIR( 7, 8) = 0x6463, - RF_CHANPAIR( 9, 10) = 0x6643, - RF_CHANPAIR(11, 12) = 0x6443, - RF_CHANPAIR(13, 14) = 0x667d, - }, - { /* table 8 */ - RF_CHANPAIR( 1, 2) = 0x6673, - RF_CHANPAIR( 3, 4) = 0x6073, - RF_CHANPAIR( 5, 6) = 0x6653, - RF_CHANPAIR( 7, 8) = 0x6453, - RF_CHANPAIR( 9, 10) = 0x6663, - RF_CHANPAIR(11, 12) = 0x6463, - RF_CHANPAIR(13, 14) = 0x6643, - }, - { /* table 9 */ - RF_CHANPAIR( 1, 2) = 0x664b, - RF_CHANPAIR( 3, 4) = 0x604b, - RF_CHANPAIR( 5, 6) = 0x6673, - RF_CHANPAIR( 7, 8) = 0x6473, - RF_CHANPAIR( 9, 10) = 0x6653, - RF_CHANPAIR(11, 12) = 0x6453, - RF_CHANPAIR(13, 14) = 0x6663, - }, - { /* table 10 */ - RF_CHANPAIR( 1, 2) = 0x666b, - RF_CHANPAIR( 3, 4) = 0x606b, - RF_CHANPAIR( 5, 6) = 0x664b, - RF_CHANPAIR( 7, 8) = 0x644b, - RF_CHANPAIR( 9, 10) = 0x6673, - RF_CHANPAIR(11, 12) = 0x6473, - RF_CHANPAIR(13, 14) = 0x6653, - }, - { /* table 11 */ - RF_CHANPAIR( 1, 2) = 0x665b, - RF_CHANPAIR( 3, 4) = 0x605b, - RF_CHANPAIR( 5, 6) = 0x666b, - RF_CHANPAIR( 7, 8) = 0x646b, - RF_CHANPAIR( 9, 10) = 0x664b, - RF_CHANPAIR(11, 12) = 0x644b, - RF_CHANPAIR(13, 14) = 0x6673, - }, - -}; - -/* The per-channel synth values for autocal. These get written to register 1. */ -static const u16 uw2453_autocal_synth[] = { - RF_CHANNEL( 1) = 0x6847, - RF_CHANNEL( 2) = 0x6847, - RF_CHANNEL( 3) = 0x6867, - RF_CHANNEL( 4) = 0x6867, - RF_CHANNEL( 5) = 0x6867, - RF_CHANNEL( 6) = 0x6867, - RF_CHANNEL( 7) = 0x6857, - RF_CHANNEL( 8) = 0x6857, - RF_CHANNEL( 9) = 0x6857, - RF_CHANNEL(10) = 0x6857, - RF_CHANNEL(11) = 0x6877, - RF_CHANNEL(12) = 0x6877, - RF_CHANNEL(13) = 0x6877, - RF_CHANNEL(14) = 0x684f, -}; - -/* The VCO configuration for autocal (all channels) */ -static const u16 UW2453_AUTOCAL_VCO_CFG = 0x6662; - -/* TX gain settings. The array index corresponds to the TX power integration - * values found in the EEPROM. The values get written to register 7. */ -static u32 uw2453_txgain[] = { - [0x00] = 0x0e313, - [0x01] = 0x0fb13, - [0x02] = 0x0e093, - [0x03] = 0x0f893, - [0x04] = 0x0ea93, - [0x05] = 0x1f093, - [0x06] = 0x1f493, - [0x07] = 0x1f693, - [0x08] = 0x1f393, - [0x09] = 0x1f35b, - [0x0a] = 0x1e6db, - [0x0b] = 0x1ff3f, - [0x0c] = 0x1ffff, - [0x0d] = 0x361d7, - [0x0e] = 0x37fbf, - [0x0f] = 0x3ff8b, - [0x10] = 0x3ff33, - [0x11] = 0x3fb3f, - [0x12] = 0x3ffff, -}; - -/* RF-specific structure */ -struct uw2453_priv { - /* index into synth/VCO config tables where PLL lock was found - * -1 means autocal */ - int config; -}; - -#define UW2453_PRIV(rf) ((struct uw2453_priv *) (rf)->priv) - -static int uw2453_synth_set_channel(struct zd_chip *chip, int channel, - bool autocal) -{ - int r; - int idx = channel - 1; - u32 val; - - if (autocal) - val = UW2453_REGWRITE(1, uw2453_autocal_synth[idx]); - else - val = UW2453_REGWRITE(1, uw2453_std_synth[idx]); - - r = zd_rfwrite_locked(chip, val, RF_RV_BITS); - if (r) - return r; - - return zd_rfwrite_locked(chip, - UW2453_REGWRITE(2, uw2453_synth_divide[idx]), RF_RV_BITS); -} - -static int uw2453_write_vco_cfg(struct zd_chip *chip, u16 value) -{ - /* vendor driver always sets these upper bits even though the specs say - * they are reserved */ - u32 val = 0x40000 | value; - return zd_rfwrite_locked(chip, UW2453_REGWRITE(3, val), RF_RV_BITS); -} - -static int uw2453_init_mode(struct zd_chip *chip) -{ - static const u32 rv[] = { - UW2453_REGWRITE(0, 0x25f98), /* enter IDLE mode */ - UW2453_REGWRITE(0, 0x25f9a), /* enter CAL_VCO mode */ - UW2453_REGWRITE(0, 0x25f94), /* enter RX/TX mode */ - UW2453_REGWRITE(0, 0x27fd4), /* power down RSSI circuit */ - }; - - return zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS); -} - -static int uw2453_set_tx_gain_level(struct zd_chip *chip, int channel) -{ - u8 int_value = chip->pwr_int_values[channel - 1]; - - if (int_value >= ARRAY_SIZE(uw2453_txgain)) { - dev_dbg_f(zd_chip_dev(chip), "can't configure TX gain for " - "int value %x on channel %d\n", int_value, channel); - return 0; - } - - return zd_rfwrite_locked(chip, - UW2453_REGWRITE(7, uw2453_txgain[int_value]), RF_RV_BITS); -} - -static int uw2453_init_hw(struct zd_rf *rf) -{ - int i, r; - int found_config = -1; - u16 intr_status; - struct zd_chip *chip = zd_rf_to_chip(rf); - - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR10, 0x89 }, { ZD_CR15, 0x20 }, - { ZD_CR17, 0x28 }, /* 6112 no change */ - { ZD_CR23, 0x38 }, { ZD_CR24, 0x20 }, { ZD_CR26, 0x93 }, - { ZD_CR27, 0x15 }, { ZD_CR28, 0x3e }, { ZD_CR29, 0x00 }, - { ZD_CR33, 0x28 }, { ZD_CR34, 0x30 }, - { ZD_CR35, 0x43 }, /* 6112 3e->43 */ - { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 }, - { ZD_CR46, 0x92 }, /* 6112 96->92 */ - { ZD_CR47, 0x1e }, - { ZD_CR48, 0x04 }, /* 5602 Roger */ - { ZD_CR49, 0xfa }, { ZD_CR79, 0x58 }, { ZD_CR80, 0x30 }, - { ZD_CR81, 0x30 }, { ZD_CR87, 0x0a }, { ZD_CR89, 0x04 }, - { ZD_CR91, 0x00 }, { ZD_CR92, 0x0a }, { ZD_CR98, 0x8d }, - { ZD_CR99, 0x28 }, { ZD_CR100, 0x02 }, - { ZD_CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */ - { ZD_CR102, 0x27 }, - { ZD_CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f - * 6221 1f->1c - */ - { ZD_CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */ - { ZD_CR109, 0x13 }, - { ZD_CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */ - { ZD_CR111, 0x13 }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 }, - { ZD_CR114, 0x23 }, /* 6221 27->23 */ - { ZD_CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */ - { ZD_CR116, 0x24 }, /* 6220 1c->24 */ - { ZD_CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */ - { ZD_CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */ - { ZD_CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */ - { ZD_CR120, 0x4f }, - { ZD_CR121, 0x1f }, /* 6220 4f->1f */ - { ZD_CR122, 0xf0 }, { ZD_CR123, 0x57 }, { ZD_CR125, 0xad }, - { ZD_CR126, 0x6c }, { ZD_CR127, 0x03 }, - { ZD_CR128, 0x14 }, /* 6302 12->11 */ - { ZD_CR129, 0x12 }, /* 6301 10->0f */ - { ZD_CR130, 0x10 }, { ZD_CR137, 0x50 }, { ZD_CR138, 0xa8 }, - { ZD_CR144, 0xac }, { ZD_CR146, 0x20 }, { ZD_CR252, 0xff }, - { ZD_CR253, 0xff }, - }; - - static const u32 rv[] = { - UW2453_REGWRITE(4, 0x2b), /* configure receiver gain */ - UW2453_REGWRITE(5, 0x19e4f), /* configure transmitter gain */ - UW2453_REGWRITE(6, 0xf81ad), /* enable RX/TX filter tuning */ - UW2453_REGWRITE(7, 0x3fffe), /* disable TX gain in test mode */ - - /* enter CAL_FIL mode, TX gain set by registers, RX gain set by pins, - * RSSI circuit powered down, reduced RSSI range */ - UW2453_REGWRITE(0, 0x25f9c), /* 5d01 cal_fil */ - - /* synthesizer configuration for channel 1 */ - UW2453_REGWRITE(1, 0x47), - UW2453_REGWRITE(2, 0x999), - - /* disable manual VCO band selection */ - UW2453_REGWRITE(3, 0x7602), - - /* enable manual VCO band selection, configure current level */ - UW2453_REGWRITE(3, 0x46063), - }; - - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - return r; - - r = zd_rfwritev_locked(chip, rv, ARRAY_SIZE(rv), RF_RV_BITS); - if (r) - return r; - - r = uw2453_init_mode(chip); - if (r) - return r; - - /* Try all standard VCO configuration settings on channel 1 */ - for (i = 0; i < ARRAY_SIZE(uw2453_std_vco_cfg) - 1; i++) { - /* Configure synthesizer for channel 1 */ - r = uw2453_synth_set_channel(chip, 1, false); - if (r) - return r; - - /* Write VCO config */ - r = uw2453_write_vco_cfg(chip, uw2453_std_vco_cfg[i][0]); - if (r) - return r; - - /* ack interrupt event */ - r = zd_iowrite16_locked(chip, 0x0f, UW2453_INTR_REG); - if (r) - return r; - - /* check interrupt status */ - r = zd_ioread16_locked(chip, &intr_status, UW2453_INTR_REG); - if (r) - return r; - - if (!(intr_status & 0xf)) { - dev_dbg_f(zd_chip_dev(chip), - "PLL locked on configuration %d\n", i); - found_config = i; - break; - } - } - - if (found_config == -1) { - /* autocal */ - dev_dbg_f(zd_chip_dev(chip), - "PLL did not lock, using autocal\n"); - - r = uw2453_synth_set_channel(chip, 1, true); - if (r) - return r; - - r = uw2453_write_vco_cfg(chip, UW2453_AUTOCAL_VCO_CFG); - if (r) - return r; - } - - /* To match the vendor driver behaviour, we use the configuration after - * the one that produced a lock. */ - UW2453_PRIV(rf)->config = found_config + 1; - - return zd_iowrite16_locked(chip, 0x06, ZD_CR203); -} - -static int uw2453_set_channel(struct zd_rf *rf, u8 channel) -{ - int r; - u16 vco_cfg; - int config = UW2453_PRIV(rf)->config; - bool autocal = (config == -1); - struct zd_chip *chip = zd_rf_to_chip(rf); - - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 }, - { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 }, - }; - - r = uw2453_synth_set_channel(chip, channel, autocal); - if (r) - return r; - - if (autocal) - vco_cfg = UW2453_AUTOCAL_VCO_CFG; - else - vco_cfg = uw2453_std_vco_cfg[config][CHAN_TO_PAIRIDX(channel)]; - - r = uw2453_write_vco_cfg(chip, vco_cfg); - if (r) - return r; - - r = uw2453_init_mode(chip); - if (r) - return r; - - r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); - if (r) - return r; - - r = uw2453_set_tx_gain_level(chip, channel); - if (r) - return r; - - return zd_iowrite16_locked(chip, 0x06, ZD_CR203); -} - -static int uw2453_switch_radio_on(struct zd_rf *rf) -{ - int r; - struct zd_chip *chip = zd_rf_to_chip(rf); - struct zd_ioreq16 ioreqs[] = { - { ZD_CR11, 0x00 }, { ZD_CR251, 0x3f }, - }; - - /* enter RXTX mode */ - r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f94), RF_RV_BITS); - if (r) - return r; - - if (zd_chip_is_zd1211b(chip)) - ioreqs[1].value = 0x7f; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static int uw2453_switch_radio_off(struct zd_rf *rf) -{ - int r; - struct zd_chip *chip = zd_rf_to_chip(rf); - static const struct zd_ioreq16 ioreqs[] = { - { ZD_CR11, 0x04 }, { ZD_CR251, 0x2f }, - }; - - /* enter IDLE mode */ - /* FIXME: shouldn't we go to SLEEP? sent email to zydas */ - r = zd_rfwrite_locked(chip, UW2453_REGWRITE(0, 0x25f90), RF_RV_BITS); - if (r) - return r; - - return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); -} - -static void uw2453_clear(struct zd_rf *rf) -{ - kfree(rf->priv); -} - -int zd_rf_init_uw2453(struct zd_rf *rf) -{ - rf->init_hw = uw2453_init_hw; - rf->set_channel = uw2453_set_channel; - rf->switch_radio_on = uw2453_switch_radio_on; - rf->switch_radio_off = uw2453_switch_radio_off; - rf->patch_6m_band_edge = zd_rf_generic_patch_6m; - rf->clear = uw2453_clear; - /* we have our own TX integration code */ - rf->update_channel_int = 0; - - rf->priv = kmalloc(sizeof(struct uw2453_priv), GFP_KERNEL); - if (rf->priv == NULL) - return -ENOMEM; - - return 0; -} - diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c deleted file mode 100644 index a912dc0..0000000 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ /dev/null @@ -1,2060 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/firmware.h> -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/skbuff.h> -#include <linux/usb.h> -#include <linux/workqueue.h> -#include <linux/module.h> -#include <net/mac80211.h> -#include <asm/unaligned.h> - -#include "zd_def.h" -#include "zd_mac.h" -#include "zd_usb.h" - -static struct usb_device_id usb_ids[] = { - /* ZD1211 */ - { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0586, 0x3409), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x079b, 0x004a), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0b3b, 0x1630), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x0df6, 0x9075), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x14ea, 0xab10), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x157e, 0x3204), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x157e, 0x3207), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x1740, 0x2000), .driver_info = DEVICE_ZD1211 }, - { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, - /* ZD1211B */ - { USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0409, 0x0248), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x054c, 0x0257), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0586, 0x340f), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0586, 0x3410), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x083a, 0xe501), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x083a, 0xe503), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x083a, 0xe506), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0b05, 0x171b), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0baf, 0x0121), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x129b, 0x1667), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B }, - { USB_DEVICE(0x2019, 0xed01), .driver_info = DEVICE_ZD1211B }, - /* "Driverless" devices that need ejecting */ - { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, - { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, - {} -}; - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("USB driver for devices with the ZD1211 chip."); -MODULE_AUTHOR("Ulrich Kunitz"); -MODULE_AUTHOR("Daniel Drake"); -MODULE_VERSION("1.0"); -MODULE_DEVICE_TABLE(usb, usb_ids); - -#define FW_ZD1211_PREFIX "zd1211/zd1211_" -#define FW_ZD1211B_PREFIX "zd1211/zd1211b_" - -static bool check_read_regs(struct zd_usb *usb, struct usb_req_read_regs *req, - unsigned int count); - -/* USB device initialization */ -static void int_urb_complete(struct urb *urb); - -static int request_fw_file( - const struct firmware **fw, const char *name, struct device *device) -{ - int r; - - dev_dbg_f(device, "fw name %s\n", name); - - r = request_firmware(fw, name, device); - if (r) - dev_err(device, - "Could not load firmware file %s. Error number %d\n", - name, r); - return r; -} - -static inline u16 get_bcdDevice(const struct usb_device *udev) -{ - return le16_to_cpu(udev->descriptor.bcdDevice); -} - -enum upload_code_flags { - REBOOT = 1, -}; - -/* Ensures that MAX_TRANSFER_SIZE is even. */ -#define MAX_TRANSFER_SIZE (USB_MAX_TRANSFER_SIZE & ~1) - -static int upload_code(struct usb_device *udev, - const u8 *data, size_t size, u16 code_offset, int flags) -{ - u8 *p; - int r; - - /* USB request blocks need "kmalloced" buffers. - */ - p = kmalloc(MAX_TRANSFER_SIZE, GFP_KERNEL); - if (!p) { - r = -ENOMEM; - goto error; - } - - size &= ~1; - while (size > 0) { - size_t transfer_size = size <= MAX_TRANSFER_SIZE ? - size : MAX_TRANSFER_SIZE; - - dev_dbg_f(&udev->dev, "transfer size %zu\n", transfer_size); - - memcpy(p, data, transfer_size); - r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - USB_REQ_FIRMWARE_DOWNLOAD, - USB_DIR_OUT | USB_TYPE_VENDOR, - code_offset, 0, p, transfer_size, 1000 /* ms */); - if (r < 0) { - dev_err(&udev->dev, - "USB control request for firmware upload" - " failed. Error number %d\n", r); - goto error; - } - transfer_size = r & ~1; - - size -= transfer_size; - data += transfer_size; - code_offset += transfer_size/sizeof(u16); - } - - if (flags & REBOOT) { - u8 ret; - - /* Use "DMA-aware" buffer. */ - r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - USB_REQ_FIRMWARE_CONFIRM, - USB_DIR_IN | USB_TYPE_VENDOR, - 0, 0, p, sizeof(ret), 5000 /* ms */); - if (r != sizeof(ret)) { - dev_err(&udev->dev, - "control request firmeware confirmation failed." - " Return value %d\n", r); - if (r >= 0) - r = -ENODEV; - goto error; - } - ret = p[0]; - if (ret & 0x80) { - dev_err(&udev->dev, - "Internal error while downloading." - " Firmware confirm return value %#04x\n", - (unsigned int)ret); - r = -ENODEV; - goto error; - } - dev_dbg_f(&udev->dev, "firmware confirm return value %#04x\n", - (unsigned int)ret); - } - - r = 0; -error: - kfree(p); - return r; -} - -static u16 get_word(const void *data, u16 offset) -{ - const __le16 *p = data; - return le16_to_cpu(p[offset]); -} - -static char *get_fw_name(struct zd_usb *usb, char *buffer, size_t size, - const char* postfix) -{ - scnprintf(buffer, size, "%s%s", - usb->is_zd1211b ? - FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX, - postfix); - return buffer; -} - -static int handle_version_mismatch(struct zd_usb *usb, - const struct firmware *ub_fw) -{ - struct usb_device *udev = zd_usb_to_usbdev(usb); - const struct firmware *ur_fw = NULL; - int offset; - int r = 0; - char fw_name[128]; - - r = request_fw_file(&ur_fw, - get_fw_name(usb, fw_name, sizeof(fw_name), "ur"), - &udev->dev); - if (r) - goto error; - - r = upload_code(udev, ur_fw->data, ur_fw->size, FW_START, REBOOT); - if (r) - goto error; - - offset = (E2P_BOOT_CODE_OFFSET * sizeof(u16)); - r = upload_code(udev, ub_fw->data + offset, ub_fw->size - offset, - E2P_START + E2P_BOOT_CODE_OFFSET, REBOOT); - - /* At this point, the vendor driver downloads the whole firmware - * image, hacks around with version IDs, and uploads it again, - * completely overwriting the boot code. We do not do this here as - * it is not required on any tested devices, and it is suspected to - * cause problems. */ -error: - release_firmware(ur_fw); - return r; -} - -static int upload_firmware(struct zd_usb *usb) -{ - int r; - u16 fw_bcdDevice; - u16 bcdDevice; - struct usb_device *udev = zd_usb_to_usbdev(usb); - const struct firmware *ub_fw = NULL; - const struct firmware *uph_fw = NULL; - char fw_name[128]; - - bcdDevice = get_bcdDevice(udev); - - r = request_fw_file(&ub_fw, - get_fw_name(usb, fw_name, sizeof(fw_name), "ub"), - &udev->dev); - if (r) - goto error; - - fw_bcdDevice = get_word(ub_fw->data, E2P_DATA_OFFSET); - - if (fw_bcdDevice != bcdDevice) { - dev_info(&udev->dev, - "firmware version %#06x and device bootcode version " - "%#06x differ\n", fw_bcdDevice, bcdDevice); - if (bcdDevice <= 0x4313) - dev_warn(&udev->dev, "device has old bootcode, please " - "report success or failure\n"); - - r = handle_version_mismatch(usb, ub_fw); - if (r) - goto error; - } else { - dev_dbg_f(&udev->dev, - "firmware device id %#06x is equal to the " - "actual device id\n", fw_bcdDevice); - } - - - r = request_fw_file(&uph_fw, - get_fw_name(usb, fw_name, sizeof(fw_name), "uphr"), - &udev->dev); - if (r) - goto error; - - r = upload_code(udev, uph_fw->data, uph_fw->size, FW_START, REBOOT); - if (r) { - dev_err(&udev->dev, - "Could not upload firmware code uph. Error number %d\n", - r); - } - - /* FALL-THROUGH */ -error: - release_firmware(ub_fw); - release_firmware(uph_fw); - return r; -} - -MODULE_FIRMWARE(FW_ZD1211B_PREFIX "ur"); -MODULE_FIRMWARE(FW_ZD1211_PREFIX "ur"); -MODULE_FIRMWARE(FW_ZD1211B_PREFIX "ub"); -MODULE_FIRMWARE(FW_ZD1211_PREFIX "ub"); -MODULE_FIRMWARE(FW_ZD1211B_PREFIX "uphr"); -MODULE_FIRMWARE(FW_ZD1211_PREFIX "uphr"); - -/* Read data from device address space using "firmware interface" which does - * not require firmware to be loaded. */ -int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len) -{ - int r; - struct usb_device *udev = zd_usb_to_usbdev(usb); - u8 *buf; - - /* Use "DMA-aware" buffer. */ - buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0, - buf, len, 5000); - if (r < 0) { - dev_err(&udev->dev, - "read over firmware interface failed: %d\n", r); - goto exit; - } else if (r != len) { - dev_err(&udev->dev, - "incomplete read over firmware interface: %d/%d\n", - r, len); - r = -EIO; - goto exit; - } - r = 0; - memcpy(data, buf, len); -exit: - kfree(buf); - return r; -} - -#define urb_dev(urb) (&(urb)->dev->dev) - -static inline void handle_regs_int_override(struct urb *urb) -{ - struct zd_usb *usb = urb->context; - struct zd_usb_interrupt *intr = &usb->intr; - - spin_lock(&intr->lock); - if (atomic_read(&intr->read_regs_enabled)) { - atomic_set(&intr->read_regs_enabled, 0); - intr->read_regs_int_overridden = 1; - complete(&intr->read_regs.completion); - } - spin_unlock(&intr->lock); -} - -static inline void handle_regs_int(struct urb *urb) -{ - struct zd_usb *usb = urb->context; - struct zd_usb_interrupt *intr = &usb->intr; - int len; - u16 int_num; - - ZD_ASSERT(in_interrupt()); - spin_lock(&intr->lock); - - int_num = le16_to_cpu(*(__le16 *)(urb->transfer_buffer+2)); - if (int_num == CR_INTERRUPT) { - struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context)); - spin_lock(&mac->lock); - memcpy(&mac->intr_buffer, urb->transfer_buffer, - USB_MAX_EP_INT_BUFFER); - spin_unlock(&mac->lock); - schedule_work(&mac->process_intr); - } else if (atomic_read(&intr->read_regs_enabled)) { - len = urb->actual_length; - intr->read_regs.length = urb->actual_length; - if (len > sizeof(intr->read_regs.buffer)) - len = sizeof(intr->read_regs.buffer); - - memcpy(intr->read_regs.buffer, urb->transfer_buffer, len); - - /* Sometimes USB_INT_ID_REGS is not overridden, but comes after - * USB_INT_ID_RETRY_FAILED. Read-reg retry then gets this - * delayed USB_INT_ID_REGS, but leaves USB_INT_ID_REGS of - * retry unhandled. Next read-reg command then might catch - * this wrong USB_INT_ID_REGS. Fix by ignoring wrong reads. - */ - if (!check_read_regs(usb, intr->read_regs.req, - intr->read_regs.req_count)) - goto out; - - atomic_set(&intr->read_regs_enabled, 0); - intr->read_regs_int_overridden = 0; - complete(&intr->read_regs.completion); - - goto out; - } - -out: - spin_unlock(&intr->lock); - - /* CR_INTERRUPT might override read_reg too. */ - if (int_num == CR_INTERRUPT && atomic_read(&intr->read_regs_enabled)) - handle_regs_int_override(urb); -} - -static void int_urb_complete(struct urb *urb) -{ - int r; - struct usb_int_header *hdr; - struct zd_usb *usb; - struct zd_usb_interrupt *intr; - - switch (urb->status) { - case 0: - break; - case -ESHUTDOWN: - case -EINVAL: - case -ENODEV: - case -ENOENT: - case -ECONNRESET: - case -EPIPE: - dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); - return; - default: - dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); - goto resubmit; - } - - if (urb->actual_length < sizeof(hdr)) { - dev_dbg_f(urb_dev(urb), "error: urb %p to small\n", urb); - goto resubmit; - } - - hdr = urb->transfer_buffer; - if (hdr->type != USB_INT_TYPE) { - dev_dbg_f(urb_dev(urb), "error: urb %p wrong type\n", urb); - goto resubmit; - } - - /* USB_INT_ID_RETRY_FAILED triggered by tx-urb submit can override - * pending USB_INT_ID_REGS causing read command timeout. - */ - usb = urb->context; - intr = &usb->intr; - if (hdr->id != USB_INT_ID_REGS && atomic_read(&intr->read_regs_enabled)) - handle_regs_int_override(urb); - - switch (hdr->id) { - case USB_INT_ID_REGS: - handle_regs_int(urb); - break; - case USB_INT_ID_RETRY_FAILED: - zd_mac_tx_failed(urb); - break; - default: - dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb, - (unsigned int)hdr->id); - goto resubmit; - } - -resubmit: - r = usb_submit_urb(urb, GFP_ATOMIC); - if (r) { - dev_dbg_f(urb_dev(urb), "error: resubmit urb %p err code %d\n", - urb, r); - /* TODO: add worker to reset intr->urb */ - } - return; -} - -static inline int int_urb_interval(struct usb_device *udev) -{ - switch (udev->speed) { - case USB_SPEED_HIGH: - return 4; - case USB_SPEED_LOW: - return 10; - case USB_SPEED_FULL: - default: - return 1; - } -} - -static inline int usb_int_enabled(struct zd_usb *usb) -{ - unsigned long flags; - struct zd_usb_interrupt *intr = &usb->intr; - struct urb *urb; - - spin_lock_irqsave(&intr->lock, flags); - urb = intr->urb; - spin_unlock_irqrestore(&intr->lock, flags); - return urb != NULL; -} - -int zd_usb_enable_int(struct zd_usb *usb) -{ - int r; - struct usb_device *udev = zd_usb_to_usbdev(usb); - struct zd_usb_interrupt *intr = &usb->intr; - struct urb *urb; - - dev_dbg_f(zd_usb_dev(usb), "\n"); - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { - r = -ENOMEM; - goto out; - } - - ZD_ASSERT(!irqs_disabled()); - spin_lock_irq(&intr->lock); - if (intr->urb) { - spin_unlock_irq(&intr->lock); - r = 0; - goto error_free_urb; - } - intr->urb = urb; - spin_unlock_irq(&intr->lock); - - r = -ENOMEM; - intr->buffer = usb_alloc_coherent(udev, USB_MAX_EP_INT_BUFFER, - GFP_KERNEL, &intr->buffer_dma); - if (!intr->buffer) { - dev_dbg_f(zd_usb_dev(usb), - "couldn't allocate transfer_buffer\n"); - goto error_set_urb_null; - } - - usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN), - intr->buffer, USB_MAX_EP_INT_BUFFER, - int_urb_complete, usb, - intr->interval); - urb->transfer_dma = intr->buffer_dma; - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb); - r = usb_submit_urb(urb, GFP_KERNEL); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "Couldn't submit urb. Error number %d\n", r); - goto error; - } - - return 0; -error: - usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, - intr->buffer, intr->buffer_dma); -error_set_urb_null: - spin_lock_irq(&intr->lock); - intr->urb = NULL; - spin_unlock_irq(&intr->lock); -error_free_urb: - usb_free_urb(urb); -out: - return r; -} - -void zd_usb_disable_int(struct zd_usb *usb) -{ - unsigned long flags; - struct usb_device *udev = zd_usb_to_usbdev(usb); - struct zd_usb_interrupt *intr = &usb->intr; - struct urb *urb; - void *buffer; - dma_addr_t buffer_dma; - - spin_lock_irqsave(&intr->lock, flags); - urb = intr->urb; - if (!urb) { - spin_unlock_irqrestore(&intr->lock, flags); - return; - } - intr->urb = NULL; - buffer = intr->buffer; - buffer_dma = intr->buffer_dma; - intr->buffer = NULL; - spin_unlock_irqrestore(&intr->lock, flags); - - usb_kill_urb(urb); - dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb); - usb_free_urb(urb); - - if (buffer) - usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, - buffer, buffer_dma); -} - -static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, - unsigned int length) -{ - int i; - const struct rx_length_info *length_info; - - if (length < sizeof(struct rx_length_info)) { - /* It's not a complete packet anyhow. */ - dev_dbg_f(zd_usb_dev(usb), "invalid, small RX packet : %d\n", - length); - return; - } - length_info = (struct rx_length_info *) - (buffer + length - sizeof(struct rx_length_info)); - - /* It might be that three frames are merged into a single URB - * transaction. We have to check for the length info tag. - * - * While testing we discovered that length_info might be unaligned, - * because if USB transactions are merged, the last packet will not - * be padded. Unaligned access might also happen if the length_info - * structure is not present. - */ - if (get_unaligned_le16(&length_info->tag) == RX_LENGTH_INFO_TAG) - { - unsigned int l, k, n; - for (i = 0, l = 0;; i++) { - k = get_unaligned_le16(&length_info->length[i]); - if (k == 0) - return; - n = l+k; - if (n > length) - return; - zd_mac_rx(zd_usb_to_hw(usb), buffer+l, k); - if (i >= 2) - return; - l = (n+3) & ~3; - } - } else { - zd_mac_rx(zd_usb_to_hw(usb), buffer, length); - } -} - -static void rx_urb_complete(struct urb *urb) -{ - int r; - struct zd_usb *usb; - struct zd_usb_rx *rx; - const u8 *buffer; - unsigned int length; - - switch (urb->status) { - case 0: - break; - case -ESHUTDOWN: - case -EINVAL: - case -ENODEV: - case -ENOENT: - case -ECONNRESET: - case -EPIPE: - dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); - return; - default: - dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); - goto resubmit; - } - - buffer = urb->transfer_buffer; - length = urb->actual_length; - usb = urb->context; - rx = &usb->rx; - - tasklet_schedule(&rx->reset_timer_tasklet); - - if (length%rx->usb_packet_size > rx->usb_packet_size-4) { - /* If there is an old first fragment, we don't care. */ - dev_dbg_f(urb_dev(urb), "*** first fragment ***\n"); - ZD_ASSERT(length <= ARRAY_SIZE(rx->fragment)); - spin_lock(&rx->lock); - memcpy(rx->fragment, buffer, length); - rx->fragment_length = length; - spin_unlock(&rx->lock); - goto resubmit; - } - - spin_lock(&rx->lock); - if (rx->fragment_length > 0) { - /* We are on a second fragment, we believe */ - ZD_ASSERT(length + rx->fragment_length <= - ARRAY_SIZE(rx->fragment)); - dev_dbg_f(urb_dev(urb), "*** second fragment ***\n"); - memcpy(rx->fragment+rx->fragment_length, buffer, length); - handle_rx_packet(usb, rx->fragment, - rx->fragment_length + length); - rx->fragment_length = 0; - spin_unlock(&rx->lock); - } else { - spin_unlock(&rx->lock); - handle_rx_packet(usb, buffer, length); - } - -resubmit: - r = usb_submit_urb(urb, GFP_ATOMIC); - if (r) - dev_dbg_f(urb_dev(urb), "urb %p resubmit error %d\n", urb, r); -} - -static struct urb *alloc_rx_urb(struct zd_usb *usb) -{ - struct usb_device *udev = zd_usb_to_usbdev(usb); - struct urb *urb; - void *buffer; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) - return NULL; - buffer = usb_alloc_coherent(udev, USB_MAX_RX_SIZE, GFP_KERNEL, - &urb->transfer_dma); - if (!buffer) { - usb_free_urb(urb); - return NULL; - } - - usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN), - buffer, USB_MAX_RX_SIZE, - rx_urb_complete, usb); - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - return urb; -} - -static void free_rx_urb(struct urb *urb) -{ - if (!urb) - return; - usb_free_coherent(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); - usb_free_urb(urb); -} - -static int __zd_usb_enable_rx(struct zd_usb *usb) -{ - int i, r; - struct zd_usb_rx *rx = &usb->rx; - struct urb **urbs; - - dev_dbg_f(zd_usb_dev(usb), "\n"); - - r = -ENOMEM; - urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); - if (!urbs) - goto error; - for (i = 0; i < RX_URBS_COUNT; i++) { - urbs[i] = alloc_rx_urb(usb); - if (!urbs[i]) - goto error; - } - - ZD_ASSERT(!irqs_disabled()); - spin_lock_irq(&rx->lock); - if (rx->urbs) { - spin_unlock_irq(&rx->lock); - r = 0; - goto error; - } - rx->urbs = urbs; - rx->urbs_count = RX_URBS_COUNT; - spin_unlock_irq(&rx->lock); - - for (i = 0; i < RX_URBS_COUNT; i++) { - r = usb_submit_urb(urbs[i], GFP_KERNEL); - if (r) - goto error_submit; - } - - return 0; -error_submit: - for (i = 0; i < RX_URBS_COUNT; i++) { - usb_kill_urb(urbs[i]); - } - spin_lock_irq(&rx->lock); - rx->urbs = NULL; - rx->urbs_count = 0; - spin_unlock_irq(&rx->lock); -error: - if (urbs) { - for (i = 0; i < RX_URBS_COUNT; i++) - free_rx_urb(urbs[i]); - } - return r; -} - -int zd_usb_enable_rx(struct zd_usb *usb) -{ - int r; - struct zd_usb_rx *rx = &usb->rx; - - mutex_lock(&rx->setup_mutex); - r = __zd_usb_enable_rx(usb); - mutex_unlock(&rx->setup_mutex); - - zd_usb_reset_rx_idle_timer(usb); - - return r; -} - -static void __zd_usb_disable_rx(struct zd_usb *usb) -{ - int i; - unsigned long flags; - struct urb **urbs; - unsigned int count; - struct zd_usb_rx *rx = &usb->rx; - - spin_lock_irqsave(&rx->lock, flags); - urbs = rx->urbs; - count = rx->urbs_count; - spin_unlock_irqrestore(&rx->lock, flags); - if (!urbs) - return; - - for (i = 0; i < count; i++) { - usb_kill_urb(urbs[i]); - free_rx_urb(urbs[i]); - } - kfree(urbs); - - spin_lock_irqsave(&rx->lock, flags); - rx->urbs = NULL; - rx->urbs_count = 0; - spin_unlock_irqrestore(&rx->lock, flags); -} - -void zd_usb_disable_rx(struct zd_usb *usb) -{ - struct zd_usb_rx *rx = &usb->rx; - - mutex_lock(&rx->setup_mutex); - __zd_usb_disable_rx(usb); - mutex_unlock(&rx->setup_mutex); - - tasklet_kill(&rx->reset_timer_tasklet); - cancel_delayed_work_sync(&rx->idle_work); -} - -static void zd_usb_reset_rx(struct zd_usb *usb) -{ - bool do_reset; - struct zd_usb_rx *rx = &usb->rx; - unsigned long flags; - - mutex_lock(&rx->setup_mutex); - - spin_lock_irqsave(&rx->lock, flags); - do_reset = rx->urbs != NULL; - spin_unlock_irqrestore(&rx->lock, flags); - - if (do_reset) { - __zd_usb_disable_rx(usb); - __zd_usb_enable_rx(usb); - } - - mutex_unlock(&rx->setup_mutex); - - if (do_reset) - zd_usb_reset_rx_idle_timer(usb); -} - -/** - * zd_usb_disable_tx - disable transmission - * @usb: the zd1211rw-private USB structure - * - * Frees all URBs in the free list and marks the transmission as disabled. - */ -void zd_usb_disable_tx(struct zd_usb *usb) -{ - struct zd_usb_tx *tx = &usb->tx; - unsigned long flags; - - atomic_set(&tx->enabled, 0); - - /* kill all submitted tx-urbs */ - usb_kill_anchored_urbs(&tx->submitted); - - spin_lock_irqsave(&tx->lock, flags); - WARN_ON(!skb_queue_empty(&tx->submitted_skbs)); - WARN_ON(tx->submitted_urbs != 0); - tx->submitted_urbs = 0; - spin_unlock_irqrestore(&tx->lock, flags); - - /* The stopped state is ignored, relying on ieee80211_wake_queues() - * in a potentionally following zd_usb_enable_tx(). - */ -} - -/** - * zd_usb_enable_tx - enables transmission - * @usb: a &struct zd_usb pointer - * - * This function enables transmission and prepares the &zd_usb_tx data - * structure. - */ -void zd_usb_enable_tx(struct zd_usb *usb) -{ - unsigned long flags; - struct zd_usb_tx *tx = &usb->tx; - - spin_lock_irqsave(&tx->lock, flags); - atomic_set(&tx->enabled, 1); - tx->submitted_urbs = 0; - ieee80211_wake_queues(zd_usb_to_hw(usb)); - tx->stopped = 0; - spin_unlock_irqrestore(&tx->lock, flags); -} - -static void tx_dec_submitted_urbs(struct zd_usb *usb) -{ - struct zd_usb_tx *tx = &usb->tx; - unsigned long flags; - - spin_lock_irqsave(&tx->lock, flags); - --tx->submitted_urbs; - if (tx->stopped && tx->submitted_urbs <= ZD_USB_TX_LOW) { - ieee80211_wake_queues(zd_usb_to_hw(usb)); - tx->stopped = 0; - } - spin_unlock_irqrestore(&tx->lock, flags); -} - -static void tx_inc_submitted_urbs(struct zd_usb *usb) -{ - struct zd_usb_tx *tx = &usb->tx; - unsigned long flags; - - spin_lock_irqsave(&tx->lock, flags); - ++tx->submitted_urbs; - if (!tx->stopped && tx->submitted_urbs > ZD_USB_TX_HIGH) { - ieee80211_stop_queues(zd_usb_to_hw(usb)); - tx->stopped = 1; - } - spin_unlock_irqrestore(&tx->lock, flags); -} - -/** - * tx_urb_complete - completes the execution of an URB - * @urb: a URB - * - * This function is called if the URB has been transferred to a device or an - * error has happened. - */ -static void tx_urb_complete(struct urb *urb) -{ - int r; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - struct zd_usb *usb; - struct zd_usb_tx *tx; - - skb = (struct sk_buff *)urb->context; - info = IEEE80211_SKB_CB(skb); - /* - * grab 'usb' pointer before handing off the skb (since - * it might be freed by zd_mac_tx_to_dev or mac80211) - */ - usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb; - tx = &usb->tx; - - switch (urb->status) { - case 0: - break; - case -ESHUTDOWN: - case -EINVAL: - case -ENODEV: - case -ENOENT: - case -ECONNRESET: - case -EPIPE: - dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); - break; - default: - dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); - goto resubmit; - } -free_urb: - skb_unlink(skb, &usb->tx.submitted_skbs); - zd_mac_tx_to_dev(skb, urb->status); - usb_free_urb(urb); - tx_dec_submitted_urbs(usb); - return; -resubmit: - usb_anchor_urb(urb, &tx->submitted); - r = usb_submit_urb(urb, GFP_ATOMIC); - if (r) { - usb_unanchor_urb(urb); - dev_dbg_f(urb_dev(urb), "error resubmit urb %p %d\n", urb, r); - goto free_urb; - } -} - -/** - * zd_usb_tx: initiates transfer of a frame of the device - * - * @usb: the zd1211rw-private USB structure - * @skb: a &struct sk_buff pointer - * - * This function tranmits a frame to the device. It doesn't wait for - * completion. The frame must contain the control set and have all the - * control set information available. - * - * The function returns 0 if the transfer has been successfully initiated. - */ -int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) -{ - int r; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct usb_device *udev = zd_usb_to_usbdev(usb); - struct urb *urb; - struct zd_usb_tx *tx = &usb->tx; - - if (!atomic_read(&tx->enabled)) { - r = -ENOENT; - goto out; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - r = -ENOMEM; - goto out; - } - - usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), - skb->data, skb->len, tx_urb_complete, skb); - - info->rate_driver_data[1] = (void *)jiffies; - skb_queue_tail(&tx->submitted_skbs, skb); - usb_anchor_urb(urb, &tx->submitted); - - r = usb_submit_urb(urb, GFP_ATOMIC); - if (r) { - dev_dbg_f(zd_usb_dev(usb), "error submit urb %p %d\n", urb, r); - usb_unanchor_urb(urb); - skb_unlink(skb, &tx->submitted_skbs); - goto error; - } - tx_inc_submitted_urbs(usb); - return 0; -error: - usb_free_urb(urb); -out: - return r; -} - -static bool zd_tx_timeout(struct zd_usb *usb) -{ - struct zd_usb_tx *tx = &usb->tx; - struct sk_buff_head *q = &tx->submitted_skbs; - struct sk_buff *skb, *skbnext; - struct ieee80211_tx_info *info; - unsigned long flags, trans_start; - bool have_timedout = false; - - spin_lock_irqsave(&q->lock, flags); - skb_queue_walk_safe(q, skb, skbnext) { - info = IEEE80211_SKB_CB(skb); - trans_start = (unsigned long)info->rate_driver_data[1]; - - if (time_is_before_jiffies(trans_start + ZD_TX_TIMEOUT)) { - have_timedout = true; - break; - } - } - spin_unlock_irqrestore(&q->lock, flags); - - return have_timedout; -} - -static void zd_tx_watchdog_handler(struct work_struct *work) -{ - struct zd_usb *usb = - container_of(work, struct zd_usb, tx.watchdog_work.work); - struct zd_usb_tx *tx = &usb->tx; - - if (!atomic_read(&tx->enabled) || !tx->watchdog_enabled) - goto out; - if (!zd_tx_timeout(usb)) - goto out; - - /* TX halted, try reset */ - dev_warn(zd_usb_dev(usb), "TX-stall detected, resetting device..."); - - usb_queue_reset_device(usb->intf); - - /* reset will stop this worker, don't rearm */ - return; -out: - queue_delayed_work(zd_workqueue, &tx->watchdog_work, - ZD_TX_WATCHDOG_INTERVAL); -} - -void zd_tx_watchdog_enable(struct zd_usb *usb) -{ - struct zd_usb_tx *tx = &usb->tx; - - if (!tx->watchdog_enabled) { - dev_dbg_f(zd_usb_dev(usb), "\n"); - queue_delayed_work(zd_workqueue, &tx->watchdog_work, - ZD_TX_WATCHDOG_INTERVAL); - tx->watchdog_enabled = 1; - } -} - -void zd_tx_watchdog_disable(struct zd_usb *usb) -{ - struct zd_usb_tx *tx = &usb->tx; - - if (tx->watchdog_enabled) { - dev_dbg_f(zd_usb_dev(usb), "\n"); - tx->watchdog_enabled = 0; - cancel_delayed_work_sync(&tx->watchdog_work); - } -} - -static void zd_rx_idle_timer_handler(struct work_struct *work) -{ - struct zd_usb *usb = - container_of(work, struct zd_usb, rx.idle_work.work); - struct zd_mac *mac = zd_usb_to_mac(usb); - - if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags)) - return; - - dev_dbg_f(zd_usb_dev(usb), "\n"); - - /* 30 seconds since last rx, reset rx */ - zd_usb_reset_rx(usb); -} - -static void zd_usb_reset_rx_idle_timer_tasklet(unsigned long param) -{ - struct zd_usb *usb = (struct zd_usb *)param; - - zd_usb_reset_rx_idle_timer(usb); -} - -void zd_usb_reset_rx_idle_timer(struct zd_usb *usb) -{ - struct zd_usb_rx *rx = &usb->rx; - - mod_delayed_work(zd_workqueue, &rx->idle_work, ZD_RX_IDLE_INTERVAL); -} - -static inline void init_usb_interrupt(struct zd_usb *usb) -{ - struct zd_usb_interrupt *intr = &usb->intr; - - spin_lock_init(&intr->lock); - intr->interval = int_urb_interval(zd_usb_to_usbdev(usb)); - init_completion(&intr->read_regs.completion); - atomic_set(&intr->read_regs_enabled, 0); - intr->read_regs.cr_int_addr = cpu_to_le16((u16)CR_INTERRUPT); -} - -static inline void init_usb_rx(struct zd_usb *usb) -{ - struct zd_usb_rx *rx = &usb->rx; - - spin_lock_init(&rx->lock); - mutex_init(&rx->setup_mutex); - if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) { - rx->usb_packet_size = 512; - } else { - rx->usb_packet_size = 64; - } - ZD_ASSERT(rx->fragment_length == 0); - INIT_DELAYED_WORK(&rx->idle_work, zd_rx_idle_timer_handler); - rx->reset_timer_tasklet.func = zd_usb_reset_rx_idle_timer_tasklet; - rx->reset_timer_tasklet.data = (unsigned long)usb; -} - -static inline void init_usb_tx(struct zd_usb *usb) -{ - struct zd_usb_tx *tx = &usb->tx; - - spin_lock_init(&tx->lock); - atomic_set(&tx->enabled, 0); - tx->stopped = 0; - skb_queue_head_init(&tx->submitted_skbs); - init_usb_anchor(&tx->submitted); - tx->submitted_urbs = 0; - tx->watchdog_enabled = 0; - INIT_DELAYED_WORK(&tx->watchdog_work, zd_tx_watchdog_handler); -} - -void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, - struct usb_interface *intf) -{ - memset(usb, 0, sizeof(*usb)); - usb->intf = usb_get_intf(intf); - usb_set_intfdata(usb->intf, hw); - init_usb_anchor(&usb->submitted_cmds); - init_usb_interrupt(usb); - init_usb_tx(usb); - init_usb_rx(usb); -} - -void zd_usb_clear(struct zd_usb *usb) -{ - usb_set_intfdata(usb->intf, NULL); - usb_put_intf(usb->intf); - ZD_MEMCLEAR(usb, sizeof(*usb)); - /* FIXME: usb_interrupt, usb_tx, usb_rx? */ -} - -static const char *speed(enum usb_device_speed speed) -{ - switch (speed) { - case USB_SPEED_LOW: - return "low"; - case USB_SPEED_FULL: - return "full"; - case USB_SPEED_HIGH: - return "high"; - default: - return "unknown speed"; - } -} - -static int scnprint_id(struct usb_device *udev, char *buffer, size_t size) -{ - return scnprintf(buffer, size, "%04hx:%04hx v%04hx %s", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct), - get_bcdDevice(udev), - speed(udev->speed)); -} - -int zd_usb_scnprint_id(struct zd_usb *usb, char *buffer, size_t size) -{ - struct usb_device *udev = interface_to_usbdev(usb->intf); - return scnprint_id(udev, buffer, size); -} - -#ifdef DEBUG -static void print_id(struct usb_device *udev) -{ - char buffer[40]; - - scnprint_id(udev, buffer, sizeof(buffer)); - buffer[sizeof(buffer)-1] = 0; - dev_dbg_f(&udev->dev, "%s\n", buffer); -} -#else -#define print_id(udev) do { } while (0) -#endif - -static int eject_installer(struct usb_interface *intf) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_host_interface *iface_desc = &intf->altsetting[0]; - struct usb_endpoint_descriptor *endpoint; - unsigned char *cmd; - u8 bulk_out_ep; - int r; - - /* Find bulk out endpoint */ - for (r = 1; r >= 0; r--) { - endpoint = &iface_desc->endpoint[r].desc; - if (usb_endpoint_dir_out(endpoint) && - usb_endpoint_xfer_bulk(endpoint)) { - bulk_out_ep = endpoint->bEndpointAddress; - break; - } - } - if (r == -1) { - dev_err(&udev->dev, - "zd1211rw: Could not find bulk out endpoint\n"); - return -ENODEV; - } - - cmd = kzalloc(31, GFP_KERNEL); - if (cmd == NULL) - return -ENODEV; - - /* USB bulk command block */ - cmd[0] = 0x55; /* bulk command signature */ - cmd[1] = 0x53; /* bulk command signature */ - cmd[2] = 0x42; /* bulk command signature */ - cmd[3] = 0x43; /* bulk command signature */ - cmd[14] = 6; /* command length */ - - cmd[15] = 0x1b; /* SCSI command: START STOP UNIT */ - cmd[19] = 0x2; /* eject disc */ - - dev_info(&udev->dev, "Ejecting virtual installer media...\n"); - r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep), - cmd, 31, NULL, 2000); - kfree(cmd); - if (r) - return r; - - /* At this point, the device disconnects and reconnects with the real - * ID numbers. */ - - usb_set_intfdata(intf, NULL); - return 0; -} - -int zd_usb_init_hw(struct zd_usb *usb) -{ - int r; - struct zd_mac *mac = zd_usb_to_mac(usb); - - dev_dbg_f(zd_usb_dev(usb), "\n"); - - r = upload_firmware(usb); - if (r) { - dev_err(zd_usb_dev(usb), - "couldn't load firmware. Error number %d\n", r); - return r; - } - - r = usb_reset_configuration(zd_usb_to_usbdev(usb)); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "couldn't reset configuration. Error number %d\n", r); - return r; - } - - r = zd_mac_init_hw(mac->hw); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "couldn't initialize mac. Error number %d\n", r); - return r; - } - - usb->initialized = 1; - return 0; -} - -static int probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - int r; - struct usb_device *udev = interface_to_usbdev(intf); - struct zd_usb *usb; - struct ieee80211_hw *hw = NULL; - - print_id(udev); - - if (id->driver_info & DEVICE_INSTALLER) - return eject_installer(intf); - - switch (udev->speed) { - case USB_SPEED_LOW: - case USB_SPEED_FULL: - case USB_SPEED_HIGH: - break; - default: - dev_dbg_f(&intf->dev, "Unknown USB speed\n"); - r = -ENODEV; - goto error; - } - - r = usb_reset_device(udev); - if (r) { - dev_err(&intf->dev, - "couldn't reset usb device. Error number %d\n", r); - goto error; - } - - hw = zd_mac_alloc_hw(intf); - if (hw == NULL) { - r = -ENOMEM; - goto error; - } - - usb = &zd_hw_mac(hw)->chip.usb; - usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0; - - r = zd_mac_preinit_hw(hw); - if (r) { - dev_dbg_f(&intf->dev, - "couldn't initialize mac. Error number %d\n", r); - goto error; - } - - r = ieee80211_register_hw(hw); - if (r) { - dev_dbg_f(&intf->dev, - "couldn't register device. Error number %d\n", r); - goto error; - } - - dev_dbg_f(&intf->dev, "successful\n"); - dev_info(&intf->dev, "%s\n", wiphy_name(hw->wiphy)); - return 0; -error: - usb_reset_device(interface_to_usbdev(intf)); - if (hw) { - zd_mac_clear(zd_hw_mac(hw)); - ieee80211_free_hw(hw); - } - return r; -} - -static void disconnect(struct usb_interface *intf) -{ - struct ieee80211_hw *hw = zd_intf_to_hw(intf); - struct zd_mac *mac; - struct zd_usb *usb; - - /* Either something really bad happened, or we're just dealing with - * a DEVICE_INSTALLER. */ - if (hw == NULL) - return; - - mac = zd_hw_mac(hw); - usb = &mac->chip.usb; - - dev_dbg_f(zd_usb_dev(usb), "\n"); - - ieee80211_unregister_hw(hw); - - /* Just in case something has gone wrong! */ - zd_usb_disable_tx(usb); - zd_usb_disable_rx(usb); - zd_usb_disable_int(usb); - - /* If the disconnect has been caused by a removal of the - * driver module, the reset allows reloading of the driver. If the - * reset will not be executed here, the upload of the firmware in the - * probe function caused by the reloading of the driver will fail. - */ - usb_reset_device(interface_to_usbdev(intf)); - - zd_mac_clear(mac); - ieee80211_free_hw(hw); - dev_dbg(&intf->dev, "disconnected\n"); -} - -static void zd_usb_resume(struct zd_usb *usb) -{ - struct zd_mac *mac = zd_usb_to_mac(usb); - int r; - - dev_dbg_f(zd_usb_dev(usb), "\n"); - - r = zd_op_start(zd_usb_to_hw(usb)); - if (r < 0) { - dev_warn(zd_usb_dev(usb), "Device resume failed " - "with error code %d. Retrying...\n", r); - if (usb->was_running) - set_bit(ZD_DEVICE_RUNNING, &mac->flags); - usb_queue_reset_device(usb->intf); - return; - } - - if (mac->type != NL80211_IFTYPE_UNSPECIFIED) { - r = zd_restore_settings(mac); - if (r < 0) { - dev_dbg(zd_usb_dev(usb), - "failed to restore settings, %d\n", r); - return; - } - } -} - -static void zd_usb_stop(struct zd_usb *usb) -{ - dev_dbg_f(zd_usb_dev(usb), "\n"); - - zd_op_stop(zd_usb_to_hw(usb)); - - zd_usb_disable_tx(usb); - zd_usb_disable_rx(usb); - zd_usb_disable_int(usb); - - usb->initialized = 0; -} - -static int pre_reset(struct usb_interface *intf) -{ - struct ieee80211_hw *hw = usb_get_intfdata(intf); - struct zd_mac *mac; - struct zd_usb *usb; - - if (!hw || intf->condition != USB_INTERFACE_BOUND) - return 0; - - mac = zd_hw_mac(hw); - usb = &mac->chip.usb; - - usb->was_running = test_bit(ZD_DEVICE_RUNNING, &mac->flags); - - zd_usb_stop(usb); - - mutex_lock(&mac->chip.mutex); - return 0; -} - -static int post_reset(struct usb_interface *intf) -{ - struct ieee80211_hw *hw = usb_get_intfdata(intf); - struct zd_mac *mac; - struct zd_usb *usb; - - if (!hw || intf->condition != USB_INTERFACE_BOUND) - return 0; - - mac = zd_hw_mac(hw); - usb = &mac->chip.usb; - - mutex_unlock(&mac->chip.mutex); - - if (usb->was_running) - zd_usb_resume(usb); - return 0; -} - -static struct usb_driver driver = { - .name = KBUILD_MODNAME, - .id_table = usb_ids, - .probe = probe, - .disconnect = disconnect, - .pre_reset = pre_reset, - .post_reset = post_reset, - .disable_hub_initiated_lpm = 1, -}; - -struct workqueue_struct *zd_workqueue; - -static int __init usb_init(void) -{ - int r; - - pr_debug("%s usb_init()\n", driver.name); - - zd_workqueue = create_singlethread_workqueue(driver.name); - if (zd_workqueue == NULL) { - printk(KERN_ERR "%s couldn't create workqueue\n", driver.name); - return -ENOMEM; - } - - r = usb_register(&driver); - if (r) { - destroy_workqueue(zd_workqueue); - printk(KERN_ERR "%s usb_register() failed. Error number %d\n", - driver.name, r); - return r; - } - - pr_debug("%s initialized\n", driver.name); - return 0; -} - -static void __exit usb_exit(void) -{ - pr_debug("%s usb_exit()\n", driver.name); - usb_deregister(&driver); - destroy_workqueue(zd_workqueue); -} - -module_init(usb_init); -module_exit(usb_exit); - -static int zd_ep_regs_out_msg(struct usb_device *udev, void *data, int len, - int *actual_length, int timeout) -{ - /* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in - * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint - * descriptor. - */ - struct usb_host_endpoint *ep; - unsigned int pipe; - - pipe = usb_sndintpipe(udev, EP_REGS_OUT); - ep = usb_pipe_endpoint(udev, pipe); - if (!ep) - return -EINVAL; - - if (usb_endpoint_xfer_int(&ep->desc)) { - return usb_interrupt_msg(udev, pipe, data, len, - actual_length, timeout); - } else { - pipe = usb_sndbulkpipe(udev, EP_REGS_OUT); - return usb_bulk_msg(udev, pipe, data, len, actual_length, - timeout); - } -} - -static int usb_int_regs_length(unsigned int count) -{ - return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); -} - -static void prepare_read_regs_int(struct zd_usb *usb, - struct usb_req_read_regs *req, - unsigned int count) -{ - struct zd_usb_interrupt *intr = &usb->intr; - - spin_lock_irq(&intr->lock); - atomic_set(&intr->read_regs_enabled, 1); - intr->read_regs.req = req; - intr->read_regs.req_count = count; - reinit_completion(&intr->read_regs.completion); - spin_unlock_irq(&intr->lock); -} - -static void disable_read_regs_int(struct zd_usb *usb) -{ - struct zd_usb_interrupt *intr = &usb->intr; - - spin_lock_irq(&intr->lock); - atomic_set(&intr->read_regs_enabled, 0); - spin_unlock_irq(&intr->lock); -} - -static bool check_read_regs(struct zd_usb *usb, struct usb_req_read_regs *req, - unsigned int count) -{ - int i; - struct zd_usb_interrupt *intr = &usb->intr; - struct read_regs_int *rr = &intr->read_regs; - struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; - - /* The created block size seems to be larger than expected. - * However results appear to be correct. - */ - if (rr->length < usb_int_regs_length(count)) { - dev_dbg_f(zd_usb_dev(usb), - "error: actual length %d less than expected %d\n", - rr->length, usb_int_regs_length(count)); - return false; - } - - if (rr->length > sizeof(rr->buffer)) { - dev_dbg_f(zd_usb_dev(usb), - "error: actual length %d exceeds buffer size %zu\n", - rr->length, sizeof(rr->buffer)); - return false; - } - - for (i = 0; i < count; i++) { - struct reg_data *rd = ®s->regs[i]; - if (rd->addr != req->addr[i]) { - dev_dbg_f(zd_usb_dev(usb), - "rd[%d] addr %#06hx expected %#06hx\n", i, - le16_to_cpu(rd->addr), - le16_to_cpu(req->addr[i])); - return false; - } - } - - return true; -} - -static int get_results(struct zd_usb *usb, u16 *values, - struct usb_req_read_regs *req, unsigned int count, - bool *retry) -{ - int r; - int i; - struct zd_usb_interrupt *intr = &usb->intr; - struct read_regs_int *rr = &intr->read_regs; - struct usb_int_regs *regs = (struct usb_int_regs *)rr->buffer; - - spin_lock_irq(&intr->lock); - - r = -EIO; - - /* Read failed because firmware bug? */ - *retry = !!intr->read_regs_int_overridden; - if (*retry) - goto error_unlock; - - if (!check_read_regs(usb, req, count)) { - dev_dbg_f(zd_usb_dev(usb), "error: invalid read regs\n"); - goto error_unlock; - } - - for (i = 0; i < count; i++) { - struct reg_data *rd = ®s->regs[i]; - values[i] = le16_to_cpu(rd->value); - } - - r = 0; -error_unlock: - spin_unlock_irq(&intr->lock); - return r; -} - -int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, - const zd_addr_t *addresses, unsigned int count) -{ - int r, i, req_len, actual_req_len, try_count = 0; - struct usb_device *udev; - struct usb_req_read_regs *req = NULL; - unsigned long timeout; - bool retry = false; - - if (count < 1) { - dev_dbg_f(zd_usb_dev(usb), "error: count is zero\n"); - return -EINVAL; - } - if (count > USB_MAX_IOREAD16_COUNT) { - dev_dbg_f(zd_usb_dev(usb), - "error: count %u exceeds possible max %u\n", - count, USB_MAX_IOREAD16_COUNT); - return -EINVAL; - } - if (in_atomic()) { - dev_dbg_f(zd_usb_dev(usb), - "error: io in atomic context not supported\n"); - return -EWOULDBLOCK; - } - if (!usb_int_enabled(usb)) { - dev_dbg_f(zd_usb_dev(usb), - "error: usb interrupt not enabled\n"); - return -EWOULDBLOCK; - } - - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - BUILD_BUG_ON(sizeof(struct usb_req_read_regs) + USB_MAX_IOREAD16_COUNT * - sizeof(__le16) > sizeof(usb->req_buf)); - BUG_ON(sizeof(struct usb_req_read_regs) + count * sizeof(__le16) > - sizeof(usb->req_buf)); - - req_len = sizeof(struct usb_req_read_regs) + count * sizeof(__le16); - req = (void *)usb->req_buf; - - req->id = cpu_to_le16(USB_REQ_READ_REGS); - for (i = 0; i < count; i++) - req->addr[i] = cpu_to_le16((u16)addresses[i]); - -retry_read: - try_count++; - udev = zd_usb_to_usbdev(usb); - prepare_read_regs_int(usb, req, count); - r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "error in zd_ep_regs_out_msg(). Error number %d\n", r); - goto error; - } - if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()\n" - " req_len %d != actual_req_len %d\n", - req_len, actual_req_len); - r = -EIO; - goto error; - } - - timeout = wait_for_completion_timeout(&usb->intr.read_regs.completion, - msecs_to_jiffies(50)); - if (!timeout) { - disable_read_regs_int(usb); - dev_dbg_f(zd_usb_dev(usb), "read timed out\n"); - r = -ETIMEDOUT; - goto error; - } - - r = get_results(usb, values, req, count, &retry); - if (retry && try_count < 20) { - dev_dbg_f(zd_usb_dev(usb), "read retry, tries so far: %d\n", - try_count); - goto retry_read; - } -error: - return r; -} - -static void iowrite16v_urb_complete(struct urb *urb) -{ - struct zd_usb *usb = urb->context; - - if (urb->status && !usb->cmd_error) - usb->cmd_error = urb->status; - - if (!usb->cmd_error && - urb->actual_length != urb->transfer_buffer_length) - usb->cmd_error = -EIO; -} - -static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) -{ - int r = 0; - struct urb *urb = usb->urb_async_waiting; - - if (!urb) - return 0; - - usb->urb_async_waiting = NULL; - - if (!last) - urb->transfer_flags |= URB_NO_INTERRUPT; - - usb_anchor_urb(urb, &usb->submitted_cmds); - r = usb_submit_urb(urb, GFP_KERNEL); - if (r) { - usb_unanchor_urb(urb); - dev_dbg_f(zd_usb_dev(usb), - "error in usb_submit_urb(). Error number %d\n", r); - goto error; - } - - /* fall-through with r == 0 */ -error: - usb_free_urb(urb); - return r; -} - -void zd_usb_iowrite16v_async_start(struct zd_usb *usb) -{ - ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds)); - ZD_ASSERT(usb->urb_async_waiting == NULL); - ZD_ASSERT(!usb->in_async); - - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - - usb->in_async = 1; - usb->cmd_error = 0; - usb->urb_async_waiting = NULL; -} - -int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) -{ - int r; - - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - ZD_ASSERT(usb->in_async); - - /* Submit last iowrite16v URB */ - r = zd_submit_waiting_urb(usb, true); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "error in zd_submit_waiting_usb(). " - "Error number %d\n", r); - - usb_kill_anchored_urbs(&usb->submitted_cmds); - goto error; - } - - if (timeout) - timeout = usb_wait_anchor_empty_timeout(&usb->submitted_cmds, - timeout); - if (!timeout) { - usb_kill_anchored_urbs(&usb->submitted_cmds); - if (usb->cmd_error == -ENOENT) { - dev_dbg_f(zd_usb_dev(usb), "timed out"); - r = -ETIMEDOUT; - goto error; - } - } - - r = usb->cmd_error; -error: - usb->in_async = 0; - return r; -} - -int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, - unsigned int count) -{ - int r; - struct usb_device *udev; - struct usb_req_write_regs *req = NULL; - int i, req_len; - struct urb *urb; - struct usb_host_endpoint *ep; - - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - ZD_ASSERT(usb->in_async); - - if (count == 0) - return 0; - if (count > USB_MAX_IOWRITE16_COUNT) { - dev_dbg_f(zd_usb_dev(usb), - "error: count %u exceeds possible max %u\n", - count, USB_MAX_IOWRITE16_COUNT); - return -EINVAL; - } - if (in_atomic()) { - dev_dbg_f(zd_usb_dev(usb), - "error: io in atomic context not supported\n"); - return -EWOULDBLOCK; - } - - udev = zd_usb_to_usbdev(usb); - - ep = usb_pipe_endpoint(udev, usb_sndintpipe(udev, EP_REGS_OUT)); - if (!ep) - return -ENOENT; - - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) - return -ENOMEM; - - req_len = sizeof(struct usb_req_write_regs) + - count * sizeof(struct reg_data); - req = kmalloc(req_len, GFP_KERNEL); - if (!req) { - r = -ENOMEM; - goto error; - } - - req->id = cpu_to_le16(USB_REQ_WRITE_REGS); - for (i = 0; i < count; i++) { - struct reg_data *rw = &req->reg_writes[i]; - rw->addr = cpu_to_le16((u16)ioreqs[i].addr); - rw->value = cpu_to_le16(ioreqs[i].value); - } - - /* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode - * endpoint is bulk. Select correct type URB by endpoint descriptor. - */ - if (usb_endpoint_xfer_int(&ep->desc)) - usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), - req, req_len, iowrite16v_urb_complete, usb, - ep->desc.bInterval); - else - usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT), - req, req_len, iowrite16v_urb_complete, usb); - - urb->transfer_flags |= URB_FREE_BUFFER; - - /* Submit previous URB */ - r = zd_submit_waiting_urb(usb, false); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "error in zd_submit_waiting_usb(). " - "Error number %d\n", r); - goto error; - } - - /* Delay submit so that URB_NO_INTERRUPT flag can be set for all URBs - * of currect batch except for very last. - */ - usb->urb_async_waiting = urb; - return 0; -error: - usb_free_urb(urb); - return r; -} - -int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, - unsigned int count) -{ - int r; - - zd_usb_iowrite16v_async_start(usb); - r = zd_usb_iowrite16v_async(usb, ioreqs, count); - if (r) { - zd_usb_iowrite16v_async_end(usb, 0); - return r; - } - return zd_usb_iowrite16v_async_end(usb, 50 /* ms */); -} - -int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) -{ - int r; - struct usb_device *udev; - struct usb_req_rfwrite *req = NULL; - int i, req_len, actual_req_len; - u16 bit_value_template; - - if (in_atomic()) { - dev_dbg_f(zd_usb_dev(usb), - "error: io in atomic context not supported\n"); - return -EWOULDBLOCK; - } - if (bits < USB_MIN_RFWRITE_BIT_COUNT) { - dev_dbg_f(zd_usb_dev(usb), - "error: bits %d are smaller than" - " USB_MIN_RFWRITE_BIT_COUNT %d\n", - bits, USB_MIN_RFWRITE_BIT_COUNT); - return -EINVAL; - } - if (bits > USB_MAX_RFWRITE_BIT_COUNT) { - dev_dbg_f(zd_usb_dev(usb), - "error: bits %d exceed USB_MAX_RFWRITE_BIT_COUNT %d\n", - bits, USB_MAX_RFWRITE_BIT_COUNT); - return -EINVAL; - } -#ifdef DEBUG - if (value & (~0UL << bits)) { - dev_dbg_f(zd_usb_dev(usb), - "error: value %#09x has bits >= %d set\n", - value, bits); - return -EINVAL; - } -#endif /* DEBUG */ - - dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits); - - r = zd_usb_ioread16(usb, &bit_value_template, ZD_CR203); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "error %d: Couldn't read ZD_CR203\n", r); - return r; - } - bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA); - - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - BUILD_BUG_ON(sizeof(struct usb_req_rfwrite) + - USB_MAX_RFWRITE_BIT_COUNT * sizeof(__le16) > - sizeof(usb->req_buf)); - BUG_ON(sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16) > - sizeof(usb->req_buf)); - - req_len = sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16); - req = (void *)usb->req_buf; - - req->id = cpu_to_le16(USB_REQ_WRITE_RF); - /* 1: 3683a, but not used in ZYDAS driver */ - req->value = cpu_to_le16(2); - req->bits = cpu_to_le16(bits); - - for (i = 0; i < bits; i++) { - u16 bv = bit_value_template; - if (value & (1 << (bits-1-i))) - bv |= RF_DATA; - req->bit_values[i] = cpu_to_le16(bv); - } - - udev = zd_usb_to_usbdev(usb); - r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); - if (r) { - dev_dbg_f(zd_usb_dev(usb), - "error in zd_ep_regs_out_msg(). Error number %d\n", r); - goto out; - } - if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()" - " req_len %d != actual_req_len %d\n", - req_len, actual_req_len); - r = -EIO; - goto out; - } - - /* FALL-THROUGH with r == 0 */ -out: - return r; -} diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h deleted file mode 100644 index a9075f2..0000000 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ /dev/null @@ -1,292 +0,0 @@ -/* ZD1211 USB-WLAN driver for Linux - * - * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> - * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _ZD_USB_H -#define _ZD_USB_H - -#include <linux/completion.h> -#include <linux/netdevice.h> -#include <linux/spinlock.h> -#include <linux/skbuff.h> -#include <linux/usb.h> - -#include "zd_def.h" - -#define ZD_USB_TX_HIGH 5 -#define ZD_USB_TX_LOW 2 - -#define ZD_TX_TIMEOUT (HZ * 5) -#define ZD_TX_WATCHDOG_INTERVAL round_jiffies_relative(HZ) -#define ZD_RX_IDLE_INTERVAL round_jiffies_relative(30 * HZ) - -enum devicetype { - DEVICE_ZD1211 = 0, - DEVICE_ZD1211B = 1, - DEVICE_INSTALLER = 2, -}; - -enum endpoints { - EP_CTRL = 0, - EP_DATA_OUT = 1, - EP_DATA_IN = 2, - EP_INT_IN = 3, - EP_REGS_OUT = 4, -}; - -enum { - USB_MAX_TRANSFER_SIZE = 4096, /* bytes */ - /* FIXME: The original driver uses this value. We have to check, - * whether the MAX_TRANSFER_SIZE is sufficient and this needs only be - * used if one combined frame is split over two USB transactions. - */ - USB_MAX_RX_SIZE = 4800, /* bytes */ - USB_MAX_IOWRITE16_COUNT = 15, - USB_MAX_IOWRITE32_COUNT = USB_MAX_IOWRITE16_COUNT/2, - USB_MAX_IOREAD16_COUNT = 15, - USB_MAX_IOREAD32_COUNT = USB_MAX_IOREAD16_COUNT/2, - USB_MIN_RFWRITE_BIT_COUNT = 16, - USB_MAX_RFWRITE_BIT_COUNT = 28, - USB_MAX_EP_INT_BUFFER = 64, - USB_ZD1211B_BCD_DEVICE = 0x4810, -}; - -enum control_requests { - USB_REQ_WRITE_REGS = 0x21, - USB_REQ_READ_REGS = 0x22, - USB_REQ_WRITE_RF = 0x23, - USB_REQ_PROG_FLASH = 0x24, - USB_REQ_EEPROM_START = 0x0128, /* ? request is a byte */ - USB_REQ_EEPROM_MID = 0x28, - USB_REQ_EEPROM_END = 0x0228, /* ? request is a byte */ - USB_REQ_FIRMWARE_DOWNLOAD = 0x30, - USB_REQ_FIRMWARE_CONFIRM = 0x31, - USB_REQ_FIRMWARE_READ_DATA = 0x32, -}; - -struct usb_req_read_regs { - __le16 id; - __le16 addr[0]; -} __packed; - -struct reg_data { - __le16 addr; - __le16 value; -} __packed; - -struct usb_req_write_regs { - __le16 id; - struct reg_data reg_writes[0]; -} __packed; - -enum { - RF_IF_LE = 0x02, - RF_CLK = 0x04, - RF_DATA = 0x08, -}; - -struct usb_req_rfwrite { - __le16 id; - __le16 value; - /* 1: 3683a */ - /* 2: other (default) */ - __le16 bits; - /* RF2595: 24 */ - __le16 bit_values[0]; - /* (ZD_CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ -} __packed; - -/* USB interrupt */ - -enum usb_int_id { - USB_INT_TYPE = 0x01, - USB_INT_ID_REGS = 0x90, - USB_INT_ID_RETRY_FAILED = 0xa0, -}; - -enum usb_int_flags { - USB_INT_READ_REGS_EN = 0x01, -}; - -struct usb_int_header { - u8 type; /* must always be 1 */ - u8 id; -} __packed; - -struct usb_int_regs { - struct usb_int_header hdr; - struct reg_data regs[0]; -} __packed; - -struct usb_int_retry_fail { - struct usb_int_header hdr; - u8 new_rate; - u8 _dummy; - u8 addr[ETH_ALEN]; - u8 ibss_wakeup_dest; -} __packed; - -struct read_regs_int { - struct completion completion; - struct usb_req_read_regs *req; - unsigned int req_count; - /* Stores the USB int structure and contains the USB address of the - * first requested register before request. - */ - u8 buffer[USB_MAX_EP_INT_BUFFER]; - int length; - __le16 cr_int_addr; -}; - -struct zd_ioreq16 { - zd_addr_t addr; - u16 value; -}; - -struct zd_ioreq32 { - zd_addr_t addr; - u32 value; -}; - -struct zd_usb_interrupt { - struct read_regs_int read_regs; - spinlock_t lock; - struct urb *urb; - void *buffer; - dma_addr_t buffer_dma; - int interval; - atomic_t read_regs_enabled; - u8 read_regs_int_overridden:1; -}; - -static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr) -{ - return (struct usb_int_regs *)intr->read_regs.buffer; -} - -#define RX_URBS_COUNT 5 - -struct zd_usb_rx { - spinlock_t lock; - struct mutex setup_mutex; - struct delayed_work idle_work; - struct tasklet_struct reset_timer_tasklet; - u8 fragment[2 * USB_MAX_RX_SIZE]; - unsigned int fragment_length; - unsigned int usb_packet_size; - struct urb **urbs; - int urbs_count; -}; - -/** - * struct zd_usb_tx - structure used for transmitting frames - * @enabled: atomic enabled flag, indicates whether tx is enabled - * @lock: lock for transmission - * @submitted: anchor for URBs sent to device - * @submitted_urbs: atomic integer that counts the URBs having sent to the - * device, which haven't been completed - * @stopped: indicates whether higher level tx queues are stopped - */ -struct zd_usb_tx { - atomic_t enabled; - spinlock_t lock; - struct delayed_work watchdog_work; - struct sk_buff_head submitted_skbs; - struct usb_anchor submitted; - int submitted_urbs; - u8 stopped:1, watchdog_enabled:1; -}; - -/* Contains the usb parts. The structure doesn't require a lock because intf - * will not be changed after initialization. - */ -struct zd_usb { - struct zd_usb_interrupt intr; - struct zd_usb_rx rx; - struct zd_usb_tx tx; - struct usb_interface *intf; - struct usb_anchor submitted_cmds; - struct urb *urb_async_waiting; - int cmd_error; - u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */ - u8 is_zd1211b:1, initialized:1, was_running:1, in_async:1; -}; - -#define zd_usb_dev(usb) (&usb->intf->dev) - -static inline struct usb_device *zd_usb_to_usbdev(struct zd_usb *usb) -{ - return interface_to_usbdev(usb->intf); -} - -static inline struct ieee80211_hw *zd_intf_to_hw(struct usb_interface *intf) -{ - return usb_get_intfdata(intf); -} - -static inline struct ieee80211_hw *zd_usb_to_hw(struct zd_usb *usb) -{ - return zd_intf_to_hw(usb->intf); -} - -void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, - struct usb_interface *intf); -int zd_usb_init_hw(struct zd_usb *usb); -void zd_usb_clear(struct zd_usb *usb); - -int zd_usb_scnprint_id(struct zd_usb *usb, char *buffer, size_t size); - -void zd_tx_watchdog_enable(struct zd_usb *usb); -void zd_tx_watchdog_disable(struct zd_usb *usb); - -int zd_usb_enable_int(struct zd_usb *usb); -void zd_usb_disable_int(struct zd_usb *usb); - -int zd_usb_enable_rx(struct zd_usb *usb); -void zd_usb_disable_rx(struct zd_usb *usb); - -void zd_usb_reset_rx_idle_timer(struct zd_usb *usb); - -void zd_usb_enable_tx(struct zd_usb *usb); -void zd_usb_disable_tx(struct zd_usb *usb); - -int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb); - -int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, - const zd_addr_t *addresses, unsigned int count); - -static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, - const zd_addr_t addr) -{ - return zd_usb_ioread16v(usb, value, &addr, 1); -} - -void zd_usb_iowrite16v_async_start(struct zd_usb *usb); -int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout); -int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, - unsigned int count); -int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, - unsigned int count); - -int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits); - -int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len); - -extern struct workqueue_struct *zd_workqueue; - -#endif /* _ZD_USB_H */ |