aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/zd1211rw
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r--drivers/net/wireless/zd1211rw/Kconfig2
-rw-r--r--drivers/net/wireless/zd1211rw/Makefile4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c436
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h545
-rw-r--r--drivers/net/wireless/zd1211rw/zd_def.h11
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c570
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h28
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c201
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c243
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_rf2959.c83
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_uw2453.c91
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c785
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h50
15 files changed, 1992 insertions, 1065 deletions
diff --git a/drivers/net/wireless/zd1211rw/Kconfig b/drivers/net/wireless/zd1211rw/Kconfig
index 5f809695f71..96c8e1de087 100644
--- a/drivers/net/wireless/zd1211rw/Kconfig
+++ b/drivers/net/wireless/zd1211rw/Kconfig
@@ -1,6 +1,6 @@
config ZD1211RW
tristate "ZyDAS ZD1211/ZD1211B USB-wireless support"
- depends on USB && MAC80211 && EXPERIMENTAL
+ depends on USB && MAC80211
select FW_LOADER
---help---
This is an experimental driver for the ZyDAS ZD1211/ZD1211B wireless
diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile
index 1907eafb9b1..5728a918e50 100644
--- a/drivers/net/wireless/zd1211rw/Makefile
+++ b/drivers/net/wireless/zd1211rw/Makefile
@@ -5,7 +5,5 @@ zd1211rw-objs := zd_chip.o zd_mac.o \
zd_rf_al7230b.o zd_rf_uw2453.o \
zd_rf.o zd_usb.o
-ifeq ($(CONFIG_ZD1211RW_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+ccflags-$(CONFIG_ZD1211RW_DEBUG) := -DDEBUG
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 6a9b66051cf..73a49b86803 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements all the hardware specific functions for the ZD1211
@@ -108,25 +107,17 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
{
int r;
int i;
- zd_addr_t *a16;
- u16 *v16;
+ 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;
- /* Allocate a single memory block for values and addresses. */
- count16 = 2*count;
- /* zd_addr_t is __nocast, so the kmalloc needs an explicit cast */
- a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
- GFP_KERNEL);
- if (!a16) {
- dev_dbg_f(zd_chip_dev(chip),
- "error ENOMEM in allocation of a16\n");
- r = -ENOMEM;
- goto out;
- }
- v16 = (u16 *)(a16 + count16);
+ /* 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;
@@ -139,7 +130,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
if (r) {
dev_dbg_f(zd_chip_dev(chip),
"error: zd_ioread16v_locked. Error number %d\n", r);
- goto out;
+ return r;
}
for (i = 0; i < count; i++) {
@@ -147,18 +138,19 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
values[i] = (v16[j] << 16) | v16[j+1];
}
-out:
- kfree((void *)a16);
- return r;
+ return 0;
}
-int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
- unsigned int count)
+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;
+ 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)
@@ -166,15 +158,8 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
if (count > USB_MAX_IOWRITE32_COUNT)
return -EINVAL;
- /* Allocate a single memory block for values and addresses. */
- count16 = 2*count;
- ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL);
- if (!ioreqs16) {
- r = -ENOMEM;
- dev_dbg_f(zd_chip_dev(chip),
- "error %d in ioreqs16 allocation\n", r);
- goto out;
- }
+ count16 = 2 * count;
+ BUG_ON(count16 * sizeof(struct zd_ioreq16) > sizeof(ioreqs16));
for (i = 0; i < count; i++) {
j = 2*i;
@@ -185,18 +170,30 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
ioreqs16[j+1].addr = ioreqs[i].addr;
}
- r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
+ 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 */
-out:
- kfree(ioreqs16);
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)
{
@@ -204,6 +201,8 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
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;
@@ -216,8 +215,9 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
}
}
- r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
+ 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);
@@ -225,7 +225,7 @@ int zd_iowrite16a_locked(struct zd_chip *chip,
}
}
- return 0;
+ return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */);
}
/* Writes a variable number of 32 bit registers. The functions will split
@@ -238,6 +238,8 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
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;
@@ -250,8 +252,9 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
}
}
- r = _zd_iowrite32v_locked(chip, &ioreqs[i], j);
+ 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 _zd_iowrite32v_locked."
" Error number %d\n", r);
@@ -259,7 +262,7 @@ int zd_iowrite32a_locked(struct zd_chip *chip,
}
}
- return 0;
+ return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */);
}
int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
@@ -370,16 +373,12 @@ error:
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 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] = {
- [0] = { .addr = CR_MAC_ADDR_P1 },
- [1] = { .addr = CR_MAC_ADDR_P2 },
- };
+ struct zd_ioreq32 reqs[2] = {in_reqs[0], in_reqs[1]};
if (mac_addr) {
reqs[0].value = (mac_addr[3] << 24)
@@ -388,9 +387,9 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
| mac_addr[0];
reqs[1].value = (mac_addr[5] << 8)
| mac_addr[4];
- dev_dbg_f(zd_chip_dev(chip), "mac addr %pM\n", mac_addr);
+ dev_dbg_f(zd_chip_dev(chip), "%s addr %pM\n", type, mac_addr);
} else {
- dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n");
+ dev_dbg_f(zd_chip_dev(chip), "set NULL %s\n", type);
}
mutex_lock(&chip->mutex);
@@ -399,6 +398,29 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
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;
@@ -534,7 +556,7 @@ int zd_chip_unlock_phy_regs(struct zd_chip *chip)
return r;
}
-/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
+/* ZD_CR157 can be optionally patched by the EEPROM for original ZD1211 */
static int patch_cr157(struct zd_chip *chip)
{
int r;
@@ -548,7 +570,7 @@ static int patch_cr157(struct zd_chip *chip)
return r;
dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
- return zd_iowrite32_locked(chip, value >> 8, CR157);
+ return zd_iowrite32_locked(chip, value >> 8, ZD_CR157);
}
/*
@@ -570,8 +592,8 @@ static int patch_6m_band_edge(struct zd_chip *chip, u8 channel)
int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
{
struct zd_ioreq16 ioreqs[] = {
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR47, 0x1e },
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+ { ZD_CR47, 0x1e },
};
/* FIXME: Channel 11 is not the edge for all regulatory domains. */
@@ -585,69 +607,69 @@ int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
static int zd1211_hw_reset_phy(struct zd_chip *chip)
{
static const struct zd_ioreq16 ioreqs[] = {
- { CR0, 0x0a }, { CR1, 0x06 }, { CR2, 0x26 },
- { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xa0 },
- { CR10, 0x81 }, { CR11, 0x00 }, { CR12, 0x7f },
- { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d },
- { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a },
- { CR19, 0x48 }, { CR20, 0x0c }, { CR21, 0x0c },
- { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 },
- { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x19 },
- { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x4b },
- { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
- { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
- { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
- { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
- { CR43, 0x10 }, { CR44, 0x12 }, { CR46, 0xff },
- { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
- { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
- { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
- { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
- { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
- { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
- { CR79, 0x68 }, { CR80, 0x64 }, { CR81, 0x64 },
- { CR82, 0x00 }, { CR83, 0x00 }, { CR84, 0x00 },
- { CR85, 0x02 }, { CR86, 0x00 }, { CR87, 0x00 },
- { CR88, 0xff }, { CR89, 0xfc }, { CR90, 0x00 },
- { CR91, 0x00 }, { CR92, 0x00 }, { CR93, 0x08 },
- { CR94, 0x00 }, { CR95, 0x00 }, { CR96, 0xff },
- { CR97, 0xe7 }, { CR98, 0x00 }, { CR99, 0x00 },
- { CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 },
- { CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 },
- { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a },
- { CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 },
- { CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e },
- { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
+ { 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 },
{ },
- { CR5, 0x00 }, { CR6, 0x00 }, { CR7, 0x00 },
- { CR8, 0x00 }, { CR9, 0x20 }, { CR12, 0xf0 },
- { CR20, 0x0e }, { CR21, 0x0e }, { CR27, 0x10 },
- { CR44, 0x33 }, { CR47, 0x1E }, { CR83, 0x24 },
- { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0C },
- { CR87, 0x12 }, { CR88, 0x0C }, { CR89, 0x00 },
- { CR90, 0x10 }, { CR91, 0x08 }, { CR93, 0x00 },
- { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x50 },
- { CR97, 0x37 }, { CR98, 0x35 }, { CR101, 0x13 },
- { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
- { CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 },
- { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
- { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
- { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
- { CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 },
- { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C },
- { CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 },
- { CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 },
- { CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c },
- { CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 },
- { CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe },
- { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
- { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
- { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
- { CR170, 0xba }, { CR171, 0xba },
- /* Note: CR204 must lead the CR203 */
- { CR204, 0x7d },
+ { 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 },
{ },
- { CR203, 0x30 },
+ { ZD_CR203, 0x30 },
};
int r, t;
@@ -674,62 +696,62 @@ out:
static int zd1211b_hw_reset_phy(struct zd_chip *chip)
{
static const struct zd_ioreq16 ioreqs[] = {
- { CR0, 0x14 }, { CR1, 0x06 }, { CR2, 0x26 },
- { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xe0 },
- { CR10, 0x81 },
- /* power control { { CR11, 1 << 6 }, */
- { CR11, 0x00 },
- { CR12, 0xf0 }, { CR13, 0x8c }, { CR14, 0x80 },
- { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e },
- { CR18, 0x0a }, { CR19, 0x48 },
- { CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
- { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 },
- { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 },
- { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 },
- { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
- { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
- { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
- { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
- { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
- { CR43, 0x10 }, { CR44, 0x33 }, { CR46, 0xff },
- { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
- { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
- { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
- { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
- { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
- { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
- { CR79, 0xf0 }, { CR80, 0x64 }, { CR81, 0x64 },
- { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 },
- { CR85, 0x00 }, { CR86, 0x0c }, { CR87, 0x12 },
- { CR88, 0x0c }, { CR89, 0x00 }, { CR90, 0x58 },
- { CR91, 0x04 }, { CR92, 0x00 }, { CR93, 0x00 },
- { CR94, 0x01 },
- { CR95, 0x20 }, /* ZD1211B */
- { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 },
- { CR99, 0x00 }, { CR100, 0x01 }, { CR101, 0x13 },
- { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
- { CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 },
- { CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 },
- { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
- { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
- { CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e },
- { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 },
- { CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 },
- { CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c },
- { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 },
- { CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
- { CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
- { CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe },
- { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
- { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
- { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
- { CR170, 0xba }, { CR171, 0xba },
- /* Note: CR204 must lead the CR203 */
- { CR204, 0x7d },
+ { 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 },
{},
- { CR203, 0x30 },
+ { ZD_CR203, 0x30 },
};
int r, t;
@@ -849,11 +871,12 @@ static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
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 (s->beacon_interval <= 5)
- s->beacon_interval = 5;
- if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval)
- s->pre_tbtt = s->beacon_interval - 1;
+ 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;
@@ -862,31 +885,57 @@ static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
reqs[1].addr = CR_PRE_TBTT;
reqs[1].value = s->pre_tbtt;
reqs[2].addr = CR_BCN_INTERVAL;
- reqs[2].value = s->beacon_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, u32 interval)
+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;
- s.beacon_interval = interval;
return set_aw_pt_bi(chip, &s);
}
-int zd_set_beacon_interval(struct zd_chip *chip, u32 interval)
+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);
+ r = set_beacon_interval(chip, interval, dtim_period, type);
mutex_unlock(&chip->mutex);
return r;
}
@@ -905,7 +954,7 @@ static int hw_init(struct zd_chip *chip)
if (r)
return r;
- return set_beacon_interval(chip, 100);
+ return set_beacon_interval(chip, 100, 0, NL80211_IFTYPE_UNSPECIFIED);
}
static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset)
@@ -1105,7 +1154,7 @@ int zd_chip_init_hw(struct zd_chip *chip)
if (r)
goto out;
/* Currently we support IEEE 802.11g for full and high speed USB.
- * It might be discussed, whether we should suppport pure b mode for
+ * It might be discussed, whether we should support pure b mode for
* full speed USB.
*/
r = set_mandatory_rates(chip, 1);
@@ -1150,24 +1199,24 @@ out:
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, CR31);
+ 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, CR68);
+ 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 = CR67;
+ ioreqs[0].addr = ZD_CR67;
ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
- ioreqs[1].addr = CR66;
+ ioreqs[1].addr = ZD_CR66;
ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
- ioreqs[2].addr = CR65;
+ 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));
@@ -1186,9 +1235,9 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
return r;
if (zd_chip_is_zd1211b(chip)) {
static const struct zd_ioreq16 ioreqs[] = {
- { CR69, 0x28 },
+ { ZD_CR69, 0x28 },
{},
- { CR69, 0x2a },
+ { ZD_CR69, 0x2a },
};
r = update_ofdm_cal(chip, channel);
@@ -1219,7 +1268,7 @@ static int patch_cck_gain(struct zd_chip *chip)
if (r)
return r;
dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
- return zd_iowrite16_locked(chip, value & 0xff, CR47);
+ return zd_iowrite16_locked(chip, value & 0xff, ZD_CR47);
}
int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
@@ -1407,6 +1456,9 @@ 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)
@@ -1416,6 +1468,7 @@ int zd_chip_enable_rxtx(struct zd_chip *chip)
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;
}
@@ -1423,6 +1476,7 @@ int zd_chip_enable_rxtx(struct zd_chip *chip)
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);
@@ -1450,9 +1504,9 @@ int zd_rfwritev_locked(struct zd_chip *chip,
int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
{
const struct zd_ioreq16 ioreqs[] = {
- { CR244, (value >> 16) & 0xff },
- { CR243, (value >> 8) & 0xff },
- { CR242, value & 0xff },
+ { 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));
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index f8bbf7d302a..b03786c9f3a 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -14,13 +14,14 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * 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"
@@ -61,277 +62,288 @@ enum {
#define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset)))
/* 8-bit hardware registers */
-#define CR0 CTL_REG(0x0000)
-#define CR1 CTL_REG(0x0004)
-#define CR2 CTL_REG(0x0008)
-#define CR3 CTL_REG(0x000C)
+#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 CR5 CTL_REG(0x0010)
+#define ZD_CR5 CTL_REG(0x0010)
/* bit 5: if set short preamble used
* bit 6: filter band - Japan channel 14 on, else off
*/
-#define CR6 CTL_REG(0x0014)
-#define CR7 CTL_REG(0x0018)
-#define CR8 CTL_REG(0x001C)
+#define ZD_CR6 CTL_REG(0x0014)
+#define ZD_CR7 CTL_REG(0x0018)
+#define ZD_CR8 CTL_REG(0x001C)
-#define CR4 CTL_REG(0x0020)
+#define ZD_CR4 CTL_REG(0x0020)
-#define CR9 CTL_REG(0x0024)
-/* bit 2: antenna switch (together with CR10) */
-#define CR10 CTL_REG(0x0028)
-/* bit 1: antenna switch (together with CR9)
- * RF2959 controls with CR11 radion on and off
+#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 CR11 CTL_REG(0x002C)
+#define ZD_CR11 CTL_REG(0x002C)
/* bit 6: TX power control for OFDM
- * RF2959 controls with CR10 radio on and off
+ * RF2959 controls with ZD_CR10 radio on and off
*/
-#define CR12 CTL_REG(0x0030)
-#define CR13 CTL_REG(0x0034)
-#define CR14 CTL_REG(0x0038)
-#define CR15 CTL_REG(0x003C)
-#define CR16 CTL_REG(0x0040)
-#define CR17 CTL_REG(0x0044)
-#define CR18 CTL_REG(0x0048)
-#define CR19 CTL_REG(0x004C)
-#define CR20 CTL_REG(0x0050)
-#define CR21 CTL_REG(0x0054)
-#define CR22 CTL_REG(0x0058)
-#define CR23 CTL_REG(0x005C)
-#define CR24 CTL_REG(0x0060) /* CCA threshold */
-#define CR25 CTL_REG(0x0064)
-#define CR26 CTL_REG(0x0068)
-#define CR27 CTL_REG(0x006C)
-#define CR28 CTL_REG(0x0070)
-#define CR29 CTL_REG(0x0074)
-#define CR30 CTL_REG(0x0078)
-#define CR31 CTL_REG(0x007C) /* TX power control for RF in CCK mode */
-#define CR32 CTL_REG(0x0080)
-#define CR33 CTL_REG(0x0084)
-#define CR34 CTL_REG(0x0088)
-#define CR35 CTL_REG(0x008C)
-#define CR36 CTL_REG(0x0090)
-#define CR37 CTL_REG(0x0094)
-#define CR38 CTL_REG(0x0098)
-#define CR39 CTL_REG(0x009C)
-#define CR40 CTL_REG(0x00A0)
-#define CR41 CTL_REG(0x00A4)
-#define CR42 CTL_REG(0x00A8)
-#define CR43 CTL_REG(0x00AC)
-#define CR44 CTL_REG(0x00B0)
-#define CR45 CTL_REG(0x00B4)
-#define CR46 CTL_REG(0x00B8)
-#define CR47 CTL_REG(0x00BC) /* CCK baseband gain
- * (patch value might be in EEPROM)
- */
-#define CR48 CTL_REG(0x00C0)
-#define CR49 CTL_REG(0x00C4)
-#define CR50 CTL_REG(0x00C8)
-#define CR51 CTL_REG(0x00CC) /* TX power control for RF in 6-36M modes */
-#define CR52 CTL_REG(0x00D0) /* TX power control for RF in 48M mode */
-#define CR53 CTL_REG(0x00D4) /* TX power control for RF in 54M mode */
-#define CR54 CTL_REG(0x00D8)
-#define CR55 CTL_REG(0x00DC)
-#define CR56 CTL_REG(0x00E0)
-#define CR57 CTL_REG(0x00E4)
-#define CR58 CTL_REG(0x00E8)
-#define CR59 CTL_REG(0x00EC)
-#define CR60 CTL_REG(0x00F0)
-#define CR61 CTL_REG(0x00F4)
-#define CR62 CTL_REG(0x00F8)
-#define CR63 CTL_REG(0x00FC)
-#define CR64 CTL_REG(0x0100)
-#define CR65 CTL_REG(0x0104) /* OFDM 54M calibration */
-#define CR66 CTL_REG(0x0108) /* OFDM 48M calibration */
-#define CR67 CTL_REG(0x010C) /* OFDM 36M calibration */
-#define CR68 CTL_REG(0x0110) /* CCK calibration */
-#define CR69 CTL_REG(0x0114)
-#define CR70 CTL_REG(0x0118)
-#define CR71 CTL_REG(0x011C)
-#define CR72 CTL_REG(0x0120)
-#define CR73 CTL_REG(0x0124)
-#define CR74 CTL_REG(0x0128)
-#define CR75 CTL_REG(0x012C)
-#define CR76 CTL_REG(0x0130)
-#define CR77 CTL_REG(0x0134)
-#define CR78 CTL_REG(0x0138)
-#define CR79 CTL_REG(0x013C)
-#define CR80 CTL_REG(0x0140)
-#define CR81 CTL_REG(0x0144)
-#define CR82 CTL_REG(0x0148)
-#define CR83 CTL_REG(0x014C)
-#define CR84 CTL_REG(0x0150)
-#define CR85 CTL_REG(0x0154)
-#define CR86 CTL_REG(0x0158)
-#define CR87 CTL_REG(0x015C)
-#define CR88 CTL_REG(0x0160)
-#define CR89 CTL_REG(0x0164)
-#define CR90 CTL_REG(0x0168)
-#define CR91 CTL_REG(0x016C)
-#define CR92 CTL_REG(0x0170)
-#define CR93 CTL_REG(0x0174)
-#define CR94 CTL_REG(0x0178)
-#define CR95 CTL_REG(0x017C)
-#define CR96 CTL_REG(0x0180)
-#define CR97 CTL_REG(0x0184)
-#define CR98 CTL_REG(0x0188)
-#define CR99 CTL_REG(0x018C)
-#define CR100 CTL_REG(0x0190)
-#define CR101 CTL_REG(0x0194)
-#define CR102 CTL_REG(0x0198)
-#define CR103 CTL_REG(0x019C)
-#define CR104 CTL_REG(0x01A0)
-#define CR105 CTL_REG(0x01A4)
-#define CR106 CTL_REG(0x01A8)
-#define CR107 CTL_REG(0x01AC)
-#define CR108 CTL_REG(0x01B0)
-#define CR109 CTL_REG(0x01B4)
-#define CR110 CTL_REG(0x01B8)
-#define CR111 CTL_REG(0x01BC)
-#define CR112 CTL_REG(0x01C0)
-#define CR113 CTL_REG(0x01C4)
-#define CR114 CTL_REG(0x01C8)
-#define CR115 CTL_REG(0x01CC)
-#define CR116 CTL_REG(0x01D0)
-#define CR117 CTL_REG(0x01D4)
-#define CR118 CTL_REG(0x01D8)
-#define CR119 CTL_REG(0x01DC)
-#define CR120 CTL_REG(0x01E0)
-#define CR121 CTL_REG(0x01E4)
-#define CR122 CTL_REG(0x01E8)
-#define CR123 CTL_REG(0x01EC)
-#define CR124 CTL_REG(0x01F0)
-#define CR125 CTL_REG(0x01F4)
-#define CR126 CTL_REG(0x01F8)
-#define CR127 CTL_REG(0x01FC)
-#define CR128 CTL_REG(0x0200)
-#define CR129 CTL_REG(0x0204)
-#define CR130 CTL_REG(0x0208)
-#define CR131 CTL_REG(0x020C)
-#define CR132 CTL_REG(0x0210)
-#define CR133 CTL_REG(0x0214)
-#define CR134 CTL_REG(0x0218)
-#define CR135 CTL_REG(0x021C)
-#define CR136 CTL_REG(0x0220)
-#define CR137 CTL_REG(0x0224)
-#define CR138 CTL_REG(0x0228)
-#define CR139 CTL_REG(0x022C)
-#define CR140 CTL_REG(0x0230)
-#define CR141 CTL_REG(0x0234)
-#define CR142 CTL_REG(0x0238)
-#define CR143 CTL_REG(0x023C)
-#define CR144 CTL_REG(0x0240)
-#define CR145 CTL_REG(0x0244)
-#define CR146 CTL_REG(0x0248)
-#define CR147 CTL_REG(0x024C)
-#define CR148 CTL_REG(0x0250)
-#define CR149 CTL_REG(0x0254)
-#define CR150 CTL_REG(0x0258)
-#define CR151 CTL_REG(0x025C)
-#define CR152 CTL_REG(0x0260)
-#define CR153 CTL_REG(0x0264)
-#define CR154 CTL_REG(0x0268)
-#define CR155 CTL_REG(0x026C)
-#define CR156 CTL_REG(0x0270)
-#define CR157 CTL_REG(0x0274)
-#define CR158 CTL_REG(0x0278)
-#define CR159 CTL_REG(0x027C)
-#define CR160 CTL_REG(0x0280)
-#define CR161 CTL_REG(0x0284)
-#define CR162 CTL_REG(0x0288)
-#define CR163 CTL_REG(0x028C)
-#define CR164 CTL_REG(0x0290)
-#define CR165 CTL_REG(0x0294)
-#define CR166 CTL_REG(0x0298)
-#define CR167 CTL_REG(0x029C)
-#define CR168 CTL_REG(0x02A0)
-#define CR169 CTL_REG(0x02A4)
-#define CR170 CTL_REG(0x02A8)
-#define CR171 CTL_REG(0x02AC)
-#define CR172 CTL_REG(0x02B0)
-#define CR173 CTL_REG(0x02B4)
-#define CR174 CTL_REG(0x02B8)
-#define CR175 CTL_REG(0x02BC)
-#define CR176 CTL_REG(0x02C0)
-#define CR177 CTL_REG(0x02C4)
-#define CR178 CTL_REG(0x02C8)
-#define CR179 CTL_REG(0x02CC)
-#define CR180 CTL_REG(0x02D0)
-#define CR181 CTL_REG(0x02D4)
-#define CR182 CTL_REG(0x02D8)
-#define CR183 CTL_REG(0x02DC)
-#define CR184 CTL_REG(0x02E0)
-#define CR185 CTL_REG(0x02E4)
-#define CR186 CTL_REG(0x02E8)
-#define CR187 CTL_REG(0x02EC)
-#define CR188 CTL_REG(0x02F0)
-#define CR189 CTL_REG(0x02F4)
-#define CR190 CTL_REG(0x02F8)
-#define CR191 CTL_REG(0x02FC)
-#define CR192 CTL_REG(0x0300)
-#define CR193 CTL_REG(0x0304)
-#define CR194 CTL_REG(0x0308)
-#define CR195 CTL_REG(0x030C)
-#define CR196 CTL_REG(0x0310)
-#define CR197 CTL_REG(0x0314)
-#define CR198 CTL_REG(0x0318)
-#define CR199 CTL_REG(0x031C)
-#define CR200 CTL_REG(0x0320)
-#define CR201 CTL_REG(0x0324)
-#define CR202 CTL_REG(0x0328)
-#define CR203 CTL_REG(0x032C) /* I2C bus template value & flash control */
-#define CR204 CTL_REG(0x0330)
-#define CR205 CTL_REG(0x0334)
-#define CR206 CTL_REG(0x0338)
-#define CR207 CTL_REG(0x033C)
-#define CR208 CTL_REG(0x0340)
-#define CR209 CTL_REG(0x0344)
-#define CR210 CTL_REG(0x0348)
-#define CR211 CTL_REG(0x034C)
-#define CR212 CTL_REG(0x0350)
-#define CR213 CTL_REG(0x0354)
-#define CR214 CTL_REG(0x0358)
-#define CR215 CTL_REG(0x035C)
-#define CR216 CTL_REG(0x0360)
-#define CR217 CTL_REG(0x0364)
-#define CR218 CTL_REG(0x0368)
-#define CR219 CTL_REG(0x036C)
-#define CR220 CTL_REG(0x0370)
-#define CR221 CTL_REG(0x0374)
-#define CR222 CTL_REG(0x0378)
-#define CR223 CTL_REG(0x037C)
-#define CR224 CTL_REG(0x0380)
-#define CR225 CTL_REG(0x0384)
-#define CR226 CTL_REG(0x0388)
-#define CR227 CTL_REG(0x038C)
-#define CR228 CTL_REG(0x0390)
-#define CR229 CTL_REG(0x0394)
-#define CR230 CTL_REG(0x0398)
-#define CR231 CTL_REG(0x039C)
-#define CR232 CTL_REG(0x03A0)
-#define CR233 CTL_REG(0x03A4)
-#define CR234 CTL_REG(0x03A8)
-#define CR235 CTL_REG(0x03AC)
-#define CR236 CTL_REG(0x03B0)
-
-#define CR240 CTL_REG(0x03C0)
-/* bit 7: host-controlled RF register writes
- * CR241-CR245: for hardware controlled writing of RF bits, not needed for
- * USB
+#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 CR241 CTL_REG(0x03C4)
-#define CR242 CTL_REG(0x03C8)
-#define CR243 CTL_REG(0x03CC)
-#define CR244 CTL_REG(0x03D0)
-#define CR245 CTL_REG(0x03D4)
-
-#define CR251 CTL_REG(0x03EC) /* only used for activation and deactivation of
- * Airoha RFs AL2230 and AL7230B
- */
-#define CR252 CTL_REG(0x03F0)
-#define CR253 CTL_REG(0x03F4)
-#define CR254 CTL_REG(0x03F8)
-#define CR255 CTL_REG(0x03FC)
+#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
@@ -546,6 +558,7 @@ enum {
#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 */
@@ -813,7 +826,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values,
static inline int zd_ioread32_locked(struct zd_chip *chip, u32 *value,
const zd_addr_t addr)
{
- return zd_ioread32v_locked(chip, value, (const zd_addr_t *)&addr, 1);
+ return zd_ioread32v_locked(chip, value, &addr, 1);
}
static inline int zd_iowrite16_locked(struct zd_chip *chip, u16 value,
@@ -881,6 +894,7 @@ static inline u8 _zd_chip_get_channel(struct zd_chip *chip)
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);
@@ -920,7 +934,8 @@ enum led_status {
int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
-int zd_set_beacon_interval(struct zd_chip *chip, u32 interval);
+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)
{
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
index 6ac597ffd3b..41bd755bc13 100644
--- a/drivers/net/wireless/zd1211rw/zd_def.h
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ZD_DEF_H
@@ -37,15 +36,21 @@ typedef u16 __nocast zd_addr_t;
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 (!(x)) { \
+ if (unlikely(!(x))) { \
pr_debug("%s:%d ASSERT %s VIOLATED!\n", \
__FILE__, __LINE__, __stringify(x)); \
dump_stack(); \
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 6107304cb94..e7af261e919 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -16,8 +16,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/netdevice.h>
@@ -138,6 +137,12 @@ static const struct ieee80211_channel zd_channels[] = {
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)
{
@@ -154,6 +159,22 @@ static int zd_reg2alpha2(u8 regdomain, char *alpha2)
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;
@@ -231,6 +252,26 @@ static int set_rx_filter(struct zd_mac *mac)
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;
@@ -238,7 +279,7 @@ static int set_mc_hash(struct zd_mac *mac)
return zd_chip_set_multicast_hash(&mac->chip, &hash);
}
-static int zd_op_start(struct ieee80211_hw *hw)
+int zd_op_start(struct ieee80211_hw *hw)
{
struct zd_mac *mac = zd_hw_mac(hw);
struct zd_chip *chip = &mac->chip;
@@ -264,9 +305,19 @@ static int zd_op_start(struct ieee80211_hw *hw)
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)
+ 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;
@@ -275,6 +326,8 @@ static int zd_op_start(struct ieee80211_hw *hw)
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);
@@ -286,19 +339,22 @@ out:
return r;
}
-static void zd_op_stop(struct ieee80211_hw *hw)
+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);
@@ -311,6 +367,66 @@ static void zd_op_stop(struct ieee80211_hw *hw)
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
@@ -368,7 +484,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
if (i<IEEE80211_TX_MAX_RATES)
info->status.rates[i].idx = -1; /* terminate */
- info->status.ack_signal = ackssi;
+ info->status.ack_signal = zd_check_signal(hw, ackssi);
ieee80211_tx_status_irqsafe(hw, skb);
}
@@ -416,9 +532,8 @@ void zd_mac_tx_failed(struct urb *urb)
tx_hdr = (struct ieee80211_hdr *)skb->data;
/* we skip all frames not matching the reported destination */
- if (unlikely(memcmp(tx_hdr->addr1, tx_status->mac, ETH_ALEN))) {
+ if (unlikely(!ether_addr_equal(tx_hdr->addr1, tx_status->mac)))
continue;
- }
/* we skip all frames not matching the reported final rate */
@@ -571,67 +686,178 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
/* FIXME: Management frame? */
}
-static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
+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;
+ 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(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
+ r = zd_iowrite32_locked(&mac->chip, 0, CR_BCN_FIFO_SEMAPHORE);
if (r < 0)
- return r;
- r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
+ goto out;
+ r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE);
if (r < 0)
- return r;
+ 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(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
+ r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE);
if (r < 0)
- return r;
- if ((++j % 100) == 0) {
- printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
- if (j >= 500) {
- printk(KERN_ERR "Giving up beacon config.\n");
- return -ETIMEDOUT;
+ 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(1);
+ msleep(20);
}
- r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1);
- if (r < 0)
- return r;
+ ioreqs[req_pos].addr = CR_BCN_FIFO;
+ ioreqs[req_pos].value = full_len - 1;
+ req_pos++;
if (zd_chip_is_zd1211b(&mac->chip)) {
- r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
- if (r < 0)
- return r;
+ ioreqs[req_pos].addr = CR_BCN_LENGTH;
+ ioreqs[req_pos].value = full_len - 1;
+ req_pos++;
}
for (j = 0 ; j < beacon->len; j++) {
- r = zd_iowrite32(&mac->chip, CR_BCN_FIFO,
- *((u8 *)(beacon->data + j)));
- if (r < 0)
- return r;
+ ioreqs[req_pos].addr = CR_BCN_FIFO;
+ ioreqs[req_pos].value = *((u8 *)(beacon->data + j));
+ req_pos++;
}
for (j = 0; j < 4; j++) {
- r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
- if (r < 0)
- return r;
+ ioreqs[req_pos].addr = CR_BCN_FIFO;
+ ioreqs[req_pos].value = 0x0;
+ req_pos++;
}
- r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
- if (r < 0)
- return r;
+ 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)
*/
- return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
- (full_len << 19));
+ 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,
@@ -648,6 +874,14 @@ static int fill_ctrlset(struct zd_mac *mac,
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;
@@ -701,7 +935,9 @@ static int fill_ctrlset(struct zd_mac *mac,
* control block of the skbuff will be initialized. If necessary the incoming
* mac80211 queues will be stopped.
*/
-static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+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);
@@ -716,11 +952,10 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
r = zd_usb_tx(&mac->chip.usb, skb);
if (r)
goto fail;
- return 0;
+ return;
fail:
dev_kfree_skb(skb);
- return 0;
}
/**
@@ -761,7 +996,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
continue;
tx_hdr = (struct ieee80211_hdr *)skb->data;
- if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN)))
+ if (likely(ether_addr_equal(tx_hdr->addr2, rx_hdr->addr1)))
{
found = 1;
break;
@@ -779,6 +1014,13 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
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);
@@ -827,7 +1069,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq;
stats.band = IEEE80211_BAND_2GHZ;
- stats.signal = status->signal_strength;
+ stats.signal = zd_check_signal(hw, status->signal_strength);
rate = zd_rx_rate(buffer, status);
@@ -882,13 +1124,16 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
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;
}
- return zd_write_mac_addr(&mac->chip, vif->addr);
+ mac->vif = vif;
+
+ return set_mac_and_bssid(mac);
}
static void zd_op_remove_interface(struct ieee80211_hw *hw,
@@ -896,8 +1141,11 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
{
struct zd_mac *mac = zd_hw_mac(hw);
mac->type = NL80211_IFTYPE_UNSPECIFIED;
- zd_set_beacon_interval(&mac->chip, 0);
+ 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)
@@ -905,49 +1153,65 @@ 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;
- return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
+ 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_process_intr(struct work_struct *work)
+static void zd_beacon_done(struct zd_mac *mac)
{
- u16 int_status;
- struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
+ struct sk_buff *skb, *beacon;
- int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4));
- if (int_status & INT_CFG_NEXT_BCN)
- dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
- else
- dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
-
- zd_chip_enable_hwint(&mac->chip);
-}
+ 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);
+ }
-static void set_multicast_hash_handler(struct work_struct *work)
-{
- struct zd_mac *mac =
- container_of(work, struct zd_mac, set_multicast_hash_work);
- struct zd_mc_hash hash;
+ /*
+ * 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);
- hash = mac->multicast_hash;
+ mac->beacon.last_update = jiffies;
spin_unlock_irq(&mac->lock);
-
- zd_chip_set_multicast_hash(&mac->chip, &hash);
}
-static void set_rx_filter_handler(struct work_struct *work)
+static void zd_process_intr(struct work_struct *work)
{
- struct zd_mac *mac =
- container_of(work, struct zd_mac, set_rx_filter_work);
- int r;
+ u16 int_status;
+ unsigned long flags;
+ struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
- dev_dbg_f(zd_mac_dev(mac), "\n");
- r = set_rx_filter(mac);
- if (r)
- dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r);
+ 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)
{
@@ -979,6 +1243,7 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
};
struct zd_mac *mac = zd_hw_mac(hw);
unsigned long flags;
+ int r;
/* Only deal with supported flags */
changed_flags &= SUPPORTED_FIF_FLAGS;
@@ -1000,11 +1265,13 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
mac->multicast_hash = hash;
spin_unlock_irqrestore(&mac->lock, flags);
- /* XXX: these can be called here now, can sleep now! */
- queue_work(zd_workqueue, &mac->set_multicast_hash_work);
+ zd_chip_set_multicast_hash(&mac->chip, &hash);
- if (changed_flags & FIF_CONTROL)
- queue_work(zd_workqueue, &mac->set_rx_filter_work);
+ 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 */
@@ -1016,20 +1283,9 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
* time. */
}
-static void set_rts_cts_work(struct work_struct *work)
+static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble)
{
- struct zd_mac *mac =
- container_of(work, struct zd_mac, set_rts_cts_work);
- unsigned long flags;
- unsigned int short_preamble;
-
mutex_lock(&mac->chip.mutex);
-
- spin_lock_irqsave(&mac->lock, flags);
- mac->updating_rts_rate = 0;
- short_preamble = mac->short_preamble;
- spin_unlock_irqrestore(&mac->lock, flags);
-
zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble);
mutex_unlock(&mac->chip.mutex);
}
@@ -1040,33 +1296,41 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
u32 changes)
{
struct zd_mac *mac = zd_hw_mac(hw);
- unsigned long flags;
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_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_mac_config_beacon(hw, beacon);
- kfree_skb(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) {
- u32 interval;
+ u16 interval = 0;
+ u8 period = 0;
+
+ if (bss_conf->enable_beacon) {
+ period = bss_conf->dtim_period;
+ interval = bss_conf->beacon_int;
+ }
- if (bss_conf->enable_beacon)
- interval = BCN_MODE_IBSS |
- bss_conf->beacon_int;
- else
- interval = 0;
+ 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);
+ zd_set_beacon_interval(&mac->chip, interval, period,
+ mac->type);
}
} else
associated = is_valid_ether_addr(bss_conf->bssid);
@@ -1078,19 +1342,15 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
/* TODO: do hardware bssid filtering */
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- spin_lock_irqsave(&mac->lock, flags);
+ spin_lock_irq(&mac->lock);
mac->short_preamble = bss_conf->use_short_preamble;
- if (!mac->updating_rts_rate) {
- mac->updating_rts_rate = 1;
- /* FIXME: should disable TX here, until work has
- * completed and RTS_CTS reg is updated */
- queue_work(zd_workqueue, &mac->set_rts_cts_work);
- }
- spin_unlock_irqrestore(&mac->lock, flags);
+ spin_unlock_irq(&mac->lock);
+
+ set_rts_cts(mac, bss_conf->use_short_preamble);
}
}
-static u64 zd_op_get_tsf(struct ieee80211_hw *hw)
+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);
@@ -1138,12 +1398,15 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SIGNAL_UNSPEC;
+ IEEE80211_HW_SIGNAL_UNSPEC |
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_MFP_CAPABLE;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_MESH_POINT) |
BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP);
hw->max_signal = 100;
hw->queues = 1;
@@ -1160,15 +1423,86 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
zd_chip_init(&mac->chip, hw, intf);
housekeeping_init(mac);
- INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
- INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
- INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler);
+ 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)
@@ -1179,6 +1513,9 @@ static void link_led_handler(struct work_struct *work)
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);
@@ -1188,6 +1525,7 @@ static void link_led_handler(struct work_struct *work)
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);
}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index a6d86b996c7..5a484235308 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ZD_MAC_H
@@ -163,6 +162,18 @@ 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
@@ -172,17 +183,19 @@ struct zd_mac {
spinlock_t lock;
spinlock_t intr_lock;
struct ieee80211_hw *hw;
+ struct ieee80211_vif *vif;
struct housekeeping housekeeping;
- struct work_struct set_multicast_hash_work;
+ struct beacon beacon;
struct work_struct set_rts_cts_work;
- struct work_struct set_rx_filter_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];
@@ -191,9 +204,6 @@ struct zd_mac {
/* Short preamble (used for RTS/CTS) */
unsigned int short_preamble:1;
- /* flags to indicate update in progress */
- unsigned int updating_rts_rate:1;
-
/* whether to pass frames with CRC errors to stack */
unsigned int pass_failed_fcs:1;
@@ -304,6 +314,10 @@ 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
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index c875ee05e22..dc179c41451 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/errno.h>
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index 79dc1035592..8f14e25e104 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ZD_RF_H
@@ -55,7 +54,7 @@ struct zd_rf {
* defaults to 1 (yes) */
u8 update_channel_int:1;
- /* whether CR47 should be patched from the EEPROM, if the appropriate
+ /* 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. */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 74a8f7a5559..99aed7d7895 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
@@ -61,31 +60,31 @@ static const u32 zd1211b_al2230_table[][3] = {
};
static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
- { CR240, 0x57 }, { CR9, 0xe0 },
+ { ZD_CR240, 0x57 }, { ZD_CR9, 0xe0 },
};
static const struct zd_ioreq16 ioreqs_init_al2230s[] = {
- { CR47, 0x1e }, /* MARK_002 */
- { CR106, 0x22 },
- { CR107, 0x2a }, /* MARK_002 */
- { CR109, 0x13 }, /* MARK_002 */
- { CR118, 0xf8 }, /* MARK_002 */
- { CR119, 0x12 }, { CR122, 0xe0 },
- { CR128, 0x10 }, /* MARK_001 from 0xe->0x10 */
- { CR129, 0x0e }, /* MARK_001 from 0xd->0x0e */
- { CR130, 0x10 }, /* MARK_001 from 0xb->0x0d */
+ { 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[] = {
- { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
- { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
- { CR203, 0x06 },
+ { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
+ { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
+ { ZD_CR203, 0x06 },
{ },
- { CR240, 0x80 },
+ { ZD_CR240, 0x80 },
};
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -94,12 +93,12 @@ static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
/* related to antenna selection? */
if (chip->new_phy_layout) {
- r = zd_iowrite16_locked(chip, 0xe1, CR9);
+ r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9);
if (r)
return r;
}
- return zd_iowrite16_locked(chip, 0x06, CR203);
+ return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
}
static int zd1211_al2230_init_hw(struct zd_rf *rf)
@@ -108,40 +107,40 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs_init[] = {
- { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 },
- { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 },
- { CR44, 0x33 }, { CR106, 0x2a }, { CR107, 0x1a },
- { CR109, 0x09 }, { CR110, 0x27 }, { CR111, 0x2b },
- { CR112, 0x2b }, { CR119, 0x0a }, { CR10, 0x89 },
+ { 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 */
- { CR17, 0x28 },
- { CR26, 0x93 }, { CR34, 0x30 },
+ { ZD_CR17, 0x28 },
+ { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 },
/* for newest (3rd cut) AL2300 */
- { CR35, 0x3e },
- { CR41, 0x24 }, { CR44, 0x32 },
+ { ZD_CR35, 0x3e },
+ { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
/* for newest (3rd cut) AL2300 */
- { CR46, 0x96 },
- { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 },
- { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 },
- { CR92, 0x0a }, { CR99, 0x28 }, { CR100, 0x00 },
- { CR101, 0x13 }, { CR102, 0x27 }, { CR106, 0x24 },
- { CR107, 0x2a }, { CR109, 0x09 }, { CR110, 0x13 },
- { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
- { CR114, 0x27 },
+ { 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 */
- { CR115, 0x24 },
- { CR116, 0x24 }, { CR117, 0xf4 }, { CR118, 0xfc },
- { CR119, 0x10 }, { CR120, 0x4f }, { CR121, 0x77 },
- { CR122, 0xe0 }, { CR137, 0x88 }, { CR252, 0xff },
- { CR253, 0xff },
+ { 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 */
- { CR251, 0x2f },
+ { ZD_CR251, 0x2f },
/* shdnb(PLL_ON)=1 */
- { CR251, 0x3f },
- { CR138, 0x28 }, { CR203, 0x06 },
+ { ZD_CR251, 0x3f },
+ { ZD_CR138, 0x28 }, { ZD_CR203, 0x06 },
};
static const u32 rv1[] = {
@@ -161,7 +160,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
0x0805b6,
0x011687,
0x000688,
- 0x0403b9, /* external control TX power (CR31) */
+ 0x0403b9, /* external control TX power (ZD_CR31) */
0x00dbba,
0x00099b,
0x0bdffc,
@@ -221,52 +220,54 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs1[] = {
- { CR10, 0x89 }, { CR15, 0x20 },
- { CR17, 0x2B }, /* for newest(3rd cut) AL2230 */
- { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 },
- { CR28, 0x3e }, { CR29, 0x00 },
- { CR33, 0x28 }, /* 5621 */
- { CR34, 0x30 },
- { CR35, 0x3e }, /* for newest(3rd cut) AL2230 */
- { CR41, 0x24 }, { CR44, 0x32 },
- { CR46, 0x99 }, /* for newest(3rd cut) AL2230 */
- { CR47, 0x1e },
+ { 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 */
- { CR48, 0x06 }, { CR49, 0xf9 }, { CR51, 0x01 },
- { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 },
- { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 },
- { CR69, 0x28 },
-
- { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 },
- { CR87, 0x0a }, { CR89, 0x04 },
- { CR91, 0x00 }, /* 5621 */
- { CR92, 0x0a },
- { CR98, 0x8d }, /* 4804, for 1212 new algorithm */
- { CR99, 0x00 }, /* 5621 */
- { CR101, 0x13 }, { CR102, 0x27 },
- { CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
- { CR107, 0x2a },
- { CR109, 0x13 }, /* 4804, for 1212 new algorithm */
- { CR110, 0x1f }, /* 4804, for 1212 new algorithm */
- { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
- { CR114, 0x27 },
- { CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) AL2230 */
- { CR116, 0x24 },
- { CR117, 0xfa }, /* for 1211b */
- { CR118, 0xfa }, /* for 1211b */
- { CR119, 0x10 },
- { CR120, 0x4f },
- { CR121, 0x6c }, /* for 1211b */
- { CR122, 0xfc }, /* E0->FC at 4902 */
- { CR123, 0x57 }, /* 5623 */
- { CR125, 0xad }, /* 4804, for 1212 new algorithm */
- { CR126, 0x6c }, /* 5614 */
- { CR127, 0x03 }, /* 4804, for 1212 new algorithm */
- { CR137, 0x50 }, /* 5614 */
- { CR138, 0xa8 },
- { CR144, 0xac }, /* 5621 */
- { CR150, 0x0d }, { CR252, 0x34 }, { CR253, 0x34 },
+ { 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[] = {
@@ -284,7 +285,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
0x6da010, /* Reg6 update for MP versio */
0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */
0x116000,
- 0x9dc020, /* External control TX power (CR31) */
+ 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 */
@@ -295,8 +296,8 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
};
static const struct zd_ioreq16 ioreqs2[] = {
- { CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
- { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
+ { ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
+ { ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
};
static const u32 rv3[] = {
@@ -308,7 +309,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
static const struct zd_ioreq16 ioreqs3[] = {
/* related to 6M band edge patching, happens unconditionally */
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
};
r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
@@ -361,8 +362,8 @@ static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel)
const u32 *rv = zd1211_al2230_table[channel-1];
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR138, 0x28 },
- { CR203, 0x06 },
+ { ZD_CR138, 0x28 },
+ { ZD_CR203, 0x06 },
};
r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS);
@@ -393,8 +394,8 @@ 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[] = {
- { CR11, 0x00 },
- { CR251, 0x3f },
+ { ZD_CR11, 0x00 },
+ { ZD_CR251, 0x3f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -404,8 +405,8 @@ 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[] = {
- { CR11, 0x00 },
- { CR251, 0x7f },
+ { ZD_CR11, 0x00 },
+ { ZD_CR251, 0x7f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -415,8 +416,8 @@ 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[] = {
- { CR11, 0x04 },
- { CR251, 0x2f },
+ { ZD_CR11, 0x04 },
+ { ZD_CR251, 0x2f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
index 65095d661e6..5fea485be57 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
@@ -68,19 +67,19 @@ static const u32 rv_init2[] = {
};
static const struct zd_ioreq16 ioreqs_sw[] = {
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR38, 0x38 }, { CR136, 0xdf },
+ { 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[] = {
- { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
- { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
- { CR203, 0x04 },
+ { ZD_CR80, 0x30 }, { ZD_CR81, 0x30 }, { ZD_CR79, 0x58 },
+ { ZD_CR12, 0xf0 }, { ZD_CR77, 0x1b }, { ZD_CR78, 0x58 },
+ { ZD_CR203, 0x04 },
{ },
- { CR240, 0x80 },
+ { ZD_CR240, 0x80 },
};
r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -89,12 +88,12 @@ static int zd1211b_al7230b_finalize(struct zd_chip *chip)
if (chip->new_phy_layout) {
/* antenna selection? */
- r = zd_iowrite16_locked(chip, 0xe5, CR9);
+ r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9);
if (r)
return r;
}
- return zd_iowrite16_locked(chip, 0x04, CR203);
+ return zd_iowrite16_locked(chip, 0x04, ZD_CR203);
}
static int zd1211_al7230b_init_hw(struct zd_rf *rf)
@@ -106,66 +105,66 @@ static int zd1211_al7230b_init_hw(struct zd_rf *rf)
* specified */
static const struct zd_ioreq16 ioreqs_1[] = {
/* This one is 7230-specific, and happens before the rest */
- { CR240, 0x57 },
+ { ZD_CR240, 0x57 },
{ },
- { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 },
- { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 },
- { CR44, 0x33 },
+ { 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) */
- { CR106, 0x22 },
- { CR107, 0x1a }, { CR109, 0x09 }, { CR110, 0x27 },
- { CR111, 0x2b }, { CR112, 0x2b }, { CR119, 0x0a },
+ { 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) */
- { CR122, 0xfc },
- { CR10, 0x89 },
+ { ZD_CR122, 0xfc },
+ { ZD_CR10, 0x89 },
/* for newest (3rd cut) AL2300 */
- { CR17, 0x28 },
- { CR26, 0x93 }, { CR34, 0x30 },
+ { ZD_CR17, 0x28 },
+ { ZD_CR26, 0x93 }, { ZD_CR34, 0x30 },
/* for newest (3rd cut) AL2300 */
- { CR35, 0x3e },
- { CR41, 0x24 }, { CR44, 0x32 },
+ { ZD_CR35, 0x3e },
+ { ZD_CR41, 0x24 }, { ZD_CR44, 0x32 },
/* for newest (3rd cut) AL2300 */
- { CR46, 0x96 },
- { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 },
- { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 },
- { CR92, 0x0a }, { CR99, 0x28 },
+ { 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) */
- { CR100, 0x02 },
- { CR101, 0x13 }, { CR102, 0x27 },
+ { ZD_CR100, 0x02 },
+ { ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
/* This value is different for 7230 (was: 0x24) */
- { CR106, 0x22 },
+ { ZD_CR106, 0x22 },
/* This value is different for 7230 (was: 0x2a) */
- { CR107, 0x3f },
- { CR109, 0x09 },
+ { ZD_CR107, 0x3f },
+ { ZD_CR109, 0x09 },
/* This value is different for 7230 (was: 0x13) */
- { CR110, 0x1f },
- { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
- { CR114, 0x27 },
+ { ZD_CR110, 0x1f },
+ { ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
+ { ZD_CR114, 0x27 },
/* for newest (3rd cut) AL2300 */
- { CR115, 0x24 },
+ { ZD_CR115, 0x24 },
/* This value is different for 7230 (was: 0x24) */
- { CR116, 0x3f },
+ { ZD_CR116, 0x3f },
/* This value is different for 7230 (was: 0xf4) */
- { CR117, 0xfa },
- { CR118, 0xfc }, { CR119, 0x10 }, { CR120, 0x4f },
- { CR121, 0x77 }, { CR137, 0x88 },
+ { ZD_CR117, 0xfa },
+ { ZD_CR118, 0xfc }, { ZD_CR119, 0x10 }, { ZD_CR120, 0x4f },
+ { ZD_CR121, 0x77 }, { ZD_CR137, 0x88 },
/* This one is 7230-specific */
- { CR138, 0xa8 },
+ { ZD_CR138, 0xa8 },
/* This value is different for 7230 (was: 0xff) */
- { CR252, 0x34 },
+ { ZD_CR252, 0x34 },
/* This value is different for 7230 (was: 0xff) */
- { CR253, 0x34 },
+ { ZD_CR253, 0x34 },
/* PLL_OFF */
- { CR251, 0x2f },
+ { ZD_CR251, 0x2f },
};
static const struct zd_ioreq16 ioreqs_2[] = {
- { CR251, 0x3f }, /* PLL_ON */
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR38, 0x38 }, { CR136, 0xdf },
+ { 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));
@@ -192,10 +191,10 @@ static int zd1211_al7230b_init_hw(struct zd_rf *rf)
if (r)
return r;
- r = zd_iowrite16_locked(chip, 0x06, CR203);
+ r = zd_iowrite16_locked(chip, 0x06, ZD_CR203);
if (r)
return r;
- r = zd_iowrite16_locked(chip, 0x80, CR240);
+ r = zd_iowrite16_locked(chip, 0x80, ZD_CR240);
if (r)
return r;
@@ -208,79 +207,79 @@ static int zd1211b_al7230b_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs_1[] = {
- { CR240, 0x57 }, { CR9, 0x9 },
+ { ZD_CR240, 0x57 }, { ZD_CR9, 0x9 },
{ },
- { CR10, 0x8b }, { CR15, 0x20 },
- { CR17, 0x2B }, /* for newest (3rd cut) AL2230 */
- { CR20, 0x10 }, /* 4N25->Stone Request */
- { CR23, 0x40 }, { CR24, 0x20 }, { CR26, 0x93 },
- { CR28, 0x3e }, { CR29, 0x00 },
- { CR33, 0x28 }, /* 5613 */
- { CR34, 0x30 },
- { CR35, 0x3e }, /* for newest (3rd cut) AL2230 */
- { CR41, 0x24 }, { CR44, 0x32 },
- { CR46, 0x99 }, /* for newest (3rd cut) AL2230 */
- { CR47, 0x1e },
+ { 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 */
- { CR48, 0x00 }, { CR49, 0x00 }, { CR51, 0x01 },
- { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 },
- { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 },
- { CR69, 0x28 },
-
- { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 },
- { CR87, 0x0A }, { CR89, 0x04 },
- { CR90, 0x58 }, /* 5112 */
- { CR91, 0x00 }, /* 5613 */
- { CR92, 0x0a },
- { CR98, 0x8d }, /* 4804, for 1212 new algorithm */
- { CR99, 0x00 }, { CR100, 0x02 }, { CR101, 0x13 },
- { CR102, 0x27 },
- { CR106, 0x20 }, /* change to 0x24 for AL7230B */
- { CR109, 0x13 }, /* 4804, for 1212 new algorithm */
- { CR112, 0x1f },
+ { 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[] = {
- { CR107, 0x28 },
- { CR110, 0x1f }, /* 5127, 0x13->0x1f */
- { CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
- { CR116, 0x2a }, { CR118, 0xfa }, { CR119, 0x12 },
- { CR121, 0x6c }, /* 5613 */
+ { 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[] = {
- { CR107, 0x24 },
- { CR110, 0x13 }, /* 5127, 0x13->0x1f */
- { CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
- { CR116, 0x24 }, { CR118, 0xfc }, { CR119, 0x11 },
- { CR121, 0x6a }, /* 5613 */
+ { 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[] = {
- { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x24 },
- { CR117, 0xfa }, { CR120, 0x4f },
- { CR122, 0xfc }, /* E0->FCh at 4901 */
- { CR123, 0x57 }, /* 5613 */
- { CR125, 0xad }, /* 4804, for 1212 new algorithm */
- { CR126, 0x6c }, /* 5613 */
- { CR127, 0x03 }, /* 4804, for 1212 new algorithm */
- { CR130, 0x10 },
- { CR131, 0x00 }, /* 5112 */
- { CR137, 0x50 }, /* 5613 */
- { CR138, 0xa8 }, /* 5112 */
- { CR144, 0xac }, /* 5613 */
- { CR148, 0x40 }, /* 5112 */
- { CR149, 0x40 }, /* 4O07, 50->40 */
- { CR150, 0x1a }, /* 5112, 0C->1A */
- { CR252, 0x34 }, { CR253, 0x34 },
- { CR251, 0x2f }, /* PLL_OFF */
+ { 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[] = {
- { CR251, 0x7f }, /* PLL_ON */
- { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
- { CR38, 0x38 }, { CR136, 0xdf },
+ { 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));
@@ -331,16 +330,16 @@ static int zd1211_al7230b_set_channel(struct zd_rf *rf, u8 channel)
static const struct zd_ioreq16 ioreqs[] = {
/* PLL_ON */
- { CR251, 0x3f },
- { CR203, 0x06 }, { CR240, 0x08 },
+ { ZD_CR251, 0x3f },
+ { ZD_CR203, 0x06 }, { ZD_CR240, 0x08 },
};
- r = zd_iowrite16_locked(chip, 0x57, CR240);
+ r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
if (r)
return r;
/* PLL_OFF */
- r = zd_iowrite16_locked(chip, 0x2f, CR251);
+ r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
if (r)
return r;
@@ -376,15 +375,15 @@ static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
const u32 *rv = chan_rv[channel-1];
struct zd_chip *chip = zd_rf_to_chip(rf);
- r = zd_iowrite16_locked(chip, 0x57, CR240);
+ r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
if (r)
return r;
- r = zd_iowrite16_locked(chip, 0xe4, CR9);
+ r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9);
if (r)
return r;
/* PLL_OFF */
- r = zd_iowrite16_locked(chip, 0x2f, CR251);
+ r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
if (r)
return r;
r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
@@ -410,7 +409,7 @@ static int zd1211b_al7230b_set_channel(struct zd_rf *rf, u8 channel)
if (r)
return r;
- r = zd_iowrite16_locked(chip, 0x7f, CR251);
+ r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251);
if (r)
return r;
@@ -421,8 +420,8 @@ 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[] = {
- { CR11, 0x00 },
- { CR251, 0x3f },
+ { ZD_CR11, 0x00 },
+ { ZD_CR251, 0x3f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -432,8 +431,8 @@ 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[] = {
- { CR11, 0x00 },
- { CR251, 0x7f },
+ { ZD_CR11, 0x00 },
+ { ZD_CR251, 0x7f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -443,8 +442,8 @@ 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[] = {
- { CR11, 0x04 },
- { CR251, 0x2f },
+ { ZD_CR11, 0x04 },
+ { ZD_CR251, 0x2f },
};
return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -456,7 +455,7 @@ 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[] = {
- { CR128, 0x14 }, { CR129, 0x12 },
+ { ZD_CR128, 0x14 }, { ZD_CR129, 0x12 },
};
/* FIXME: Channel 11 is not the edge for all regulatory domains. */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
index 0597d862fbd..a93f657a41c 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
@@ -152,44 +151,44 @@ static int rf2959_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR2, 0x1E }, { CR9, 0x20 }, { CR10, 0x89 },
- { CR11, 0x00 }, { CR15, 0xD0 }, { CR17, 0x68 },
- { CR19, 0x4a }, { CR20, 0x0c }, { CR21, 0x0E },
- { CR23, 0x48 },
+ { 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 */
- { CR24, 0x14 },
- /* { CR24, 0x20 }, */
- { CR26, 0x90 }, { CR27, 0x30 }, { CR29, 0x20 },
- { CR31, 0xb2 }, { CR32, 0x43 }, { CR33, 0x28 },
- { CR38, 0x30 }, { CR34, 0x0f }, { CR35, 0xF0 },
- { CR41, 0x2a }, { CR46, 0x7F }, { CR47, 0x1E },
- { CR51, 0xc5 }, { CR52, 0xc5 }, { CR53, 0xc5 },
- { CR79, 0x58 }, { CR80, 0x30 }, { CR81, 0x30 },
- { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 },
- { CR85, 0x00 }, { CR86, 0x10 }, { CR87, 0x2A },
- { CR88, 0x10 }, { CR89, 0x24 }, { CR90, 0x18 },
- /* { CR91, 0x18 }, */
- /* should solve continous CTS frame problems */
- { CR91, 0x00 },
- { CR92, 0x0a }, { CR93, 0x00 }, { CR94, 0x01 },
- { CR95, 0x00 }, { CR96, 0x40 }, { CR97, 0x37 },
- { CR98, 0x05 }, { CR99, 0x28 }, { CR100, 0x00 },
- { CR101, 0x13 }, { CR102, 0x27 }, { CR103, 0x27 },
- { CR104, 0x18 }, { CR105, 0x12 },
+ { 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 */
- { CR106, 0x1a },
- /* { CR106, 0x22 }, */
- { CR107, 0x24 }, { CR108, 0x0a }, { CR109, 0x13 },
- { CR110, 0x2F }, { CR111, 0x27 }, { CR112, 0x27 },
- { CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x40 },
- { CR116, 0x40 }, { CR117, 0xF0 }, { CR118, 0xF0 },
- { CR119, 0x16 },
+ { 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 */
- { CR122, 0x00 },
- /* { CR122, 0xff }, */
- { CR127, 0x03 }, { CR131, 0x08 }, { CR138, 0x28 },
- { CR148, 0x44 }, { CR150, 0x10 }, { CR169, 0xBB },
- { CR170, 0xBB },
+ { 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[] = {
@@ -210,7 +209,7 @@ static int rf2959_init_hw(struct zd_rf *rf)
*/
0x294128, /* internal power */
/* 0x28252c, */ /* External control TX power */
- /* CR31_CCK, CR51_6-36M, CR52_48M, CR53_54M */
+ /* ZD_CR31_CCK, ZD_CR51_6-36M, ZD_CR52_48M, ZD_CR53_54M */
0x2c0000,
0x300000,
0x340000, /* REG13(0xD) */
@@ -245,8 +244,8 @@ static int rf2959_set_channel(struct zd_rf *rf, u8 channel)
static int rf2959_switch_radio_on(struct zd_rf *rf)
{
static const struct zd_ioreq16 ioreqs[] = {
- { CR10, 0x89 },
- { CR11, 0x00 },
+ { ZD_CR10, 0x89 },
+ { ZD_CR11, 0x00 },
};
struct zd_chip *chip = zd_rf_to_chip(rf);
@@ -256,8 +255,8 @@ static int rf2959_switch_radio_on(struct zd_rf *rf)
static int rf2959_switch_radio_off(struct zd_rf *rf)
{
static const struct zd_ioreq16 ioreqs[] = {
- { CR10, 0x15 },
- { CR11, 0x81 },
+ { ZD_CR10, 0x15 },
+ { ZD_CR11, 0x81 },
};
struct zd_chip *chip = zd_rf_to_chip(rf);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
index 9e74eb1b67d..61b92402735 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
@@ -314,46 +313,48 @@ static int uw2453_init_hw(struct zd_rf *rf)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR10, 0x89 }, { CR15, 0x20 },
- { CR17, 0x28 }, /* 6112 no change */
- { CR23, 0x38 }, { CR24, 0x20 }, { CR26, 0x93 },
- { CR27, 0x15 }, { CR28, 0x3e }, { CR29, 0x00 },
- { CR33, 0x28 }, { CR34, 0x30 },
- { CR35, 0x43 }, /* 6112 3e->43 */
- { CR41, 0x24 }, { CR44, 0x32 },
- { CR46, 0x92 }, /* 6112 96->92 */
- { CR47, 0x1e },
- { CR48, 0x04 }, /* 5602 Roger */
- { CR49, 0xfa }, { CR79, 0x58 }, { CR80, 0x30 },
- { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 },
- { CR91, 0x00 }, { CR92, 0x0a }, { CR98, 0x8d },
- { CR99, 0x28 }, { CR100, 0x02 },
- { CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
- { CR102, 0x27 },
- { CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f 6221 1f->1c */
- { CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
- { CR109, 0x13 },
- { CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
- { CR111, 0x13 }, { CR112, 0x1f }, { CR113, 0x27 },
- { CR114, 0x23 }, /* 6221 27->23 */
- { CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
- { CR116, 0x24 }, /* 6220 1c->24 */
- { CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
- { CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
- { CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
- { CR120, 0x4f },
- { CR121, 0x1f }, /* 6220 4f->1f */
- { CR122, 0xf0 }, { CR123, 0x57 }, { CR125, 0xad },
- { CR126, 0x6c }, { CR127, 0x03 },
- { CR128, 0x14 }, /* 6302 12->11 */
- { CR129, 0x12 }, /* 6301 10->0f */
- { CR130, 0x10 }, { CR137, 0x50 }, { CR138, 0xa8 },
- { CR144, 0xac }, { CR146, 0x20 }, { CR252, 0xff },
- { CR253, 0xff },
+ { 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 reciever gain */
+ 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 */
@@ -433,7 +434,7 @@ static int uw2453_init_hw(struct zd_rf *rf)
* the one that produced a lock. */
UW2453_PRIV(rf)->config = found_config + 1;
- return zd_iowrite16_locked(chip, 0x06, CR203);
+ return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
}
static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
@@ -445,8 +446,8 @@ static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
struct zd_chip *chip = zd_rf_to_chip(rf);
static const struct zd_ioreq16 ioreqs[] = {
- { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
- { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
+ { 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);
@@ -474,7 +475,7 @@ static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
if (r)
return r;
- return zd_iowrite16_locked(chip, 0x06, CR203);
+ return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
}
static int uw2453_switch_radio_on(struct zd_rf *rf)
@@ -482,7 +483,7 @@ 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[] = {
- { CR11, 0x00 }, { CR251, 0x3f },
+ { ZD_CR11, 0x00 }, { ZD_CR251, 0x3f },
};
/* enter RXTX mode */
@@ -501,7 +502,7 @@ 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[] = {
- { CR11, 0x04 }, { CR251, 0x2f },
+ { ZD_CR11, 0x04 }, { ZD_CR251, 0x2f },
};
/* enter IDLE mode */
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 06041cb1c42..a912dc05111 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -15,8 +15,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
@@ -28,6 +27,7 @@
#include <linux/skbuff.h>
#include <linux/usb.h>
#include <linux/workqueue.h>
+#include <linux/module.h>
#include <net/mac80211.h>
#include <asm/unaligned.h>
@@ -60,6 +60,7 @@ static struct usb_device_id usb_ids[] = {
{ 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 */
@@ -110,6 +111,9 @@ 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);
@@ -150,7 +154,6 @@ static int upload_code(struct usb_device *udev,
*/
p = kmalloc(MAX_TRANSFER_SIZE, GFP_KERNEL);
if (!p) {
- dev_err(&udev->dev, "out of memory\n");
r = -ENOMEM;
goto error;
}
@@ -364,6 +367,20 @@ exit:
#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;
@@ -377,28 +394,50 @@ static inline void handle_regs_int(struct urb *urb)
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 (intr->read_regs_enabled) {
- intr->read_regs.length = len = urb->actual_length;
-
+ } 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);
- intr->read_regs_enabled = 0;
+
+ /* 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:
@@ -409,8 +448,10 @@ static void int_urb_complete(struct urb *urb)
case -ENOENT:
case -ECONNRESET:
case -EPIPE:
- goto kfree;
+ 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;
}
@@ -425,6 +466,14 @@ static void int_urb_complete(struct urb *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);
@@ -441,12 +490,11 @@ static void int_urb_complete(struct urb *urb)
resubmit:
r = usb_submit_urb(urb, GFP_ATOMIC);
if (r) {
- dev_dbg_f(urb_dev(urb), "resubmit urb %p\n", urb);
- goto kfree;
+ dev_dbg_f(urb_dev(urb), "error: resubmit urb %p err code %d\n",
+ urb, r);
+ /* TODO: add worker to reset intr->urb */
}
return;
-kfree:
- kfree(urb->transfer_buffer);
}
static inline int int_urb_interval(struct usb_device *udev)
@@ -477,9 +525,8 @@ static inline int usb_int_enabled(struct zd_usb *usb)
int zd_usb_enable_int(struct zd_usb *usb)
{
int r;
- struct usb_device *udev;
+ struct usb_device *udev = zd_usb_to_usbdev(usb);
struct zd_usb_interrupt *intr = &usb->intr;
- void *transfer_buffer = NULL;
struct urb *urb;
dev_dbg_f(zd_usb_dev(usb), "\n");
@@ -500,20 +547,21 @@ int zd_usb_enable_int(struct zd_usb *usb)
intr->urb = urb;
spin_unlock_irq(&intr->lock);
- /* TODO: make it a DMA buffer */
r = -ENOMEM;
- transfer_buffer = kmalloc(USB_MAX_EP_INT_BUFFER, GFP_KERNEL);
- if (!transfer_buffer) {
+ 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;
}
- udev = zd_usb_to_usbdev(usb);
usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN),
- transfer_buffer, USB_MAX_EP_INT_BUFFER,
+ 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);
@@ -525,7 +573,8 @@ int zd_usb_enable_int(struct zd_usb *usb)
return 0;
error:
- kfree(transfer_buffer);
+ 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;
@@ -539,8 +588,11 @@ out:
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;
@@ -549,11 +601,18 @@ void zd_usb_disable_int(struct zd_usb *usb)
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,
@@ -564,8 +623,8 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
if (length < sizeof(struct rx_length_info)) {
/* It's not a complete packet anyhow. */
- printk("%s: invalid, small RX packet : %d\n",
- __func__, length);
+ dev_dbg_f(zd_usb_dev(usb), "invalid, small RX packet : %d\n",
+ length);
return;
}
length_info = (struct rx_length_info *)
@@ -601,6 +660,7 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
static void rx_urb_complete(struct urb *urb)
{
+ int r;
struct zd_usb *usb;
struct zd_usb_rx *rx;
const u8 *buffer;
@@ -615,6 +675,7 @@ static void rx_urb_complete(struct urb *urb)
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);
@@ -626,6 +687,8 @@ static void rx_urb_complete(struct urb *urb)
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");
@@ -654,7 +717,9 @@ static void rx_urb_complete(struct urb *urb)
}
resubmit:
- usb_submit_urb(urb, GFP_ATOMIC);
+ 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)
@@ -690,7 +755,7 @@ static void free_rx_urb(struct urb *urb)
usb_free_urb(urb);
}
-int zd_usb_enable_rx(struct zd_usb *usb)
+static int __zd_usb_enable_rx(struct zd_usb *usb)
{
int i, r;
struct zd_usb_rx *rx = &usb->rx;
@@ -742,7 +807,21 @@ error:
return r;
}
-void zd_usb_disable_rx(struct zd_usb *usb)
+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;
@@ -769,6 +848,41 @@ void zd_usb_disable_rx(struct zd_usb *usb)
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
@@ -779,19 +893,21 @@ void zd_usb_disable_tx(struct zd_usb *usb)
{
struct zd_usb_tx *tx = &usb->tx;
unsigned long flags;
- struct list_head *pos, *n;
+
+ atomic_set(&tx->enabled, 0);
+
+ /* kill all submitted tx-urbs */
+ usb_kill_anchored_urbs(&tx->submitted);
spin_lock_irqsave(&tx->lock, flags);
- list_for_each_safe(pos, n, &tx->free_urb_list) {
- list_del(pos);
- usb_free_urb(list_entry(pos, struct urb, urb_list));
- }
- tx->enabled = 0;
+ 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().
*/
- spin_unlock_irqrestore(&tx->lock, flags);
}
/**
@@ -807,63 +923,13 @@ void zd_usb_enable_tx(struct zd_usb *usb)
struct zd_usb_tx *tx = &usb->tx;
spin_lock_irqsave(&tx->lock, flags);
- tx->enabled = 1;
+ 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);
}
-/**
- * alloc_tx_urb - provides an tx URB
- * @usb: a &struct zd_usb pointer
- *
- * Allocates a new URB. If possible takes the urb from the free list in
- * usb->tx.
- */
-static struct urb *alloc_tx_urb(struct zd_usb *usb)
-{
- struct zd_usb_tx *tx = &usb->tx;
- unsigned long flags;
- struct list_head *entry;
- struct urb *urb;
-
- spin_lock_irqsave(&tx->lock, flags);
- if (list_empty(&tx->free_urb_list)) {
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- goto out;
- }
- entry = tx->free_urb_list.next;
- list_del(entry);
- urb = list_entry(entry, struct urb, urb_list);
-out:
- spin_unlock_irqrestore(&tx->lock, flags);
- return urb;
-}
-
-/**
- * free_tx_urb - frees a used tx URB
- * @usb: a &struct zd_usb pointer
- * @urb: URB to be freed
- *
- * Frees the transmission URB, which means to put it on the free URB
- * list.
- */
-static void free_tx_urb(struct zd_usb *usb, struct urb *urb)
-{
- struct zd_usb_tx *tx = &usb->tx;
- unsigned long flags;
-
- spin_lock_irqsave(&tx->lock, flags);
- if (!tx->enabled) {
- usb_free_urb(urb);
- goto out;
- }
- list_add(&urb->urb_list, &tx->free_urb_list);
-out:
- spin_unlock_irqrestore(&tx->lock, flags);
-}
-
static void tx_dec_submitted_urbs(struct zd_usb *usb)
{
struct zd_usb_tx *tx = &usb->tx;
@@ -905,6 +971,16 @@ static void tx_urb_complete(struct urb *urb)
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:
@@ -922,20 +998,16 @@ static void tx_urb_complete(struct urb *urb)
goto resubmit;
}
free_urb:
- skb = (struct sk_buff *)urb->context;
- /*
- * grab 'usb' pointer before handing off the skb (since
- * it might be freed by zd_mac_tx_to_dev or mac80211)
- */
- info = IEEE80211_SKB_CB(skb);
- usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb;
+ skb_unlink(skb, &usb->tx.submitted_skbs);
zd_mac_tx_to_dev(skb, urb->status);
- free_tx_urb(usb, urb);
+ 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;
}
@@ -956,10 +1028,17 @@ resubmit:
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 = alloc_tx_urb(usb);
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
r = -ENOMEM;
goto out;
@@ -968,17 +1047,124 @@ int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb)
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)
+ 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:
- free_tx_urb(usb, urb);
+ 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;
@@ -986,29 +1172,39 @@ static inline void init_usb_interrupt(struct zd_usb *usb)
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);
- tx->enabled = 0;
+ atomic_set(&tx->enabled, 0);
tx->stopped = 0;
- INIT_LIST_HEAD(&tx->free_urb_list);
+ 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,
@@ -1017,6 +1213,7 @@ void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw,
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);
@@ -1240,6 +1437,7 @@ static void disconnect(struct usb_interface *intf)
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);
@@ -1255,11 +1453,93 @@ static void disconnect(struct usb_interface *intf)
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;
@@ -1298,18 +1578,47 @@ static void __exit usb_exit(void)
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)
+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);
- intr->read_regs_enabled = 1;
- INIT_COMPLETION(intr->read_regs.completion);
+ 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);
}
@@ -1318,22 +1627,18 @@ static void disable_read_regs_int(struct zd_usb *usb)
struct zd_usb_interrupt *intr = &usb->intr;
spin_lock_irq(&intr->lock);
- intr->read_regs_enabled = 0;
+ atomic_set(&intr->read_regs_enabled, 0);
spin_unlock_irq(&intr->lock);
}
-static int get_results(struct zd_usb *usb, u16 *values,
- struct usb_req_read_regs *req, unsigned int count)
+static bool check_read_regs(struct zd_usb *usb, struct usb_req_read_regs *req,
+ unsigned int count)
{
- 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;
/* The created block size seems to be larger than expected.
* However results appear to be correct.
*/
@@ -1341,13 +1646,14 @@ static int get_results(struct zd_usb *usb, u16 *values,
dev_dbg_f(zd_usb_dev(usb),
"error: actual length %d less than expected %d\n",
rr->length, usb_int_regs_length(count));
- goto error_unlock;
+ 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));
- goto error_unlock;
+ return false;
}
for (i = 0; i < count; i++) {
@@ -1357,8 +1663,39 @@ static int get_results(struct zd_usb *usb, u16 *values,
"rd[%d] addr %#06hx expected %#06hx\n", i,
le16_to_cpu(rd->addr),
le16_to_cpu(req->addr[i]));
- goto error_unlock;
+ 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 = &regs->regs[i];
values[i] = le16_to_cpu(rd->value);
}
@@ -1371,11 +1708,11 @@ error_unlock:
int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
const zd_addr_t *addresses, unsigned int count)
{
- int r;
- int i, req_len, actual_req_len;
+ 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");
@@ -1393,30 +1730,36 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
return -EWOULDBLOCK;
}
if (!usb_int_enabled(usb)) {
- dev_dbg_f(zd_usb_dev(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 = kmalloc(req_len, GFP_KERNEL);
- if (!req)
- return -ENOMEM;
+ 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);
- r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
- req, req_len, &actual_req_len, 1000 /* ms */);
+ 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 usb_bulk_msg(). Error number %d\n", r);
+ "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 usb_bulk_msg()\n"
+ 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;
@@ -1424,7 +1767,7 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
}
timeout = wait_for_completion_timeout(&usb->intr.read_regs.completion,
- msecs_to_jiffies(1000));
+ msecs_to_jiffies(50));
if (!timeout) {
disable_read_regs_int(usb);
dev_dbg_f(zd_usb_dev(usb), "read timed out\n");
@@ -1432,19 +1775,117 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
goto error;
}
- r = get_results(usb, values, req, count);
+ 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:
- kfree(req);
return r;
}
-int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
- unsigned int count)
+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, actual_req_len;
+ 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;
@@ -1460,11 +1901,23 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
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)
- return -ENOMEM;
+ if (!req) {
+ r = -ENOMEM;
+ goto error;
+ }
req->id = cpu_to_le16(USB_REQ_WRITE_REGS);
for (i = 0; i < count; i++) {
@@ -1473,29 +1926,52 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
rw->value = cpu_to_le16(ioreqs[i].value);
}
- udev = zd_usb_to_usbdev(usb);
- r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
- req, req_len, &actual_req_len, 1000 /* ms */);
+ /* 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 usb_bulk_msg(). Error number %d\n", r);
- goto error;
- }
- if (req_len != actual_req_len) {
- dev_dbg_f(zd_usb_dev(usb),
- "error in usb_bulk_msg()"
- " req_len %d != actual_req_len %d\n",
- req_len, actual_req_len);
- r = -EIO;
+ "error in zd_submit_waiting_usb(). "
+ "Error number %d\n", r);
goto error;
}
- /* FALL-THROUGH with r == 0 */
+ /* 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:
- kfree(req);
+ 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;
@@ -1533,18 +2009,23 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits);
- r = zd_usb_ioread16(usb, &bit_value_template, CR203);
+ r = zd_usb_ioread16(usb, &bit_value_template, ZD_CR203);
if (r) {
dev_dbg_f(zd_usb_dev(usb),
- "error %d: Couldn't read CR203\n", r);
- goto out;
+ "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 = kmalloc(req_len, GFP_KERNEL);
- if (!req)
- return -ENOMEM;
+ req = (void *)usb->req_buf;
req->id = cpu_to_le16(USB_REQ_WRITE_RF);
/* 1: 3683a, but not used in ZYDAS driver */
@@ -1559,15 +2040,14 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
}
udev = zd_usb_to_usbdev(usb);
- r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
- req, req_len, &actual_req_len, 1000 /* ms */);
+ 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 usb_bulk_msg(). Error number %d\n", r);
+ "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 usb_bulk_msg()"
+ 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;
@@ -1576,6 +2056,5 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits)
/* FALL-THROUGH with r == 0 */
out:
- kfree(req);
return r;
}
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index 1b1655cb7cb..a9075f22517 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -14,8 +14,7 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ZD_USB_H
@@ -32,6 +31,10 @@
#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,
@@ -105,7 +108,7 @@ struct usb_req_rfwrite {
__le16 bits;
/* RF2595: 24 */
__le16 bit_values[0];
- /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
+ /* (ZD_CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
} __packed;
/* USB interrupt */
@@ -140,6 +143,8 @@ struct usb_int_retry_fail {
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.
*/
@@ -162,8 +167,11 @@ 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;
- u8 read_regs_enabled:1;
+ 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)
@@ -175,7 +183,10 @@ static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr)
struct zd_usb_rx {
spinlock_t lock;
- u8 fragment[2*USB_MAX_RX_SIZE];
+ 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;
@@ -184,19 +195,21 @@ struct zd_usb_rx {
/**
* struct zd_usb_tx - structure used for transmitting frames
+ * @enabled: atomic enabled flag, indicates whether tx is enabled
* @lock: lock for transmission
- * @free_urb_list: list of free URBs, contains all the URBs, which can be used
+ * @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
- * @enabled: enabled flag, indicates whether tx is enabled
* @stopped: indicates whether higher level tx queues are stopped
*/
struct zd_usb_tx {
+ atomic_t enabled;
spinlock_t lock;
- struct list_head free_urb_list;
+ struct delayed_work watchdog_work;
+ struct sk_buff_head submitted_skbs;
+ struct usb_anchor submitted;
int submitted_urbs;
- int enabled;
- int stopped;
+ u8 stopped:1, watchdog_enabled:1;
};
/* Contains the usb parts. The structure doesn't require a lock because intf
@@ -207,7 +220,11 @@ struct zd_usb {
struct zd_usb_rx rx;
struct zd_usb_tx tx;
struct usb_interface *intf;
- u8 is_zd1211b:1, initialized:1;
+ 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)
@@ -234,12 +251,17 @@ 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);
@@ -251,9 +273,13 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value,
const zd_addr_t addr)
{
- return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1);
+ 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);