aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-01-05 10:12:45 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-01-05 10:13:24 -0500
commit1032c736e81cdf490ae62f86da7efe67c3c3e61d (patch)
treea0c3919849f97dbbc5ea7c6a9ac1d7a639e44a73 /drivers/net/wireless
parent117ff42fd43e92d24c6aa6f3e4f0f1e1edada140 (diff)
parentcb00ec382b57d35b955c085198cd54a0c1fcdc94 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/b43legacy/dma.c
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath5k/trace.h5
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig25
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile37
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c10
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.c5
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.c10
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c431
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c3
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c97
-rw-r--r--drivers/net/wireless/b43/b43.h11
-rw-r--r--drivers/net/wireless/b43/phy_n.c355
-rw-r--r--drivers/net/wireless/b43/phy_n.h6
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c106
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h20
-rw-r--r--drivers/net/wireless/b43legacy/dma.c65
-rw-r--r--drivers/net/wireless/b43legacy/dma.h5
-rw-r--r--drivers/net/wireless/b43legacy/main.c86
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h4
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_wx.c25
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c11
-rw-r--r--drivers/net/wireless/iwlegacy/3945-rs.c31
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c20
-rw-r--r--drivers/net/wireless/iwlegacy/3945.h21
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c71
-rw-r--r--drivers/net/wireless/iwlegacy/4965.c19
-rw-r--r--drivers/net/wireless/iwlegacy/4965.h8
-rw-r--r--drivers/net/wireless/iwlegacy/common.c161
-rw-r--r--drivers/net/wireless/iwlegacy/common.h206
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-sta.c817
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c10
-rw-r--r--drivers/net/wireless/mwl8k.c138
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c47
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c65
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c16
46 files changed, 999 insertions, 1981 deletions
diff --git a/drivers/net/wireless/ath/ath5k/trace.h b/drivers/net/wireless/ath/ath5k/trace.h
index 39f002ed4a88..00f015819344 100644
--- a/drivers/net/wireless/ath/ath5k/trace.h
+++ b/drivers/net/wireless/ath/ath5k/trace.h
@@ -3,7 +3,8 @@
3 3
4#include <linux/tracepoint.h> 4#include <linux/tracepoint.h>
5 5
6#ifndef CONFIG_ATH5K_TRACER 6
7#if !defined(CONFIG_ATH5K_TRACER) || defined(__CHECKER__)
7#undef TRACE_EVENT 8#undef TRACE_EVENT
8#define TRACE_EVENT(name, proto, ...) \ 9#define TRACE_EVENT(name, proto, ...) \
9static inline void trace_ ## name(proto) {} 10static inline void trace_ ## name(proto) {}
@@ -93,7 +94,7 @@ TRACE_EVENT(ath5k_tx_complete,
93 94
94#endif /* __TRACE_ATH5K_H */ 95#endif /* __TRACE_ATH5K_H */
95 96
96#ifdef CONFIG_ATH5K_TRACER 97#if defined(CONFIG_ATH5K_TRACER) && !defined(__CHECKER__)
97 98
98#undef TRACE_INCLUDE_PATH 99#undef TRACE_INCLUDE_PATH
99#define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k 100#define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index d755a5e7ed20..3d5f8be20eac 100644
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -1,29 +1,12 @@
1config ATH6KL 1config ATH6KL
2 tristate "Atheros mobile chipsets support" 2 tristate "Atheros ath6kl support"
3
4config ATH6KL_SDIO
5 tristate "Atheros ath6kl SDIO support"
6 depends on ATH6KL
7 depends on MMC 3 depends on MMC
8 depends on CFG80211 4 depends on CFG80211
9 ---help--- 5 ---help---
10 This module adds support for wireless adapters based on 6 This module adds support for wireless adapters based on
11 Atheros AR6003 and AR6004 chipsets running over SDIO. If you 7 Atheros AR6003 chipset running over SDIO. If you choose to
12 choose to build it as a module, it will be called ath6kl_sdio. 8 build it as a module, it will be called ath6kl. Pls note
13 Please note that AR6002 and AR6001 are not supported by this 9 that AR6002 and AR6001 are not supported by this driver.
14 driver.
15
16config ATH6KL_USB
17 tristate "Atheros ath6kl USB support"
18 depends on ATH6KL
19 depends on USB
20 depends on CFG80211
21 depends on EXPERIMENTAL
22 ---help---
23 This module adds support for wireless adapters based on
24 Atheros AR6004 chipset running over USB. This is still under
25 implementation and it isn't functional. If you choose to
26 build it as a module, it will be called ath6kl_usb.
27 10
28config ATH6KL_DEBUG 11config ATH6KL_DEBUG
29 bool "Atheros ath6kl debugging" 12 bool "Atheros ath6kl debugging"
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index e14cef9c3c0e..707069303550 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -21,30 +21,17 @@
21# Author(s): ="Atheros" 21# Author(s): ="Atheros"
22#------------------------------------------------------------------------------ 22#------------------------------------------------------------------------------
23 23
24obj-$(CONFIG_ATH6KL_SDIO) := ath6kl_sdio.o 24obj-$(CONFIG_ATH6KL) := ath6kl.o
25ath6kl_sdio-y += debug.o 25ath6kl-y += debug.o
26ath6kl_sdio-y += hif.o 26ath6kl-y += hif.o
27ath6kl_sdio-y += htc.o 27ath6kl-y += htc.o
28ath6kl_sdio-y += bmi.o 28ath6kl-y += bmi.o
29ath6kl_sdio-y += cfg80211.o 29ath6kl-y += cfg80211.o
30ath6kl_sdio-y += init.o 30ath6kl-y += init.o
31ath6kl_sdio-y += main.o 31ath6kl-y += main.o
32ath6kl_sdio-y += txrx.o 32ath6kl-y += txrx.o
33ath6kl_sdio-y += wmi.o 33ath6kl-y += wmi.o
34ath6kl_sdio-y += sdio.o 34ath6kl-y += sdio.o
35ath6kl_sdio-$(CONFIG_NL80211_TESTMODE) += testmode.o 35ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o
36
37obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o
38ath6kl_usb-y += debug.o
39ath6kl_usb-y += hif.o
40ath6kl_usb-y += htc.o
41ath6kl_usb-y += bmi.o
42ath6kl_usb-y += cfg80211.o
43ath6kl_usb-y += init.o
44ath6kl_usb-y += main.o
45ath6kl_usb-y += txrx.o
46ath6kl_usb-y += wmi.o
47ath6kl_usb-y += usb.o
48ath6kl_usb-$(CONFIG_NL80211_TESTMODE) += testmode.o
49 36
50ccflags-y += -D__CHECK_ENDIAN__ 37ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index aef00d5a1438..bce3575c310a 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -57,14 +57,8 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
57 return ret; 57 return ret;
58 } 58 }
59 59
60 if (ar->hif_type == ATH6KL_HIF_TYPE_USB) { 60 ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
61 ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info, 61 sizeof(targ_info->version));
62 sizeof(*targ_info));
63 } else {
64 ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
65 sizeof(targ_info->version));
66 }
67
68 if (ret) { 62 if (ret) {
69 ath6kl_err("Unable to recv target info: %d\n", ret); 63 ath6kl_err("Unable to recv target info: %d\n", ret);
70 return ret; 64 return ret;
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index e569c652e35c..9853c9c125c1 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -41,7 +41,6 @@ enum ATH6K_DEBUG_MASK {
41 ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */ 41 ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */
42 ATH6KL_DBG_WMI_DUMP = BIT(19), 42 ATH6KL_DBG_WMI_DUMP = BIT(19),
43 ATH6KL_DBG_SUSPEND = BIT(20), 43 ATH6KL_DBG_SUSPEND = BIT(20),
44 ATH6KL_DBG_USB = BIT(21),
45 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ 44 ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
46}; 45};
47 46
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index 0772ef650174..e57da35e59fa 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -689,11 +689,6 @@ int ath6kl_hif_setup(struct ath6kl_device *dev)
689 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", 689 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
690 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); 690 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
691 691
692 /* usb doesn't support enabling interrupts */
693 /* FIXME: remove check once USB support is implemented */
694 if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)
695 return 0;
696
697 status = ath6kl_hif_disable_intrs(dev); 692 status = ath6kl_hif_disable_intrs(dev);
698 693
699fail_setup: 694fail_setup:
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index b01702258faf..f3b63ca25c7e 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -2543,12 +2543,6 @@ int ath6kl_htc_wait_target(struct htc_target *target)
2543 struct htc_service_connect_resp resp; 2543 struct htc_service_connect_resp resp;
2544 int status; 2544 int status;
2545 2545
2546 /* FIXME: remove once USB support is implemented */
2547 if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {
2548 ath6kl_err("HTC doesn't support USB yet. Patience!\n");
2549 return -EOPNOTSUPP;
2550 }
2551
2552 /* we should be getting 1 control message that the target is ready */ 2546 /* we should be getting 1 control message that the target is ready */
2553 packet = htc_wait_for_ctrl_msg(target); 2547 packet = htc_wait_for_ctrl_msg(target);
2554 2548
@@ -2778,9 +2772,7 @@ void ath6kl_htc_cleanup(struct htc_target *target)
2778{ 2772{
2779 struct htc_packet *packet, *tmp_packet; 2773 struct htc_packet *packet, *tmp_packet;
2780 2774
2781 /* FIXME: remove check once USB support is implemented */ 2775 ath6kl_hif_cleanup_scatter(target->dev->ar);
2782 if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)
2783 ath6kl_hif_cleanup_scatter(target->dev->ar);
2784 2776
2785 list_for_each_entry_safe(packet, tmp_packet, 2777 list_for_each_entry_safe(packet, tmp_packet,
2786 &target->free_ctrl_txbuf, list) { 2778 &target->free_ctrl_txbuf, list) {
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 15c3f56caf4f..9475e2d0d0b7 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -1332,7 +1332,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = {
1332MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); 1332MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
1333 1333
1334static struct sdio_driver ath6kl_sdio_driver = { 1334static struct sdio_driver ath6kl_sdio_driver = {
1335 .name = "ath6kl_sdio", 1335 .name = "ath6kl",
1336 .id_table = ath6kl_sdio_devices, 1336 .id_table = ath6kl_sdio_devices,
1337 .probe = ath6kl_sdio_probe, 1337 .probe = ath6kl_sdio_probe,
1338 .remove = ath6kl_sdio_remove, 1338 .remove = ath6kl_sdio_remove,
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
deleted file mode 100644
index e3cf397fcafe..000000000000
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ /dev/null
@@ -1,431 +0,0 @@
1/*
2 * Copyright (c) 2007-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/module.h>
18#include <linux/usb.h>
19
20#include "debug.h"
21#include "core.h"
22
23/* usb device object */
24struct ath6kl_usb {
25 struct usb_device *udev;
26 struct usb_interface *interface;
27 u8 *diag_cmd_buffer;
28 u8 *diag_resp_buffer;
29 struct ath6kl *ar;
30};
31
32/* diagnostic command defnitions */
33#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1
34#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2
35#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD 3
36#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP 4
37
38#define ATH6KL_USB_CTRL_DIAG_CC_READ 0
39#define ATH6KL_USB_CTRL_DIAG_CC_WRITE 1
40
41struct ath6kl_usb_ctrl_diag_cmd_write {
42 __le32 cmd;
43 __le32 address;
44 __le32 value;
45 __le32 _pad[1];
46} __packed;
47
48struct ath6kl_usb_ctrl_diag_cmd_read {
49 __le32 cmd;
50 __le32 address;
51} __packed;
52
53struct ath6kl_usb_ctrl_diag_resp_read {
54 __le32 value;
55} __packed;
56
57#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write))
58#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read))
59
60static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb)
61{
62 usb_set_intfdata(ar_usb->interface, NULL);
63
64 kfree(ar_usb->diag_cmd_buffer);
65 kfree(ar_usb->diag_resp_buffer);
66
67 kfree(ar_usb);
68}
69
70static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface)
71{
72 struct ath6kl_usb *ar_usb = NULL;
73 struct usb_device *dev = interface_to_usbdev(interface);
74 int status = 0;
75
76 ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL);
77 if (ar_usb == NULL)
78 goto fail_ath6kl_usb_create;
79
80 memset(ar_usb, 0, sizeof(struct ath6kl_usb));
81 usb_set_intfdata(interface, ar_usb);
82 ar_usb->udev = dev;
83 ar_usb->interface = interface;
84
85 ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL);
86 if (ar_usb->diag_cmd_buffer == NULL) {
87 status = -ENOMEM;
88 goto fail_ath6kl_usb_create;
89 }
90
91 ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP,
92 GFP_KERNEL);
93 if (ar_usb->diag_resp_buffer == NULL) {
94 status = -ENOMEM;
95 goto fail_ath6kl_usb_create;
96 }
97
98fail_ath6kl_usb_create:
99 if (status != 0) {
100 ath6kl_usb_destroy(ar_usb);
101 ar_usb = NULL;
102 }
103 return ar_usb;
104}
105
106static void ath6kl_usb_device_detached(struct usb_interface *interface)
107{
108 struct ath6kl_usb *ar_usb;
109
110 ar_usb = usb_get_intfdata(interface);
111 if (ar_usb == NULL)
112 return;
113
114 ath6kl_stop_txrx(ar_usb->ar);
115
116 ath6kl_core_cleanup(ar_usb->ar);
117
118 ath6kl_usb_destroy(ar_usb);
119}
120
121static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
122 u8 req, u16 value, u16 index, void *data,
123 u32 size)
124{
125 u8 *buf = NULL;
126 int ret;
127
128 if (size > 0) {
129 buf = kmalloc(size, GFP_KERNEL);
130 if (buf == NULL)
131 return -ENOMEM;
132
133 memcpy(buf, data, size);
134 }
135
136 /* note: if successful returns number of bytes transfered */
137 ret = usb_control_msg(ar_usb->udev,
138 usb_sndctrlpipe(ar_usb->udev, 0),
139 req,
140 USB_DIR_OUT | USB_TYPE_VENDOR |
141 USB_RECIP_DEVICE, value, index, buf,
142 size, 1000);
143
144 if (ret < 0) {
145 ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
146 __func__, ret);
147 }
148
149 kfree(buf);
150
151 return 0;
152}
153
154static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
155 u8 req, u16 value, u16 index, void *data,
156 u32 size)
157{
158 u8 *buf = NULL;
159 int ret;
160
161 if (size > 0) {
162 buf = kmalloc(size, GFP_KERNEL);
163 if (buf == NULL)
164 return -ENOMEM;
165 }
166
167 /* note: if successful returns number of bytes transfered */
168 ret = usb_control_msg(ar_usb->udev,
169 usb_rcvctrlpipe(ar_usb->udev, 0),
170 req,
171 USB_DIR_IN | USB_TYPE_VENDOR |
172 USB_RECIP_DEVICE, value, index, buf,
173 size, 2 * HZ);
174
175 if (ret < 0) {
176 ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
177 __func__, ret);
178 }
179
180 memcpy((u8 *) data, buf, size);
181
182 kfree(buf);
183
184 return 0;
185}
186
187static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb,
188 u8 req_val, u8 *req_buf, u32 req_len,
189 u8 resp_val, u8 *resp_buf, u32 *resp_len)
190{
191 int ret;
192
193 /* send command */
194 ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0,
195 req_buf, req_len);
196
197 if (ret != 0)
198 return ret;
199
200 if (resp_buf == NULL) {
201 /* no expected response */
202 return ret;
203 }
204
205 /* get response */
206 ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0,
207 resp_buf, *resp_len);
208
209 return ret;
210}
211
212static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
213{
214 struct ath6kl_usb *ar_usb = ar->hif_priv;
215 struct ath6kl_usb_ctrl_diag_resp_read *resp;
216 struct ath6kl_usb_ctrl_diag_cmd_read *cmd;
217 u32 resp_len;
218 int ret;
219
220 cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer;
221
222 memset(cmd, 0, sizeof(*cmd));
223 cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ;
224 cmd->address = cpu_to_le32(address);
225 resp_len = sizeof(*resp);
226
227 ret = ath6kl_usb_ctrl_msg_exchange(ar_usb,
228 ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
229 (u8 *) cmd,
230 sizeof(struct ath6kl_usb_ctrl_diag_cmd_write),
231 ATH6KL_USB_CONTROL_REQ_DIAG_RESP,
232 ar_usb->diag_resp_buffer, &resp_len);
233
234 if (ret)
235 return ret;
236
237 resp = (struct ath6kl_usb_ctrl_diag_resp_read *)
238 ar_usb->diag_resp_buffer;
239
240 *data = le32_to_cpu(resp->value);
241
242 return ret;
243}
244
245static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
246{
247 struct ath6kl_usb *ar_usb = ar->hif_priv;
248 struct ath6kl_usb_ctrl_diag_cmd_write *cmd;
249
250 cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer;
251
252 memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write));
253 cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE);
254 cmd->address = cpu_to_le32(address);
255 cmd->value = data;
256
257 return ath6kl_usb_ctrl_msg_exchange(ar_usb,
258 ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
259 (u8 *) cmd,
260 sizeof(*cmd),
261 0, NULL, NULL);
262
263}
264
265static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
266{
267 struct ath6kl_usb *ar_usb = ar->hif_priv;
268 int ret;
269
270 /* get response */
271 ret = ath6kl_usb_submit_ctrl_in(ar_usb,
272 ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
273 0, 0, buf, len);
274 if (ret != 0) {
275 ath6kl_err("Unable to read the bmi data from the device: %d\n",
276 ret);
277 return ret;
278 }
279
280 return 0;
281}
282
283static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
284{
285 struct ath6kl_usb *ar_usb = ar->hif_priv;
286 int ret;
287
288 /* send command */
289 ret = ath6kl_usb_submit_ctrl_out(ar_usb,
290 ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD,
291 0, 0, buf, len);
292 if (ret != 0) {
293 ath6kl_err("unable to send the bmi data to the device: %d\n",
294 ret);
295 return ret;
296 }
297
298 return 0;
299}
300
301static int ath6kl_usb_power_on(struct ath6kl *ar)
302{
303 return 0;
304}
305
306static int ath6kl_usb_power_off(struct ath6kl *ar)
307{
308 return 0;
309}
310
311static const struct ath6kl_hif_ops ath6kl_usb_ops = {
312 .diag_read32 = ath6kl_usb_diag_read32,
313 .diag_write32 = ath6kl_usb_diag_write32,
314 .bmi_read = ath6kl_usb_bmi_read,
315 .bmi_write = ath6kl_usb_bmi_write,
316 .power_on = ath6kl_usb_power_on,
317 .power_off = ath6kl_usb_power_off,
318};
319
320/* ath6kl usb driver registered functions */
321static int ath6kl_usb_probe(struct usb_interface *interface,
322 const struct usb_device_id *id)
323{
324 struct usb_device *dev = interface_to_usbdev(interface);
325 struct ath6kl *ar;
326 struct ath6kl_usb *ar_usb = NULL;
327 int vendor_id, product_id;
328 int ret = 0;
329
330 usb_get_dev(dev);
331
332 vendor_id = le16_to_cpu(dev->descriptor.idVendor);
333 product_id = le16_to_cpu(dev->descriptor.idProduct);
334
335 ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id);
336 ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id);
337
338 if (interface->cur_altsetting)
339 ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n",
340 interface->cur_altsetting->desc.bInterfaceNumber);
341
342
343 if (dev->speed == USB_SPEED_HIGH)
344 ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n");
345 else
346 ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n");
347
348 ar_usb = ath6kl_usb_create(interface);
349
350 if (ar_usb == NULL) {
351 ret = -ENOMEM;
352 goto err_usb_put;
353 }
354
355 ar = ath6kl_core_alloc(&ar_usb->udev->dev);
356 if (ar == NULL) {
357 ath6kl_err("Failed to alloc ath6kl core\n");
358 ret = -ENOMEM;
359 goto err_usb_destroy;
360 }
361
362 ar->hif_priv = ar_usb;
363 ar->hif_type = ATH6KL_HIF_TYPE_USB;
364 ar->hif_ops = &ath6kl_usb_ops;
365 ar->mbox_info.block_size = 16;
366 ar->bmi.max_data_size = 252;
367
368 ar_usb->ar = ar;
369
370 ret = ath6kl_core_init(ar);
371 if (ret) {
372 ath6kl_err("Failed to init ath6kl core: %d\n", ret);
373 goto err_core_free;
374 }
375
376 return ret;
377
378err_core_free:
379 ath6kl_core_free(ar);
380err_usb_destroy:
381 ath6kl_usb_destroy(ar_usb);
382err_usb_put:
383 usb_put_dev(dev);
384
385 return ret;
386}
387
388static void ath6kl_usb_remove(struct usb_interface *interface)
389{
390 usb_put_dev(interface_to_usbdev(interface));
391 ath6kl_usb_device_detached(interface);
392}
393
394/* table of devices that work with this driver */
395static struct usb_device_id ath6kl_usb_ids[] = {
396 {USB_DEVICE(0x0cf3, 0x9374)},
397 { /* Terminating entry */ },
398};
399
400MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids);
401
402static struct usb_driver ath6kl_usb_driver = {
403 .name = "ath6kl_usb",
404 .probe = ath6kl_usb_probe,
405 .disconnect = ath6kl_usb_remove,
406 .id_table = ath6kl_usb_ids,
407};
408
409static int ath6kl_usb_init(void)
410{
411 usb_register(&ath6kl_usb_driver);
412 return 0;
413}
414
415static void ath6kl_usb_exit(void)
416{
417 usb_deregister(&ath6kl_usb_driver);
418}
419
420module_init(ath6kl_usb_init);
421module_exit(ath6kl_usb_exit);
422
423MODULE_AUTHOR("Atheros Communications, Inc.");
424MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices");
425MODULE_LICENSE("Dual BSD/GPL");
426MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE);
427MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
428MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
429MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
430MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
431MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 391def99314c..9fbcbddea165 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3538,13 +3538,13 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3538static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz) 3538static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz)
3539{ 3539{
3540 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 3540 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
3541 __le32 val; 3541 __le16 val;
3542 3542
3543 if (is_2ghz) 3543 if (is_2ghz)
3544 val = eep->modalHeader2G.switchcomspdt; 3544 val = eep->modalHeader2G.switchcomspdt;
3545 else 3545 else
3546 val = eep->modalHeader5G.switchcomspdt; 3546 val = eep->modalHeader5G.switchcomspdt;
3547 return le32_to_cpu(val); 3547 return le16_to_cpu(val);
3548} 3548}
3549 3549
3550 3550
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 4a315155d779..88c81c5706b2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -583,7 +583,7 @@ void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
583 583
584void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start, 584void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
585 u32 ts_paddr_start, 585 u32 ts_paddr_start,
586 u8 size) 586 u16 size)
587{ 587{
588 588
589 ah->ts_paddr_start = ts_paddr_start; 589 ah->ts_paddr_start = ts_paddr_start;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index c50449387bf1..e203b51e968b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -118,5 +118,5 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah,
118void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah); 118void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah);
119void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start, 119void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
120 u32 ts_paddr_start, 120 u32 ts_paddr_start,
121 u8 size); 121 u16 size);
122#endif 122#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
index 48803ee9c0d6..458bedf0b0ae 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
@@ -16,6 +16,7 @@
16 16
17#include "hw.h" 17#include "hw.h"
18#include "ar9003_phy.h" 18#include "ar9003_phy.h"
19#include "ar9003_rtt.h"
19 20
20#define RTT_RESTORE_TIMEOUT 1000 21#define RTT_RESTORE_TIMEOUT 1000
21#define RTT_ACCESS_TIMEOUT 100 22#define RTT_ACCESS_TIMEOUT 100
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 95276e914c1b..b30e9fc6433f 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -97,7 +97,7 @@ enum buffer_type {
97#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) 97#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
98#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) 98#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
99 99
100#define ATH_TXSTATUS_RING_SIZE 64 100#define ATH_TXSTATUS_RING_SIZE 512
101 101
102#define DS2PHYS(_dd, _ds) \ 102#define DS2PHYS(_dd, _ds) \
103 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) 103 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index dc5fd569690f..b8967e482e6e 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -356,6 +356,7 @@ void ath_beacon_tasklet(unsigned long data)
356 struct ath_buf *bf = NULL; 356 struct ath_buf *bf = NULL;
357 struct ieee80211_vif *vif; 357 struct ieee80211_vif *vif;
358 struct ath_tx_status ts; 358 struct ath_tx_status ts;
359 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
359 int slot; 360 int slot;
360 u32 bfaddr, bc = 0; 361 u32 bfaddr, bc = 0;
361 362
@@ -456,10 +457,12 @@ void ath_beacon_tasklet(unsigned long data)
456 if (bfaddr != 0) { 457 if (bfaddr != 0) {
457 /* NB: cabq traffic should already be queued and primed */ 458 /* NB: cabq traffic should already be queued and primed */
458 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); 459 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
459 ath9k_hw_txstart(ah, sc->beacon.beaconq); 460
461 if (!edma)
462 ath9k_hw_txstart(ah, sc->beacon.beaconq);
460 463
461 sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ 464 sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */
462 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 465 if (edma) {
463 spin_lock_bh(&sc->sc_pcu_lock); 466 spin_lock_bh(&sc->sc_pcu_lock);
464 ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts); 467 ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts);
465 spin_unlock_bh(&sc->sc_pcu_lock); 468 spin_unlock_bh(&sc->sc_pcu_lock);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 48205c2960b5..6a29004a71b0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1016,7 +1016,7 @@ struct ath_hw {
1016 u32 ts_paddr_start; 1016 u32 ts_paddr_start;
1017 u32 ts_paddr_end; 1017 u32 ts_paddr_end;
1018 u16 ts_tail; 1018 u16 ts_tail;
1019 u8 ts_size; 1019 u16 ts_size;
1020 1020
1021 u32 bb_watchdog_last_status; 1021 u32 bb_watchdog_last_status;
1022 u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ 1022 u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index fee8c6f0b251..05c23ea4c633 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -20,7 +20,7 @@
20#include "ath9k.h" 20#include "ath9k.h"
21#include "mci.h" 21#include "mci.h"
22 22
23u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; 23static const u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 };
24 24
25static struct ath_mci_profile_info* 25static struct ath_mci_profile_info*
26ath_mci_find_profile(struct ath_mci_profile *mci, 26ath_mci_find_profile(struct ath_mci_profile *mci,
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 9aa01997b1ea..3182408ffe35 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -105,16 +105,19 @@ static int ath_max_4ms_framelen[4][32] = {
105/*********************/ 105/*********************/
106 106
107static void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) 107static void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq)
108 __acquires(&txq->axq_lock)
108{ 109{
109 spin_lock_bh(&txq->axq_lock); 110 spin_lock_bh(&txq->axq_lock);
110} 111}
111 112
112static void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) 113static void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq)
114 __releases(&txq->axq_lock)
113{ 115{
114 spin_unlock_bh(&txq->axq_lock); 116 spin_unlock_bh(&txq->axq_lock);
115} 117}
116 118
117static void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) 119static void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
120 __releases(&txq->axq_lock)
118{ 121{
119 struct sk_buff_head q; 122 struct sk_buff_head q;
120 struct sk_buff *skb; 123 struct sk_buff *skb;
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index cba9d0435dc4..3de61adacd34 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -146,13 +146,15 @@ static bool valid_cpu_addr(const u32 address)
146 return false; 146 return false;
147} 147}
148 148
149static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) 149static int carl9170_fw_checksum(struct ar9170 *ar, const __u8 *data,
150 size_t len)
150{ 151{
151 const struct carl9170fw_otus_desc *otus_desc; 152 const struct carl9170fw_otus_desc *otus_desc;
152 const struct carl9170fw_chk_desc *chk_desc;
153 const struct carl9170fw_last_desc *last_desc; 153 const struct carl9170fw_last_desc *last_desc;
154 const struct carl9170fw_txsq_desc *txsq_desc; 154 const struct carl9170fw_chk_desc *chk_desc;
155 u16 if_comb_types; 155 unsigned long fin, diff;
156 unsigned int dsc_len;
157 u32 crc32;
156 158
157 last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, 159 last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC,
158 sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); 160 sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER);
@@ -170,36 +172,68 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
170 chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC, 172 chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC,
171 sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER); 173 sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER);
172 174
173 if (chk_desc) { 175 if (!chk_desc) {
174 unsigned long fin, diff; 176 dev_warn(&ar->udev->dev, "Unprotected firmware image.\n");
175 unsigned int dsc_len; 177 return 0;
176 u32 crc32; 178 }
177 179
178 dsc_len = min_t(unsigned int, len, 180 dsc_len = min_t(unsigned int, len,
179 (unsigned long)chk_desc - (unsigned long)otus_desc); 181 (unsigned long)chk_desc - (unsigned long)otus_desc);
180 182
181 fin = (unsigned long) last_desc + sizeof(*last_desc); 183 fin = (unsigned long) last_desc + sizeof(*last_desc);
182 diff = fin - (unsigned long) otus_desc; 184 diff = fin - (unsigned long) otus_desc;
183 185
184 if (diff < len) 186 if (diff < len)
185 len -= diff; 187 len -= diff;
186 188
187 if (len < 256) 189 if (len < 256)
188 return -EIO; 190 return -EIO;
189 191
190 crc32 = crc32_le(~0, data, len); 192 crc32 = crc32_le(~0, data, len);
191 if (cpu_to_le32(crc32) != chk_desc->fw_crc32) { 193 if (cpu_to_le32(crc32) != chk_desc->fw_crc32) {
192 dev_err(&ar->udev->dev, "fw checksum test failed.\n"); 194 dev_err(&ar->udev->dev, "fw checksum test failed.\n");
193 return -ENOEXEC; 195 return -ENOEXEC;
194 } 196 }
197
198 crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len);
199 if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) {
200 dev_err(&ar->udev->dev, "descriptor check failed.\n");
201 return -EINVAL;
202 }
203 return 0;
204}
195 205
196 crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len); 206static int carl9170_fw_tx_sequence(struct ar9170 *ar)
197 if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) { 207{
198 dev_err(&ar->udev->dev, "descriptor check failed.\n"); 208 const struct carl9170fw_txsq_desc *txsq_desc;
209
210 txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, sizeof(*txsq_desc),
211 CARL9170FW_TXSQ_DESC_CUR_VER);
212 if (txsq_desc) {
213 ar->fw.tx_seq_table = le32_to_cpu(txsq_desc->seq_table_addr);
214 if (!valid_cpu_addr(ar->fw.tx_seq_table))
199 return -EINVAL; 215 return -EINVAL;
200 }
201 } else { 216 } else {
202 dev_warn(&ar->udev->dev, "Unprotected firmware image.\n"); 217 ar->fw.tx_seq_table = 0;
218 }
219
220 return 0;
221}
222
223static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
224{
225 const struct carl9170fw_otus_desc *otus_desc;
226 int err;
227 u16 if_comb_types;
228
229 err = carl9170_fw_checksum(ar, data, len);
230 if (err)
231 return err;
232
233 otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC,
234 sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER);
235 if (!otus_desc) {
236 return -ENODATA;
203 } 237 }
204 238
205#define SUPP(feat) \ 239#define SUPP(feat) \
@@ -321,19 +355,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
321 355
322 ar->hw->wiphy->interface_modes |= if_comb_types; 356 ar->hw->wiphy->interface_modes |= if_comb_types;
323 357
324 txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC,
325 sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER);
326
327 if (txsq_desc) {
328 ar->fw.tx_seq_table = le32_to_cpu(txsq_desc->seq_table_addr);
329 if (!valid_cpu_addr(ar->fw.tx_seq_table))
330 return -EINVAL;
331 } else {
332 ar->fw.tx_seq_table = 0;
333 }
334
335#undef SUPPORTED 358#undef SUPPORTED
336 return 0; 359 return carl9170_fw_tx_sequence(ar);
337} 360}
338 361
339static struct carl9170fw_desc_head * 362static struct carl9170fw_desc_head *
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index f19605e8eb4c..16e8f8058155 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -191,6 +191,9 @@
191#define B43_BFH_BUCKBOOST 0x0020 /* has buck/booster */ 191#define B43_BFH_BUCKBOOST 0x0020 /* has buck/booster */
192#define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna 192#define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna
193 * with bluetooth */ 193 * with bluetooth */
194#define B43_BFH_NOCBUCK 0x0080
195#define B43_BFH_PALDO 0x0200
196#define B43_BFH_EXTLNA_5GHZ 0x1000 /* has an external LNA (5GHz mode) */
194 197
195/* SPROM boardflags2_lo values */ 198/* SPROM boardflags2_lo values */
196#define B43_BFL2_RXBB_INT_REG_DIS 0x0001 /* external RX BB regulator present */ 199#define B43_BFL2_RXBB_INT_REG_DIS 0x0001 /* external RX BB regulator present */
@@ -204,6 +207,14 @@
204#define B43_BFL2_SKWRKFEM_BRD 0x0100 /* 4321mcm93 uses Skyworks FEM */ 207#define B43_BFL2_SKWRKFEM_BRD 0x0100 /* 4321mcm93 uses Skyworks FEM */
205#define B43_BFL2_SPUR_WAR 0x0200 /* has a workaround for clock-harmonic spurs */ 208#define B43_BFL2_SPUR_WAR 0x0200 /* has a workaround for clock-harmonic spurs */
206#define B43_BFL2_GPLL_WAR 0x0400 /* altenative G-band PLL settings implemented */ 209#define B43_BFL2_GPLL_WAR 0x0400 /* altenative G-band PLL settings implemented */
210#define B43_BFL2_SINGLEANT_CCK 0x1000
211#define B43_BFL2_2G_SPUR_WAR 0x2000
212
213/* SPROM boardflags2_hi values */
214#define B43_BFH2_GPLL_WAR2 0x0001
215#define B43_BFH2_IPALVLSHIFT_3P3 0x0002
216#define B43_BFH2_INTERNDET_TXIQCAL 0x0004
217#define B43_BFH2_XTALBUFOUTEN 0x0008
207 218
208/* GPIO register offset, in both ChipCommon and PCI core. */ 219/* GPIO register offset, in both ChipCommon and PCI core. */
209#define B43_GPIO_CONTROL 0x6c 220#define B43_GPIO_CONTROL 0x6c
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 0d25fe4069bf..bf5a43855358 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -167,7 +167,7 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
167 b43_phy_mask(dev, val_addr, 167 b43_phy_mask(dev, val_addr,
168 ~(rf_ctrl->val_mask)); 168 ~(rf_ctrl->val_mask));
169 } else { 169 } else {
170 if (core == 0 || ((1 << core) & i) != 0) { 170 if (core == 0 || ((1 << i) & core)) {
171 b43_phy_set(dev, en_addr, field); 171 b43_phy_set(dev, en_addr, field);
172 b43_phy_maskset(dev, val_addr, 172 b43_phy_maskset(dev, val_addr,
173 ~(rf_ctrl->val_mask), 173 ~(rf_ctrl->val_mask),
@@ -200,7 +200,7 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
200 addr = B43_PHY_N((i == 0) ? 200 addr = B43_PHY_N((i == 0) ?
201 rf_ctrl->addr0 : rf_ctrl->addr1); 201 rf_ctrl->addr0 : rf_ctrl->addr1);
202 202
203 if ((core & (1 << i)) != 0) 203 if ((1 << i) & core)
204 b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask), 204 b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask),
205 (value << rf_ctrl->shift)); 205 (value << rf_ctrl->shift));
206 206
@@ -956,7 +956,7 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
956 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1); 956 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
957 } 957 }
958 for (i = 0; i < 100; i++) { 958 for (i = 0; i < 100; i++) {
959 if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) { 959 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
960 i = 0; 960 i = 0;
961 break; 961 break;
962 } 962 }
@@ -1511,7 +1511,8 @@ static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev)
1511 /* Prepare values */ 1511 /* Prepare values */
1512 ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL) 1512 ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL)
1513 & B43_NPHY_BANDCTL_5GHZ; 1513 & B43_NPHY_BANDCTL_5GHZ;
1514 ext_lna = sprom->boardflags_lo & B43_BFL_EXTLNA; 1514 ext_lna = ghz5 ? sprom->boardflags_hi & B43_BFH_EXTLNA_5GHZ :
1515 sprom->boardflags_lo & B43_BFL_EXTLNA;
1515 e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna); 1516 e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna);
1516 if (ghz5 && dev->phy.rev >= 5) 1517 if (ghz5 && dev->phy.rev >= 5)
1517 rssi_gain = 0x90; 1518 rssi_gain = 0x90;
@@ -1562,7 +1563,6 @@ static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev)
1562 b43_phy_write(dev, 0x2A7, e->init_gain); 1563 b43_phy_write(dev, 0x2A7, e->init_gain);
1563 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, 1564 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2,
1564 e->rfseq_init); 1565 e->rfseq_init);
1565 b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain);
1566 1566
1567 /* TODO: check defines. Do not match variables names */ 1567 /* TODO: check defines. Do not match variables names */
1568 b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain); 1568 b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain);
@@ -1929,6 +1929,117 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
1929} 1929}
1930 1930
1931/************************************************** 1931/**************************************************
1932 * Tx/Rx common
1933 **************************************************/
1934
1935/*
1936 * Transmits a known value for LO calibration
1937 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
1938 */
1939static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
1940 bool iqmode, bool dac_test)
1941{
1942 u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
1943 if (samp == 0)
1944 return -1;
1945 b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
1946 return 0;
1947}
1948
1949/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
1950static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
1951{
1952 struct b43_phy_n *nphy = dev->phy.n;
1953
1954 bool override = false;
1955 u16 chain = 0x33;
1956
1957 if (nphy->txrx_chain == 0) {
1958 chain = 0x11;
1959 override = true;
1960 } else if (nphy->txrx_chain == 1) {
1961 chain = 0x22;
1962 override = true;
1963 }
1964
1965 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
1966 ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN),
1967 chain);
1968
1969 if (override)
1970 b43_phy_set(dev, B43_NPHY_RFSEQMODE,
1971 B43_NPHY_RFSEQMODE_CAOVER);
1972 else
1973 b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
1974 ~B43_NPHY_RFSEQMODE_CAOVER);
1975}
1976
1977/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
1978static void b43_nphy_stop_playback(struct b43_wldev *dev)
1979{
1980 struct b43_phy_n *nphy = dev->phy.n;
1981 u16 tmp;
1982
1983 if (nphy->hang_avoid)
1984 b43_nphy_stay_in_carrier_search(dev, 1);
1985
1986 tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT);
1987 if (tmp & 0x1)
1988 b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP);
1989 else if (tmp & 0x2)
1990 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1991
1992 b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004);
1993
1994 if (nphy->bb_mult_save & 0x80000000) {
1995 tmp = nphy->bb_mult_save & 0xFFFF;
1996 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1997 nphy->bb_mult_save = 0;
1998 }
1999
2000 if (nphy->hang_avoid)
2001 b43_nphy_stay_in_carrier_search(dev, 0);
2002}
2003
2004/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */
2005static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
2006 struct nphy_txgains target,
2007 struct nphy_iqcal_params *params)
2008{
2009 int i, j, indx;
2010 u16 gain;
2011
2012 if (dev->phy.rev >= 3) {
2013 params->txgm = target.txgm[core];
2014 params->pga = target.pga[core];
2015 params->pad = target.pad[core];
2016 params->ipa = target.ipa[core];
2017 params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
2018 (params->pad << 4) | (params->ipa);
2019 for (j = 0; j < 5; j++)
2020 params->ncorr[j] = 0x79;
2021 } else {
2022 gain = (target.pad[core]) | (target.pga[core] << 4) |
2023 (target.txgm[core] << 8);
2024
2025 indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ?
2026 1 : 0;
2027 for (i = 0; i < 9; i++)
2028 if (tbl_iqcal_gainparams[indx][i][0] == gain)
2029 break;
2030 i = min(i, 8);
2031
2032 params->txgm = tbl_iqcal_gainparams[indx][i][1];
2033 params->pga = tbl_iqcal_gainparams[indx][i][2];
2034 params->pad = tbl_iqcal_gainparams[indx][i][3];
2035 params->cal_gain = (params->txgm << 7) | (params->pga << 4) |
2036 (params->pad << 2);
2037 for (j = 0; j < 4; j++)
2038 params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j];
2039 }
2040}
2041
2042/**************************************************
1932 * Tx and Rx 2043 * Tx and Rx
1933 **************************************************/ 2044 **************************************************/
1934 2045
@@ -2107,7 +2218,7 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
2107 } 2218 }
2108 } 2219 }
2109 if (dev->phy.rev < 7 && 2220 if (dev->phy.rev < 7 &&
2110 (txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 10)) 2221 (txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 100))
2111 txpi[0] = txpi[1] = 91; 2222 txpi[0] = txpi[1] = 91;
2112 2223
2113 /* 2224 /*
@@ -2186,6 +2297,129 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
2186 b43_nphy_stay_in_carrier_search(dev, 0); 2297 b43_nphy_stay_in_carrier_search(dev, 0);
2187} 2298}
2188 2299
2300static void b43_nphy_ipa_internal_tssi_setup(struct b43_wldev *dev)
2301{
2302 struct b43_phy *phy = &dev->phy;
2303
2304 u8 core;
2305 u16 r; /* routing */
2306
2307 if (phy->rev >= 7) {
2308 for (core = 0; core < 2; core++) {
2309 r = core ? 0x190 : 0x170;
2310 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2311 b43_radio_write(dev, r + 0x5, 0x5);
2312 b43_radio_write(dev, r + 0x9, 0xE);
2313 if (phy->rev != 5)
2314 b43_radio_write(dev, r + 0xA, 0);
2315 if (phy->rev != 7)
2316 b43_radio_write(dev, r + 0xB, 1);
2317 else
2318 b43_radio_write(dev, r + 0xB, 0x31);
2319 } else {
2320 b43_radio_write(dev, r + 0x5, 0x9);
2321 b43_radio_write(dev, r + 0x9, 0xC);
2322 b43_radio_write(dev, r + 0xB, 0x0);
2323 if (phy->rev != 5)
2324 b43_radio_write(dev, r + 0xA, 1);
2325 else
2326 b43_radio_write(dev, r + 0xA, 0x31);
2327 }
2328 b43_radio_write(dev, r + 0x6, 0);
2329 b43_radio_write(dev, r + 0x7, 0);
2330 b43_radio_write(dev, r + 0x8, 3);
2331 b43_radio_write(dev, r + 0xC, 0);
2332 }
2333 } else {
2334 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
2335 b43_radio_write(dev, B2056_SYN_RESERVED_ADDR31, 0x128);
2336 else
2337 b43_radio_write(dev, B2056_SYN_RESERVED_ADDR31, 0x80);
2338 b43_radio_write(dev, B2056_SYN_RESERVED_ADDR30, 0);
2339 b43_radio_write(dev, B2056_SYN_GPIO_MASTER1, 0x29);
2340
2341 for (core = 0; core < 2; core++) {
2342 r = core ? B2056_TX1 : B2056_TX0;
2343
2344 b43_radio_write(dev, r | B2056_TX_IQCAL_VCM_HG, 0);
2345 b43_radio_write(dev, r | B2056_TX_IQCAL_IDAC, 0);
2346 b43_radio_write(dev, r | B2056_TX_TSSI_VCM, 3);
2347 b43_radio_write(dev, r | B2056_TX_TX_AMP_DET, 0);
2348 b43_radio_write(dev, r | B2056_TX_TSSI_MISC1, 8);
2349 b43_radio_write(dev, r | B2056_TX_TSSI_MISC2, 0);
2350 b43_radio_write(dev, r | B2056_TX_TSSI_MISC3, 0);
2351 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2352 b43_radio_write(dev, r | B2056_TX_TX_SSI_MASTER,
2353 0x5);
2354 if (phy->rev != 5)
2355 b43_radio_write(dev, r | B2056_TX_TSSIA,
2356 0x00);
2357 if (phy->rev >= 5)
2358 b43_radio_write(dev, r | B2056_TX_TSSIG,
2359 0x31);
2360 else
2361 b43_radio_write(dev, r | B2056_TX_TSSIG,
2362 0x11);
2363 b43_radio_write(dev, r | B2056_TX_TX_SSI_MUX,
2364 0xE);
2365 } else {
2366 b43_radio_write(dev, r | B2056_TX_TX_SSI_MASTER,
2367 0x9);
2368 b43_radio_write(dev, r | B2056_TX_TSSIA, 0x31);
2369 b43_radio_write(dev, r | B2056_TX_TSSIG, 0x0);
2370 b43_radio_write(dev, r | B2056_TX_TX_SSI_MUX,
2371 0xC);
2372 }
2373 }
2374 }
2375}
2376
2377/*
2378 * Stop radio and transmit known signal. Then check received signal strength to
2379 * get TSSI (Transmit Signal Strength Indicator).
2380 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlIdleTssi
2381 */
2382static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
2383{
2384 struct b43_phy *phy = &dev->phy;
2385 struct b43_phy_n *nphy = dev->phy.n;
2386
2387 u32 tmp;
2388 s32 rssi[4] = { };
2389
2390 /* TODO: check if we can transmit */
2391
2392 if (b43_nphy_ipa(dev))
2393 b43_nphy_ipa_internal_tssi_setup(dev);
2394
2395 if (phy->rev >= 7)
2396 ; /* TODO: Override Rev7 with 0x2000, 0, 3, 0, 0 as arguments */
2397 else if (phy->rev >= 3)
2398 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, false);
2399
2400 b43_nphy_stop_playback(dev);
2401 b43_nphy_tx_tone(dev, 0xFA0, 0, false, false);
2402 udelay(20);
2403 tmp = b43_nphy_poll_rssi(dev, 4, rssi, 1);
2404 b43_nphy_stop_playback(dev);
2405 b43_nphy_rssi_select(dev, 0, 0);
2406
2407 if (phy->rev >= 7)
2408 ; /* TODO: Override Rev7 with 0x2000, 0, 3, 1, 0 as arguments */
2409 else if (phy->rev >= 3)
2410 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, true);
2411
2412 if (phy->rev >= 3) {
2413 nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF;
2414 nphy->pwr_ctl_info[1].idle_tssi_5g = (tmp >> 8) & 0xFF;
2415 } else {
2416 nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 16) & 0xFF;
2417 nphy->pwr_ctl_info[1].idle_tssi_5g = tmp & 0xFF;
2418 }
2419 nphy->pwr_ctl_info[0].idle_tssi_2g = (tmp >> 24) & 0xFF;
2420 nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF;
2421}
2422
2189static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) 2423static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
2190{ 2424{
2191 struct b43_phy *phy = &dev->phy; 2425 struct b43_phy *phy = &dev->phy;
@@ -2290,34 +2524,6 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
2290 } 2524 }
2291} 2525}
2292 2526
2293/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
2294static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
2295{
2296 struct b43_phy_n *nphy = dev->phy.n;
2297
2298 bool override = false;
2299 u16 chain = 0x33;
2300
2301 if (nphy->txrx_chain == 0) {
2302 chain = 0x11;
2303 override = true;
2304 } else if (nphy->txrx_chain == 1) {
2305 chain = 0x22;
2306 override = true;
2307 }
2308
2309 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
2310 ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN),
2311 chain);
2312
2313 if (override)
2314 b43_phy_set(dev, B43_NPHY_RFSEQMODE,
2315 B43_NPHY_RFSEQMODE_CAOVER);
2316 else
2317 b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
2318 ~B43_NPHY_RFSEQMODE_CAOVER);
2319}
2320
2321/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ 2527/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
2322static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est, 2528static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est,
2323 u16 samps, u8 time, bool wait) 2529 u16 samps, u8 time, bool wait)
@@ -2569,33 +2775,6 @@ static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
2569 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]); 2775 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]);
2570} 2776}
2571 2777
2572/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
2573static void b43_nphy_stop_playback(struct b43_wldev *dev)
2574{
2575 struct b43_phy_n *nphy = dev->phy.n;
2576 u16 tmp;
2577
2578 if (nphy->hang_avoid)
2579 b43_nphy_stay_in_carrier_search(dev, 1);
2580
2581 tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT);
2582 if (tmp & 0x1)
2583 b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP);
2584 else if (tmp & 0x2)
2585 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
2586
2587 b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004);
2588
2589 if (nphy->bb_mult_save & 0x80000000) {
2590 tmp = nphy->bb_mult_save & 0xFFFF;
2591 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
2592 nphy->bb_mult_save = 0;
2593 }
2594
2595 if (nphy->hang_avoid)
2596 b43_nphy_stay_in_carrier_search(dev, 0);
2597}
2598
2599/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */ 2778/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */
2600static void b43_nphy_spur_workaround(struct b43_wldev *dev) 2779static void b43_nphy_spur_workaround(struct b43_wldev *dev)
2601{ 2780{
@@ -2655,20 +2834,6 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
2655 b43_nphy_stay_in_carrier_search(dev, 0); 2834 b43_nphy_stay_in_carrier_search(dev, 0);
2656} 2835}
2657 2836
2658/*
2659 * Transmits a known value for LO calibration
2660 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
2661 */
2662static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
2663 bool iqmode, bool dac_test)
2664{
2665 u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
2666 if (samp == 0)
2667 return -1;
2668 b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
2669 return 0;
2670}
2671
2672/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ 2837/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
2673static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) 2838static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
2674{ 2839{
@@ -2872,44 +3037,6 @@ static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
2872 } 3037 }
2873} 3038}
2874 3039
2875/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */
2876static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
2877 struct nphy_txgains target,
2878 struct nphy_iqcal_params *params)
2879{
2880 int i, j, indx;
2881 u16 gain;
2882
2883 if (dev->phy.rev >= 3) {
2884 params->txgm = target.txgm[core];
2885 params->pga = target.pga[core];
2886 params->pad = target.pad[core];
2887 params->ipa = target.ipa[core];
2888 params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
2889 (params->pad << 4) | (params->ipa);
2890 for (j = 0; j < 5; j++)
2891 params->ncorr[j] = 0x79;
2892 } else {
2893 gain = (target.pad[core]) | (target.pga[core] << 4) |
2894 (target.txgm[core] << 8);
2895
2896 indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ?
2897 1 : 0;
2898 for (i = 0; i < 9; i++)
2899 if (tbl_iqcal_gainparams[indx][i][0] == gain)
2900 break;
2901 i = min(i, 8);
2902
2903 params->txgm = tbl_iqcal_gainparams[indx][i][1];
2904 params->pga = tbl_iqcal_gainparams[indx][i][2];
2905 params->pad = tbl_iqcal_gainparams[indx][i][3];
2906 params->cal_gain = (params->txgm << 7) | (params->pga << 4) |
2907 (params->pad << 2);
2908 for (j = 0; j < 4; j++)
2909 params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j];
2910 }
2911}
2912
2913/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */ 3040/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */
2914static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core) 3041static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
2915{ 3042{
@@ -3982,7 +4109,7 @@ int b43_phy_initn(struct b43_wldev *dev)
3982 tx_pwr_state = nphy->txpwrctrl; 4109 tx_pwr_state = nphy->txpwrctrl;
3983 b43_nphy_tx_power_ctrl(dev, false); 4110 b43_nphy_tx_power_ctrl(dev, false);
3984 b43_nphy_tx_power_fix(dev); 4111 b43_nphy_tx_power_fix(dev);
3985 /* TODO N PHY TX Power Control Idle TSSI */ 4112 b43_nphy_tx_power_ctl_idle_tssi(dev);
3986 /* TODO N PHY TX Power Control Setup */ 4113 /* TODO N PHY TX Power Control Setup */
3987 b43_nphy_tx_gain_table_upload(dev); 4114 b43_nphy_tx_gain_table_upload(dev);
3988 4115
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 56ef97b5b815..5de8f74cc02f 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -765,6 +765,11 @@ struct b43_phy_n_txpwrindex {
765 u16 locomp; 765 u16 locomp;
766}; 766};
767 767
768struct b43_phy_n_pwr_ctl_info {
769 u8 idle_tssi_2g;
770 u8 idle_tssi_5g;
771};
772
768struct b43_phy_n { 773struct b43_phy_n {
769 u8 antsel_type; 774 u8 antsel_type;
770 u8 cal_orig_pwr_idx[2]; 775 u8 cal_orig_pwr_idx[2];
@@ -798,6 +803,7 @@ struct b43_phy_n {
798 u16 txiqlocal_bestc[11]; 803 u16 txiqlocal_bestc[11];
799 bool txiqlocal_coeffsvalid; 804 bool txiqlocal_coeffsvalid;
800 struct b43_phy_n_txpwrindex txpwrindex[2]; 805 struct b43_phy_n_txpwrindex txpwrindex[2];
806 struct b43_phy_n_pwr_ctl_info pwr_ctl_info[2];
801 struct b43_chanspec txiqlocal_chanspec; 807 struct b43_chanspec txiqlocal_chanspec;
802 808
803 u8 txrx_chain; 809 u8 txrx_chain;
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 3252560e9fa1..f7def13524dd 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2752,7 +2752,18 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
2752 { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ 2752 { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */
2753}; 2753};
2754 2754
2755struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = { 2755struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = {
2756 { 10, 14, 19, 27 },
2757 { -5, 6, 10, 15 },
2758 { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA },
2759 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2760 0x427E,
2761 { 0x413F, 0x413F, 0x413F, 0x413F },
2762 0x007E, 0x0066, 0x1074,
2763 0x18, 0x18, 0x18,
2764 0x01D0, 0x5,
2765};
2766struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][4] = {
2756 { /* 2GHz */ 2767 { /* 2GHz */
2757 { /* PHY rev 3 */ 2768 { /* PHY rev 3 */
2758 { 7, 11, 16, 23 }, 2769 { 7, 11, 16, 23 },
@@ -2776,15 +2787,26 @@ struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = {
2776 0x18, 0x18, 0x18, 2787 0x18, 0x18, 0x18,
2777 0x01A1, 0x5, 2788 0x01A1, 0x5,
2778 }, 2789 },
2779 { /* PHY rev 5+ */ 2790 { /* PHY rev 5 */
2780 { 9, 13, 18, 26 }, 2791 { 9, 13, 18, 26 },
2781 { -3, 7, 11, 16 }, 2792 { -3, 7, 11, 16 },
2782 { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, 2793 { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA },
2783 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 2794 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2784 0x427E, /* invalid for external LNA! */ 2795 0x427E, /* invalid for external LNA! */
2785 { 0x413F, 0x413F, 0x413F, 0x413F }, /* invalid for external LNA! */ 2796 { 0x413F, 0x413F, 0x413F, 0x413F }, /* invalid for external LNA! */
2786 0x1076, 0x0066, 0x106A, 2797 0x1076, 0x0066, 0x0000, /* low is invalid (the last one) */
2787 0xC, 0xC, 0xC, 2798 0x18, 0x18, 0x18,
2799 0x01D0, 0x9,
2800 },
2801 { /* PHY rev 6+ */
2802 { 8, 13, 18, 25 },
2803 { -5, 6, 10, 14 },
2804 { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA },
2805 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2806 0x527E, /* invalid for external LNA! */
2807 { 0x513F, 0x513F, 0x513F, 0x513F }, /* invalid for external LNA! */
2808 0x1076, 0x0066, 0x0000, /* low is invalid (the last one) */
2809 0x18, 0x18, 0x18,
2788 0x01D0, 0x5, 2810 0x01D0, 0x5,
2789 }, 2811 },
2790 }, 2812 },
@@ -2811,7 +2833,7 @@ struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = {
2811 0x24, 0x24, 0x24, 2833 0x24, 0x24, 0x24,
2812 0x0107, 25, 2834 0x0107, 25,
2813 }, 2835 },
2814 { /* PHY rev 5+ */ 2836 { /* PHY rev 5 */
2815 { 6, 10, 16, 21 }, 2837 { 6, 10, 16, 21 },
2816 { -7, 0, 4, 8 }, 2838 { -7, 0, 4, 8 },
2817 { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD }, 2839 { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD },
@@ -2822,6 +2844,17 @@ struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = {
2822 0x24, 0x24, 0x24, 2844 0x24, 0x24, 0x24,
2823 0x00A9, 25, 2845 0x00A9, 25,
2824 }, 2846 },
2847 { /* PHY rev 6+ */
2848 { 6, 10, 16, 21 },
2849 { -7, 0, 4, 8 },
2850 { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD },
2851 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
2852 0x729E,
2853 { 0x714F, 0x714F, 0x714F, 0x714F },
2854 0x029E, 0x2084, 0x2086,
2855 0x24, 0x24, 0x24, /* low is invalid for radio rev 11! */
2856 0x00F0, 25,
2857 },
2825 }, 2858 },
2826}; 2859};
2827 2860
@@ -3098,26 +3131,67 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
3098{ 3131{
3099 struct nphy_gain_ctl_workaround_entry *e; 3132 struct nphy_gain_ctl_workaround_entry *e;
3100 u8 phy_idx; 3133 u8 phy_idx;
3134 u8 tr_iso = ghz5 ? dev->dev->bus_sprom->fem.ghz5.tr_iso :
3135 dev->dev->bus_sprom->fem.ghz2.tr_iso;
3136
3137 if (!ghz5 && dev->phy.rev >= 6 && dev->phy.radio_rev == 11)
3138 return &nphy_gain_ctl_wa_phy6_radio11_ghz2;
3101 3139
3102 B43_WARN_ON(dev->phy.rev < 3); 3140 B43_WARN_ON(dev->phy.rev < 3);
3103 if (dev->phy.rev >= 5) 3141 if (dev->phy.rev >= 6)
3142 phy_idx = 3;
3143 else if (dev->phy.rev == 5)
3104 phy_idx = 2; 3144 phy_idx = 2;
3105 else if (dev->phy.rev == 4) 3145 else if (dev->phy.rev == 4)
3106 phy_idx = 1; 3146 phy_idx = 1;
3107 else 3147 else
3108 phy_idx = 0; 3148 phy_idx = 0;
3109
3110 e = &nphy_gain_ctl_workaround[ghz5][phy_idx]; 3149 e = &nphy_gain_ctl_workaround[ghz5][phy_idx];
3111 3150
3112 /* Only one entry differs for external LNA, so instead making whole 3151 /* Some workarounds to the workarounds... */
3113 * table 2 times bigger, hack is here 3152 if (ghz5 && dev->phy.rev >= 6) {
3114 */ 3153 if (dev->phy.radio_rev == 11 &&
3115 if (!ghz5 && dev->phy.rev >= 5 && ext_lna) { 3154 !b43_channel_type_is_40mhz(dev->phy.channel_type))
3116 e->rfseq_init[0] &= 0x0FFF; 3155 e->cliplo_gain = 0x2d;
3117 e->rfseq_init[1] &= 0x0FFF; 3156 } else if (!ghz5 && dev->phy.rev >= 5) {
3118 e->rfseq_init[2] &= 0x0FFF; 3157 if (ext_lna) {
3119 e->rfseq_init[3] &= 0x0FFF; 3158 e->rfseq_init[0] &= ~0x4000;
3120 e->init_gain &= 0x0FFF; 3159 e->rfseq_init[1] &= ~0x4000;
3160 e->rfseq_init[2] &= ~0x4000;
3161 e->rfseq_init[3] &= ~0x4000;
3162 e->init_gain &= ~0x4000;
3163 }
3164 switch (tr_iso) {
3165 case 0:
3166 e->cliplo_gain = 0x0062;
3167 case 1:
3168 e->cliplo_gain = 0x0064;
3169 case 2:
3170 e->cliplo_gain = 0x006a;
3171 case 3:
3172 e->cliplo_gain = 0x106a;
3173 case 4:
3174 e->cliplo_gain = 0x106c;
3175 case 5:
3176 e->cliplo_gain = 0x1074;
3177 case 6:
3178 e->cliplo_gain = 0x107c;
3179 case 7:
3180 e->cliplo_gain = 0x207c;
3181 default:
3182 e->cliplo_gain = 0x106a;
3183 }
3184 } else if (ghz5 && dev->phy.rev == 4 && ext_lna) {
3185 e->rfseq_init[0] &= ~0x4000;
3186 e->rfseq_init[1] &= ~0x4000;
3187 e->rfseq_init[2] &= ~0x4000;
3188 e->rfseq_init[3] &= ~0x4000;
3189 e->init_gain &= ~0x4000;
3190 e->rfseq_init[0] |= 0x1000;
3191 e->rfseq_init[1] |= 0x1000;
3192 e->rfseq_init[2] |= 0x1000;
3193 e->rfseq_init[3] |= 0x1000;
3194 e->init_gain |= 0x1000;
3121 } 3195 }
3122 3196
3123 return e; 3197 return e;
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 1d4fc9db7f5e..98e3d44400c6 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -560,8 +560,16 @@ struct b43legacy_key {
560 u8 algorithm; 560 u8 algorithm;
561}; 561};
562 562
563#define B43legacy_QOS_QUEUE_NUM 4
564
563struct b43legacy_wldev; 565struct b43legacy_wldev;
564 566
567/* QOS parameters for a queue. */
568struct b43legacy_qos_params {
569 /* The QOS parameters */
570 struct ieee80211_tx_queue_params p;
571};
572
565/* Data structure for the WLAN parts (802.11 cores) of the b43legacy chip. */ 573/* Data structure for the WLAN parts (802.11 cores) of the b43legacy chip. */
566struct b43legacy_wl { 574struct b43legacy_wl {
567 /* Pointer to the active wireless device on this chip */ 575 /* Pointer to the active wireless device on this chip */
@@ -611,6 +619,18 @@ struct b43legacy_wl {
611 bool beacon1_uploaded; 619 bool beacon1_uploaded;
612 bool beacon_templates_virgin; /* Never wrote the templates? */ 620 bool beacon_templates_virgin; /* Never wrote the templates? */
613 struct work_struct beacon_update_trigger; 621 struct work_struct beacon_update_trigger;
622 /* The current QOS parameters for the 4 queues. */
623 struct b43legacy_qos_params qos_params[B43legacy_QOS_QUEUE_NUM];
624
625 /* Packet transmit work */
626 struct work_struct tx_work;
627
628 /* Queue of packets to be transmitted. */
629 struct sk_buff_head tx_queue[B43legacy_QOS_QUEUE_NUM];
630
631 /* Flag that implement the queues stopping. */
632 bool tx_queue_stopped[B43legacy_QOS_QUEUE_NUM];
633
614}; 634};
615 635
616/* Pointers to the firmware data and meta information about it. */ 636/* Pointers to the firmware data and meta information about it. */
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 1ee31c55c7ba..f1f8bd09bd87 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -727,7 +727,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
727 } else 727 } else
728 B43legacy_WARN_ON(1); 728 B43legacy_WARN_ON(1);
729 } 729 }
730 spin_lock_init(&ring->lock);
731#ifdef CONFIG_B43LEGACY_DEBUG 730#ifdef CONFIG_B43LEGACY_DEBUG
732 ring->last_injected_overflow = jiffies; 731 ring->last_injected_overflow = jiffies;
733#endif 732#endif
@@ -1144,10 +1143,8 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1144{ 1143{
1145 struct b43legacy_dmaring *ring; 1144 struct b43legacy_dmaring *ring;
1146 int err = 0; 1145 int err = 0;
1147 unsigned long flags;
1148 1146
1149 ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); 1147 ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
1150 spin_lock_irqsave(&ring->lock, flags);
1151 B43legacy_WARN_ON(!ring->tx); 1148 B43legacy_WARN_ON(!ring->tx);
1152 1149
1153 if (unlikely(ring->stopped)) { 1150 if (unlikely(ring->stopped)) {
@@ -1157,16 +1154,14 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1157 * For now, just refuse the transmit. */ 1154 * For now, just refuse the transmit. */
1158 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) 1155 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
1159 b43legacyerr(dev->wl, "Packet after queue stopped\n"); 1156 b43legacyerr(dev->wl, "Packet after queue stopped\n");
1160 err = -ENOSPC; 1157 return -ENOSPC;
1161 goto out_unlock;
1162 } 1158 }
1163 1159
1164 if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) { 1160 if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) {
1165 /* If we get here, we have a real error with the queue 1161 /* If we get here, we have a real error with the queue
1166 * full, but queues not stopped. */ 1162 * full, but queues not stopped. */
1167 b43legacyerr(dev->wl, "DMA queue overflow\n"); 1163 b43legacyerr(dev->wl, "DMA queue overflow\n");
1168 err = -ENOSPC; 1164 return -ENOSPC;
1169 goto out_unlock;
1170 } 1165 }
1171 1166
1172 /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing 1167 /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
@@ -1176,25 +1171,23 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1176 /* Drop this packet, as we don't have the encryption key 1171 /* Drop this packet, as we don't have the encryption key
1177 * anymore and must not transmit it unencrypted. */ 1172 * anymore and must not transmit it unencrypted. */
1178 dev_kfree_skb_any(skb); 1173 dev_kfree_skb_any(skb);
1179 err = 0; 1174 return 0;
1180 goto out_unlock;
1181 } 1175 }
1182 if (unlikely(err)) { 1176 if (unlikely(err)) {
1183 b43legacyerr(dev->wl, "DMA tx mapping failure\n"); 1177 b43legacyerr(dev->wl, "DMA tx mapping failure\n");
1184 goto out_unlock; 1178 return err;
1185 } 1179 }
1186 if ((free_slots(ring) < SLOTS_PER_PACKET) || 1180 if ((free_slots(ring) < SLOTS_PER_PACKET) ||
1187 should_inject_overflow(ring)) { 1181 should_inject_overflow(ring)) {
1188 /* This TX ring is full. */ 1182 /* This TX ring is full. */
1189 ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring)); 1183 unsigned int skb_mapping = skb_get_queue_mapping(skb);
1184 ieee80211_stop_queue(dev->wl->hw, skb_mapping);
1185 dev->wl->tx_queue_stopped[skb_mapping] = 1;
1190 ring->stopped = true; 1186 ring->stopped = true;
1191 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) 1187 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
1192 b43legacydbg(dev->wl, "Stopped TX ring %d\n", 1188 b43legacydbg(dev->wl, "Stopped TX ring %d\n",
1193 ring->index); 1189 ring->index);
1194 } 1190 }
1195out_unlock:
1196 spin_unlock_irqrestore(&ring->lock, flags);
1197
1198 return err; 1191 return err;
1199} 1192}
1200 1193
@@ -1205,14 +1198,29 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1205 struct b43legacy_dmadesc_meta *meta; 1198 struct b43legacy_dmadesc_meta *meta;
1206 int retry_limit; 1199 int retry_limit;
1207 int slot; 1200 int slot;
1201 int firstused;
1208 1202
1209 ring = parse_cookie(dev, status->cookie, &slot); 1203 ring = parse_cookie(dev, status->cookie, &slot);
1210 if (unlikely(!ring)) 1204 if (unlikely(!ring))
1211 return; 1205 return;
1212 B43legacy_WARN_ON(!irqs_disabled());
1213 spin_lock(&ring->lock);
1214
1215 B43legacy_WARN_ON(!ring->tx); 1206 B43legacy_WARN_ON(!ring->tx);
1207
1208 /* Sanity check: TX packets are processed in-order on one ring.
1209 * Check if the slot deduced from the cookie really is the first
1210 * used slot. */
1211 firstused = ring->current_slot - ring->used_slots + 1;
1212 if (firstused < 0)
1213 firstused = ring->nr_slots + firstused;
1214 if (unlikely(slot != firstused)) {
1215 /* This possibly is a firmware bug and will result in
1216 * malfunction, memory leaks and/or stall of DMA functionality.
1217 */
1218 b43legacydbg(dev->wl, "Out of order TX status report on DMA "
1219 "ring %d. Expected %d, but got %d\n",
1220 ring->index, firstused, slot);
1221 return;
1222 }
1223
1216 while (1) { 1224 while (1) {
1217 B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); 1225 B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));
1218 op32_idx2desc(ring, slot, &meta); 1226 op32_idx2desc(ring, slot, &meta);
@@ -1285,14 +1293,21 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1285 dev->stats.last_tx = jiffies; 1293 dev->stats.last_tx = jiffies;
1286 if (ring->stopped) { 1294 if (ring->stopped) {
1287 B43legacy_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET); 1295 B43legacy_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
1288 ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring));
1289 ring->stopped = false; 1296 ring->stopped = false;
1297 }
1298
1299 if (dev->wl->tx_queue_stopped[ring->queue_prio]) {
1300 dev->wl->tx_queue_stopped[ring->queue_prio] = 0;
1301 } else {
1302 /* If the driver queue is running wake the corresponding
1303 * mac80211 queue. */
1304 ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
1290 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE)) 1305 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
1291 b43legacydbg(dev->wl, "Woke up TX ring %d\n", 1306 b43legacydbg(dev->wl, "Woke up TX ring %d\n",
1292 ring->index); 1307 ring->index);
1293 } 1308 }
1294 1309 /* Add work to the queue. */
1295 spin_unlock(&ring->lock); 1310 ieee80211_queue_work(dev->wl->hw, &dev->wl->tx_work);
1296} 1311}
1297 1312
1298static void dma_rx(struct b43legacy_dmaring *ring, 1313static void dma_rx(struct b43legacy_dmaring *ring,
@@ -1415,22 +1430,14 @@ void b43legacy_dma_rx(struct b43legacy_dmaring *ring)
1415 1430
1416static void b43legacy_dma_tx_suspend_ring(struct b43legacy_dmaring *ring) 1431static void b43legacy_dma_tx_suspend_ring(struct b43legacy_dmaring *ring)
1417{ 1432{
1418 unsigned long flags;
1419
1420 spin_lock_irqsave(&ring->lock, flags);
1421 B43legacy_WARN_ON(!ring->tx); 1433 B43legacy_WARN_ON(!ring->tx);
1422 op32_tx_suspend(ring); 1434 op32_tx_suspend(ring);
1423 spin_unlock_irqrestore(&ring->lock, flags);
1424} 1435}
1425 1436
1426static void b43legacy_dma_tx_resume_ring(struct b43legacy_dmaring *ring) 1437static void b43legacy_dma_tx_resume_ring(struct b43legacy_dmaring *ring)
1427{ 1438{
1428 unsigned long flags;
1429
1430 spin_lock_irqsave(&ring->lock, flags);
1431 B43legacy_WARN_ON(!ring->tx); 1439 B43legacy_WARN_ON(!ring->tx);
1432 op32_tx_resume(ring); 1440 op32_tx_resume(ring);
1433 spin_unlock_irqrestore(&ring->lock, flags);
1434} 1441}
1435 1442
1436void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev) 1443void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev)
diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h
index 504a58767e95..c3282f906bc7 100644
--- a/drivers/net/wireless/b43legacy/dma.h
+++ b/drivers/net/wireless/b43legacy/dma.h
@@ -150,8 +150,9 @@ struct b43legacy_dmaring {
150 enum b43legacy_dmatype type; 150 enum b43legacy_dmatype type;
151 /* Boolean. Is this ring stopped at ieee80211 level? */ 151 /* Boolean. Is this ring stopped at ieee80211 level? */
152 bool stopped; 152 bool stopped;
153 /* Lock, only used for TX. */ 153 /* The QOS priority assigned to this ring. Only used for TX rings.
154 spinlock_t lock; 154 * This is the mac80211 "queue" value. */
155 u8 queue_prio;
155 struct b43legacy_wldev *dev; 156 struct b43legacy_wldev *dev;
156#ifdef CONFIG_B43LEGACY_DEBUG 157#ifdef CONFIG_B43LEGACY_DEBUG
157 /* Maximum number of used slots. */ 158 /* Maximum number of used slots. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 200138cdb030..75e70bce40f6 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2440,30 +2440,64 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
2440 return err; 2440 return err;
2441} 2441}
2442 2442
2443static void b43legacy_tx_work(struct work_struct *work)
2444{
2445 struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl,
2446 tx_work);
2447 struct b43legacy_wldev *dev;
2448 struct sk_buff *skb;
2449 int queue_num;
2450 int err = 0;
2451
2452 mutex_lock(&wl->mutex);
2453 dev = wl->current_dev;
2454 if (unlikely(!dev || b43legacy_status(dev) < B43legacy_STAT_STARTED)) {
2455 mutex_unlock(&wl->mutex);
2456 return;
2457 }
2458
2459 for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) {
2460 while (skb_queue_len(&wl->tx_queue[queue_num])) {
2461 skb = skb_dequeue(&wl->tx_queue[queue_num]);
2462 if (b43legacy_using_pio(dev))
2463 err = b43legacy_pio_tx(dev, skb);
2464 else
2465 err = b43legacy_dma_tx(dev, skb);
2466 if (err == -ENOSPC) {
2467 wl->tx_queue_stopped[queue_num] = 1;
2468 ieee80211_stop_queue(wl->hw, queue_num);
2469 skb_queue_head(&wl->tx_queue[queue_num], skb);
2470 break;
2471 }
2472 if (unlikely(err))
2473 dev_kfree_skb(skb); /* Drop it */
2474 err = 0;
2475 }
2476
2477 if (!err)
2478 wl->tx_queue_stopped[queue_num] = 0;
2479 }
2480
2481 mutex_unlock(&wl->mutex);
2482}
2483
2443static void b43legacy_op_tx(struct ieee80211_hw *hw, 2484static void b43legacy_op_tx(struct ieee80211_hw *hw,
2444 struct sk_buff *skb) 2485 struct sk_buff *skb)
2445{ 2486{
2446 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); 2487 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2447 struct b43legacy_wldev *dev = wl->current_dev;
2448 int err = -ENODEV;
2449 unsigned long flags;
2450 2488
2451 if (unlikely(!dev)) 2489 if (unlikely(skb->len < 2 + 2 + 6)) {
2452 goto out; 2490 /* Too short, this can't be a valid frame. */
2453 if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED))
2454 goto out;
2455 /* DMA-TX is done without a global lock. */
2456 if (b43legacy_using_pio(dev)) {
2457 spin_lock_irqsave(&wl->irq_lock, flags);
2458 err = b43legacy_pio_tx(dev, skb);
2459 spin_unlock_irqrestore(&wl->irq_lock, flags);
2460 } else
2461 err = b43legacy_dma_tx(dev, skb);
2462out:
2463 if (unlikely(err)) {
2464 /* Drop the packet. */
2465 dev_kfree_skb_any(skb); 2491 dev_kfree_skb_any(skb);
2492 return;
2466 } 2493 }
2494 B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags);
2495
2496 skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb);
2497 if (!wl->tx_queue_stopped[skb->queue_mapping])
2498 ieee80211_queue_work(wl->hw, &wl->tx_work);
2499 else
2500 ieee80211_stop_queue(wl->hw, skb->queue_mapping);
2467} 2501}
2468 2502
2469static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, 2503static int b43legacy_op_conf_tx(struct ieee80211_hw *hw,
@@ -2879,6 +2913,7 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
2879{ 2913{
2880 struct b43legacy_wl *wl = dev->wl; 2914 struct b43legacy_wl *wl = dev->wl;
2881 unsigned long flags; 2915 unsigned long flags;
2916 int queue_num;
2882 2917
2883 if (b43legacy_status(dev) < B43legacy_STAT_STARTED) 2918 if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
2884 return; 2919 return;
@@ -2898,11 +2933,16 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
2898 /* Must unlock as it would otherwise deadlock. No races here. 2933 /* Must unlock as it would otherwise deadlock. No races here.
2899 * Cancel the possibly running self-rearming periodic work. */ 2934 * Cancel the possibly running self-rearming periodic work. */
2900 cancel_delayed_work_sync(&dev->periodic_work); 2935 cancel_delayed_work_sync(&dev->periodic_work);
2936 cancel_work_sync(&wl->tx_work);
2901 mutex_lock(&wl->mutex); 2937 mutex_lock(&wl->mutex);
2902 2938
2903 ieee80211_stop_queues(wl->hw); /* FIXME this could cause a deadlock */ 2939 /* Drain all TX queues. */
2940 for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) {
2941 while (skb_queue_len(&wl->tx_queue[queue_num]))
2942 dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num]));
2943 }
2904 2944
2905 b43legacy_mac_suspend(dev); 2945b43legacy_mac_suspend(dev);
2906 free_irq(dev->dev->irq, dev); 2946 free_irq(dev->dev->irq, dev);
2907 b43legacydbg(wl, "Wireless interface stopped\n"); 2947 b43legacydbg(wl, "Wireless interface stopped\n");
2908} 2948}
@@ -3748,6 +3788,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
3748 struct ieee80211_hw *hw; 3788 struct ieee80211_hw *hw;
3749 struct b43legacy_wl *wl; 3789 struct b43legacy_wl *wl;
3750 int err = -ENOMEM; 3790 int err = -ENOMEM;
3791 int queue_num;
3751 3792
3752 b43legacy_sprom_fixup(dev->bus); 3793 b43legacy_sprom_fixup(dev->bus);
3753 3794
@@ -3782,6 +3823,13 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
3782 mutex_init(&wl->mutex); 3823 mutex_init(&wl->mutex);
3783 INIT_LIST_HEAD(&wl->devlist); 3824 INIT_LIST_HEAD(&wl->devlist);
3784 INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work); 3825 INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work);
3826 INIT_WORK(&wl->tx_work, b43legacy_tx_work);
3827
3828 /* Initialize queues and flags. */
3829 for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) {
3830 skb_queue_head_init(&wl->tx_queue[queue_num]);
3831 wl->tx_queue_stopped[queue_num] = 0;
3832 }
3785 3833
3786 ssb_set_devtypedata(dev, wl); 3834 ssb_set_devtypedata(dev, wl);
3787 b43legacyinfo(wl, "Broadcom %04X WLAN found (core revision %u)\n", 3835 b43legacyinfo(wl, "Broadcom %04X WLAN found (core revision %u)\n",
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index 3d5821eeb054..8874588fb929 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -805,9 +805,6 @@ struct libipw_device {
805 /* WEP and other encryption related settings at the device level */ 805 /* WEP and other encryption related settings at the device level */
806 int open_wep; /* Set to 1 to allow unencrypted frames */ 806 int open_wep; /* Set to 1 to allow unencrypted frames */
807 807
808 int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
809 * WEP key changes */
810
811 /* If the host performs {en,de}cryption, then set to 1 */ 808 /* If the host performs {en,de}cryption, then set to 1 */
812 int host_encrypt; 809 int host_encrypt;
813 int host_encrypt_msdu; 810 int host_encrypt_msdu;
@@ -860,7 +857,6 @@ struct libipw_device {
860 struct libipw_security * sec); 857 struct libipw_security * sec);
861 netdev_tx_t (*hard_start_xmit) (struct libipw_txb * txb, 858 netdev_tx_t (*hard_start_xmit) (struct libipw_txb * txb,
862 struct net_device * dev, int pri); 859 struct net_device * dev, int pri);
863 int (*reset_port) (struct net_device * dev);
864 int (*is_queue_full) (struct net_device * dev, int pri); 860 int (*is_queue_full) (struct net_device * dev, int pri);
865 861
866 int (*handle_management) (struct net_device * dev, 862 int (*handle_management) (struct net_device * dev,
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c
index 6623e5052254..1571505b1a38 100644
--- a/drivers/net/wireless/ipw2x00/libipw_wx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_wx.c
@@ -474,17 +474,6 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
474 if (ieee->set_security) 474 if (ieee->set_security)
475 ieee->set_security(dev, &sec); 475 ieee->set_security(dev, &sec);
476 476
477 /* Do not reset port if card is in Managed mode since resetting will
478 * generate new IEEE 802.11 authentication which may end up in looping
479 * with IEEE 802.1X. If your hardware requires a reset after WEP
480 * configuration (for example... Prism2), implement the reset_port in
481 * the callbacks structures used to initialize the 802.11 stack. */
482 if (ieee->reset_on_keychange &&
483 ieee->iw_mode != IW_MODE_INFRA &&
484 ieee->reset_port && ieee->reset_port(dev)) {
485 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
486 return -EINVAL;
487 }
488 return 0; 477 return 0;
489} 478}
490 479
@@ -688,20 +677,6 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee,
688 if (ieee->set_security) 677 if (ieee->set_security)
689 ieee->set_security(ieee->dev, &sec); 678 ieee->set_security(ieee->dev, &sec);
690 679
691 /*
692 * Do not reset port if card is in Managed mode since resetting will
693 * generate new IEEE 802.11 authentication which may end up in looping
694 * with IEEE 802.1X. If your hardware requires a reset after WEP
695 * configuration (for example... Prism2), implement the reset_port in
696 * the callbacks structures used to initialize the 802.11 stack.
697 */
698 if (ieee->reset_on_keychange &&
699 ieee->iw_mode != IW_MODE_INFRA &&
700 ieee->reset_port && ieee->reset_port(dev)) {
701 LIBIPW_DEBUG_WX("%s: reset_port failed\n", dev->name);
702 return -EINVAL;
703 }
704
705 return ret; 680 return ret;
706} 681}
707 682
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index daef6b58f6cc..54b2d391e91a 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -570,8 +570,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
570 /* TODO need this for burst mode later on */ 570 /* TODO need this for burst mode later on */
571 il3945_build_tx_cmd_basic(il, out_cmd, info, hdr, sta_id); 571 il3945_build_tx_cmd_basic(il, out_cmd, info, hdr, sta_id);
572 572
573 /* set is_hcca to 0; it probably will never be implemented */ 573 il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id);
574 il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id, 0);
575 574
576 /* Total # bytes to be transmitted */ 575 /* Total # bytes to be transmitted */
577 len = (u16) skb->len; 576 len = (u16) skb->len;
@@ -2624,12 +2623,12 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
2624 } 2623 }
2625 2624
2626 /* 2625 /*
2627 * If active scaning is requested but a certain channel 2626 * If active scaning is requested but a certain channel is marked
2628 * is marked passive, we can do active scanning if we 2627 * passive, we can do active scanning if we detect transmissions. For
2629 * detect transmissions. 2628 * passive only scanning disable switching to active on any channel.
2630 */ 2629 */
2631 scan->good_CRC_th = 2630 scan->good_CRC_th =
2632 is_active ? IL_GOOD_CRC_TH_DEFAULT : IL_GOOD_CRC_TH_DISABLED; 2631 is_active ? IL_GOOD_CRC_TH_DEFAULT : IL_GOOD_CRC_TH_NEVER;
2633 2632
2634 len = 2633 len =
2635 il_fill_probe_req(il, (struct ieee80211_mgmt *)scan->data, 2634 il_fill_probe_req(il, (struct ieee80211_mgmt *)scan->data,
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c
index 30ad404f8df7..d7a83f229190 100644
--- a/drivers/net/wireless/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/3945-rs.c
@@ -86,16 +86,16 @@ static struct il3945_tpt_entry il3945_tpt_table_g[] = {
86 {-92, RATE_1M_IDX} 86 {-92, RATE_1M_IDX}
87}; 87};
88 88
89#define RATE_MAX_WINDOW 62 89#define RATE_MAX_WINDOW 62
90#define RATE_FLUSH (3*HZ) 90#define RATE_FLUSH (3*HZ)
91#define RATE_WIN_FLUSH (HZ/2) 91#define RATE_WIN_FLUSH (HZ/2)
92#define IL39_RATE_HIGH_TH 11520 92#define IL39_RATE_HIGH_TH 11520
93#define IL_SUCCESS_UP_TH 8960 93#define IL_SUCCESS_UP_TH 8960
94#define IL_SUCCESS_DOWN_TH 10880 94#define IL_SUCCESS_DOWN_TH 10880
95#define RATE_MIN_FAILURE_TH 6 95#define RATE_MIN_FAILURE_TH 6
96#define RATE_MIN_SUCCESS_TH 8 96#define RATE_MIN_SUCCESS_TH 8
97#define RATE_DECREASE_TH 1920 97#define RATE_DECREASE_TH 1920
98#define RATE_RETRY_TH 15 98#define RATE_RETRY_TH 15
99 99
100static u8 100static u8
101il3945_get_rate_idx_by_rssi(s32 rssi, enum ieee80211_band band) 101il3945_get_rate_idx_by_rssi(s32 rssi, enum ieee80211_band band)
@@ -112,12 +112,10 @@ il3945_get_rate_idx_by_rssi(s32 rssi, enum ieee80211_band band)
112 tpt_table = il3945_tpt_table_g; 112 tpt_table = il3945_tpt_table_g;
113 table_size = ARRAY_SIZE(il3945_tpt_table_g); 113 table_size = ARRAY_SIZE(il3945_tpt_table_g);
114 break; 114 break;
115
116 case IEEE80211_BAND_5GHZ: 115 case IEEE80211_BAND_5GHZ:
117 tpt_table = il3945_tpt_table_a; 116 tpt_table = il3945_tpt_table_a;
118 table_size = ARRAY_SIZE(il3945_tpt_table_a); 117 table_size = ARRAY_SIZE(il3945_tpt_table_a);
119 break; 118 break;
120
121 default: 119 default:
122 BUG(); 120 BUG();
123 break; 121 break;
@@ -126,7 +124,7 @@ il3945_get_rate_idx_by_rssi(s32 rssi, enum ieee80211_band band)
126 while (idx < table_size && rssi < tpt_table[idx].min_rssi) 124 while (idx < table_size && rssi < tpt_table[idx].min_rssi)
127 idx++; 125 idx++;
128 126
129 idx = min(idx, (table_size - 1)); 127 idx = min(idx, table_size - 1);
130 128
131 return tpt_table[idx].idx; 129 return tpt_table[idx].idx;
132} 130}
@@ -328,7 +326,6 @@ il3945_collect_tx_data(struct il3945_rs_sta *rs_sta,
328 win->stamp = jiffies; 326 win->stamp = jiffies;
329 327
330 spin_unlock_irqrestore(&rs_sta->lock, flags); 328 spin_unlock_irqrestore(&rs_sta->lock, flags);
331
332} 329}
333 330
334/* 331/*
@@ -386,8 +383,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
386 /* For 5 GHz band it start at IL_FIRST_OFDM_RATE */ 383 /* For 5 GHz band it start at IL_FIRST_OFDM_RATE */
387 if (sband->band == IEEE80211_BAND_5GHZ) { 384 if (sband->band == IEEE80211_BAND_5GHZ) {
388 rs_sta->last_txrate_idx += IL_FIRST_OFDM_RATE; 385 rs_sta->last_txrate_idx += IL_FIRST_OFDM_RATE;
389 il->_3945.sta_supp_rates = 386 il->_3945.sta_supp_rates <<= IL_FIRST_OFDM_RATE;
390 il->_3945.sta_supp_rates << IL_FIRST_OFDM_RATE;
391 } 387 }
392 388
393out: 389out:
@@ -406,7 +402,6 @@ il3945_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
406static void 402static void
407il3945_rs_free(void *il) 403il3945_rs_free(void *il)
408{ 404{
409 return;
410} 405}
411 406
412static void * 407static void *
@@ -791,19 +786,16 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
791 786
792 switch (scale_action) { 787 switch (scale_action) {
793 case -1: 788 case -1:
794
795 /* Decrese rate */ 789 /* Decrese rate */
796 if (low != RATE_INVALID) 790 if (low != RATE_INVALID)
797 idx = low; 791 idx = low;
798 break; 792 break;
799
800 case 1: 793 case 1:
801 /* Increase rate */ 794 /* Increase rate */
802 if (high != RATE_INVALID) 795 if (high != RATE_INVALID)
803 idx = high; 796 idx = high;
804 797
805 break; 798 break;
806
807 case 0: 799 case 0:
808 default: 800 default:
809 /* No change */ 801 /* No change */
@@ -958,7 +950,6 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
958 } else 950 } else
959 rs_sta->expected_tpt = il3945_expected_tpt_g; 951 rs_sta->expected_tpt = il3945_expected_tpt_g;
960 break; 952 break;
961
962 case IEEE80211_BAND_5GHZ: 953 case IEEE80211_BAND_5GHZ:
963 rs_sta->expected_tpt = il3945_expected_tpt_a; 954 rs_sta->expected_tpt = il3945_expected_tpt_a;
964 break; 955 break;
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index 863664f9ba8b..1489b1573a6a 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -680,13 +680,13 @@ il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
680void 680void
681il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd, 681il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd,
682 struct ieee80211_tx_info *info, 682 struct ieee80211_tx_info *info,
683 struct ieee80211_hdr *hdr, int sta_id, int tx_id) 683 struct ieee80211_hdr *hdr, int sta_id)
684{ 684{
685 u16 hw_value = ieee80211_get_tx_rate(il->hw, info)->hw_value; 685 u16 hw_value = ieee80211_get_tx_rate(il->hw, info)->hw_value;
686 u16 rate_idx = min(hw_value & 0xffff, RATE_COUNT_3945); 686 u16 rate_idx = min(hw_value & 0xffff, RATE_COUNT_3945 - 1);
687 u16 rate_mask; 687 u16 rate_mask;
688 int rate; 688 int rate;
689 u8 rts_retry_limit; 689 const u8 rts_retry_limit = 7;
690 u8 data_retry_limit; 690 u8 data_retry_limit;
691 __le32 tx_flags; 691 __le32 tx_flags;
692 __le16 fc = hdr->frame_control; 692 __le16 fc = hdr->frame_control;
@@ -705,15 +705,8 @@ il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd,
705 else 705 else
706 data_retry_limit = IL_DEFAULT_TX_RETRY; 706 data_retry_limit = IL_DEFAULT_TX_RETRY;
707 tx_cmd->data_retry_limit = data_retry_limit; 707 tx_cmd->data_retry_limit = data_retry_limit;
708 708 /* Set retry limit on RTS packets */
709 if (tx_id >= IL39_CMD_QUEUE_NUM) 709 tx_cmd->rts_retry_limit = min(data_retry_limit, rts_retry_limit);
710 rts_retry_limit = 3;
711 else
712 rts_retry_limit = 7;
713
714 if (data_retry_limit < rts_retry_limit)
715 rts_retry_limit = data_retry_limit;
716 tx_cmd->rts_retry_limit = rts_retry_limit;
717 710
718 tx_cmd->rate = rate; 711 tx_cmd->rate = rate;
719 tx_cmd->tx_flags = tx_flags; 712 tx_cmd->tx_flags = tx_flags;
@@ -2331,8 +2324,7 @@ il3945_init_hw_rate_table(struct il_priv *il)
2331 for (i = 0; i < ARRAY_SIZE(il3945_rates); i++) { 2324 for (i = 0; i < ARRAY_SIZE(il3945_rates); i++) {
2332 idx = il3945_rates[i].table_rs_idx; 2325 idx = il3945_rates[i].table_rs_idx;
2333 2326
2334 table[idx].rate_n_flags = 2327 table[idx].rate_n_flags = cpu_to_le16(il3945_rates[i].plcp);
2335 il3945_hw_set_rate_n_flags(il3945_rates[i].plcp, 0);
2336 table[idx].try_cnt = il->retry_rate; 2328 table[idx].try_cnt = il->retry_rate;
2337 prev_idx = il3945_get_prev_ieee_rate(i); 2329 prev_idx = il3945_get_prev_ieee_rate(i);
2338 table[idx].next_rate_idx = il3945_rates[prev_idx].table_rs_idx; 2330 table[idx].next_rate_idx = il3945_rates[prev_idx].table_rs_idx;
diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h
index 2b2895c544d7..9f42f79f8778 100644
--- a/drivers/net/wireless/iwlegacy/3945.h
+++ b/drivers/net/wireless/iwlegacy/3945.h
@@ -239,8 +239,7 @@ extern unsigned int il3945_hw_get_beacon_cmd(struct il_priv *il,
239 u8 rate); 239 u8 rate);
240void il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd, 240void il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd,
241 struct ieee80211_tx_info *info, 241 struct ieee80211_tx_info *info,
242 struct ieee80211_hdr *hdr, int sta_id, 242 struct ieee80211_hdr *hdr, int sta_id);
243 int tx_id);
244extern int il3945_hw_reg_send_txpower(struct il_priv *il); 243extern int il3945_hw_reg_send_txpower(struct il_priv *il);
245extern int il3945_hw_reg_set_txpower(struct il_priv *il, s8 power); 244extern int il3945_hw_reg_set_txpower(struct il_priv *il, s8 power);
246extern void il3945_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb); 245extern void il3945_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb);
@@ -476,24 +475,6 @@ struct il3945_shared {
476 __le32 tx_base_ptr[8]; 475 __le32 tx_base_ptr[8];
477} __packed; 476} __packed;
478 477
479static inline u8
480il3945_hw_get_rate(__le16 rate_n_flags)
481{
482 return le16_to_cpu(rate_n_flags) & 0xFF;
483}
484
485static inline u16
486il3945_hw_get_rate_n_flags(__le16 rate_n_flags)
487{
488 return le16_to_cpu(rate_n_flags);
489}
490
491static inline __le16
492il3945_hw_set_rate_n_flags(u8 rate, u16 flags)
493{
494 return cpu_to_le16((u16) rate | flags);
495}
496
497/************************************/ 478/************************************/
498/* iwl3945 Flow Handler Definitions */ 479/* iwl3945 Flow Handler Definitions */
499/************************************/ 480/************************************/
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 4aaef4135564..1667232af647 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -819,10 +819,19 @@ il4965_get_channels_for_scan(struct il_priv *il, struct ieee80211_vif *vif,
819 return added; 819 return added;
820} 820}
821 821
822static inline u32 822static void
823il4965_ant_idx_to_flags(u8 ant_idx) 823il4965_toggle_tx_ant(struct il_priv *il, u8 *ant, u8 valid)
824{ 824{
825 return BIT(ant_idx) << RATE_MCS_ANT_POS; 825 int i;
826 u8 ind = *ant;
827
828 for (i = 0; i < RATE_ANT_NUM - 1; i++) {
829 ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
830 if (valid & BIT(ind)) {
831 *ant = ind;
832 return;
833 }
834 }
826} 835}
827 836
828int 837int
@@ -960,11 +969,9 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
960 if (il->cfg->scan_rx_antennas[band]) 969 if (il->cfg->scan_rx_antennas[band])
961 rx_ant = il->cfg->scan_rx_antennas[band]; 970 rx_ant = il->cfg->scan_rx_antennas[band];
962 971
963 il->scan_tx_ant[band] = 972 il4965_toggle_tx_ant(il, &il->scan_tx_ant[band], scan_tx_antennas);
964 il4965_toggle_tx_ant(il, il->scan_tx_ant[band], scan_tx_antennas); 973 rate_flags |= BIT(il->scan_tx_ant[band]) << RATE_MCS_ANT_POS;
965 rate_flags |= il4965_ant_idx_to_flags(il->scan_tx_ant[band]); 974 scan->tx_cmd.rate_n_flags = cpu_to_le32(rate | rate_flags);
966 scan->tx_cmd.rate_n_flags =
967 il4965_hw_set_rate_n_flags(rate, rate_flags);
968 975
969 /* In power save mode use one chain, otherwise use all chains */ 976 /* In power save mode use one chain, otherwise use all chains */
970 if (test_bit(S_POWER_PMI, &il->status)) { 977 if (test_bit(S_POWER_PMI, &il->status)) {
@@ -1171,20 +1178,6 @@ il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx)
1171 active_rx_cnt < idle_rx_cnt); 1178 active_rx_cnt < idle_rx_cnt);
1172} 1179}
1173 1180
1174u8
1175il4965_toggle_tx_ant(struct il_priv *il, u8 ant, u8 valid)
1176{
1177 int i;
1178 u8 ind = ant;
1179
1180 for (i = 0; i < RATE_ANT_NUM - 1; i++) {
1181 ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
1182 if (valid & BIT(ind))
1183 return ind;
1184 }
1185 return ant;
1186}
1187
1188static const char * 1181static const char *
1189il4965_get_fh_string(int cmd) 1182il4965_get_fh_string(int cmd)
1190{ 1183{
@@ -1530,15 +1523,13 @@ il4965_tx_cmd_build_basic(struct il_priv *il, struct sk_buff *skb,
1530 tx_cmd->next_frame_len = 0; 1523 tx_cmd->next_frame_len = 0;
1531} 1524}
1532 1525
1533#define RTS_DFAULT_RETRY_LIMIT 60
1534
1535static void 1526static void
1536il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd, 1527il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd,
1537 struct ieee80211_tx_info *info, __le16 fc) 1528 struct ieee80211_tx_info *info, __le16 fc)
1538{ 1529{
1530 const u8 rts_retry_limit = 60;
1539 u32 rate_flags; 1531 u32 rate_flags;
1540 int rate_idx; 1532 int rate_idx;
1541 u8 rts_retry_limit;
1542 u8 data_retry_limit; 1533 u8 data_retry_limit;
1543 u8 rate_plcp; 1534 u8 rate_plcp;
1544 1535
@@ -1548,12 +1539,8 @@ il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd,
1548 else 1539 else
1549 data_retry_limit = IL4965_DEFAULT_TX_RETRY; 1540 data_retry_limit = IL4965_DEFAULT_TX_RETRY;
1550 tx_cmd->data_retry_limit = data_retry_limit; 1541 tx_cmd->data_retry_limit = data_retry_limit;
1551
1552 /* Set retry limit on RTS packets */ 1542 /* Set retry limit on RTS packets */
1553 rts_retry_limit = RTS_DFAULT_RETRY_LIMIT; 1543 tx_cmd->rts_retry_limit = min(data_retry_limit, rts_retry_limit);
1554 if (data_retry_limit < rts_retry_limit)
1555 rts_retry_limit = data_retry_limit;
1556 tx_cmd->rts_retry_limit = rts_retry_limit;
1557 1544
1558 /* DATA packets will use the uCode station table for rate/antenna 1545 /* DATA packets will use the uCode station table for rate/antenna
1559 * selection */ 1546 * selection */
@@ -1588,15 +1575,11 @@ il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd,
1588 rate_flags |= RATE_MCS_CCK_MSK; 1575 rate_flags |= RATE_MCS_CCK_MSK;
1589 1576
1590 /* Set up antennas */ 1577 /* Set up antennas */
1591 il->mgmt_tx_ant = 1578 il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant);
1592 il4965_toggle_tx_ant(il, il->mgmt_tx_ant, 1579 rate_flags |= BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS;
1593 il->hw_params.valid_tx_ant);
1594
1595 rate_flags |= il4965_ant_idx_to_flags(il->mgmt_tx_ant);
1596 1580
1597 /* Set the rate in the TX cmd */ 1581 /* Set the rate in the TX cmd */
1598 tx_cmd->rate_n_flags = 1582 tx_cmd->rate_n_flags = cpu_to_le32(rate_plcp | rate_flags);
1599 il4965_hw_set_rate_n_flags(rate_plcp, rate_flags);
1600} 1583}
1601 1584
1602static void 1585static void
@@ -2756,7 +2739,7 @@ il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id)
2756 rate_flags |= 2739 rate_flags |=
2757 il4965_first_antenna(il->hw_params. 2740 il4965_first_antenna(il->hw_params.
2758 valid_tx_ant) << RATE_MCS_ANT_POS; 2741 valid_tx_ant) << RATE_MCS_ANT_POS;
2759 rate_n_flags = il4965_hw_set_rate_n_flags(il_rates[r].plcp, rate_flags); 2742 rate_n_flags = cpu_to_le32(il_rates[r].plcp | rate_flags);
2760 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) 2743 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
2761 link_cmd->rs_table[i].rate_n_flags = rate_n_flags; 2744 link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
2762 2745
@@ -3540,14 +3523,11 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
3540 3523
3541 /* Set up packet rate and flags */ 3524 /* Set up packet rate and flags */
3542 rate = il_get_lowest_plcp(il, il->beacon_ctx); 3525 rate = il_get_lowest_plcp(il, il->beacon_ctx);
3543 il->mgmt_tx_ant = 3526 il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant);
3544 il4965_toggle_tx_ant(il, il->mgmt_tx_ant, 3527 rate_flags = BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS;
3545 il->hw_params.valid_tx_ant);
3546 rate_flags = il4965_ant_idx_to_flags(il->mgmt_tx_ant);
3547 if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE)) 3528 if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE))
3548 rate_flags |= RATE_MCS_CCK_MSK; 3529 rate_flags |= RATE_MCS_CCK_MSK;
3549 tx_beacon_cmd->tx.rate_n_flags = 3530 tx_beacon_cmd->tx.rate_n_flags = cpu_to_le32(rate | rate_flags);
3550 il4965_hw_set_rate_n_flags(rate, rate_flags);
3551 3531
3552 return sizeof(*tx_beacon_cmd) + frame_size; 3532 return sizeof(*tx_beacon_cmd) + frame_size;
3553} 3533}
@@ -3800,13 +3780,12 @@ il4965_hdl_beacon(struct il_priv *il, struct il_rx_buf *rxb)
3800#ifdef CONFIG_IWLEGACY_DEBUG 3780#ifdef CONFIG_IWLEGACY_DEBUG
3801 u8 rate = il4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); 3781 u8 rate = il4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
3802 3782
3803 D_RX("beacon status %x retries %d iss %d " "tsf %d %d rate %d\n", 3783 D_RX("beacon status %x retries %d iss %d tsf:0x%.8x%.8x rate %d\n",
3804 le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, 3784 le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
3805 beacon->beacon_notify_hdr.failure_frame, 3785 beacon->beacon_notify_hdr.failure_frame,
3806 le32_to_cpu(beacon->ibss_mgr_status), 3786 le32_to_cpu(beacon->ibss_mgr_status),
3807 le32_to_cpu(beacon->high_tsf), le32_to_cpu(beacon->low_tsf), rate); 3787 le32_to_cpu(beacon->high_tsf), le32_to_cpu(beacon->low_tsf), rate);
3808#endif 3788#endif
3809
3810 il->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); 3789 il->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
3811} 3790}
3812 3791
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c
index 84c54dccf195..cacbc03880b0 100644
--- a/drivers/net/wireless/iwlegacy/4965.c
+++ b/drivers/net/wireless/iwlegacy/4965.c
@@ -2114,24 +2114,6 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
2114 spin_unlock_irqrestore(&il->sta_lock, flags); 2114 spin_unlock_irqrestore(&il->sta_lock, flags);
2115} 2115}
2116 2116
2117static void
2118il4965_hdl_beacon(struct il_priv *il, struct il_rx_buf *rxb)
2119{
2120 struct il_rx_pkt *pkt = rxb_addr(rxb);
2121 struct il4965_beacon_notif *beacon = (void *)pkt->u.raw;
2122 u8 rate __maybe_unused =
2123 il4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
2124
2125 D_RX("beacon status %#x, retries:%d ibssmgr:%d "
2126 "tsf:0x%.8x%.8x rate:%d\n",
2127 le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
2128 beacon->beacon_notify_hdr.failure_frame,
2129 le32_to_cpu(beacon->ibss_mgr_status),
2130 le32_to_cpu(beacon->high_tsf), le32_to_cpu(beacon->low_tsf), rate);
2131
2132 il->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
2133}
2134
2135/* Set up 4965-specific Rx frame reply handlers */ 2117/* Set up 4965-specific Rx frame reply handlers */
2136static void 2118static void
2137il4965_handler_setup(struct il_priv *il) 2119il4965_handler_setup(struct il_priv *il)
@@ -2140,7 +2122,6 @@ il4965_handler_setup(struct il_priv *il)
2140 il->handlers[N_RX] = il4965_hdl_rx; 2122 il->handlers[N_RX] = il4965_hdl_rx;
2141 /* Tx response */ 2123 /* Tx response */
2142 il->handlers[C_TX] = il4965_hdl_tx; 2124 il->handlers[C_TX] = il4965_hdl_tx;
2143 il->handlers[N_BEACON] = il4965_hdl_beacon;
2144} 2125}
2145 2126
2146static struct il_hcmd_ops il4965_hcmd = { 2127static struct il_hcmd_ops il4965_hcmd = {
diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h
index 74472314bc37..f280e0161b17 100644
--- a/drivers/net/wireless/iwlegacy/4965.h
+++ b/drivers/net/wireless/iwlegacy/4965.h
@@ -107,8 +107,6 @@ void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 idx);
107void il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq, 107void il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
108 int tx_fifo_id, int scd_retry); 108 int tx_fifo_id, int scd_retry);
109 109
110u8 il4965_toggle_tx_ant(struct il_priv *il, u8 ant_idx, u8 valid);
111
112/* rx */ 110/* rx */
113void il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb); 111void il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb);
114bool il4965_good_plcp_health(struct il_priv *il, struct il_rx_pkt *pkt); 112bool il4965_good_plcp_health(struct il_priv *il, struct il_rx_pkt *pkt);
@@ -169,12 +167,6 @@ il4965_hw_get_rate(__le32 rate_n_flags)
169 return le32_to_cpu(rate_n_flags) & 0xFF; 167 return le32_to_cpu(rate_n_flags) & 0xFF;
170} 168}
171 169
172static inline __le32
173il4965_hw_set_rate_n_flags(u8 rate, u32 flags)
174{
175 return cpu_to_le32(flags | (u32) rate);
176}
177
178/* eeprom */ 170/* eeprom */
179void il4965_eeprom_get_mac(const struct il_priv *il, u8 * mac); 171void il4965_eeprom_get_mac(const struct il_priv *il, u8 * mac);
180int il4965_eeprom_acquire_semaphore(struct il_priv *il); 172int il4965_eeprom_acquire_semaphore(struct il_priv *il);
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 881ba043770a..36454d0bbeed 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -42,6 +42,167 @@
42 42
43#include "common.h" 43#include "common.h"
44 44
45int
46_il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout)
47{
48 const int interval = 10; /* microseconds */
49 int t = 0;
50
51 do {
52 if ((_il_rd(il, addr) & mask) == (bits & mask))
53 return t;
54 udelay(interval);
55 t += interval;
56 } while (t < timeout);
57
58 return -ETIMEDOUT;
59}
60EXPORT_SYMBOL(_il_poll_bit);
61
62void
63il_set_bit(struct il_priv *p, u32 r, u32 m)
64{
65 unsigned long reg_flags;
66
67 spin_lock_irqsave(&p->reg_lock, reg_flags);
68 _il_set_bit(p, r, m);
69 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
70}
71EXPORT_SYMBOL(il_set_bit);
72
73void
74il_clear_bit(struct il_priv *p, u32 r, u32 m)
75{
76 unsigned long reg_flags;
77
78 spin_lock_irqsave(&p->reg_lock, reg_flags);
79 _il_clear_bit(p, r, m);
80 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
81}
82EXPORT_SYMBOL(il_clear_bit);
83
84int
85_il_grab_nic_access(struct il_priv *il)
86{
87 int ret;
88 u32 val;
89
90 /* this bit wakes up the NIC */
91 _il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
92
93 /*
94 * These bits say the device is running, and should keep running for
95 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
96 * but they do not indicate that embedded SRAM is restored yet;
97 * 3945 and 4965 have volatile SRAM, and must save/restore contents
98 * to/from host DRAM when sleeping/waking for power-saving.
99 * Each direction takes approximately 1/4 millisecond; with this
100 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
101 * series of register accesses are expected (e.g. reading Event Log),
102 * to keep device from sleeping.
103 *
104 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
105 * SRAM is okay/restored. We don't check that here because this call
106 * is just for hardware register access; but GP1 MAC_SLEEP check is a
107 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
108 *
109 */
110 ret =
111 _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
112 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
113 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
114 if (ret < 0) {
115 val = _il_rd(il, CSR_GP_CNTRL);
116 IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
117 _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
118 return -EIO;
119 }
120
121 return 0;
122}
123EXPORT_SYMBOL_GPL(_il_grab_nic_access);
124
125int
126il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout)
127{
128 const int interval = 10; /* microseconds */
129 int t = 0;
130
131 do {
132 if ((il_rd(il, addr) & mask) == mask)
133 return t;
134 udelay(interval);
135 t += interval;
136 } while (t < timeout);
137
138 return -ETIMEDOUT;
139}
140EXPORT_SYMBOL(il_poll_bit);
141
142u32
143il_rd_prph(struct il_priv *il, u32 reg)
144{
145 unsigned long reg_flags;
146 u32 val;
147
148 spin_lock_irqsave(&il->reg_lock, reg_flags);
149 _il_grab_nic_access(il);
150 val = _il_rd_prph(il, reg);
151 _il_release_nic_access(il);
152 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
153 return val;
154}
155EXPORT_SYMBOL(il_rd_prph);
156
157void
158il_wr_prph(struct il_priv *il, u32 addr, u32 val)
159{
160 unsigned long reg_flags;
161
162 spin_lock_irqsave(&il->reg_lock, reg_flags);
163 if (!_il_grab_nic_access(il)) {
164 _il_wr_prph(il, addr, val);
165 _il_release_nic_access(il);
166 }
167 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
168}
169EXPORT_SYMBOL(il_wr_prph);
170
171u32
172il_read_targ_mem(struct il_priv *il, u32 addr)
173{
174 unsigned long reg_flags;
175 u32 value;
176
177 spin_lock_irqsave(&il->reg_lock, reg_flags);
178 _il_grab_nic_access(il);
179
180 _il_wr(il, HBUS_TARG_MEM_RADDR, addr);
181 rmb();
182 value = _il_rd(il, HBUS_TARG_MEM_RDAT);
183
184 _il_release_nic_access(il);
185 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
186 return value;
187}
188EXPORT_SYMBOL(il_read_targ_mem);
189
190void
191il_write_targ_mem(struct il_priv *il, u32 addr, u32 val)
192{
193 unsigned long reg_flags;
194
195 spin_lock_irqsave(&il->reg_lock, reg_flags);
196 if (!_il_grab_nic_access(il)) {
197 _il_wr(il, HBUS_TARG_MEM_WADDR, addr);
198 wmb();
199 _il_wr(il, HBUS_TARG_MEM_WDAT, val);
200 _il_release_nic_access(il);
201 }
202 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
203}
204EXPORT_SYMBOL(il_write_targ_mem);
205
45const char * 206const char *
46il_get_cmd_string(u8 cmd) 207il_get_cmd_string(u8 cmd)
47{ 208{
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 1bc0b02f559c..abfa388588be 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -31,6 +31,7 @@
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/leds.h> 32#include <linux/leds.h>
33#include <linux/wait.h> 33#include <linux/wait.h>
34#include <linux/io.h>
34#include <net/mac80211.h> 35#include <net/mac80211.h>
35#include <net/ieee80211_radiotap.h> 36#include <net/ieee80211_radiotap.h>
36 37
@@ -2163,7 +2164,15 @@ void il_tx_cmd_protection(struct il_priv *il, struct ieee80211_tx_info *info,
2163 2164
2164irqreturn_t il_isr(int irq, void *data); 2165irqreturn_t il_isr(int irq, void *data);
2165 2166
2166#include <linux/io.h> 2167extern void il_set_bit(struct il_priv *p, u32 r, u32 m);
2168extern void il_clear_bit(struct il_priv *p, u32 r, u32 m);
2169extern int _il_grab_nic_access(struct il_priv *il);
2170extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout);
2171extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout);
2172extern u32 il_rd_prph(struct il_priv *il, u32 reg);
2173extern void il_wr_prph(struct il_priv *il, u32 addr, u32 val);
2174extern u32 il_read_targ_mem(struct il_priv *il, u32 addr);
2175extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val);
2167 2176
2168static inline void 2177static inline void
2169_il_write8(struct il_priv *il, u32 ofs, u8 val) 2178_il_write8(struct il_priv *il, u32 ofs, u8 val)
@@ -2184,38 +2193,6 @@ _il_rd(struct il_priv *il, u32 ofs)
2184 return ioread32(il->hw_base + ofs); 2193 return ioread32(il->hw_base + ofs);
2185} 2194}
2186 2195
2187#define IL_POLL_INTERVAL 10 /* microseconds */
2188static inline int
2189_il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout)
2190{
2191 int t = 0;
2192
2193 do {
2194 if ((_il_rd(il, addr) & mask) == (bits & mask))
2195 return t;
2196 udelay(IL_POLL_INTERVAL);
2197 t += IL_POLL_INTERVAL;
2198 } while (t < timeout);
2199
2200 return -ETIMEDOUT;
2201}
2202
2203static inline void
2204_il_set_bit(struct il_priv *il, u32 reg, u32 mask)
2205{
2206 _il_wr(il, reg, _il_rd(il, reg) | mask);
2207}
2208
2209static inline void
2210il_set_bit(struct il_priv *p, u32 r, u32 m)
2211{
2212 unsigned long reg_flags;
2213
2214 spin_lock_irqsave(&p->reg_lock, reg_flags);
2215 _il_set_bit(p, r, m);
2216 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
2217}
2218
2219static inline void 2196static inline void
2220_il_clear_bit(struct il_priv *il, u32 reg, u32 mask) 2197_il_clear_bit(struct il_priv *il, u32 reg, u32 mask)
2221{ 2198{
@@ -2223,53 +2200,9 @@ _il_clear_bit(struct il_priv *il, u32 reg, u32 mask)
2223} 2200}
2224 2201
2225static inline void 2202static inline void
2226il_clear_bit(struct il_priv *p, u32 r, u32 m) 2203_il_set_bit(struct il_priv *il, u32 reg, u32 mask)
2227{
2228 unsigned long reg_flags;
2229
2230 spin_lock_irqsave(&p->reg_lock, reg_flags);
2231 _il_clear_bit(p, r, m);
2232 spin_unlock_irqrestore(&p->reg_lock, reg_flags);
2233}
2234
2235static inline int
2236_il_grab_nic_access(struct il_priv *il)
2237{ 2204{
2238 int ret; 2205 _il_wr(il, reg, _il_rd(il, reg) | mask);
2239 u32 val;
2240
2241 /* this bit wakes up the NIC */
2242 _il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
2243
2244 /*
2245 * These bits say the device is running, and should keep running for
2246 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
2247 * but they do not indicate that embedded SRAM is restored yet;
2248 * 3945 and 4965 have volatile SRAM, and must save/restore contents
2249 * to/from host DRAM when sleeping/waking for power-saving.
2250 * Each direction takes approximately 1/4 millisecond; with this
2251 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
2252 * series of register accesses are expected (e.g. reading Event Log),
2253 * to keep device from sleeping.
2254 *
2255 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
2256 * SRAM is okay/restored. We don't check that here because this call
2257 * is just for hardware register access; but GP1 MAC_SLEEP check is a
2258 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
2259 *
2260 */
2261 ret =
2262 _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
2263 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
2264 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
2265 if (ret < 0) {
2266 val = _il_rd(il, CSR_GP_CNTRL);
2267 IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
2268 _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
2269 return -EIO;
2270 }
2271
2272 return 0;
2273} 2206}
2274 2207
2275static inline void 2208static inline void
@@ -2290,7 +2223,6 @@ il_rd(struct il_priv *il, u32 reg)
2290 _il_release_nic_access(il); 2223 _il_release_nic_access(il);
2291 spin_unlock_irqrestore(&il->reg_lock, reg_flags); 2224 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2292 return value; 2225 return value;
2293
2294} 2226}
2295 2227
2296static inline void 2228static inline void
@@ -2306,32 +2238,6 @@ il_wr(struct il_priv *il, u32 reg, u32 value)
2306 spin_unlock_irqrestore(&il->reg_lock, reg_flags); 2238 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2307} 2239}
2308 2240
2309static inline void
2310il_write_reg_buf(struct il_priv *il, u32 reg, u32 len, u32 * values)
2311{
2312 u32 count = sizeof(u32);
2313
2314 if (il != NULL && values != NULL) {
2315 for (; 0 < len; len -= count, reg += count, values++)
2316 il_wr(il, reg, *values);
2317 }
2318}
2319
2320static inline int
2321il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout)
2322{
2323 int t = 0;
2324
2325 do {
2326 if ((il_rd(il, addr) & mask) == mask)
2327 return t;
2328 udelay(IL_POLL_INTERVAL);
2329 t += IL_POLL_INTERVAL;
2330 } while (t < timeout);
2331
2332 return -ETIMEDOUT;
2333}
2334
2335static inline u32 2241static inline u32
2336_il_rd_prph(struct il_priv *il, u32 reg) 2242_il_rd_prph(struct il_priv *il, u32 reg)
2337{ 2243{
@@ -2340,20 +2246,6 @@ _il_rd_prph(struct il_priv *il, u32 reg)
2340 return _il_rd(il, HBUS_TARG_PRPH_RDAT); 2246 return _il_rd(il, HBUS_TARG_PRPH_RDAT);
2341} 2247}
2342 2248
2343static inline u32
2344il_rd_prph(struct il_priv *il, u32 reg)
2345{
2346 unsigned long reg_flags;
2347 u32 val;
2348
2349 spin_lock_irqsave(&il->reg_lock, reg_flags);
2350 _il_grab_nic_access(il);
2351 val = _il_rd_prph(il, reg);
2352 _il_release_nic_access(il);
2353 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2354 return val;
2355}
2356
2357static inline void 2249static inline void
2358_il_wr_prph(struct il_priv *il, u32 addr, u32 val) 2250_il_wr_prph(struct il_priv *il, u32 addr, u32 val)
2359{ 2251{
@@ -2363,37 +2255,17 @@ _il_wr_prph(struct il_priv *il, u32 addr, u32 val)
2363} 2255}
2364 2256
2365static inline void 2257static inline void
2366il_wr_prph(struct il_priv *il, u32 addr, u32 val)
2367{
2368 unsigned long reg_flags;
2369
2370 spin_lock_irqsave(&il->reg_lock, reg_flags);
2371 if (!_il_grab_nic_access(il)) {
2372 _il_wr_prph(il, addr, val);
2373 _il_release_nic_access(il);
2374 }
2375 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2376}
2377
2378#define _il_set_bits_prph(il, reg, mask) \
2379_il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask))
2380
2381static inline void
2382il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask) 2258il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask)
2383{ 2259{
2384 unsigned long reg_flags; 2260 unsigned long reg_flags;
2385 2261
2386 spin_lock_irqsave(&il->reg_lock, reg_flags); 2262 spin_lock_irqsave(&il->reg_lock, reg_flags);
2387 _il_grab_nic_access(il); 2263 _il_grab_nic_access(il);
2388 _il_set_bits_prph(il, reg, mask); 2264 _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));
2389 _il_release_nic_access(il); 2265 _il_release_nic_access(il);
2390 spin_unlock_irqrestore(&il->reg_lock, reg_flags); 2266 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2391} 2267}
2392 2268
2393#define _il_set_bits_mask_prph(il, reg, bits, mask) \
2394_il_wr_prph(il, reg, \
2395 ((_il_rd_prph(il, reg) & mask) | bits))
2396
2397static inline void 2269static inline void
2398il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask) 2270il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask)
2399{ 2271{
@@ -2401,7 +2273,7 @@ il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask)
2401 2273
2402 spin_lock_irqsave(&il->reg_lock, reg_flags); 2274 spin_lock_irqsave(&il->reg_lock, reg_flags);
2403 _il_grab_nic_access(il); 2275 _il_grab_nic_access(il);
2404 _il_set_bits_mask_prph(il, reg, bits, mask); 2276 _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));
2405 _il_release_nic_access(il); 2277 _il_release_nic_access(il);
2406 spin_unlock_irqrestore(&il->reg_lock, reg_flags); 2278 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2407} 2279}
@@ -2420,56 +2292,6 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask)
2420 spin_unlock_irqrestore(&il->reg_lock, reg_flags); 2292 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2421} 2293}
2422 2294
2423static inline u32
2424il_read_targ_mem(struct il_priv *il, u32 addr)
2425{
2426 unsigned long reg_flags;
2427 u32 value;
2428
2429 spin_lock_irqsave(&il->reg_lock, reg_flags);
2430 _il_grab_nic_access(il);
2431
2432 _il_wr(il, HBUS_TARG_MEM_RADDR, addr);
2433 rmb();
2434 value = _il_rd(il, HBUS_TARG_MEM_RDAT);
2435
2436 _il_release_nic_access(il);
2437 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2438 return value;
2439}
2440
2441static inline void
2442il_write_targ_mem(struct il_priv *il, u32 addr, u32 val)
2443{
2444 unsigned long reg_flags;
2445
2446 spin_lock_irqsave(&il->reg_lock, reg_flags);
2447 if (!_il_grab_nic_access(il)) {
2448 _il_wr(il, HBUS_TARG_MEM_WADDR, addr);
2449 wmb();
2450 _il_wr(il, HBUS_TARG_MEM_WDAT, val);
2451 _il_release_nic_access(il);
2452 }
2453 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2454}
2455
2456static inline void
2457il_write_targ_mem_buf(struct il_priv *il, u32 addr, u32 len, u32 * values)
2458{
2459 unsigned long reg_flags;
2460
2461 spin_lock_irqsave(&il->reg_lock, reg_flags);
2462 if (!_il_grab_nic_access(il)) {
2463 _il_wr(il, HBUS_TARG_MEM_WADDR, addr);
2464 wmb();
2465 for (; 0 < len; len -= sizeof(u32), values++)
2466 _il_wr(il, HBUS_TARG_MEM_WDAT, *values);
2467
2468 _il_release_nic_access(il);
2469 }
2470 spin_unlock_irqrestore(&il->reg_lock, reg_flags);
2471}
2472
2473#define HW_KEY_DYNAMIC 0 2295#define HW_KEY_DYNAMIC 0
2474#define HW_KEY_DEFAULT 1 2296#define HW_KEY_DEFAULT 1
2475 2297
diff --git a/drivers/net/wireless/iwlegacy/iwl-sta.c b/drivers/net/wireless/iwlegacy/iwl-sta.c
deleted file mode 100644
index 75fe315f66b4..000000000000
--- a/drivers/net/wireless/iwlegacy/iwl-sta.c
+++ /dev/null
@@ -1,817 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <net/mac80211.h>
31#include <linux/etherdevice.h>
32#include <linux/sched.h>
33#include <linux/lockdep.h>
34#include <linux/export.h>
35
36#include "iwl-dev.h"
37#include "iwl-core.h"
38#include "iwl-sta.h"
39
40/* il->sta_lock must be held */
41static void il_sta_ucode_activate(struct il_priv *il, u8 sta_id)
42{
43
44 if (!(il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE))
45 IL_ERR(
46 "ACTIVATE a non DRIVER active station id %u addr %pM\n",
47 sta_id, il->stations[sta_id].sta.sta.addr);
48
49 if (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) {
50 D_ASSOC(
51 "STA id %u addr %pM already present"
52 " in uCode (according to driver)\n",
53 sta_id, il->stations[sta_id].sta.sta.addr);
54 } else {
55 il->stations[sta_id].used |= IL_STA_UCODE_ACTIVE;
56 D_ASSOC("Added STA id %u addr %pM to uCode\n",
57 sta_id, il->stations[sta_id].sta.sta.addr);
58 }
59}
60
61static int il_process_add_sta_resp(struct il_priv *il,
62 struct il_addsta_cmd *addsta,
63 struct il_rx_pkt *pkt,
64 bool sync)
65{
66 u8 sta_id = addsta->sta.sta_id;
67 unsigned long flags;
68 int ret = -EIO;
69
70 if (pkt->hdr.flags & IL_CMD_FAILED_MSK) {
71 IL_ERR("Bad return from C_ADD_STA (0x%08X)\n",
72 pkt->hdr.flags);
73 return ret;
74 }
75
76 D_INFO("Processing response for adding station %u\n",
77 sta_id);
78
79 spin_lock_irqsave(&il->sta_lock, flags);
80
81 switch (pkt->u.add_sta.status) {
82 case ADD_STA_SUCCESS_MSK:
83 D_INFO("C_ADD_STA PASSED\n");
84 il_sta_ucode_activate(il, sta_id);
85 ret = 0;
86 break;
87 case ADD_STA_NO_ROOM_IN_TBL:
88 IL_ERR("Adding station %d failed, no room in table.\n",
89 sta_id);
90 break;
91 case ADD_STA_NO_BLOCK_ACK_RESOURCE:
92 IL_ERR(
93 "Adding station %d failed, no block ack resource.\n",
94 sta_id);
95 break;
96 case ADD_STA_MODIFY_NON_EXIST_STA:
97 IL_ERR("Attempting to modify non-existing station %d\n",
98 sta_id);
99 break;
100 default:
101 D_ASSOC("Received C_ADD_STA:(0x%08X)\n",
102 pkt->u.add_sta.status);
103 break;
104 }
105
106 D_INFO("%s station id %u addr %pM\n",
107 il->stations[sta_id].sta.mode ==
108 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
109 sta_id, il->stations[sta_id].sta.sta.addr);
110
111 /*
112 * XXX: The MAC address in the command buffer is often changed from
113 * the original sent to the device. That is, the MAC address
114 * written to the command buffer often is not the same MAC address
115 * read from the command buffer when the command returns. This
116 * issue has not yet been resolved and this debugging is left to
117 * observe the problem.
118 */
119 D_INFO("%s station according to cmd buffer %pM\n",
120 il->stations[sta_id].sta.mode ==
121 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
122 addsta->sta.addr);
123 spin_unlock_irqrestore(&il->sta_lock, flags);
124
125 return ret;
126}
127
128static void il_add_sta_callback(struct il_priv *il,
129 struct il_device_cmd *cmd,
130 struct il_rx_pkt *pkt)
131{
132 struct il_addsta_cmd *addsta =
133 (struct il_addsta_cmd *)cmd->cmd.payload;
134
135 il_process_add_sta_resp(il, addsta, pkt, false);
136
137}
138
139int il_send_add_sta(struct il_priv *il,
140 struct il_addsta_cmd *sta, u8 flags)
141{
142 struct il_rx_pkt *pkt = NULL;
143 int ret = 0;
144 u8 data[sizeof(*sta)];
145 struct il_host_cmd cmd = {
146 .id = C_ADD_STA,
147 .flags = flags,
148 .data = data,
149 };
150 u8 sta_id __maybe_unused = sta->sta.sta_id;
151
152 D_INFO("Adding sta %u (%pM) %ssynchronously\n",
153 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
154
155 if (flags & CMD_ASYNC)
156 cmd.callback = il_add_sta_callback;
157 else {
158 cmd.flags |= CMD_WANT_SKB;
159 might_sleep();
160 }
161
162 cmd.len = il->cfg->ops->utils->build_addsta_hcmd(sta, data);
163 ret = il_send_cmd(il, &cmd);
164
165 if (ret || (flags & CMD_ASYNC))
166 return ret;
167
168 if (ret == 0) {
169 pkt = (struct il_rx_pkt *)cmd.reply_page;
170 ret = il_process_add_sta_resp(il, sta, pkt, true);
171 }
172 il_free_pages(il, cmd.reply_page);
173
174 return ret;
175}
176EXPORT_SYMBOL(il_send_add_sta);
177
178static void il_set_ht_add_station(struct il_priv *il, u8 idx,
179 struct ieee80211_sta *sta,
180 struct il_rxon_context *ctx)
181{
182 struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
183 __le32 sta_flags;
184 u8 mimo_ps_mode;
185
186 if (!sta || !sta_ht_inf->ht_supported)
187 goto done;
188
189 mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
190 D_ASSOC("spatial multiplexing power save mode: %s\n",
191 (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
192 "static" :
193 (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
194 "dynamic" : "disabled");
195
196 sta_flags = il->stations[idx].sta.station_flags;
197
198 sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
199
200 switch (mimo_ps_mode) {
201 case WLAN_HT_CAP_SM_PS_STATIC:
202 sta_flags |= STA_FLG_MIMO_DIS_MSK;
203 break;
204 case WLAN_HT_CAP_SM_PS_DYNAMIC:
205 sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
206 break;
207 case WLAN_HT_CAP_SM_PS_DISABLED:
208 break;
209 default:
210 IL_WARN("Invalid MIMO PS mode %d\n", mimo_ps_mode);
211 break;
212 }
213
214 sta_flags |= cpu_to_le32(
215 (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
216
217 sta_flags |= cpu_to_le32(
218 (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
219
220 if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
221 sta_flags |= STA_FLG_HT40_EN_MSK;
222 else
223 sta_flags &= ~STA_FLG_HT40_EN_MSK;
224
225 il->stations[idx].sta.station_flags = sta_flags;
226 done:
227 return;
228}
229
230/**
231 * il_prep_station - Prepare station information for addition
232 *
233 * should be called with sta_lock held
234 */
235u8 il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
236 const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
237{
238 struct il_station_entry *station;
239 int i;
240 u8 sta_id = IL_INVALID_STATION;
241 u16 rate;
242
243 if (is_ap)
244 sta_id = ctx->ap_sta_id;
245 else if (is_broadcast_ether_addr(addr))
246 sta_id = ctx->bcast_sta_id;
247 else
248 for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) {
249 if (!compare_ether_addr(il->stations[i].sta.sta.addr,
250 addr)) {
251 sta_id = i;
252 break;
253 }
254
255 if (!il->stations[i].used &&
256 sta_id == IL_INVALID_STATION)
257 sta_id = i;
258 }
259
260 /*
261 * These two conditions have the same outcome, but keep them
262 * separate
263 */
264 if (unlikely(sta_id == IL_INVALID_STATION))
265 return sta_id;
266
267 /*
268 * uCode is not able to deal with multiple requests to add a
269 * station. Keep track if one is in progress so that we do not send
270 * another.
271 */
272 if (il->stations[sta_id].used & IL_STA_UCODE_INPROGRESS) {
273 D_INFO(
274 "STA %d already in process of being added.\n",
275 sta_id);
276 return sta_id;
277 }
278
279 if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) &&
280 (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) &&
281 !compare_ether_addr(il->stations[sta_id].sta.sta.addr, addr)) {
282 D_ASSOC(
283 "STA %d (%pM) already added, not adding again.\n",
284 sta_id, addr);
285 return sta_id;
286 }
287
288 station = &il->stations[sta_id];
289 station->used = IL_STA_DRIVER_ACTIVE;
290 D_ASSOC("Add STA to driver ID %d: %pM\n",
291 sta_id, addr);
292 il->num_stations++;
293
294 /* Set up the C_ADD_STA command to send to device */
295 memset(&station->sta, 0, sizeof(struct il_addsta_cmd));
296 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
297 station->sta.mode = 0;
298 station->sta.sta.sta_id = sta_id;
299 station->sta.station_flags = ctx->station_flags;
300 station->ctxid = ctx->ctxid;
301
302 if (sta) {
303 struct il_station_priv_common *sta_priv;
304
305 sta_priv = (void *)sta->drv_priv;
306 sta_priv->ctx = ctx;
307 }
308
309 /*
310 * OK to call unconditionally, since local stations (IBSS BSSID
311 * STA and broadcast STA) pass in a NULL sta, and mac80211
312 * doesn't allow HT IBSS.
313 */
314 il_set_ht_add_station(il, sta_id, sta, ctx);
315
316 /* 3945 only */
317 rate = (il->band == IEEE80211_BAND_5GHZ) ?
318 RATE_6M_PLCP : RATE_1M_PLCP;
319 /* Turn on both antennas for the station... */
320 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
321
322 return sta_id;
323
324}
325EXPORT_SYMBOL_GPL(il_prep_station);
326
327#define STA_WAIT_TIMEOUT (HZ/2)
328
329/**
330 * il_add_station_common -
331 */
332int
333il_add_station_common(struct il_priv *il,
334 struct il_rxon_context *ctx,
335 const u8 *addr, bool is_ap,
336 struct ieee80211_sta *sta, u8 *sta_id_r)
337{
338 unsigned long flags_spin;
339 int ret = 0;
340 u8 sta_id;
341 struct il_addsta_cmd sta_cmd;
342
343 *sta_id_r = 0;
344 spin_lock_irqsave(&il->sta_lock, flags_spin);
345 sta_id = il_prep_station(il, ctx, addr, is_ap, sta);
346 if (sta_id == IL_INVALID_STATION) {
347 IL_ERR("Unable to prepare station %pM for addition\n",
348 addr);
349 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
350 return -EINVAL;
351 }
352
353 /*
354 * uCode is not able to deal with multiple requests to add a
355 * station. Keep track if one is in progress so that we do not send
356 * another.
357 */
358 if (il->stations[sta_id].used & IL_STA_UCODE_INPROGRESS) {
359 D_INFO(
360 "STA %d already in process of being added.\n",
361 sta_id);
362 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
363 return -EEXIST;
364 }
365
366 if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) &&
367 (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE)) {
368 D_ASSOC(
369 "STA %d (%pM) already added, not adding again.\n",
370 sta_id, addr);
371 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
372 return -EEXIST;
373 }
374
375 il->stations[sta_id].used |= IL_STA_UCODE_INPROGRESS;
376 memcpy(&sta_cmd, &il->stations[sta_id].sta,
377 sizeof(struct il_addsta_cmd));
378 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
379
380 /* Add station to device's station table */
381 ret = il_send_add_sta(il, &sta_cmd, CMD_SYNC);
382 if (ret) {
383 spin_lock_irqsave(&il->sta_lock, flags_spin);
384 IL_ERR("Adding station %pM failed.\n",
385 il->stations[sta_id].sta.sta.addr);
386 il->stations[sta_id].used &= ~IL_STA_DRIVER_ACTIVE;
387 il->stations[sta_id].used &= ~IL_STA_UCODE_INPROGRESS;
388 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
389 }
390 *sta_id_r = sta_id;
391 return ret;
392}
393EXPORT_SYMBOL(il_add_station_common);
394
395/**
396 * il_sta_ucode_deactivate - deactivate ucode status for a station
397 *
398 * il->sta_lock must be held
399 */
400static void il_sta_ucode_deactivate(struct il_priv *il, u8 sta_id)
401{
402 /* Ucode must be active and driver must be non active */
403 if ((il->stations[sta_id].used &
404 (IL_STA_UCODE_ACTIVE | IL_STA_DRIVER_ACTIVE)) !=
405 IL_STA_UCODE_ACTIVE)
406 IL_ERR("removed non active STA %u\n", sta_id);
407
408 il->stations[sta_id].used &= ~IL_STA_UCODE_ACTIVE;
409
410 memset(&il->stations[sta_id], 0, sizeof(struct il_station_entry));
411 D_ASSOC("Removed STA %u\n", sta_id);
412}
413
414static int il_send_remove_station(struct il_priv *il,
415 const u8 *addr, int sta_id,
416 bool temporary)
417{
418 struct il_rx_pkt *pkt;
419 int ret;
420
421 unsigned long flags_spin;
422 struct il_rem_sta_cmd rm_sta_cmd;
423
424 struct il_host_cmd cmd = {
425 .id = C_REM_STA,
426 .len = sizeof(struct il_rem_sta_cmd),
427 .flags = CMD_SYNC,
428 .data = &rm_sta_cmd,
429 };
430
431 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
432 rm_sta_cmd.num_sta = 1;
433 memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
434
435 cmd.flags |= CMD_WANT_SKB;
436
437 ret = il_send_cmd(il, &cmd);
438
439 if (ret)
440 return ret;
441
442 pkt = (struct il_rx_pkt *)cmd.reply_page;
443 if (pkt->hdr.flags & IL_CMD_FAILED_MSK) {
444 IL_ERR("Bad return from C_REM_STA (0x%08X)\n",
445 pkt->hdr.flags);
446 ret = -EIO;
447 }
448
449 if (!ret) {
450 switch (pkt->u.rem_sta.status) {
451 case REM_STA_SUCCESS_MSK:
452 if (!temporary) {
453 spin_lock_irqsave(&il->sta_lock, flags_spin);
454 il_sta_ucode_deactivate(il, sta_id);
455 spin_unlock_irqrestore(&il->sta_lock,
456 flags_spin);
457 }
458 D_ASSOC("C_REM_STA PASSED\n");
459 break;
460 default:
461 ret = -EIO;
462 IL_ERR("C_REM_STA failed\n");
463 break;
464 }
465 }
466 il_free_pages(il, cmd.reply_page);
467
468 return ret;
469}
470
471/**
472 * il_remove_station - Remove driver's knowledge of station.
473 */
474int il_remove_station(struct il_priv *il, const u8 sta_id,
475 const u8 *addr)
476{
477 unsigned long flags;
478
479 if (!il_is_ready(il)) {
480 D_INFO(
481 "Unable to remove station %pM, device not ready.\n",
482 addr);
483 /*
484 * It is typical for stations to be removed when we are
485 * going down. Return success since device will be down
486 * soon anyway
487 */
488 return 0;
489 }
490
491 D_ASSOC("Removing STA from driver:%d %pM\n",
492 sta_id, addr);
493
494 if (WARN_ON(sta_id == IL_INVALID_STATION))
495 return -EINVAL;
496
497 spin_lock_irqsave(&il->sta_lock, flags);
498
499 if (!(il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE)) {
500 D_INFO("Removing %pM but non DRIVER active\n",
501 addr);
502 goto out_err;
503 }
504
505 if (!(il->stations[sta_id].used & IL_STA_UCODE_ACTIVE)) {
506 D_INFO("Removing %pM but non UCODE active\n",
507 addr);
508 goto out_err;
509 }
510
511 if (il->stations[sta_id].used & IL_STA_LOCAL) {
512 kfree(il->stations[sta_id].lq);
513 il->stations[sta_id].lq = NULL;
514 }
515
516 il->stations[sta_id].used &= ~IL_STA_DRIVER_ACTIVE;
517
518 il->num_stations--;
519
520 BUG_ON(il->num_stations < 0);
521
522 spin_unlock_irqrestore(&il->sta_lock, flags);
523
524 return il_send_remove_station(il, addr, sta_id, false);
525out_err:
526 spin_unlock_irqrestore(&il->sta_lock, flags);
527 return -EINVAL;
528}
529EXPORT_SYMBOL_GPL(il_remove_station);
530
531/**
532 * il_clear_ucode_stations - clear ucode station table bits
533 *
534 * This function clears all the bits in the driver indicating
535 * which stations are active in the ucode. Call when something
536 * other than explicit station management would cause this in
537 * the ucode, e.g. unassociated RXON.
538 */
539void il_clear_ucode_stations(struct il_priv *il,
540 struct il_rxon_context *ctx)
541{
542 int i;
543 unsigned long flags_spin;
544 bool cleared = false;
545
546 D_INFO("Clearing ucode stations in driver\n");
547
548 spin_lock_irqsave(&il->sta_lock, flags_spin);
549 for (i = 0; i < il->hw_params.max_stations; i++) {
550 if (ctx && ctx->ctxid != il->stations[i].ctxid)
551 continue;
552
553 if (il->stations[i].used & IL_STA_UCODE_ACTIVE) {
554 D_INFO(
555 "Clearing ucode active for station %d\n", i);
556 il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;
557 cleared = true;
558 }
559 }
560 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
561
562 if (!cleared)
563 D_INFO(
564 "No active stations found to be cleared\n");
565}
566EXPORT_SYMBOL(il_clear_ucode_stations);
567
568/**
569 * il_restore_stations() - Restore driver known stations to device
570 *
571 * All stations considered active by driver, but not present in ucode, is
572 * restored.
573 *
574 * Function sleeps.
575 */
576void
577il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
578{
579 struct il_addsta_cmd sta_cmd;
580 struct il_link_quality_cmd lq;
581 unsigned long flags_spin;
582 int i;
583 bool found = false;
584 int ret;
585 bool send_lq;
586
587 if (!il_is_ready(il)) {
588 D_INFO(
589 "Not ready yet, not restoring any stations.\n");
590 return;
591 }
592
593 D_ASSOC("Restoring all known stations ... start.\n");
594 spin_lock_irqsave(&il->sta_lock, flags_spin);
595 for (i = 0; i < il->hw_params.max_stations; i++) {
596 if (ctx->ctxid != il->stations[i].ctxid)
597 continue;
598 if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) &&
599 !(il->stations[i].used & IL_STA_UCODE_ACTIVE)) {
600 D_ASSOC("Restoring sta %pM\n",
601 il->stations[i].sta.sta.addr);
602 il->stations[i].sta.mode = 0;
603 il->stations[i].used |= IL_STA_UCODE_INPROGRESS;
604 found = true;
605 }
606 }
607
608 for (i = 0; i < il->hw_params.max_stations; i++) {
609 if ((il->stations[i].used & IL_STA_UCODE_INPROGRESS)) {
610 memcpy(&sta_cmd, &il->stations[i].sta,
611 sizeof(struct il_addsta_cmd));
612 send_lq = false;
613 if (il->stations[i].lq) {
614 memcpy(&lq, il->stations[i].lq,
615 sizeof(struct il_link_quality_cmd));
616 send_lq = true;
617 }
618 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
619 ret = il_send_add_sta(il, &sta_cmd, CMD_SYNC);
620 if (ret) {
621 spin_lock_irqsave(&il->sta_lock, flags_spin);
622 IL_ERR("Adding station %pM failed.\n",
623 il->stations[i].sta.sta.addr);
624 il->stations[i].used &=
625 ~IL_STA_DRIVER_ACTIVE;
626 il->stations[i].used &=
627 ~IL_STA_UCODE_INPROGRESS;
628 spin_unlock_irqrestore(&il->sta_lock,
629 flags_spin);
630 }
631 /*
632 * Rate scaling has already been initialized, send
633 * current LQ command
634 */
635 if (send_lq)
636 il_send_lq_cmd(il, ctx, &lq,
637 CMD_SYNC, true);
638 spin_lock_irqsave(&il->sta_lock, flags_spin);
639 il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS;
640 }
641 }
642
643 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
644 if (!found)
645 D_INFO("Restoring all known stations"
646 " .... no stations to be restored.\n");
647 else
648 D_INFO("Restoring all known stations"
649 " .... complete.\n");
650}
651EXPORT_SYMBOL(il_restore_stations);
652
653int il_get_free_ucode_key_idx(struct il_priv *il)
654{
655 int i;
656
657 for (i = 0; i < il->sta_key_max_num; i++)
658 if (!test_and_set_bit(i, &il->ucode_key_table))
659 return i;
660
661 return WEP_INVALID_OFFSET;
662}
663EXPORT_SYMBOL(il_get_free_ucode_key_idx);
664
665void il_dealloc_bcast_stations(struct il_priv *il)
666{
667 unsigned long flags;
668 int i;
669
670 spin_lock_irqsave(&il->sta_lock, flags);
671 for (i = 0; i < il->hw_params.max_stations; i++) {
672 if (!(il->stations[i].used & IL_STA_BCAST))
673 continue;
674
675 il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;
676 il->num_stations--;
677 BUG_ON(il->num_stations < 0);
678 kfree(il->stations[i].lq);
679 il->stations[i].lq = NULL;
680 }
681 spin_unlock_irqrestore(&il->sta_lock, flags);
682}
683EXPORT_SYMBOL_GPL(il_dealloc_bcast_stations);
684
685#ifdef CONFIG_IWLEGACY_DEBUG
686static void il_dump_lq_cmd(struct il_priv *il,
687 struct il_link_quality_cmd *lq)
688{
689 int i;
690 D_RATE("lq station id 0x%x\n", lq->sta_id);
691 D_RATE("lq ant 0x%X 0x%X\n",
692 lq->general_params.single_stream_ant_msk,
693 lq->general_params.dual_stream_ant_msk);
694
695 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
696 D_RATE("lq idx %d 0x%X\n",
697 i, lq->rs_table[i].rate_n_flags);
698}
699#else
700static inline void il_dump_lq_cmd(struct il_priv *il,
701 struct il_link_quality_cmd *lq)
702{
703}
704#endif
705
706/**
707 * il_is_lq_table_valid() - Test one aspect of LQ cmd for validity
708 *
709 * It sometimes happens when a HT rate has been in use and we
710 * loose connectivity with AP then mac80211 will first tell us that the
711 * current channel is not HT anymore before removing the station. In such a
712 * scenario the RXON flags will be updated to indicate we are not
713 * communicating HT anymore, but the LQ command may still contain HT rates.
714 * Test for this to prevent driver from sending LQ command between the time
715 * RXON flags are updated and when LQ command is updated.
716 */
717static bool il_is_lq_table_valid(struct il_priv *il,
718 struct il_rxon_context *ctx,
719 struct il_link_quality_cmd *lq)
720{
721 int i;
722
723 if (ctx->ht.enabled)
724 return true;
725
726 D_INFO("Channel %u is not an HT channel\n",
727 ctx->active.channel);
728 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
729 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) &
730 RATE_MCS_HT_MSK) {
731 D_INFO(
732 "idx %d of LQ expects HT channel\n",
733 i);
734 return false;
735 }
736 }
737 return true;
738}
739
740/**
741 * il_send_lq_cmd() - Send link quality command
742 * @init: This command is sent as part of station initialization right
743 * after station has been added.
744 *
745 * The link quality command is sent as the last step of station creation.
746 * This is the special case in which init is set and we call a callback in
747 * this case to clear the state indicating that station creation is in
748 * progress.
749 */
750int il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
751 struct il_link_quality_cmd *lq, u8 flags, bool init)
752{
753 int ret = 0;
754 unsigned long flags_spin;
755
756 struct il_host_cmd cmd = {
757 .id = C_TX_LINK_QUALITY_CMD,
758 .len = sizeof(struct il_link_quality_cmd),
759 .flags = flags,
760 .data = lq,
761 };
762
763 if (WARN_ON(lq->sta_id == IL_INVALID_STATION))
764 return -EINVAL;
765
766
767 spin_lock_irqsave(&il->sta_lock, flags_spin);
768 if (!(il->stations[lq->sta_id].used & IL_STA_DRIVER_ACTIVE)) {
769 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
770 return -EINVAL;
771 }
772 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
773
774 il_dump_lq_cmd(il, lq);
775 BUG_ON(init && (cmd.flags & CMD_ASYNC));
776
777 if (il_is_lq_table_valid(il, ctx, lq))
778 ret = il_send_cmd(il, &cmd);
779 else
780 ret = -EINVAL;
781
782 if (cmd.flags & CMD_ASYNC)
783 return ret;
784
785 if (init) {
786 D_INFO("init LQ command complete,"
787 " clearing sta addition status for sta %d\n",
788 lq->sta_id);
789 spin_lock_irqsave(&il->sta_lock, flags_spin);
790 il->stations[lq->sta_id].used &= ~IL_STA_UCODE_INPROGRESS;
791 spin_unlock_irqrestore(&il->sta_lock, flags_spin);
792 }
793 return ret;
794}
795EXPORT_SYMBOL(il_send_lq_cmd);
796
797int il_mac_sta_remove(struct ieee80211_hw *hw,
798 struct ieee80211_vif *vif,
799 struct ieee80211_sta *sta)
800{
801 struct il_priv *il = hw->priv;
802 struct il_station_priv_common *sta_common = (void *)sta->drv_priv;
803 int ret;
804
805 D_INFO("received request to remove station %pM\n",
806 sta->addr);
807 mutex_lock(&il->mutex);
808 D_INFO("proceeding to remove station %pM\n",
809 sta->addr);
810 ret = il_remove_station(il, sta_common->sta_id, sta->addr);
811 if (ret)
812 IL_ERR("Error removing station %pM\n",
813 sta->addr);
814 mutex_unlock(&il->mutex);
815 return ret;
816}
817EXPORT_SYMBOL(il_mac_sta_remove);
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index cb9da25bd81d..67d6e324e26f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -88,18 +88,16 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans)
88 return -EINVAL; 88 return -EINVAL;
89 89
90 /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ 90 /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */
91 rxq->bd = dma_alloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, 91 rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
92 &rxq->bd_dma, GFP_KERNEL); 92 &rxq->bd_dma, GFP_KERNEL);
93 if (!rxq->bd) 93 if (!rxq->bd)
94 goto err_bd; 94 goto err_bd;
95 memset(rxq->bd, 0, sizeof(__le32) * RX_QUEUE_SIZE);
96 95
97 /*Allocate the driver's pointer to receive buffer status */ 96 /*Allocate the driver's pointer to receive buffer status */
98 rxq->rb_stts = dma_alloc_coherent(dev, sizeof(*rxq->rb_stts), 97 rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts),
99 &rxq->rb_stts_dma, GFP_KERNEL); 98 &rxq->rb_stts_dma, GFP_KERNEL);
100 if (!rxq->rb_stts) 99 if (!rxq->rb_stts)
101 goto err_rb_stts; 100 goto err_rb_stts;
102 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
103 101
104 return 0; 102 return 0;
105 103
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 036491f08e9b..7becea3dec65 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -28,7 +28,7 @@
28 28
29#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver" 29#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
30#define MWL8K_NAME KBUILD_MODNAME 30#define MWL8K_NAME KBUILD_MODNAME
31#define MWL8K_VERSION "0.12" 31#define MWL8K_VERSION "0.13"
32 32
33/* Module parameters */ 33/* Module parameters */
34static bool ap_mode_default; 34static bool ap_mode_default;
@@ -198,6 +198,7 @@ struct mwl8k_priv {
198 /* firmware access */ 198 /* firmware access */
199 struct mutex fw_mutex; 199 struct mutex fw_mutex;
200 struct task_struct *fw_mutex_owner; 200 struct task_struct *fw_mutex_owner;
201 struct task_struct *hw_restart_owner;
201 int fw_mutex_depth; 202 int fw_mutex_depth;
202 struct completion *hostcmd_wait; 203 struct completion *hostcmd_wait;
203 204
@@ -262,6 +263,10 @@ struct mwl8k_priv {
262 */ 263 */
263 struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES]; 264 struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];
264 265
266 /* To perform the task of reloading the firmware */
267 struct work_struct fw_reload;
268 bool hw_restart_in_progress;
269
265 /* async firmware loading state */ 270 /* async firmware loading state */
266 unsigned fw_state; 271 unsigned fw_state;
267 char *fw_pref; 272 char *fw_pref;
@@ -1498,6 +1503,18 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1498 1503
1499 might_sleep(); 1504 might_sleep();
1500 1505
1506 /* Since fw restart is in progress, allow only the firmware
1507 * commands from the restart code and block the other
1508 * commands since they are going to fail in any case since
1509 * the firmware has crashed
1510 */
1511 if (priv->hw_restart_in_progress) {
1512 if (priv->hw_restart_owner == current)
1513 return 0;
1514 else
1515 return -EBUSY;
1516 }
1517
1501 /* 1518 /*
1502 * The TX queues are stopped at this point, so this test 1519 * The TX queues are stopped at this point, so this test
1503 * doesn't need to take ->tx_lock. 1520 * doesn't need to take ->tx_lock.
@@ -1541,6 +1558,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1541 wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n", 1558 wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n",
1542 MWL8K_TX_WAIT_TIMEOUT_MS); 1559 MWL8K_TX_WAIT_TIMEOUT_MS);
1543 mwl8k_dump_tx_rings(hw); 1560 mwl8k_dump_tx_rings(hw);
1561 priv->hw_restart_in_progress = true;
1562 ieee80211_queue_work(hw, &priv->fw_reload);
1544 1563
1545 rc = -ETIMEDOUT; 1564 rc = -ETIMEDOUT;
1546 } 1565 }
@@ -2058,7 +2077,9 @@ static int mwl8k_fw_lock(struct ieee80211_hw *hw)
2058 2077
2059 rc = mwl8k_tx_wait_empty(hw); 2078 rc = mwl8k_tx_wait_empty(hw);
2060 if (rc) { 2079 if (rc) {
2061 ieee80211_wake_queues(hw); 2080 if (!priv->hw_restart_in_progress)
2081 ieee80211_wake_queues(hw);
2082
2062 mutex_unlock(&priv->fw_mutex); 2083 mutex_unlock(&priv->fw_mutex);
2063 2084
2064 return rc; 2085 return rc;
@@ -2077,7 +2098,9 @@ static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
2077 struct mwl8k_priv *priv = hw->priv; 2098 struct mwl8k_priv *priv = hw->priv;
2078 2099
2079 if (!--priv->fw_mutex_depth) { 2100 if (!--priv->fw_mutex_depth) {
2080 ieee80211_wake_queues(hw); 2101 if (!priv->hw_restart_in_progress)
2102 ieee80211_wake_queues(hw);
2103
2081 priv->fw_mutex_owner = NULL; 2104 priv->fw_mutex_owner = NULL;
2082 mutex_unlock(&priv->fw_mutex); 2105 mutex_unlock(&priv->fw_mutex);
2083 } 2106 }
@@ -4398,7 +4421,8 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
4398 struct mwl8k_priv *priv = hw->priv; 4421 struct mwl8k_priv *priv = hw->priv;
4399 int i; 4422 int i;
4400 4423
4401 mwl8k_cmd_radio_disable(hw); 4424 if (!priv->hw_restart_in_progress)
4425 mwl8k_cmd_radio_disable(hw);
4402 4426
4403 ieee80211_stop_queues(hw); 4427 ieee80211_stop_queues(hw);
4404 4428
@@ -4499,6 +4523,16 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
4499 return 0; 4523 return 0;
4500} 4524}
4501 4525
4526static void mwl8k_remove_vif(struct mwl8k_priv *priv, struct mwl8k_vif *vif)
4527{
4528 /* Has ieee80211_restart_hw re-added the removed interfaces? */
4529 if (!priv->macids_used)
4530 return;
4531
4532 priv->macids_used &= ~(1 << vif->macid);
4533 list_del(&vif->list);
4534}
4535
4502static void mwl8k_remove_interface(struct ieee80211_hw *hw, 4536static void mwl8k_remove_interface(struct ieee80211_hw *hw,
4503 struct ieee80211_vif *vif) 4537 struct ieee80211_vif *vif)
4504{ 4538{
@@ -4510,8 +4544,54 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
4510 4544
4511 mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00"); 4545 mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");
4512 4546
4513 priv->macids_used &= ~(1 << mwl8k_vif->macid); 4547 mwl8k_remove_vif(priv, mwl8k_vif);
4514 list_del(&mwl8k_vif->list); 4548}
4549
4550static void mwl8k_hw_restart_work(struct work_struct *work)
4551{
4552 struct mwl8k_priv *priv =
4553 container_of(work, struct mwl8k_priv, fw_reload);
4554 struct ieee80211_hw *hw = priv->hw;
4555 struct mwl8k_device_info *di;
4556 int rc;
4557
4558 /* If some command is waiting for a response, clear it */
4559 if (priv->hostcmd_wait != NULL) {
4560 complete(priv->hostcmd_wait);
4561 priv->hostcmd_wait = NULL;
4562 }
4563
4564 priv->hw_restart_owner = current;
4565 di = priv->device_info;
4566 mwl8k_fw_lock(hw);
4567
4568 if (priv->ap_fw)
4569 rc = mwl8k_reload_firmware(hw, di->fw_image_ap);
4570 else
4571 rc = mwl8k_reload_firmware(hw, di->fw_image_sta);
4572
4573 if (rc)
4574 goto fail;
4575
4576 priv->hw_restart_owner = NULL;
4577 priv->hw_restart_in_progress = false;
4578
4579 /*
4580 * This unlock will wake up the queues and
4581 * also opens the command path for other
4582 * commands
4583 */
4584 mwl8k_fw_unlock(hw);
4585
4586 ieee80211_restart_hw(hw);
4587
4588 wiphy_err(hw->wiphy, "Firmware restarted successfully\n");
4589
4590 return;
4591fail:
4592 mwl8k_fw_unlock(hw);
4593
4594 wiphy_err(hw->wiphy, "Firmware restart failed\n");
4515} 4595}
4516 4596
4517static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) 4597static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
@@ -5024,7 +5104,11 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5024 for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) { 5104 for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
5025 rc = mwl8k_check_ba(hw, stream); 5105 rc = mwl8k_check_ba(hw, stream);
5026 5106
5027 if (!rc) 5107 /* If HW restart is in progress mwl8k_post_cmd will
5108 * return -EBUSY. Avoid retrying mwl8k_check_ba in
5109 * such cases
5110 */
5111 if (!rc || rc == -EBUSY)
5028 break; 5112 break;
5029 /* 5113 /*
5030 * HW queues take time to be flushed, give them 5114 * HW queues take time to be flushed, give them
@@ -5263,12 +5347,15 @@ fail:
5263 mwl8k_release_firmware(priv); 5347 mwl8k_release_firmware(priv);
5264} 5348}
5265 5349
5350#define MAX_RESTART_ATTEMPTS 1
5266static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image, 5351static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
5267 bool nowait) 5352 bool nowait)
5268{ 5353{
5269 struct mwl8k_priv *priv = hw->priv; 5354 struct mwl8k_priv *priv = hw->priv;
5270 int rc; 5355 int rc;
5356 int count = MAX_RESTART_ATTEMPTS;
5271 5357
5358retry:
5272 /* Reset firmware and hardware */ 5359 /* Reset firmware and hardware */
5273 mwl8k_hw_reset(priv); 5360 mwl8k_hw_reset(priv);
5274 5361
@@ -5290,6 +5377,16 @@ static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
5290 /* Reclaim memory once firmware is successfully loaded */ 5377 /* Reclaim memory once firmware is successfully loaded */
5291 mwl8k_release_firmware(priv); 5378 mwl8k_release_firmware(priv);
5292 5379
5380 if (rc && count) {
5381 /* FW did not start successfully;
5382 * lets try one more time
5383 */
5384 count--;
5385 wiphy_err(hw->wiphy, "Trying to reload the firmware again\n");
5386 msleep(20);
5387 goto retry;
5388 }
5389
5293 return rc; 5390 return rc;
5294} 5391}
5295 5392
@@ -5365,7 +5462,14 @@ static int mwl8k_probe_hw(struct ieee80211_hw *hw)
5365 goto err_free_queues; 5462 goto err_free_queues;
5366 } 5463 }
5367 5464
5368 memset(priv->ampdu, 0, sizeof(priv->ampdu)); 5465 /*
5466 * When hw restart is requested,
5467 * mac80211 will take care of clearing
5468 * the ampdu streams, so do not clear
5469 * the ampdu state here
5470 */
5471 if (!priv->hw_restart_in_progress)
5472 memset(priv->ampdu, 0, sizeof(priv->ampdu));
5369 5473
5370 /* 5474 /*
5371 * Temporarily enable interrupts. Initial firmware host 5475 * Temporarily enable interrupts. Initial firmware host
@@ -5439,10 +5543,20 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
5439{ 5543{
5440 int i, rc = 0; 5544 int i, rc = 0;
5441 struct mwl8k_priv *priv = hw->priv; 5545 struct mwl8k_priv *priv = hw->priv;
5546 struct mwl8k_vif *vif, *tmp_vif;
5442 5547
5443 mwl8k_stop(hw); 5548 mwl8k_stop(hw);
5444 mwl8k_rxq_deinit(hw, 0); 5549 mwl8k_rxq_deinit(hw, 0);
5445 5550
5551 /*
5552 * All the existing interfaces are re-added by the ieee80211_reconfig;
5553 * which means driver should remove existing interfaces before calling
5554 * ieee80211_restart_hw
5555 */
5556 if (priv->hw_restart_in_progress)
5557 list_for_each_entry_safe(vif, tmp_vif, &priv->vif_list, list)
5558 mwl8k_remove_vif(priv, vif);
5559
5446 for (i = 0; i < mwl8k_tx_queues(priv); i++) 5560 for (i = 0; i < mwl8k_tx_queues(priv); i++)
5447 mwl8k_txq_deinit(hw, i); 5561 mwl8k_txq_deinit(hw, i);
5448 5562
@@ -5454,6 +5568,9 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
5454 if (rc) 5568 if (rc)
5455 goto fail; 5569 goto fail;
5456 5570
5571 if (priv->hw_restart_in_progress)
5572 return rc;
5573
5457 rc = mwl8k_start(hw); 5574 rc = mwl8k_start(hw);
5458 if (rc) 5575 if (rc)
5459 goto fail; 5576 goto fail;
@@ -5524,6 +5641,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
5524 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 5641 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
5525 /* Handle watchdog ba events */ 5642 /* Handle watchdog ba events */
5526 INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events); 5643 INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events);
5644 /* To reload the firmware if it crashes */
5645 INIT_WORK(&priv->fw_reload, mwl8k_hw_restart_work);
5527 5646
5528 /* TX reclaim and RX tasklets. */ 5647 /* TX reclaim and RX tasklets. */
5529 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw); 5648 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
@@ -5667,6 +5786,9 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
5667 rc = mwl8k_init_firmware(hw, priv->fw_pref, true); 5786 rc = mwl8k_init_firmware(hw, priv->fw_pref, true);
5668 if (rc) 5787 if (rc)
5669 goto err_stop_firmware; 5788 goto err_stop_firmware;
5789
5790 priv->hw_restart_in_progress = false;
5791
5670 return rc; 5792 return rc;
5671 5793
5672err_stop_firmware: 5794err_stop_firmware:
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 4778620347c4..2571a2fa3d09 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -50,7 +50,7 @@
50 * RF2853 2.4G/5G 3T3R 50 * RF2853 2.4G/5G 3T3R
51 * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) 51 * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
52 * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) 52 * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
53 * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) 53 * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
54 * RF5370 2.4G 1T1R 54 * RF5370 2.4G 1T1R
55 * RF5390 2.4G 1T1R 55 * RF5390 2.4G 1T1R
56 */ 56 */
@@ -66,7 +66,7 @@
66#define RF2853 0x000a 66#define RF2853 0x000a
67#define RF3320 0x000b 67#define RF3320 0x000b
68#define RF3322 0x000c 68#define RF3322 0x000c
69#define RF3853 0x000d 69#define RF3053 0x000d
70#define RF5370 0x5370 70#define RF5370 0x5370
71#define RF5390 0x5390 71#define RF5390 0x5390
72 72
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index e5df380d4fbe..22a1a8fc6e02 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1944,19 +1944,24 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
1944 info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); 1944 info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2);
1945 } 1945 }
1946 1946
1947 if (rt2x00_rf(rt2x00dev, RF2020) || 1947 switch (rt2x00dev->chip.rf) {
1948 rt2x00_rf(rt2x00dev, RF3020) || 1948 case RF2020:
1949 rt2x00_rf(rt2x00dev, RF3021) || 1949 case RF3020:
1950 rt2x00_rf(rt2x00dev, RF3022) || 1950 case RF3021:
1951 rt2x00_rf(rt2x00dev, RF3320)) 1951 case RF3022:
1952 case RF3320:
1952 rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); 1953 rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
1953 else if (rt2x00_rf(rt2x00dev, RF3052)) 1954 break;
1955 case RF3052:
1954 rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); 1956 rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
1955 else if (rt2x00_rf(rt2x00dev, RF5370) || 1957 break;
1956 rt2x00_rf(rt2x00dev, RF5390)) 1958 case RF5370:
1959 case RF5390:
1957 rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); 1960 rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
1958 else 1961 break;
1962 default:
1959 rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); 1963 rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
1964 }
1960 1965
1961 /* 1966 /*
1962 * Change BBP settings 1967 * Change BBP settings
@@ -3932,15 +3937,18 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
3932 rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), 3937 rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET),
3933 value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); 3938 value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
3934 3939
3935 if (!rt2x00_rt(rt2x00dev, RT2860) && 3940 switch (rt2x00dev->chip.rt) {
3936 !rt2x00_rt(rt2x00dev, RT2872) && 3941 case RT2860:
3937 !rt2x00_rt(rt2x00dev, RT2883) && 3942 case RT2872:
3938 !rt2x00_rt(rt2x00dev, RT3070) && 3943 case RT2883:
3939 !rt2x00_rt(rt2x00dev, RT3071) && 3944 case RT3070:
3940 !rt2x00_rt(rt2x00dev, RT3090) && 3945 case RT3071:
3941 !rt2x00_rt(rt2x00dev, RT3390) && 3946 case RT3090:
3942 !rt2x00_rt(rt2x00dev, RT3572) && 3947 case RT3390:
3943 !rt2x00_rt(rt2x00dev, RT5390)) { 3948 case RT3572:
3949 case RT5390:
3950 break;
3951 default:
3944 ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); 3952 ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
3945 return -ENODEV; 3953 return -ENODEV;
3946 } 3954 }
@@ -4554,6 +4562,9 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
4554 survey->channel_time_ext_busy = busy_ext / 1000; 4562 survey->channel_time_ext_busy = busy_ext / 1000;
4555 } 4563 }
4556 4564
4565 if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
4566 survey->filled |= SURVEY_INFO_IN_USE;
4567
4557 return 0; 4568 return 0;
4558 4569
4559} 4570}
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index ee01d2e883a0..f8eb49f5ac29 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -400,10 +400,10 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
400 /* 400 /*
401 * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is 401 * The size of TXINFO_W0_USB_DMA_TX_PKT_LEN is
402 * TXWI + 802.11 header + L2 pad + payload + pad, 402 * TXWI + 802.11 header + L2 pad + payload + pad,
403 * so need to decrease size of TXINFO and USB end pad. 403 * so need to decrease size of TXINFO.
404 */ 404 */
405 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, 405 rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
406 entry->skb->len - TXINFO_DESC_SIZE - 4); 406 roundup(entry->skb->len, 4) - TXINFO_DESC_SIZE);
407 rt2x00_set_field32(&word, TXINFO_W0_WIV, 407 rt2x00_set_field32(&word, TXINFO_W0_WIV,
408 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); 408 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
409 rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); 409 rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
@@ -421,37 +421,20 @@ static void rt2800usb_write_tx_desc(struct queue_entry *entry,
421 skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; 421 skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
422} 422}
423 423
424static void rt2800usb_write_tx_data(struct queue_entry *entry, 424/*
425 struct txentry_desc *txdesc) 425 * TX data initialization
426 */
427static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
426{ 428{
427 unsigned int len;
428 int err;
429
430 rt2800_write_tx_data(entry, txdesc);
431
432 /* 429 /*
433 * pad(1~3 bytes) is added after each 802.11 payload. 430 * pad(1~3 bytes) is needed after each 802.11 payload.
434 * USB end pad(4 bytes) is added at each USB bulk out packet end. 431 * USB end pad(4 bytes) is needed at each USB bulk out packet end.
435 * TX frame format is : 432 * TX frame format is :
436 * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad | 433 * | TXINFO | TXWI | 802.11 header | L2 pad | payload | pad | USB end pad |
437 * |<------------- tx_pkt_len ------------->| 434 * |<------------- tx_pkt_len ------------->|
438 */ 435 */
439 len = roundup(entry->skb->len, 4) + 4;
440 err = skb_padto(entry->skb, len);
441 if (unlikely(err)) {
442 WARNING(entry->queue->rt2x00dev, "TX SKB padding error, out of memory\n");
443 return;
444 }
445 436
446 entry->skb->len = len; 437 return roundup(entry->skb->len, 4) + 4;
447}
448
449/*
450 * TX data initialization
451 */
452static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
453{
454 return entry->skb->len;
455} 438}
456 439
457/* 440/*
@@ -807,7 +790,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
807 .flush_queue = rt2x00usb_flush_queue, 790 .flush_queue = rt2x00usb_flush_queue,
808 .tx_dma_done = rt2800usb_tx_dma_done, 791 .tx_dma_done = rt2800usb_tx_dma_done,
809 .write_tx_desc = rt2800usb_write_tx_desc, 792 .write_tx_desc = rt2800usb_write_tx_desc,
810 .write_tx_data = rt2800usb_write_tx_data, 793 .write_tx_data = rt2800_write_tx_data,
811 .write_beacon = rt2800_write_beacon, 794 .write_beacon = rt2800_write_beacon,
812 .clear_beacon = rt2800_clear_beacon, 795 .clear_beacon = rt2800_clear_beacon,
813 .get_tx_data_len = rt2800usb_get_tx_data_len, 796 .get_tx_data_len = rt2800usb_get_tx_data_len,
@@ -914,12 +897,14 @@ static struct usb_device_id rt2800usb_device_table[] = {
914 { USB_DEVICE(0x050d, 0x8053) }, 897 { USB_DEVICE(0x050d, 0x8053) },
915 { USB_DEVICE(0x050d, 0x805c) }, 898 { USB_DEVICE(0x050d, 0x805c) },
916 { USB_DEVICE(0x050d, 0x815c) }, 899 { USB_DEVICE(0x050d, 0x815c) },
900 { USB_DEVICE(0x050d, 0x825a) },
917 { USB_DEVICE(0x050d, 0x825b) }, 901 { USB_DEVICE(0x050d, 0x825b) },
918 { USB_DEVICE(0x050d, 0x935a) }, 902 { USB_DEVICE(0x050d, 0x935a) },
919 { USB_DEVICE(0x050d, 0x935b) }, 903 { USB_DEVICE(0x050d, 0x935b) },
920 /* Buffalo */ 904 /* Buffalo */
921 { USB_DEVICE(0x0411, 0x00e8) }, 905 { USB_DEVICE(0x0411, 0x00e8) },
922 { USB_DEVICE(0x0411, 0x0158) }, 906 { USB_DEVICE(0x0411, 0x0158) },
907 { USB_DEVICE(0x0411, 0x015d) },
923 { USB_DEVICE(0x0411, 0x016f) }, 908 { USB_DEVICE(0x0411, 0x016f) },
924 { USB_DEVICE(0x0411, 0x01a2) }, 909 { USB_DEVICE(0x0411, 0x01a2) },
925 /* Corega */ 910 /* Corega */
@@ -934,6 +919,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
934 { USB_DEVICE(0x07d1, 0x3c0e) }, 919 { USB_DEVICE(0x07d1, 0x3c0e) },
935 { USB_DEVICE(0x07d1, 0x3c0f) }, 920 { USB_DEVICE(0x07d1, 0x3c0f) },
936 { USB_DEVICE(0x07d1, 0x3c11) }, 921 { USB_DEVICE(0x07d1, 0x3c11) },
922 { USB_DEVICE(0x07d1, 0x3c13) },
923 { USB_DEVICE(0x07d1, 0x3c15) },
937 { USB_DEVICE(0x07d1, 0x3c16) }, 924 { USB_DEVICE(0x07d1, 0x3c16) },
938 /* Draytek */ 925 /* Draytek */
939 { USB_DEVICE(0x07fa, 0x7712) }, 926 { USB_DEVICE(0x07fa, 0x7712) },
@@ -943,6 +930,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
943 { USB_DEVICE(0x7392, 0x7711) }, 930 { USB_DEVICE(0x7392, 0x7711) },
944 { USB_DEVICE(0x7392, 0x7717) }, 931 { USB_DEVICE(0x7392, 0x7717) },
945 { USB_DEVICE(0x7392, 0x7718) }, 932 { USB_DEVICE(0x7392, 0x7718) },
933 { USB_DEVICE(0x7392, 0x7722) },
946 /* Encore */ 934 /* Encore */
947 { USB_DEVICE(0x203d, 0x1480) }, 935 { USB_DEVICE(0x203d, 0x1480) },
948 { USB_DEVICE(0x203d, 0x14a9) }, 936 { USB_DEVICE(0x203d, 0x14a9) },
@@ -976,6 +964,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
976 { USB_DEVICE(0x13b1, 0x0031) }, 964 { USB_DEVICE(0x13b1, 0x0031) },
977 { USB_DEVICE(0x1737, 0x0070) }, 965 { USB_DEVICE(0x1737, 0x0070) },
978 { USB_DEVICE(0x1737, 0x0071) }, 966 { USB_DEVICE(0x1737, 0x0071) },
967 { USB_DEVICE(0x1737, 0x0077) },
968 { USB_DEVICE(0x1737, 0x0078) },
979 /* Logitec */ 969 /* Logitec */
980 { USB_DEVICE(0x0789, 0x0162) }, 970 { USB_DEVICE(0x0789, 0x0162) },
981 { USB_DEVICE(0x0789, 0x0163) }, 971 { USB_DEVICE(0x0789, 0x0163) },
@@ -999,9 +989,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
999 { USB_DEVICE(0x0db0, 0x871b) }, 989 { USB_DEVICE(0x0db0, 0x871b) },
1000 { USB_DEVICE(0x0db0, 0x871c) }, 990 { USB_DEVICE(0x0db0, 0x871c) },
1001 { USB_DEVICE(0x0db0, 0x899a) }, 991 { USB_DEVICE(0x0db0, 0x899a) },
992 /* Ovislink */
993 { USB_DEVICE(0x1b75, 0x3071) },
994 { USB_DEVICE(0x1b75, 0x3072) },
1002 /* Para */ 995 /* Para */
1003 { USB_DEVICE(0x20b8, 0x8888) }, 996 { USB_DEVICE(0x20b8, 0x8888) },
1004 /* Pegatron */ 997 /* Pegatron */
998 { USB_DEVICE(0x1d4d, 0x0002) },
1005 { USB_DEVICE(0x1d4d, 0x000c) }, 999 { USB_DEVICE(0x1d4d, 0x000c) },
1006 { USB_DEVICE(0x1d4d, 0x000e) }, 1000 { USB_DEVICE(0x1d4d, 0x000e) },
1007 { USB_DEVICE(0x1d4d, 0x0011) }, 1001 { USB_DEVICE(0x1d4d, 0x0011) },
@@ -1054,7 +1048,9 @@ static struct usb_device_id rt2800usb_device_table[] = {
1054 /* Sparklan */ 1048 /* Sparklan */
1055 { USB_DEVICE(0x15a9, 0x0006) }, 1049 { USB_DEVICE(0x15a9, 0x0006) },
1056 /* Sweex */ 1050 /* Sweex */
1051 { USB_DEVICE(0x177f, 0x0153) },
1057 { USB_DEVICE(0x177f, 0x0302) }, 1052 { USB_DEVICE(0x177f, 0x0302) },
1053 { USB_DEVICE(0x177f, 0x0313) },
1058 /* U-Media */ 1054 /* U-Media */
1059 { USB_DEVICE(0x157e, 0x300e) }, 1055 { USB_DEVICE(0x157e, 0x300e) },
1060 { USB_DEVICE(0x157e, 0x3013) }, 1056 { USB_DEVICE(0x157e, 0x3013) },
@@ -1138,25 +1134,20 @@ static struct usb_device_id rt2800usb_device_table[] = {
1138 { USB_DEVICE(0x13d3, 0x3322) }, 1134 { USB_DEVICE(0x13d3, 0x3322) },
1139 /* Belkin */ 1135 /* Belkin */
1140 { USB_DEVICE(0x050d, 0x1003) }, 1136 { USB_DEVICE(0x050d, 0x1003) },
1141 { USB_DEVICE(0x050d, 0x825a) },
1142 /* Buffalo */ 1137 /* Buffalo */
1143 { USB_DEVICE(0x0411, 0x012e) }, 1138 { USB_DEVICE(0x0411, 0x012e) },
1144 { USB_DEVICE(0x0411, 0x0148) }, 1139 { USB_DEVICE(0x0411, 0x0148) },
1145 { USB_DEVICE(0x0411, 0x0150) }, 1140 { USB_DEVICE(0x0411, 0x0150) },
1146 { USB_DEVICE(0x0411, 0x015d) },
1147 /* Corega */ 1141 /* Corega */
1148 { USB_DEVICE(0x07aa, 0x0041) }, 1142 { USB_DEVICE(0x07aa, 0x0041) },
1149 { USB_DEVICE(0x07aa, 0x0042) }, 1143 { USB_DEVICE(0x07aa, 0x0042) },
1150 { USB_DEVICE(0x18c5, 0x0008) }, 1144 { USB_DEVICE(0x18c5, 0x0008) },
1151 /* D-Link */ 1145 /* D-Link */
1152 { USB_DEVICE(0x07d1, 0x3c0b) }, 1146 { USB_DEVICE(0x07d1, 0x3c0b) },
1153 { USB_DEVICE(0x07d1, 0x3c13) },
1154 { USB_DEVICE(0x07d1, 0x3c15) },
1155 { USB_DEVICE(0x07d1, 0x3c17) }, 1147 { USB_DEVICE(0x07d1, 0x3c17) },
1156 { USB_DEVICE(0x2001, 0x3c17) }, 1148 { USB_DEVICE(0x2001, 0x3c17) },
1157 /* Edimax */ 1149 /* Edimax */
1158 { USB_DEVICE(0x7392, 0x4085) }, 1150 { USB_DEVICE(0x7392, 0x4085) },
1159 { USB_DEVICE(0x7392, 0x7722) },
1160 /* Encore */ 1151 /* Encore */
1161 { USB_DEVICE(0x203d, 0x14a1) }, 1152 { USB_DEVICE(0x203d, 0x14a1) },
1162 /* Fujitsu Stylistic 550 */ 1153 /* Fujitsu Stylistic 550 */
@@ -1172,20 +1163,13 @@ static struct usb_device_id rt2800usb_device_table[] = {
1172 /* LevelOne */ 1163 /* LevelOne */
1173 { USB_DEVICE(0x1740, 0x0605) }, 1164 { USB_DEVICE(0x1740, 0x0605) },
1174 { USB_DEVICE(0x1740, 0x0615) }, 1165 { USB_DEVICE(0x1740, 0x0615) },
1175 /* Linksys */
1176 { USB_DEVICE(0x1737, 0x0077) },
1177 { USB_DEVICE(0x1737, 0x0078) },
1178 /* Logitec */ 1166 /* Logitec */
1179 { USB_DEVICE(0x0789, 0x0168) }, 1167 { USB_DEVICE(0x0789, 0x0168) },
1180 { USB_DEVICE(0x0789, 0x0169) }, 1168 { USB_DEVICE(0x0789, 0x0169) },
1181 /* Motorola */ 1169 /* Motorola */
1182 { USB_DEVICE(0x100d, 0x9032) }, 1170 { USB_DEVICE(0x100d, 0x9032) },
1183 /* Ovislink */
1184 { USB_DEVICE(0x1b75, 0x3071) },
1185 { USB_DEVICE(0x1b75, 0x3072) },
1186 /* Pegatron */ 1171 /* Pegatron */
1187 { USB_DEVICE(0x05a6, 0x0101) }, 1172 { USB_DEVICE(0x05a6, 0x0101) },
1188 { USB_DEVICE(0x1d4d, 0x0002) },
1189 { USB_DEVICE(0x1d4d, 0x0010) }, 1173 { USB_DEVICE(0x1d4d, 0x0010) },
1190 /* Planex */ 1174 /* Planex */
1191 { USB_DEVICE(0x2019, 0x5201) }, 1175 { USB_DEVICE(0x2019, 0x5201) },
@@ -1204,9 +1188,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
1204 { USB_DEVICE(0x083a, 0xc522) }, 1188 { USB_DEVICE(0x083a, 0xc522) },
1205 { USB_DEVICE(0x083a, 0xd522) }, 1189 { USB_DEVICE(0x083a, 0xd522) },
1206 { USB_DEVICE(0x083a, 0xf511) }, 1190 { USB_DEVICE(0x083a, 0xf511) },
1207 /* Sweex */
1208 { USB_DEVICE(0x177f, 0x0153) },
1209 { USB_DEVICE(0x177f, 0x0313) },
1210 /* Zyxel */ 1191 /* Zyxel */
1211 { USB_DEVICE(0x0586, 0x341a) }, 1192 { USB_DEVICE(0x0586, 0x341a) },
1212#endif 1193#endif
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 99ff12d0c29d..b03b22c47b18 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -189,9 +189,9 @@ struct rt2x00_chip {
189#define RT3090 0x3090 /* 2.4GHz PCIe */ 189#define RT3090 0x3090 /* 2.4GHz PCIe */
190#define RT3390 0x3390 190#define RT3390 0x3390
191#define RT3572 0x3572 191#define RT3572 0x3572
192#define RT3593 0x3593 /* PCIe */ 192#define RT3593 0x3593
193#define RT3883 0x3883 /* WSOC */ 193#define RT3883 0x3883 /* WSOC */
194#define RT5390 0x5390 /* 2.4GHz */ 194#define RT5390 0x5390 /* 2.4GHz */
195 195
196 u16 rf; 196 u16 rf;
197 u16 rev; 197 u16 rev;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 1e31050dafc9..2eea3866504d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -298,12 +298,22 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data)
298 return false; 298 return false;
299 299
300 /* 300 /*
301 * USB devices cannot blindly pass the skb->len as the 301 * USB devices require certain padding at the end of each frame
302 * length of the data to usb_fill_bulk_urb. Pass the skb 302 * and urb. Those paddings are not included in skbs. Pass entry
303 * to the driver to determine what the length should be. 303 * to the driver to determine what the overall length should be.
304 */ 304 */
305 length = rt2x00dev->ops->lib->get_tx_data_len(entry); 305 length = rt2x00dev->ops->lib->get_tx_data_len(entry);
306 306
307 status = skb_padto(entry->skb, length);
308 if (unlikely(status)) {
309 /* TODO: report something more appropriate than IO_FAILED. */
310 WARNING(rt2x00dev, "TX SKB padding error, out of memory\n");
311 set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
312 rt2x00lib_dmadone(entry);
313
314 return false;
315 }
316
307 usb_fill_bulk_urb(entry_priv->urb, usb_dev, 317 usb_fill_bulk_urb(entry_priv->urb, usb_dev,
308 usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), 318 usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
309 entry->skb->data, length, 319 entry->skb->data, length,