diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-01-03 15:16:34 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-01-03 15:16:34 -0500 |
commit | 57adc1fcbae2c13104ce291b40f23e40a414fa87 (patch) | |
tree | a22d95cd3a96cbd515cd24fb0833739576c5e92f | |
parent | faa85aa24286a9e14ae7cc797352350c3ac39986 (diff) | |
parent | dc0d633e35643662f27a0b1c531da3cd6b204b9c (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
drivers/net/wireless/b43/dma.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
179 files changed, 7880 insertions, 6435 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ea5ad1cbbd3d..fbfba802a3d7 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -101,6 +101,7 @@ static struct usb_device_id btusb_table[] = { | |||
101 | { USB_DEVICE(0x0c10, 0x0000) }, | 101 | { USB_DEVICE(0x0c10, 0x0000) }, |
102 | 102 | ||
103 | /* Broadcom BCM20702A0 */ | 103 | /* Broadcom BCM20702A0 */ |
104 | { USB_DEVICE(0x0a5c, 0x21e3) }, | ||
104 | { USB_DEVICE(0x413c, 0x8197) }, | 105 | { USB_DEVICE(0x413c, 0x8197) }, |
105 | 106 | ||
106 | { } /* Terminating entry */ | 107 | { } /* Terminating entry */ |
@@ -508,15 +509,10 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) | |||
508 | 509 | ||
509 | pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); | 510 | pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); |
510 | 511 | ||
511 | urb->dev = data->udev; | 512 | usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete, |
512 | urb->pipe = pipe; | 513 | hdev, data->isoc_rx_ep->bInterval); |
513 | urb->context = hdev; | ||
514 | urb->complete = btusb_isoc_complete; | ||
515 | urb->interval = data->isoc_rx_ep->bInterval; | ||
516 | 514 | ||
517 | urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; | 515 | urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; |
518 | urb->transfer_buffer = buf; | ||
519 | urb->transfer_buffer_length = size; | ||
520 | 516 | ||
521 | __fill_isoc_descriptor(urb, size, | 517 | __fill_isoc_descriptor(urb, size, |
522 | le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); | 518 | le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); |
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index d1214696a35b..d716b748e574 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile | |||
@@ -11,3 +11,4 @@ ath-objs := main.o \ | |||
11 | key.o | 11 | key.o |
12 | 12 | ||
13 | ath-$(CONFIG_ATH_DEBUG) += debug.o | 13 | ath-$(CONFIG_ATH_DEBUG) += debug.o |
14 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index c1d699fd5717..efc01110dc34 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -255,7 +255,7 @@ enum ATH_DEBUG { | |||
255 | 255 | ||
256 | #define ath_dbg(common, dbg_mask, fmt, ...) \ | 256 | #define ath_dbg(common, dbg_mask, fmt, ...) \ |
257 | do { \ | 257 | do { \ |
258 | if ((common)->debug_mask & dbg_mask) \ | 258 | if ((common)->debug_mask & ATH_DBG_##dbg_mask) \ |
259 | _ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ | 259 | _ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ |
260 | } while (0) | 260 | } while (0) |
261 | 261 | ||
@@ -265,10 +265,13 @@ do { \ | |||
265 | #else | 265 | #else |
266 | 266 | ||
267 | static inline __attribute__ ((format (printf, 3, 4))) | 267 | static inline __attribute__ ((format (printf, 3, 4))) |
268 | void ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask, | 268 | void _ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask, |
269 | const char *fmt, ...) | 269 | const char *fmt, ...) |
270 | { | 270 | { |
271 | } | 271 | } |
272 | #define ath_dbg(common, dbg_mask, fmt, ...) \ | ||
273 | _ath_dbg(common, ATH_DBG_##dbg_mask, fmt, ##__VA_ARGS__) | ||
274 | |||
272 | #define ATH_DBG_WARN(foo, arg...) do {} while (0) | 275 | #define ATH_DBG_WARN(foo, arg...) do {} while (0) |
273 | #define ATH_DBG_WARN_ON_ONCE(foo) ({ \ | 276 | #define ATH_DBG_WARN_ON_ONCE(foo) ({ \ |
274 | int __ret_warn_once = !!(foo); \ | 277 | int __ret_warn_once = !!(foo); \ |
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index 3d5f8be20eac..d755a5e7ed20 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig | |||
@@ -1,12 +1,29 @@ | |||
1 | config ATH6KL | 1 | config ATH6KL |
2 | tristate "Atheros ath6kl support" | 2 | tristate "Atheros mobile chipsets support" |
3 | |||
4 | config ATH6KL_SDIO | ||
5 | tristate "Atheros ath6kl SDIO support" | ||
6 | depends on ATH6KL | ||
3 | depends on MMC | 7 | depends on MMC |
4 | depends on CFG80211 | 8 | depends on CFG80211 |
5 | ---help--- | 9 | ---help--- |
6 | This module adds support for wireless adapters based on | 10 | This module adds support for wireless adapters based on |
7 | Atheros AR6003 chipset running over SDIO. If you choose to | 11 | Atheros AR6003 and AR6004 chipsets running over SDIO. If you |
8 | build it as a module, it will be called ath6kl. Pls note | 12 | choose to build it as a module, it will be called ath6kl_sdio. |
9 | that AR6002 and AR6001 are not supported by this driver. | 13 | Please note that AR6002 and AR6001 are not supported by this |
14 | driver. | ||
15 | |||
16 | config 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. | ||
10 | 27 | ||
11 | config ATH6KL_DEBUG | 28 | config ATH6KL_DEBUG |
12 | bool "Atheros ath6kl debugging" | 29 | bool "Atheros ath6kl debugging" |
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 707069303550..e14cef9c3c0e 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile | |||
@@ -21,17 +21,30 @@ | |||
21 | # Author(s): ="Atheros" | 21 | # Author(s): ="Atheros" |
22 | #------------------------------------------------------------------------------ | 22 | #------------------------------------------------------------------------------ |
23 | 23 | ||
24 | obj-$(CONFIG_ATH6KL) := ath6kl.o | 24 | obj-$(CONFIG_ATH6KL_SDIO) := ath6kl_sdio.o |
25 | ath6kl-y += debug.o | 25 | ath6kl_sdio-y += debug.o |
26 | ath6kl-y += hif.o | 26 | ath6kl_sdio-y += hif.o |
27 | ath6kl-y += htc.o | 27 | ath6kl_sdio-y += htc.o |
28 | ath6kl-y += bmi.o | 28 | ath6kl_sdio-y += bmi.o |
29 | ath6kl-y += cfg80211.o | 29 | ath6kl_sdio-y += cfg80211.o |
30 | ath6kl-y += init.o | 30 | ath6kl_sdio-y += init.o |
31 | ath6kl-y += main.o | 31 | ath6kl_sdio-y += main.o |
32 | ath6kl-y += txrx.o | 32 | ath6kl_sdio-y += txrx.o |
33 | ath6kl-y += wmi.o | 33 | ath6kl_sdio-y += wmi.o |
34 | ath6kl-y += sdio.o | 34 | ath6kl_sdio-y += sdio.o |
35 | ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o | 35 | ath6kl_sdio-$(CONFIG_NL80211_TESTMODE) += testmode.o |
36 | |||
37 | obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o | ||
38 | ath6kl_usb-y += debug.o | ||
39 | ath6kl_usb-y += hif.o | ||
40 | ath6kl_usb-y += htc.o | ||
41 | ath6kl_usb-y += bmi.o | ||
42 | ath6kl_usb-y += cfg80211.o | ||
43 | ath6kl_usb-y += init.o | ||
44 | ath6kl_usb-y += main.o | ||
45 | ath6kl_usb-y += txrx.o | ||
46 | ath6kl_usb-y += wmi.o | ||
47 | ath6kl_usb-y += usb.o | ||
48 | ath6kl_usb-$(CONFIG_NL80211_TESTMODE) += testmode.o | ||
36 | 49 | ||
37 | ccflags-y += -D__CHECK_ENDIAN__ | 50 | ccflags-y += -D__CHECK_ENDIAN__ |
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index a962fe4c6b7e..aef00d5a1438 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c | |||
@@ -19,165 +19,6 @@ | |||
19 | #include "target.h" | 19 | #include "target.h" |
20 | #include "debug.h" | 20 | #include "debug.h" |
21 | 21 | ||
22 | static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar) | ||
23 | { | ||
24 | u32 addr; | ||
25 | unsigned long timeout; | ||
26 | int ret; | ||
27 | |||
28 | ar->bmi.cmd_credits = 0; | ||
29 | |||
30 | /* Read the counter register to get the command credits */ | ||
31 | addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4; | ||
32 | |||
33 | timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT); | ||
34 | while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) { | ||
35 | |||
36 | /* | ||
37 | * Hit the credit counter with a 4-byte access, the first byte | ||
38 | * read will hit the counter and cause a decrement, while the | ||
39 | * remaining 3 bytes has no effect. The rationale behind this | ||
40 | * is to make all HIF accesses 4-byte aligned. | ||
41 | */ | ||
42 | ret = hif_read_write_sync(ar, addr, | ||
43 | (u8 *)&ar->bmi.cmd_credits, 4, | ||
44 | HIF_RD_SYNC_BYTE_INC); | ||
45 | if (ret) { | ||
46 | ath6kl_err("Unable to decrement the command credit count register: %d\n", | ||
47 | ret); | ||
48 | return ret; | ||
49 | } | ||
50 | |||
51 | /* The counter is only 8 bits. | ||
52 | * Ignore anything in the upper 3 bytes | ||
53 | */ | ||
54 | ar->bmi.cmd_credits &= 0xFF; | ||
55 | } | ||
56 | |||
57 | if (!ar->bmi.cmd_credits) { | ||
58 | ath6kl_err("bmi communication timeout\n"); | ||
59 | return -ETIMEDOUT; | ||
60 | } | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar) | ||
66 | { | ||
67 | unsigned long timeout; | ||
68 | u32 rx_word = 0; | ||
69 | int ret = 0; | ||
70 | |||
71 | timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT); | ||
72 | while (time_before(jiffies, timeout) && !rx_word) { | ||
73 | ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS, | ||
74 | (u8 *)&rx_word, sizeof(rx_word), | ||
75 | HIF_RD_SYNC_BYTE_INC); | ||
76 | if (ret) { | ||
77 | ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n"); | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | /* all we really want is one bit */ | ||
82 | rx_word &= (1 << ENDPOINT1); | ||
83 | } | ||
84 | |||
85 | if (!rx_word) { | ||
86 | ath6kl_err("bmi_recv_buf FIFO empty\n"); | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len) | ||
94 | { | ||
95 | int ret; | ||
96 | u32 addr; | ||
97 | |||
98 | ret = ath6kl_get_bmi_cmd_credits(ar); | ||
99 | if (ret) | ||
100 | return ret; | ||
101 | |||
102 | addr = ar->mbox_info.htc_addr; | ||
103 | |||
104 | ret = hif_read_write_sync(ar, addr, buf, len, | ||
105 | HIF_WR_SYNC_BYTE_INC); | ||
106 | if (ret) | ||
107 | ath6kl_err("unable to send the bmi data to the device\n"); | ||
108 | |||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static int ath6kl_bmi_recv_buf(struct ath6kl *ar, u8 *buf, u32 len) | ||
113 | { | ||
114 | int ret; | ||
115 | u32 addr; | ||
116 | |||
117 | /* | ||
118 | * During normal bootup, small reads may be required. | ||
119 | * Rather than issue an HIF Read and then wait as the Target | ||
120 | * adds successive bytes to the FIFO, we wait here until | ||
121 | * we know that response data is available. | ||
122 | * | ||
123 | * This allows us to cleanly timeout on an unexpected | ||
124 | * Target failure rather than risk problems at the HIF level. | ||
125 | * In particular, this avoids SDIO timeouts and possibly garbage | ||
126 | * data on some host controllers. And on an interconnect | ||
127 | * such as Compact Flash (as well as some SDIO masters) which | ||
128 | * does not provide any indication on data timeout, it avoids | ||
129 | * a potential hang or garbage response. | ||
130 | * | ||
131 | * Synchronization is more difficult for reads larger than the | ||
132 | * size of the MBOX FIFO (128B), because the Target is unable | ||
133 | * to push the 129th byte of data until AFTER the Host posts an | ||
134 | * HIF Read and removes some FIFO data. So for large reads the | ||
135 | * Host proceeds to post an HIF Read BEFORE all the data is | ||
136 | * actually available to read. Fortunately, large BMI reads do | ||
137 | * not occur in practice -- they're supported for debug/development. | ||
138 | * | ||
139 | * So Host/Target BMI synchronization is divided into these cases: | ||
140 | * CASE 1: length < 4 | ||
141 | * Should not happen | ||
142 | * | ||
143 | * CASE 2: 4 <= length <= 128 | ||
144 | * Wait for first 4 bytes to be in FIFO | ||
145 | * If CONSERVATIVE_BMI_READ is enabled, also wait for | ||
146 | * a BMI command credit, which indicates that the ENTIRE | ||
147 | * response is available in the the FIFO | ||
148 | * | ||
149 | * CASE 3: length > 128 | ||
150 | * Wait for the first 4 bytes to be in FIFO | ||
151 | * | ||
152 | * For most uses, a small timeout should be sufficient and we will | ||
153 | * usually see a response quickly; but there may be some unusual | ||
154 | * (debug) cases of BMI_EXECUTE where we want an larger timeout. | ||
155 | * For now, we use an unbounded busy loop while waiting for | ||
156 | * BMI_EXECUTE. | ||
157 | * | ||
158 | * If BMI_EXECUTE ever needs to support longer-latency execution, | ||
159 | * especially in production, this code needs to be enhanced to sleep | ||
160 | * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently | ||
161 | * a function of Host processor speed. | ||
162 | */ | ||
163 | if (len >= 4) { /* NB: Currently, always true */ | ||
164 | ret = ath6kl_bmi_get_rx_lkahd(ar); | ||
165 | if (ret) | ||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | addr = ar->mbox_info.htc_addr; | ||
170 | ret = hif_read_write_sync(ar, addr, buf, len, | ||
171 | HIF_RD_SYNC_BYTE_INC); | ||
172 | if (ret) { | ||
173 | ath6kl_err("Unable to read the bmi data from the device: %d\n", | ||
174 | ret); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | int ath6kl_bmi_done(struct ath6kl *ar) | 22 | int ath6kl_bmi_done(struct ath6kl *ar) |
182 | { | 23 | { |
183 | int ret; | 24 | int ret; |
@@ -190,7 +31,7 @@ int ath6kl_bmi_done(struct ath6kl *ar) | |||
190 | 31 | ||
191 | ar->bmi.done_sent = true; | 32 | ar->bmi.done_sent = true; |
192 | 33 | ||
193 | ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid)); | 34 | ret = ath6kl_hif_bmi_write(ar, (u8 *)&cid, sizeof(cid)); |
194 | if (ret) { | 35 | if (ret) { |
195 | ath6kl_err("Unable to send bmi done: %d\n", ret); | 36 | ath6kl_err("Unable to send bmi done: %d\n", ret); |
196 | return ret; | 37 | return ret; |
@@ -210,14 +51,20 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, | |||
210 | return -EACCES; | 51 | return -EACCES; |
211 | } | 52 | } |
212 | 53 | ||
213 | ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid)); | 54 | ret = ath6kl_hif_bmi_write(ar, (u8 *)&cid, sizeof(cid)); |
214 | if (ret) { | 55 | if (ret) { |
215 | ath6kl_err("Unable to send get target info: %d\n", ret); | 56 | ath6kl_err("Unable to send get target info: %d\n", ret); |
216 | return ret; | 57 | return ret; |
217 | } | 58 | } |
218 | 59 | ||
219 | ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version, | 60 | if (ar->hif_type == ATH6KL_HIF_TYPE_USB) { |
220 | sizeof(targ_info->version)); | 61 | ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info, |
62 | sizeof(*targ_info)); | ||
63 | } else { | ||
64 | ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, | ||
65 | sizeof(targ_info->version)); | ||
66 | } | ||
67 | |||
221 | if (ret) { | 68 | if (ret) { |
222 | ath6kl_err("Unable to recv target info: %d\n", ret); | 69 | ath6kl_err("Unable to recv target info: %d\n", ret); |
223 | return ret; | 70 | return ret; |
@@ -225,7 +72,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, | |||
225 | 72 | ||
226 | if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) { | 73 | if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) { |
227 | /* Determine how many bytes are in the Target's targ_info */ | 74 | /* Determine how many bytes are in the Target's targ_info */ |
228 | ret = ath6kl_bmi_recv_buf(ar, | 75 | ret = ath6kl_hif_bmi_read(ar, |
229 | (u8 *)&targ_info->byte_count, | 76 | (u8 *)&targ_info->byte_count, |
230 | sizeof(targ_info->byte_count)); | 77 | sizeof(targ_info->byte_count)); |
231 | if (ret) { | 78 | if (ret) { |
@@ -244,7 +91,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, | |||
244 | } | 91 | } |
245 | 92 | ||
246 | /* Read the remainder of the targ_info */ | 93 | /* Read the remainder of the targ_info */ |
247 | ret = ath6kl_bmi_recv_buf(ar, | 94 | ret = ath6kl_hif_bmi_read(ar, |
248 | ((u8 *)targ_info) + | 95 | ((u8 *)targ_info) + |
249 | sizeof(targ_info->byte_count), | 96 | sizeof(targ_info->byte_count), |
250 | sizeof(*targ_info) - | 97 | sizeof(*targ_info) - |
@@ -276,8 +123,8 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
276 | return -EACCES; | 123 | return -EACCES; |
277 | } | 124 | } |
278 | 125 | ||
279 | size = BMI_DATASZ_MAX + sizeof(cid) + sizeof(addr) + sizeof(len); | 126 | size = ar->bmi.max_data_size + sizeof(cid) + sizeof(addr) + sizeof(len); |
280 | if (size > MAX_BMI_CMDBUF_SZ) { | 127 | if (size > ar->bmi.max_cmd_size) { |
281 | WARN_ON(1); | 128 | WARN_ON(1); |
282 | return -EINVAL; | 129 | return -EINVAL; |
283 | } | 130 | } |
@@ -290,8 +137,8 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
290 | len_remain = len; | 137 | len_remain = len; |
291 | 138 | ||
292 | while (len_remain) { | 139 | while (len_remain) { |
293 | rx_len = (len_remain < BMI_DATASZ_MAX) ? | 140 | rx_len = (len_remain < ar->bmi.max_data_size) ? |
294 | len_remain : BMI_DATASZ_MAX; | 141 | len_remain : ar->bmi.max_data_size; |
295 | offset = 0; | 142 | offset = 0; |
296 | memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid)); | 143 | memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid)); |
297 | offset += sizeof(cid); | 144 | offset += sizeof(cid); |
@@ -300,13 +147,13 @@ int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
300 | memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len)); | 147 | memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len)); |
301 | offset += sizeof(len); | 148 | offset += sizeof(len); |
302 | 149 | ||
303 | ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); | 150 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
304 | if (ret) { | 151 | if (ret) { |
305 | ath6kl_err("Unable to write to the device: %d\n", | 152 | ath6kl_err("Unable to write to the device: %d\n", |
306 | ret); | 153 | ret); |
307 | return ret; | 154 | return ret; |
308 | } | 155 | } |
309 | ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len); | 156 | ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, rx_len); |
310 | if (ret) { | 157 | if (ret) { |
311 | ath6kl_err("Unable to read from the device: %d\n", | 158 | ath6kl_err("Unable to read from the device: %d\n", |
312 | ret); | 159 | ret); |
@@ -326,7 +173,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
326 | u32 offset; | 173 | u32 offset; |
327 | u32 len_remain, tx_len; | 174 | u32 len_remain, tx_len; |
328 | const u32 header = sizeof(cid) + sizeof(addr) + sizeof(len); | 175 | const u32 header = sizeof(cid) + sizeof(addr) + sizeof(len); |
329 | u8 aligned_buf[BMI_DATASZ_MAX]; | 176 | u8 aligned_buf[400]; |
330 | u8 *src; | 177 | u8 *src; |
331 | 178 | ||
332 | if (ar->bmi.done_sent) { | 179 | if (ar->bmi.done_sent) { |
@@ -334,12 +181,15 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
334 | return -EACCES; | 181 | return -EACCES; |
335 | } | 182 | } |
336 | 183 | ||
337 | if ((BMI_DATASZ_MAX + header) > MAX_BMI_CMDBUF_SZ) { | 184 | if ((ar->bmi.max_data_size + header) > ar->bmi.max_cmd_size) { |
338 | WARN_ON(1); | 185 | WARN_ON(1); |
339 | return -EINVAL; | 186 | return -EINVAL; |
340 | } | 187 | } |
341 | 188 | ||
342 | memset(ar->bmi.cmd_buf, 0, BMI_DATASZ_MAX + header); | 189 | if (WARN_ON(ar->bmi.max_data_size > sizeof(aligned_buf))) |
190 | return -E2BIG; | ||
191 | |||
192 | memset(ar->bmi.cmd_buf, 0, ar->bmi.max_data_size + header); | ||
343 | 193 | ||
344 | ath6kl_dbg(ATH6KL_DBG_BMI, | 194 | ath6kl_dbg(ATH6KL_DBG_BMI, |
345 | "bmi write memory: addr: 0x%x, len: %d\n", addr, len); | 195 | "bmi write memory: addr: 0x%x, len: %d\n", addr, len); |
@@ -348,7 +198,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
348 | while (len_remain) { | 198 | while (len_remain) { |
349 | src = &buf[len - len_remain]; | 199 | src = &buf[len - len_remain]; |
350 | 200 | ||
351 | if (len_remain < (BMI_DATASZ_MAX - header)) { | 201 | if (len_remain < (ar->bmi.max_data_size - header)) { |
352 | if (len_remain & 3) { | 202 | if (len_remain & 3) { |
353 | /* align it with 4 bytes */ | 203 | /* align it with 4 bytes */ |
354 | len_remain = len_remain + | 204 | len_remain = len_remain + |
@@ -358,7 +208,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
358 | } | 208 | } |
359 | tx_len = len_remain; | 209 | tx_len = len_remain; |
360 | } else { | 210 | } else { |
361 | tx_len = (BMI_DATASZ_MAX - header); | 211 | tx_len = (ar->bmi.max_data_size - header); |
362 | } | 212 | } |
363 | 213 | ||
364 | offset = 0; | 214 | offset = 0; |
@@ -371,7 +221,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) | |||
371 | memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len); | 221 | memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len); |
372 | offset += tx_len; | 222 | offset += tx_len; |
373 | 223 | ||
374 | ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); | 224 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
375 | if (ret) { | 225 | if (ret) { |
376 | ath6kl_err("Unable to write to the device: %d\n", | 226 | ath6kl_err("Unable to write to the device: %d\n", |
377 | ret); | 227 | ret); |
@@ -396,7 +246,7 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param) | |||
396 | } | 246 | } |
397 | 247 | ||
398 | size = sizeof(cid) + sizeof(addr) + sizeof(param); | 248 | size = sizeof(cid) + sizeof(addr) + sizeof(param); |
399 | if (size > MAX_BMI_CMDBUF_SZ) { | 249 | if (size > ar->bmi.max_cmd_size) { |
400 | WARN_ON(1); | 250 | WARN_ON(1); |
401 | return -EINVAL; | 251 | return -EINVAL; |
402 | } | 252 | } |
@@ -413,13 +263,13 @@ int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param) | |||
413 | memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param)); | 263 | memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param)); |
414 | offset += sizeof(*param); | 264 | offset += sizeof(*param); |
415 | 265 | ||
416 | ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); | 266 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
417 | if (ret) { | 267 | if (ret) { |
418 | ath6kl_err("Unable to write to the device: %d\n", ret); | 268 | ath6kl_err("Unable to write to the device: %d\n", ret); |
419 | return ret; | 269 | return ret; |
420 | } | 270 | } |
421 | 271 | ||
422 | ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param)); | 272 | ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, sizeof(*param)); |
423 | if (ret) { | 273 | if (ret) { |
424 | ath6kl_err("Unable to read from the device: %d\n", ret); | 274 | ath6kl_err("Unable to read from the device: %d\n", ret); |
425 | return ret; | 275 | return ret; |
@@ -443,7 +293,7 @@ int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr) | |||
443 | } | 293 | } |
444 | 294 | ||
445 | size = sizeof(cid) + sizeof(addr); | 295 | size = sizeof(cid) + sizeof(addr); |
446 | if (size > MAX_BMI_CMDBUF_SZ) { | 296 | if (size > ar->bmi.max_cmd_size) { |
447 | WARN_ON(1); | 297 | WARN_ON(1); |
448 | return -EINVAL; | 298 | return -EINVAL; |
449 | } | 299 | } |
@@ -457,7 +307,7 @@ int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr) | |||
457 | memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); | 307 | memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); |
458 | offset += sizeof(addr); | 308 | offset += sizeof(addr); |
459 | 309 | ||
460 | ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); | 310 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
461 | if (ret) { | 311 | if (ret) { |
462 | ath6kl_err("Unable to write to the device: %d\n", ret); | 312 | ath6kl_err("Unable to write to the device: %d\n", ret); |
463 | return ret; | 313 | return ret; |
@@ -479,7 +329,7 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param) | |||
479 | } | 329 | } |
480 | 330 | ||
481 | size = sizeof(cid) + sizeof(addr); | 331 | size = sizeof(cid) + sizeof(addr); |
482 | if (size > MAX_BMI_CMDBUF_SZ) { | 332 | if (size > ar->bmi.max_cmd_size) { |
483 | WARN_ON(1); | 333 | WARN_ON(1); |
484 | return -EINVAL; | 334 | return -EINVAL; |
485 | } | 335 | } |
@@ -493,13 +343,13 @@ int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param) | |||
493 | memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); | 343 | memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); |
494 | offset += sizeof(addr); | 344 | offset += sizeof(addr); |
495 | 345 | ||
496 | ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); | 346 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
497 | if (ret) { | 347 | if (ret) { |
498 | ath6kl_err("Unable to write to the device: %d\n", ret); | 348 | ath6kl_err("Unable to write to the device: %d\n", ret); |
499 | return ret; | 349 | return ret; |
500 | } | 350 | } |
501 | 351 | ||
502 | ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param)); | 352 | ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, sizeof(*param)); |
503 | if (ret) { | 353 | if (ret) { |
504 | ath6kl_err("Unable to read from the device: %d\n", ret); | 354 | ath6kl_err("Unable to read from the device: %d\n", ret); |
505 | return ret; | 355 | return ret; |
@@ -522,7 +372,7 @@ int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param) | |||
522 | } | 372 | } |
523 | 373 | ||
524 | size = sizeof(cid) + sizeof(addr) + sizeof(param); | 374 | size = sizeof(cid) + sizeof(addr) + sizeof(param); |
525 | if (size > MAX_BMI_CMDBUF_SZ) { | 375 | if (size > ar->bmi.max_cmd_size) { |
526 | WARN_ON(1); | 376 | WARN_ON(1); |
527 | return -EINVAL; | 377 | return -EINVAL; |
528 | } | 378 | } |
@@ -540,7 +390,7 @@ int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param) | |||
540 | memcpy(&(ar->bmi.cmd_buf[offset]), ¶m, sizeof(param)); | 390 | memcpy(&(ar->bmi.cmd_buf[offset]), ¶m, sizeof(param)); |
541 | offset += sizeof(param); | 391 | offset += sizeof(param); |
542 | 392 | ||
543 | ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); | 393 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
544 | if (ret) { | 394 | if (ret) { |
545 | ath6kl_err("Unable to write to the device: %d\n", ret); | 395 | ath6kl_err("Unable to write to the device: %d\n", ret); |
546 | return ret; | 396 | return ret; |
@@ -563,8 +413,8 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len) | |||
563 | return -EACCES; | 413 | return -EACCES; |
564 | } | 414 | } |
565 | 415 | ||
566 | size = BMI_DATASZ_MAX + header; | 416 | size = ar->bmi.max_data_size + header; |
567 | if (size > MAX_BMI_CMDBUF_SZ) { | 417 | if (size > ar->bmi.max_cmd_size) { |
568 | WARN_ON(1); | 418 | WARN_ON(1); |
569 | return -EINVAL; | 419 | return -EINVAL; |
570 | } | 420 | } |
@@ -575,8 +425,8 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len) | |||
575 | 425 | ||
576 | len_remain = len; | 426 | len_remain = len; |
577 | while (len_remain) { | 427 | while (len_remain) { |
578 | tx_len = (len_remain < (BMI_DATASZ_MAX - header)) ? | 428 | tx_len = (len_remain < (ar->bmi.max_data_size - header)) ? |
579 | len_remain : (BMI_DATASZ_MAX - header); | 429 | len_remain : (ar->bmi.max_data_size - header); |
580 | 430 | ||
581 | offset = 0; | 431 | offset = 0; |
582 | memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid)); | 432 | memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid)); |
@@ -587,7 +437,7 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len) | |||
587 | tx_len); | 437 | tx_len); |
588 | offset += tx_len; | 438 | offset += tx_len; |
589 | 439 | ||
590 | ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); | 440 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
591 | if (ret) { | 441 | if (ret) { |
592 | ath6kl_err("Unable to write to the device: %d\n", | 442 | ath6kl_err("Unable to write to the device: %d\n", |
593 | ret); | 443 | ret); |
@@ -613,7 +463,7 @@ int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr) | |||
613 | } | 463 | } |
614 | 464 | ||
615 | size = sizeof(cid) + sizeof(addr); | 465 | size = sizeof(cid) + sizeof(addr); |
616 | if (size > MAX_BMI_CMDBUF_SZ) { | 466 | if (size > ar->bmi.max_cmd_size) { |
617 | WARN_ON(1); | 467 | WARN_ON(1); |
618 | return -EINVAL; | 468 | return -EINVAL; |
619 | } | 469 | } |
@@ -629,7 +479,7 @@ int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr) | |||
629 | memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); | 479 | memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr)); |
630 | offset += sizeof(addr); | 480 | offset += sizeof(addr); |
631 | 481 | ||
632 | ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset); | 482 | ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); |
633 | if (ret) { | 483 | if (ret) { |
634 | ath6kl_err("Unable to start LZ stream to the device: %d\n", | 484 | ath6kl_err("Unable to start LZ stream to the device: %d\n", |
635 | ret); | 485 | ret); |
@@ -677,8 +527,13 @@ void ath6kl_bmi_reset(struct ath6kl *ar) | |||
677 | 527 | ||
678 | int ath6kl_bmi_init(struct ath6kl *ar) | 528 | int ath6kl_bmi_init(struct ath6kl *ar) |
679 | { | 529 | { |
680 | ar->bmi.cmd_buf = kzalloc(MAX_BMI_CMDBUF_SZ, GFP_ATOMIC); | 530 | if (WARN_ON(ar->bmi.max_data_size == 0)) |
531 | return -EINVAL; | ||
532 | |||
533 | /* cmd + addr + len + data_size */ | ||
534 | ar->bmi.max_cmd_size = ar->bmi.max_data_size + (sizeof(u32) * 3); | ||
681 | 535 | ||
536 | ar->bmi.cmd_buf = kzalloc(ar->bmi.max_cmd_size, GFP_ATOMIC); | ||
682 | if (!ar->bmi.cmd_buf) | 537 | if (!ar->bmi.cmd_buf) |
683 | return -ENOMEM; | 538 | return -ENOMEM; |
684 | 539 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h index 009e8f650ab1..f1ca6812456d 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.h +++ b/drivers/net/wireless/ath/ath6kl/bmi.h | |||
@@ -44,12 +44,6 @@ | |||
44 | * BMI handles all required Target-side cache flushing. | 44 | * BMI handles all required Target-side cache flushing. |
45 | */ | 45 | */ |
46 | 46 | ||
47 | #define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \ | ||
48 | (sizeof(u32) * 3 /* cmd + addr + len */)) | ||
49 | |||
50 | /* Maximum data size used for BMI transfers */ | ||
51 | #define BMI_DATASZ_MAX 256 | ||
52 | |||
53 | /* BMI Commands */ | 47 | /* BMI Commands */ |
54 | 48 | ||
55 | #define BMI_NO_COMMAND 0 | 49 | #define BMI_NO_COMMAND 0 |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 02526044acb9..6c59a217b1a1 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -23,10 +23,8 @@ | |||
23 | #include "testmode.h" | 23 | #include "testmode.h" |
24 | 24 | ||
25 | static unsigned int ath6kl_p2p; | 25 | static unsigned int ath6kl_p2p; |
26 | static unsigned int multi_norm_if_support; | ||
27 | 26 | ||
28 | module_param(ath6kl_p2p, uint, 0644); | 27 | module_param(ath6kl_p2p, uint, 0644); |
29 | module_param(multi_norm_if_support, uint, 0644); | ||
30 | 28 | ||
31 | #define RATETAB_ENT(_rate, _rateid, _flags) { \ | 29 | #define RATETAB_ENT(_rate, _rateid, _flags) { \ |
32 | .bitrate = (_rate), \ | 30 | .bitrate = (_rate), \ |
@@ -127,6 +125,37 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = { | |||
127 | 125 | ||
128 | #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */ | 126 | #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */ |
129 | 127 | ||
128 | /* returns true if scheduled scan was stopped */ | ||
129 | static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif) | ||
130 | { | ||
131 | struct ath6kl *ar = vif->ar; | ||
132 | |||
133 | if (ar->state != ATH6KL_STATE_SCHED_SCAN) | ||
134 | return false; | ||
135 | |||
136 | del_timer_sync(&vif->sched_scan_timer); | ||
137 | |||
138 | ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | ||
139 | ATH6KL_HOST_MODE_AWAKE); | ||
140 | |||
141 | ar->state = ATH6KL_STATE_ON; | ||
142 | |||
143 | return true; | ||
144 | } | ||
145 | |||
146 | static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif) | ||
147 | { | ||
148 | struct ath6kl *ar = vif->ar; | ||
149 | bool stopped; | ||
150 | |||
151 | stopped = __ath6kl_cfg80211_sscan_stop(vif); | ||
152 | |||
153 | if (!stopped) | ||
154 | return; | ||
155 | |||
156 | cfg80211_sched_scan_stopped(ar->wiphy); | ||
157 | } | ||
158 | |||
130 | static int ath6kl_set_wpa_version(struct ath6kl_vif *vif, | 159 | static int ath6kl_set_wpa_version(struct ath6kl_vif *vif, |
131 | enum nl80211_wpa_versions wpa_version) | 160 | enum nl80211_wpa_versions wpa_version) |
132 | { | 161 | { |
@@ -205,6 +234,10 @@ static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast) | |||
205 | *ar_cipher = AES_CRYPT; | 234 | *ar_cipher = AES_CRYPT; |
206 | *ar_cipher_len = 0; | 235 | *ar_cipher_len = 0; |
207 | break; | 236 | break; |
237 | case WLAN_CIPHER_SUITE_SMS4: | ||
238 | *ar_cipher = WAPI_CRYPT; | ||
239 | *ar_cipher_len = 0; | ||
240 | break; | ||
208 | default: | 241 | default: |
209 | ath6kl_err("cipher 0x%x not supported\n", cipher); | 242 | ath6kl_err("cipher 0x%x not supported\n", cipher); |
210 | return -ENOTSUPP; | 243 | return -ENOTSUPP; |
@@ -355,7 +388,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, | |||
355 | 388 | ||
356 | if (type == NL80211_IFTYPE_STATION || | 389 | if (type == NL80211_IFTYPE_STATION || |
357 | type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) { | 390 | type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) { |
358 | for (i = 0; i < MAX_NUM_VIF; i++) { | 391 | for (i = 0; i < ar->vif_max; i++) { |
359 | if ((ar->avail_idx_map >> i) & BIT(0)) { | 392 | if ((ar->avail_idx_map >> i) & BIT(0)) { |
360 | *if_idx = i; | 393 | *if_idx = i; |
361 | return true; | 394 | return true; |
@@ -365,7 +398,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, | |||
365 | 398 | ||
366 | if (type == NL80211_IFTYPE_P2P_CLIENT || | 399 | if (type == NL80211_IFTYPE_P2P_CLIENT || |
367 | type == NL80211_IFTYPE_P2P_GO) { | 400 | type == NL80211_IFTYPE_P2P_GO) { |
368 | for (i = ar->max_norm_iface; i < MAX_NUM_VIF; i++) { | 401 | for (i = ar->max_norm_iface; i < ar->vif_max; i++) { |
369 | if ((ar->avail_idx_map >> i) & BIT(0)) { | 402 | if ((ar->avail_idx_map >> i) & BIT(0)) { |
370 | *if_idx = i; | 403 | *if_idx = i; |
371 | return true; | 404 | return true; |
@@ -382,6 +415,9 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
382 | struct ath6kl *ar = ath6kl_priv(dev); | 415 | struct ath6kl *ar = ath6kl_priv(dev); |
383 | struct ath6kl_vif *vif = netdev_priv(dev); | 416 | struct ath6kl_vif *vif = netdev_priv(dev); |
384 | int status; | 417 | int status; |
418 | u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE; | ||
419 | |||
420 | ath6kl_cfg80211_sscan_disable(vif); | ||
385 | 421 | ||
386 | vif->sme_state = SME_CONNECTING; | 422 | vif->sme_state = SME_CONNECTING; |
387 | 423 | ||
@@ -427,9 +463,12 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
427 | 463 | ||
428 | if (sme->ie && (sme->ie_len > 0)) { | 464 | if (sme->ie && (sme->ie_len > 0)) { |
429 | status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); | 465 | status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); |
430 | if (status) | 466 | if (status) { |
467 | up(&ar->sem); | ||
431 | return status; | 468 | return status; |
432 | } | 469 | } |
470 | } else | ||
471 | ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG; | ||
433 | 472 | ||
434 | if (test_bit(CONNECTED, &vif->flags) && | 473 | if (test_bit(CONNECTED, &vif->flags) && |
435 | vif->ssid_len == sme->ssid_len && | 474 | vif->ssid_len == sme->ssid_len && |
@@ -519,6 +558,9 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
519 | 558 | ||
520 | vif->nw_type = vif->next_mode; | 559 | vif->nw_type = vif->next_mode; |
521 | 560 | ||
561 | if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) | ||
562 | nw_subtype = SUBTYPE_P2PCLIENT; | ||
563 | |||
522 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, | 564 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
523 | "%s: connect called with authmode %d dot11 auth %d" | 565 | "%s: connect called with authmode %d dot11 auth %d" |
524 | " PW crypto %d PW crypto len %d GRP crypto %d" | 566 | " PW crypto %d PW crypto len %d GRP crypto %d" |
@@ -536,7 +578,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
536 | vif->grp_crypto, vif->grp_crypto_len, | 578 | vif->grp_crypto, vif->grp_crypto_len, |
537 | vif->ssid_len, vif->ssid, | 579 | vif->ssid_len, vif->ssid, |
538 | vif->req_bssid, vif->ch_hint, | 580 | vif->req_bssid, vif->ch_hint, |
539 | ar->connect_ctrl_flags); | 581 | ar->connect_ctrl_flags, nw_subtype); |
540 | 582 | ||
541 | up(&ar->sem); | 583 | up(&ar->sem); |
542 | 584 | ||
@@ -563,17 +605,28 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, | |||
563 | return 0; | 605 | return 0; |
564 | } | 606 | } |
565 | 607 | ||
566 | static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, const u8 *bssid, | 608 | static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, |
609 | enum network_type nw_type, | ||
610 | const u8 *bssid, | ||
567 | struct ieee80211_channel *chan, | 611 | struct ieee80211_channel *chan, |
568 | const u8 *beacon_ie, size_t beacon_ie_len) | 612 | const u8 *beacon_ie, size_t beacon_ie_len) |
569 | { | 613 | { |
570 | struct ath6kl *ar = vif->ar; | 614 | struct ath6kl *ar = vif->ar; |
571 | struct cfg80211_bss *bss; | 615 | struct cfg80211_bss *bss; |
616 | u16 cap_mask, cap_val; | ||
572 | u8 *ie; | 617 | u8 *ie; |
573 | 618 | ||
619 | if (nw_type & ADHOC_NETWORK) { | ||
620 | cap_mask = WLAN_CAPABILITY_IBSS; | ||
621 | cap_val = WLAN_CAPABILITY_IBSS; | ||
622 | } else { | ||
623 | cap_mask = WLAN_CAPABILITY_ESS; | ||
624 | cap_val = WLAN_CAPABILITY_ESS; | ||
625 | } | ||
626 | |||
574 | bss = cfg80211_get_bss(ar->wiphy, chan, bssid, | 627 | bss = cfg80211_get_bss(ar->wiphy, chan, bssid, |
575 | vif->ssid, vif->ssid_len, WLAN_CAPABILITY_ESS, | 628 | vif->ssid, vif->ssid_len, |
576 | WLAN_CAPABILITY_ESS); | 629 | cap_mask, cap_val); |
577 | if (bss == NULL) { | 630 | if (bss == NULL) { |
578 | /* | 631 | /* |
579 | * Since cfg80211 may not yet know about the BSS, | 632 | * Since cfg80211 may not yet know about the BSS, |
@@ -591,13 +644,12 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, const u8 *bssid, | |||
591 | memcpy(ie + 2, vif->ssid, vif->ssid_len); | 644 | memcpy(ie + 2, vif->ssid, vif->ssid_len); |
592 | memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len); | 645 | memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len); |
593 | bss = cfg80211_inform_bss(ar->wiphy, chan, | 646 | bss = cfg80211_inform_bss(ar->wiphy, chan, |
594 | bssid, 0, WLAN_CAPABILITY_ESS, 100, | 647 | bssid, 0, cap_val, 100, |
595 | ie, 2 + vif->ssid_len + beacon_ie_len, | 648 | ie, 2 + vif->ssid_len + beacon_ie_len, |
596 | 0, GFP_KERNEL); | 649 | 0, GFP_KERNEL); |
597 | if (bss) | 650 | if (bss) |
598 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for " | 651 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to " |
599 | "%pM prior to indicating connect/roamed " | 652 | "cfg80211\n", bssid); |
600 | "event\n", bssid); | ||
601 | kfree(ie); | 653 | kfree(ie); |
602 | } else | 654 | } else |
603 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss " | 655 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss " |
@@ -660,16 +712,16 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, | |||
660 | 712 | ||
661 | chan = ieee80211_get_channel(ar->wiphy, (int) channel); | 713 | chan = ieee80211_get_channel(ar->wiphy, (int) channel); |
662 | 714 | ||
663 | 715 | if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info, | |
664 | if (nw_type & ADHOC_NETWORK) { | 716 | beacon_ie_len) < 0) { |
665 | cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); | 717 | ath6kl_err("could not add cfg80211 bss entry\n"); |
666 | return; | 718 | return; |
667 | } | 719 | } |
668 | 720 | ||
669 | if (ath6kl_add_bss_if_needed(vif, bssid, chan, assoc_info, | 721 | if (nw_type & ADHOC_NETWORK) { |
670 | beacon_ie_len) < 0) { | 722 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", |
671 | ath6kl_err("could not add cfg80211 bss entry for " | 723 | nw_type & ADHOC_CREATOR ? "creator" : "joiner"); |
672 | "connect/roamed notification\n"); | 724 | cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); |
673 | return; | 725 | return; |
674 | } | 726 | } |
675 | 727 | ||
@@ -691,12 +743,14 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, | |||
691 | static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy, | 743 | static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy, |
692 | struct net_device *dev, u16 reason_code) | 744 | struct net_device *dev, u16 reason_code) |
693 | { | 745 | { |
694 | struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev); | 746 | struct ath6kl *ar = ath6kl_priv(dev); |
695 | struct ath6kl_vif *vif = netdev_priv(dev); | 747 | struct ath6kl_vif *vif = netdev_priv(dev); |
696 | 748 | ||
697 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__, | 749 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__, |
698 | reason_code); | 750 | reason_code); |
699 | 751 | ||
752 | ath6kl_cfg80211_sscan_disable(vif); | ||
753 | |||
700 | if (!ath6kl_cfg80211_ready(vif)) | 754 | if (!ath6kl_cfg80211_ready(vif)) |
701 | return -EIO; | 755 | return -EIO; |
702 | 756 | ||
@@ -789,7 +843,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, | |||
789 | static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | 843 | static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, |
790 | struct cfg80211_scan_request *request) | 844 | struct cfg80211_scan_request *request) |
791 | { | 845 | { |
792 | struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev); | 846 | struct ath6kl *ar = ath6kl_priv(ndev); |
793 | struct ath6kl_vif *vif = netdev_priv(ndev); | 847 | struct ath6kl_vif *vif = netdev_priv(ndev); |
794 | s8 n_channels = 0; | 848 | s8 n_channels = 0; |
795 | u16 *channels = NULL; | 849 | u16 *channels = NULL; |
@@ -799,6 +853,8 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | |||
799 | if (!ath6kl_cfg80211_ready(vif)) | 853 | if (!ath6kl_cfg80211_ready(vif)) |
800 | return -EIO; | 854 | return -EIO; |
801 | 855 | ||
856 | ath6kl_cfg80211_sscan_disable(vif); | ||
857 | |||
802 | if (!ar->usr_bss_filter) { | 858 | if (!ar->usr_bss_filter) { |
803 | clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); | 859 | clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); |
804 | ret = ath6kl_wmi_bssfilter_cmd( | 860 | ret = ath6kl_wmi_bssfilter_cmd( |
@@ -824,6 +880,10 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | |||
824 | request->ssids[i].ssid); | 880 | request->ssids[i].ssid); |
825 | } | 881 | } |
826 | 882 | ||
883 | /* | ||
884 | * FIXME: we should clear the IE in fw if it's not set so just | ||
885 | * remove the check altogether | ||
886 | */ | ||
827 | if (request->ie) { | 887 | if (request->ie) { |
828 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, | 888 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, |
829 | WMI_FRAME_PROBE_REQ, | 889 | WMI_FRAME_PROBE_REQ, |
@@ -860,9 +920,25 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | |||
860 | if (test_bit(CONNECTED, &vif->flags)) | 920 | if (test_bit(CONNECTED, &vif->flags)) |
861 | force_fg_scan = 1; | 921 | force_fg_scan = 1; |
862 | 922 | ||
863 | ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN, | 923 | if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, |
864 | force_fg_scan, false, 0, 0, n_channels, | 924 | ar->fw_capabilities)) { |
865 | channels); | 925 | /* |
926 | * If capable of doing P2P mgmt operations using | ||
927 | * station interface, send additional information like | ||
928 | * supported rates to advertise and xmit rates for | ||
929 | * probe requests | ||
930 | */ | ||
931 | ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, | ||
932 | WMI_LONG_SCAN, force_fg_scan, | ||
933 | false, 0, 0, n_channels, | ||
934 | channels, request->no_cck, | ||
935 | request->rates); | ||
936 | } else { | ||
937 | ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, | ||
938 | WMI_LONG_SCAN, force_fg_scan, | ||
939 | false, 0, 0, n_channels, | ||
940 | channels); | ||
941 | } | ||
866 | if (ret) | 942 | if (ret) |
867 | ath6kl_err("wmi_startscan_cmd failed\n"); | 943 | ath6kl_err("wmi_startscan_cmd failed\n"); |
868 | else | 944 | else |
@@ -905,7 +981,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
905 | const u8 *mac_addr, | 981 | const u8 *mac_addr, |
906 | struct key_params *params) | 982 | struct key_params *params) |
907 | { | 983 | { |
908 | struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev); | 984 | struct ath6kl *ar = ath6kl_priv(ndev); |
909 | struct ath6kl_vif *vif = netdev_priv(ndev); | 985 | struct ath6kl_vif *vif = netdev_priv(ndev); |
910 | struct ath6kl_key *key = NULL; | 986 | struct ath6kl_key *key = NULL; |
911 | u8 key_usage; | 987 | u8 key_usage; |
@@ -937,13 +1013,19 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
937 | key_usage = GROUP_USAGE; | 1013 | key_usage = GROUP_USAGE; |
938 | 1014 | ||
939 | if (params) { | 1015 | if (params) { |
1016 | int seq_len = params->seq_len; | ||
1017 | if (params->cipher == WLAN_CIPHER_SUITE_SMS4 && | ||
1018 | seq_len > ATH6KL_KEY_SEQ_LEN) { | ||
1019 | /* Only first half of the WPI PN is configured */ | ||
1020 | seq_len = ATH6KL_KEY_SEQ_LEN; | ||
1021 | } | ||
940 | if (params->key_len > WLAN_MAX_KEY_LEN || | 1022 | if (params->key_len > WLAN_MAX_KEY_LEN || |
941 | params->seq_len > sizeof(key->seq)) | 1023 | seq_len > sizeof(key->seq)) |
942 | return -EINVAL; | 1024 | return -EINVAL; |
943 | 1025 | ||
944 | key->key_len = params->key_len; | 1026 | key->key_len = params->key_len; |
945 | memcpy(key->key, params->key, key->key_len); | 1027 | memcpy(key->key, params->key, key->key_len); |
946 | key->seq_len = params->seq_len; | 1028 | key->seq_len = seq_len; |
947 | memcpy(key->seq, params->seq, key->seq_len); | 1029 | memcpy(key->seq, params->seq, key->seq_len); |
948 | key->cipher = params->cipher; | 1030 | key->cipher = params->cipher; |
949 | } | 1031 | } |
@@ -961,6 +1043,9 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
961 | case WLAN_CIPHER_SUITE_CCMP: | 1043 | case WLAN_CIPHER_SUITE_CCMP: |
962 | key_type = AES_CRYPT; | 1044 | key_type = AES_CRYPT; |
963 | break; | 1045 | break; |
1046 | case WLAN_CIPHER_SUITE_SMS4: | ||
1047 | key_type = WAPI_CRYPT; | ||
1048 | break; | ||
964 | 1049 | ||
965 | default: | 1050 | default: |
966 | return -ENOTSUPP; | 1051 | return -ENOTSUPP; |
@@ -976,10 +1061,9 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
976 | __func__, key_index, key->key_len, key_type, | 1061 | __func__, key_index, key->key_len, key_type, |
977 | key_usage, key->seq_len); | 1062 | key_usage, key->seq_len); |
978 | 1063 | ||
979 | vif->def_txkey_index = key_index; | ||
980 | |||
981 | if (vif->nw_type == AP_NETWORK && !pairwise && | 1064 | if (vif->nw_type == AP_NETWORK && !pairwise && |
982 | (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) { | 1065 | (key_type == TKIP_CRYPT || key_type == AES_CRYPT || |
1066 | key_type == WAPI_CRYPT) && params) { | ||
983 | ar->ap_mode_bkey.valid = true; | 1067 | ar->ap_mode_bkey.valid = true; |
984 | ar->ap_mode_bkey.key_index = key_index; | 1068 | ar->ap_mode_bkey.key_index = key_index; |
985 | ar->ap_mode_bkey.key_type = key_type; | 1069 | ar->ap_mode_bkey.key_type = key_type; |
@@ -1012,8 +1096,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | |||
1012 | return 0; | 1096 | return 0; |
1013 | } | 1097 | } |
1014 | 1098 | ||
1015 | return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, | 1099 | return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index, |
1016 | vif->def_txkey_index, | ||
1017 | key_type, key_usage, key->key_len, | 1100 | key_type, key_usage, key->key_len, |
1018 | key->seq, key->seq_len, key->key, | 1101 | key->seq, key->seq_len, key->key, |
1019 | KEY_OP_INIT_VAL, | 1102 | KEY_OP_INIT_VAL, |
@@ -1024,7 +1107,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
1024 | u8 key_index, bool pairwise, | 1107 | u8 key_index, bool pairwise, |
1025 | const u8 *mac_addr) | 1108 | const u8 *mac_addr) |
1026 | { | 1109 | { |
1027 | struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev); | 1110 | struct ath6kl *ar = ath6kl_priv(ndev); |
1028 | struct ath6kl_vif *vif = netdev_priv(ndev); | 1111 | struct ath6kl_vif *vif = netdev_priv(ndev); |
1029 | 1112 | ||
1030 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index); | 1113 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index); |
@@ -1090,7 +1173,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy, | |||
1090 | u8 key_index, bool unicast, | 1173 | u8 key_index, bool unicast, |
1091 | bool multicast) | 1174 | bool multicast) |
1092 | { | 1175 | { |
1093 | struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev); | 1176 | struct ath6kl *ar = ath6kl_priv(ndev); |
1094 | struct ath6kl_vif *vif = netdev_priv(ndev); | 1177 | struct ath6kl_vif *vif = netdev_priv(ndev); |
1095 | struct ath6kl_key *key = NULL; | 1178 | struct ath6kl_key *key = NULL; |
1096 | u8 key_usage; | 1179 | u8 key_usage; |
@@ -1181,11 +1264,12 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
1181 | */ | 1264 | */ |
1182 | static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, | 1265 | static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, |
1183 | enum nl80211_tx_power_setting type, | 1266 | enum nl80211_tx_power_setting type, |
1184 | int dbm) | 1267 | int mbm) |
1185 | { | 1268 | { |
1186 | struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); | 1269 | struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); |
1187 | struct ath6kl_vif *vif; | 1270 | struct ath6kl_vif *vif; |
1188 | u8 ath6kl_dbm; | 1271 | u8 ath6kl_dbm; |
1272 | int dbm = MBM_TO_DBM(mbm); | ||
1189 | 1273 | ||
1190 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__, | 1274 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__, |
1191 | type, dbm); | 1275 | type, dbm); |
@@ -1288,7 +1372,7 @@ static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, | |||
1288 | struct net_device *ndev; | 1372 | struct net_device *ndev; |
1289 | u8 if_idx, nw_type; | 1373 | u8 if_idx, nw_type; |
1290 | 1374 | ||
1291 | if (ar->num_vif == MAX_NUM_VIF) { | 1375 | if (ar->num_vif == ar->vif_max) { |
1292 | ath6kl_err("Reached maximum number of supported vif\n"); | 1376 | ath6kl_err("Reached maximum number of supported vif\n"); |
1293 | return ERR_PTR(-EINVAL); | 1377 | return ERR_PTR(-EINVAL); |
1294 | } | 1378 | } |
@@ -1333,9 +1417,6 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy, | |||
1333 | 1417 | ||
1334 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type); | 1418 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type); |
1335 | 1419 | ||
1336 | if (!ath6kl_cfg80211_ready(vif)) | ||
1337 | return -EIO; | ||
1338 | |||
1339 | switch (type) { | 1420 | switch (type) { |
1340 | case NL80211_IFTYPE_STATION: | 1421 | case NL80211_IFTYPE_STATION: |
1341 | vif->next_mode = INFRA_NETWORK; | 1422 | vif->next_mode = INFRA_NETWORK; |
@@ -1426,7 +1507,7 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy, | |||
1426 | vif->grp_crypto, vif->grp_crypto_len, | 1507 | vif->grp_crypto, vif->grp_crypto_len, |
1427 | vif->ssid_len, vif->ssid, | 1508 | vif->ssid_len, vif->ssid, |
1428 | vif->req_bssid, vif->ch_hint, | 1509 | vif->req_bssid, vif->ch_hint, |
1429 | ar->connect_ctrl_flags); | 1510 | ar->connect_ctrl_flags, SUBTYPE_NONE); |
1430 | set_bit(CONNECT_PEND, &vif->flags); | 1511 | set_bit(CONNECT_PEND, &vif->flags); |
1431 | 1512 | ||
1432 | return 0; | 1513 | return 0; |
@@ -1453,6 +1534,7 @@ static const u32 cipher_suites[] = { | |||
1453 | WLAN_CIPHER_SUITE_TKIP, | 1534 | WLAN_CIPHER_SUITE_TKIP, |
1454 | WLAN_CIPHER_SUITE_CCMP, | 1535 | WLAN_CIPHER_SUITE_CCMP, |
1455 | CCKM_KRK_CIPHER_SUITE, | 1536 | CCKM_KRK_CIPHER_SUITE, |
1537 | WLAN_CIPHER_SUITE_SMS4, | ||
1456 | }; | 1538 | }; |
1457 | 1539 | ||
1458 | static bool is_rate_legacy(s32 rate) | 1540 | static bool is_rate_legacy(s32 rate) |
@@ -1779,7 +1861,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, | |||
1779 | 1861 | ||
1780 | case ATH6KL_CFG_SUSPEND_DEEPSLEEP: | 1862 | case ATH6KL_CFG_SUSPEND_DEEPSLEEP: |
1781 | 1863 | ||
1782 | ath6kl_cfg80211_stop(ar); | 1864 | ath6kl_cfg80211_stop_all(ar); |
1783 | 1865 | ||
1784 | /* save the current power mode before enabling power save */ | 1866 | /* save the current power mode before enabling power save */ |
1785 | ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; | 1867 | ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; |
@@ -1796,7 +1878,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, | |||
1796 | 1878 | ||
1797 | case ATH6KL_CFG_SUSPEND_CUTPOWER: | 1879 | case ATH6KL_CFG_SUSPEND_CUTPOWER: |
1798 | 1880 | ||
1799 | ath6kl_cfg80211_stop(ar); | 1881 | ath6kl_cfg80211_stop_all(ar); |
1800 | 1882 | ||
1801 | if (ar->state == ATH6KL_STATE_OFF) { | 1883 | if (ar->state == ATH6KL_STATE_OFF) { |
1802 | ath6kl_dbg(ATH6KL_DBG_SUSPEND, | 1884 | ath6kl_dbg(ATH6KL_DBG_SUSPEND, |
@@ -1816,6 +1898,13 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, | |||
1816 | 1898 | ||
1817 | break; | 1899 | break; |
1818 | 1900 | ||
1901 | case ATH6KL_CFG_SUSPEND_SCHED_SCAN: | ||
1902 | /* | ||
1903 | * Nothing needed for schedule scan, firmware is already in | ||
1904 | * wow mode and sleeping most of the time. | ||
1905 | */ | ||
1906 | break; | ||
1907 | |||
1819 | default: | 1908 | default: |
1820 | break; | 1909 | break; |
1821 | } | 1910 | } |
@@ -1864,6 +1953,9 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) | |||
1864 | } | 1953 | } |
1865 | break; | 1954 | break; |
1866 | 1955 | ||
1956 | case ATH6KL_STATE_SCHED_SCAN: | ||
1957 | break; | ||
1958 | |||
1867 | default: | 1959 | default: |
1868 | break; | 1960 | break; |
1869 | } | 1961 | } |
@@ -1987,7 +2079,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
1987 | int ies_len; | 2079 | int ies_len; |
1988 | struct wmi_connect_cmd p; | 2080 | struct wmi_connect_cmd p; |
1989 | int res; | 2081 | int res; |
1990 | int i; | 2082 | int i, ret; |
1991 | 2083 | ||
1992 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add); | 2084 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add); |
1993 | 2085 | ||
@@ -2045,7 +2137,9 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
2045 | if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) | 2137 | if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) |
2046 | return -EOPNOTSUPP; /* TODO */ | 2138 | return -EOPNOTSUPP; /* TODO */ |
2047 | 2139 | ||
2048 | vif->dot11_auth_mode = OPEN_AUTH; | 2140 | ret = ath6kl_set_auth_type(vif, info->auth_type); |
2141 | if (ret) | ||
2142 | return ret; | ||
2049 | 2143 | ||
2050 | memset(&p, 0, sizeof(p)); | 2144 | memset(&p, 0, sizeof(p)); |
2051 | 2145 | ||
@@ -2081,6 +2175,9 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
2081 | case WLAN_CIPHER_SUITE_CCMP: | 2175 | case WLAN_CIPHER_SUITE_CCMP: |
2082 | p.prwise_crypto_type |= AES_CRYPT; | 2176 | p.prwise_crypto_type |= AES_CRYPT; |
2083 | break; | 2177 | break; |
2178 | case WLAN_CIPHER_SUITE_SMS4: | ||
2179 | p.prwise_crypto_type |= WAPI_CRYPT; | ||
2180 | break; | ||
2084 | } | 2181 | } |
2085 | } | 2182 | } |
2086 | if (p.prwise_crypto_type == 0) { | 2183 | if (p.prwise_crypto_type == 0) { |
@@ -2100,6 +2197,9 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
2100 | case WLAN_CIPHER_SUITE_CCMP: | 2197 | case WLAN_CIPHER_SUITE_CCMP: |
2101 | p.grp_crypto_type = AES_CRYPT; | 2198 | p.grp_crypto_type = AES_CRYPT; |
2102 | break; | 2199 | break; |
2200 | case WLAN_CIPHER_SUITE_SMS4: | ||
2201 | p.grp_crypto_type = WAPI_CRYPT; | ||
2202 | break; | ||
2103 | default: | 2203 | default: |
2104 | p.grp_crypto_type = NONE_CRYPT; | 2204 | p.grp_crypto_type = NONE_CRYPT; |
2105 | break; | 2205 | break; |
@@ -2114,6 +2214,16 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, | |||
2114 | p.dot11_auth_mode = vif->dot11_auth_mode; | 2214 | p.dot11_auth_mode = vif->dot11_auth_mode; |
2115 | p.ch = cpu_to_le16(vif->next_chan); | 2215 | p.ch = cpu_to_le16(vif->next_chan); |
2116 | 2216 | ||
2217 | if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) { | ||
2218 | p.nw_subtype = SUBTYPE_P2PGO; | ||
2219 | } else { | ||
2220 | /* | ||
2221 | * Due to firmware limitation, it is not possible to | ||
2222 | * do P2P mgmt operations in AP mode | ||
2223 | */ | ||
2224 | p.nw_subtype = SUBTYPE_NONE; | ||
2225 | } | ||
2226 | |||
2117 | res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p); | 2227 | res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p); |
2118 | if (res < 0) | 2228 | if (res < 0) |
2119 | return res; | 2229 | return res; |
@@ -2279,9 +2389,23 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2279 | } | 2389 | } |
2280 | 2390 | ||
2281 | *cookie = id; | 2391 | *cookie = id; |
2282 | return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id, | 2392 | |
2283 | chan->center_freq, wait, | 2393 | if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, |
2284 | buf, len); | 2394 | ar->fw_capabilities)) { |
2395 | /* | ||
2396 | * If capable of doing P2P mgmt operations using | ||
2397 | * station interface, send additional information like | ||
2398 | * supported rates to advertise and xmit rates for | ||
2399 | * probe requests | ||
2400 | */ | ||
2401 | return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, | ||
2402 | chan->center_freq, wait, | ||
2403 | buf, len, no_cck); | ||
2404 | } else { | ||
2405 | return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id, | ||
2406 | chan->center_freq, wait, | ||
2407 | buf, len); | ||
2408 | } | ||
2285 | } | 2409 | } |
2286 | 2410 | ||
2287 | static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, | 2411 | static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, |
@@ -2302,6 +2426,90 @@ static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, | |||
2302 | } | 2426 | } |
2303 | } | 2427 | } |
2304 | 2428 | ||
2429 | static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, | ||
2430 | struct net_device *dev, | ||
2431 | struct cfg80211_sched_scan_request *request) | ||
2432 | { | ||
2433 | struct ath6kl *ar = ath6kl_priv(dev); | ||
2434 | struct ath6kl_vif *vif = netdev_priv(dev); | ||
2435 | u16 interval; | ||
2436 | int ret; | ||
2437 | u8 i; | ||
2438 | |||
2439 | if (ar->state != ATH6KL_STATE_ON) | ||
2440 | return -EIO; | ||
2441 | |||
2442 | if (vif->sme_state != SME_DISCONNECTED) | ||
2443 | return -EBUSY; | ||
2444 | |||
2445 | for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) { | ||
2446 | ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, | ||
2447 | i, DISABLE_SSID_FLAG, | ||
2448 | 0, NULL); | ||
2449 | } | ||
2450 | |||
2451 | /* fw uses seconds, also make sure that it's >0 */ | ||
2452 | interval = max_t(u16, 1, request->interval / 1000); | ||
2453 | |||
2454 | ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, | ||
2455 | interval, interval, | ||
2456 | 10, 0, 0, 0, 3, 0, 0, 0); | ||
2457 | |||
2458 | if (request->n_ssids && request->ssids[0].ssid_len) { | ||
2459 | for (i = 0; i < request->n_ssids; i++) { | ||
2460 | ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, | ||
2461 | i, SPECIFIC_SSID_FLAG, | ||
2462 | request->ssids[i].ssid_len, | ||
2463 | request->ssids[i].ssid); | ||
2464 | } | ||
2465 | } | ||
2466 | |||
2467 | ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, | ||
2468 | ATH6KL_WOW_MODE_ENABLE, | ||
2469 | WOW_FILTER_SSID, | ||
2470 | WOW_HOST_REQ_DELAY); | ||
2471 | if (ret) { | ||
2472 | ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret); | ||
2473 | return ret; | ||
2474 | } | ||
2475 | |||
2476 | /* this also clears IE in fw if it's not set */ | ||
2477 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, | ||
2478 | WMI_FRAME_PROBE_REQ, | ||
2479 | request->ie, request->ie_len); | ||
2480 | if (ret) { | ||
2481 | ath6kl_warn("Failed to set probe request IE for scheduled scan: %d", | ||
2482 | ret); | ||
2483 | return ret; | ||
2484 | } | ||
2485 | |||
2486 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | ||
2487 | ATH6KL_HOST_MODE_ASLEEP); | ||
2488 | if (ret) { | ||
2489 | ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n", | ||
2490 | ret); | ||
2491 | return ret; | ||
2492 | } | ||
2493 | |||
2494 | ar->state = ATH6KL_STATE_SCHED_SCAN; | ||
2495 | |||
2496 | return ret; | ||
2497 | } | ||
2498 | |||
2499 | static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy, | ||
2500 | struct net_device *dev) | ||
2501 | { | ||
2502 | struct ath6kl_vif *vif = netdev_priv(dev); | ||
2503 | bool stopped; | ||
2504 | |||
2505 | stopped = __ath6kl_cfg80211_sscan_stop(vif); | ||
2506 | |||
2507 | if (!stopped) | ||
2508 | return -EIO; | ||
2509 | |||
2510 | return 0; | ||
2511 | } | ||
2512 | |||
2305 | static const struct ieee80211_txrx_stypes | 2513 | static const struct ieee80211_txrx_stypes |
2306 | ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { | 2514 | ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { |
2307 | [NL80211_IFTYPE_STATION] = { | 2515 | [NL80211_IFTYPE_STATION] = { |
@@ -2359,25 +2567,17 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { | |||
2359 | .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel, | 2567 | .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel, |
2360 | .mgmt_tx = ath6kl_mgmt_tx, | 2568 | .mgmt_tx = ath6kl_mgmt_tx, |
2361 | .mgmt_frame_register = ath6kl_mgmt_frame_register, | 2569 | .mgmt_frame_register = ath6kl_mgmt_frame_register, |
2570 | .sched_scan_start = ath6kl_cfg80211_sscan_start, | ||
2571 | .sched_scan_stop = ath6kl_cfg80211_sscan_stop, | ||
2362 | }; | 2572 | }; |
2363 | 2573 | ||
2364 | void ath6kl_cfg80211_stop(struct ath6kl *ar) | 2574 | void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) |
2365 | { | 2575 | { |
2366 | struct ath6kl_vif *vif; | 2576 | ath6kl_cfg80211_sscan_disable(vif); |
2367 | |||
2368 | /* FIXME: for multi vif */ | ||
2369 | vif = ath6kl_vif_first(ar); | ||
2370 | if (!vif) { | ||
2371 | /* save the current power mode before enabling power save */ | ||
2372 | ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; | ||
2373 | |||
2374 | if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0) | ||
2375 | ath6kl_warn("ath6kl_deep_sleep_enable: " | ||
2376 | "wmi_powermode_cmd failed\n"); | ||
2377 | return; | ||
2378 | } | ||
2379 | 2577 | ||
2380 | switch (vif->sme_state) { | 2578 | switch (vif->sme_state) { |
2579 | case SME_DISCONNECTED: | ||
2580 | break; | ||
2381 | case SME_CONNECTING: | 2581 | case SME_CONNECTING: |
2382 | cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0, | 2582 | cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0, |
2383 | NULL, 0, | 2583 | NULL, 0, |
@@ -2385,33 +2585,50 @@ void ath6kl_cfg80211_stop(struct ath6kl *ar) | |||
2385 | GFP_KERNEL); | 2585 | GFP_KERNEL); |
2386 | break; | 2586 | break; |
2387 | case SME_CONNECTED: | 2587 | case SME_CONNECTED: |
2388 | default: | ||
2389 | /* | ||
2390 | * FIXME: oddly enough smeState is in DISCONNECTED during | ||
2391 | * suspend, why? Need to send disconnected event in that | ||
2392 | * state. | ||
2393 | */ | ||
2394 | cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL); | 2588 | cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL); |
2395 | break; | 2589 | break; |
2396 | } | 2590 | } |
2397 | 2591 | ||
2398 | if (test_bit(CONNECTED, &vif->flags) || | 2592 | if (test_bit(CONNECTED, &vif->flags) || |
2399 | test_bit(CONNECT_PEND, &vif->flags)) | 2593 | test_bit(CONNECT_PEND, &vif->flags)) |
2400 | ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); | 2594 | ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx); |
2401 | 2595 | ||
2402 | vif->sme_state = SME_DISCONNECTED; | 2596 | vif->sme_state = SME_DISCONNECTED; |
2403 | clear_bit(CONNECTED, &vif->flags); | 2597 | clear_bit(CONNECTED, &vif->flags); |
2404 | clear_bit(CONNECT_PEND, &vif->flags); | 2598 | clear_bit(CONNECT_PEND, &vif->flags); |
2405 | 2599 | ||
2406 | /* disable scanning */ | 2600 | /* disable scanning */ |
2407 | if (ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF, 0, 0, | 2601 | if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF, |
2408 | 0, 0, 0, 0, 0, 0, 0) != 0) | 2602 | 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0) |
2409 | printk(KERN_WARNING "ath6kl: failed to disable scan " | 2603 | ath6kl_warn("failed to disable scan during stop\n"); |
2410 | "during suspend\n"); | ||
2411 | 2604 | ||
2412 | ath6kl_cfg80211_scan_complete_event(vif, true); | 2605 | ath6kl_cfg80211_scan_complete_event(vif, true); |
2413 | } | 2606 | } |
2414 | 2607 | ||
2608 | void ath6kl_cfg80211_stop_all(struct ath6kl *ar) | ||
2609 | { | ||
2610 | struct ath6kl_vif *vif; | ||
2611 | |||
2612 | vif = ath6kl_vif_first(ar); | ||
2613 | if (!vif) { | ||
2614 | /* save the current power mode before enabling power save */ | ||
2615 | ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; | ||
2616 | |||
2617 | if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0) | ||
2618 | ath6kl_warn("ath6kl_deep_sleep_enable: " | ||
2619 | "wmi_powermode_cmd failed\n"); | ||
2620 | return; | ||
2621 | } | ||
2622 | |||
2623 | /* | ||
2624 | * FIXME: we should take ar->list_lock to protect changes in the | ||
2625 | * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop() | ||
2626 | * sleeps. | ||
2627 | */ | ||
2628 | list_for_each_entry(vif, &ar->vif_list, list) | ||
2629 | ath6kl_cfg80211_stop(vif); | ||
2630 | } | ||
2631 | |||
2415 | struct ath6kl *ath6kl_core_alloc(struct device *dev) | 2632 | struct ath6kl *ath6kl_core_alloc(struct device *dev) |
2416 | { | 2633 | { |
2417 | struct ath6kl *ar; | 2634 | struct ath6kl *ar; |
@@ -2427,17 +2644,12 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev) | |||
2427 | } | 2644 | } |
2428 | 2645 | ||
2429 | ar = wiphy_priv(wiphy); | 2646 | ar = wiphy_priv(wiphy); |
2430 | if (!multi_norm_if_support) | 2647 | ar->p2p = !!ath6kl_p2p; |
2431 | ar->p2p = !!ath6kl_p2p; | ||
2432 | ar->wiphy = wiphy; | 2648 | ar->wiphy = wiphy; |
2433 | ar->dev = dev; | 2649 | ar->dev = dev; |
2434 | 2650 | ||
2435 | if (multi_norm_if_support) | 2651 | ar->vif_max = 1; |
2436 | ar->max_norm_iface = 2; | ||
2437 | else | ||
2438 | ar->max_norm_iface = 1; | ||
2439 | 2652 | ||
2440 | /* FIXME: Remove this once the multivif support is enabled */ | ||
2441 | ar->max_norm_iface = 1; | 2653 | ar->max_norm_iface = 1; |
2442 | 2654 | ||
2443 | spin_lock_init(&ar->lock); | 2655 | spin_lock_init(&ar->lock); |
@@ -2459,9 +2671,6 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev) | |||
2459 | ar->tx_pwr = 0; | 2671 | ar->tx_pwr = 0; |
2460 | 2672 | ||
2461 | ar->intra_bss = 1; | 2673 | ar->intra_bss = 1; |
2462 | memset(&ar->sc_params, 0, sizeof(ar->sc_params)); | ||
2463 | ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT; | ||
2464 | ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS; | ||
2465 | ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; | 2674 | ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; |
2466 | 2675 | ||
2467 | ar->state = ATH6KL_STATE_OFF; | 2676 | ar->state = ATH6KL_STATE_OFF; |
@@ -2522,6 +2731,8 @@ int ath6kl_register_ieee80211_hw(struct ath6kl *ar) | |||
2522 | wiphy->wowlan.pattern_min_len = 1; | 2731 | wiphy->wowlan.pattern_min_len = 1; |
2523 | wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; | 2732 | wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; |
2524 | 2733 | ||
2734 | wiphy->max_sched_scan_ssids = 10; | ||
2735 | |||
2525 | ret = wiphy_register(wiphy); | 2736 | ret = wiphy_register(wiphy); |
2526 | if (ret < 0) { | 2737 | if (ret < 0) { |
2527 | ath6kl_err("couldn't register wiphy device\n"); | 2738 | ath6kl_err("couldn't register wiphy device\n"); |
@@ -2541,6 +2752,9 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif) | |||
2541 | 2752 | ||
2542 | setup_timer(&vif->disconnect_timer, disconnect_timer_handler, | 2753 | setup_timer(&vif->disconnect_timer, disconnect_timer_handler, |
2543 | (unsigned long) vif->ndev); | 2754 | (unsigned long) vif->ndev); |
2755 | setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer, | ||
2756 | (unsigned long) vif); | ||
2757 | |||
2544 | set_bit(WMM_ENABLED, &vif->flags); | 2758 | set_bit(WMM_ENABLED, &vif->flags); |
2545 | spin_lock_init(&vif->if_lock); | 2759 | spin_lock_init(&vif->if_lock); |
2546 | 2760 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 59fa9d859def..81f20a572315 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h | |||
@@ -20,7 +20,8 @@ | |||
20 | enum ath6kl_cfg_suspend_mode { | 20 | enum ath6kl_cfg_suspend_mode { |
21 | ATH6KL_CFG_SUSPEND_DEEPSLEEP, | 21 | ATH6KL_CFG_SUSPEND_DEEPSLEEP, |
22 | ATH6KL_CFG_SUSPEND_CUTPOWER, | 22 | ATH6KL_CFG_SUSPEND_CUTPOWER, |
23 | ATH6KL_CFG_SUSPEND_WOW | 23 | ATH6KL_CFG_SUSPEND_WOW, |
24 | ATH6KL_CFG_SUSPEND_SCHED_SCAN, | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | 27 | struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, |
@@ -52,6 +53,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, | |||
52 | 53 | ||
53 | int ath6kl_cfg80211_resume(struct ath6kl *ar); | 54 | int ath6kl_cfg80211_resume(struct ath6kl *ar); |
54 | 55 | ||
55 | void ath6kl_cfg80211_stop(struct ath6kl *ar); | 56 | void ath6kl_cfg80211_stop(struct ath6kl_vif *vif); |
57 | void ath6kl_cfg80211_stop_all(struct ath6kl *ar); | ||
56 | 58 | ||
57 | #endif /* ATH6KL_CFG80211_H */ | 59 | #endif /* ATH6KL_CFG80211_H */ |
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index 41e465f29e63..bfd6597763da 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h | |||
@@ -71,6 +71,7 @@ enum crypto_type { | |||
71 | WEP_CRYPT = 0x02, | 71 | WEP_CRYPT = 0x02, |
72 | TKIP_CRYPT = 0x04, | 72 | TKIP_CRYPT = 0x04, |
73 | AES_CRYPT = 0x08, | 73 | AES_CRYPT = 0x08, |
74 | WAPI_CRYPT = 0x10, | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | struct htc_endpoint_credit_dist; | 77 | struct htc_endpoint_credit_dist; |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index e7e095e536a7..c863a28f2e0c 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -70,10 +70,20 @@ enum ath6kl_fw_ie_type { | |||
70 | ATH6KL_FW_IE_RESERVED_RAM_SIZE = 5, | 70 | ATH6KL_FW_IE_RESERVED_RAM_SIZE = 5, |
71 | ATH6KL_FW_IE_CAPABILITIES = 6, | 71 | ATH6KL_FW_IE_CAPABILITIES = 6, |
72 | ATH6KL_FW_IE_PATCH_ADDR = 7, | 72 | ATH6KL_FW_IE_PATCH_ADDR = 7, |
73 | ATH6KL_FW_IE_BOARD_ADDR = 8, | ||
74 | ATH6KL_FW_IE_VIF_MAX = 9, | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | enum ath6kl_fw_capability { | 77 | enum ath6kl_fw_capability { |
76 | ATH6KL_FW_CAPABILITY_HOST_P2P = 0, | 78 | ATH6KL_FW_CAPABILITY_HOST_P2P = 0, |
79 | ATH6KL_FW_CAPABILITY_SCHED_SCAN = 1, | ||
80 | |||
81 | /* | ||
82 | * Firmware is capable of supporting P2P mgmt operations on a | ||
83 | * station interface. After group formation, the station | ||
84 | * interface will become a P2P client/GO interface as the case may be | ||
85 | */ | ||
86 | ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, | ||
77 | 87 | ||
78 | /* this needs to be last */ | 88 | /* this needs to be last */ |
79 | ATH6KL_FW_CAPABILITY_MAX, | 89 | ATH6KL_FW_CAPABILITY_MAX, |
@@ -88,37 +98,47 @@ struct ath6kl_fw_ie { | |||
88 | }; | 98 | }; |
89 | 99 | ||
90 | /* AR6003 1.0 definitions */ | 100 | /* AR6003 1.0 definitions */ |
91 | #define AR6003_REV1_VERSION 0x300002ba | 101 | #define AR6003_HW_1_0_VERSION 0x300002ba |
92 | 102 | ||
93 | /* AR6003 2.0 definitions */ | 103 | /* AR6003 2.0 definitions */ |
94 | #define AR6003_REV2_VERSION 0x30000384 | 104 | #define AR6003_HW_2_0_VERSION 0x30000384 |
95 | #define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910 | 105 | #define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS 0x57e910 |
96 | #define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" | 106 | #define AR6003_HW_2_0_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" |
97 | #define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" | 107 | #define AR6003_HW_2_0_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" |
98 | #define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin" | 108 | #define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin" |
99 | #define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" | 109 | #define AR6003_HW_2_0_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" |
100 | #define AR6003_REV2_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin" | 110 | #define AR6003_HW_2_0_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin" |
101 | #define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" | 111 | #define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" |
102 | #define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin" | 112 | #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ |
113 | "ath6k/AR6003/hw2.0/bdata.SD31.bin" | ||
103 | 114 | ||
104 | /* AR6003 3.0 definitions */ | 115 | /* AR6003 3.0 definitions */ |
105 | #define AR6003_REV3_VERSION 0x30000582 | 116 | #define AR6003_HW_2_1_1_VERSION 0x30000582 |
106 | #define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" | 117 | #define AR6003_HW_2_1_1_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" |
107 | #define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" | 118 | #define AR6003_HW_2_1_1_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" |
108 | #define AR6003_REV3_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin" | 119 | #define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE \ |
109 | #define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" | 120 | "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin" |
110 | #define AR6003_REV3_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin" | 121 | #define AR6003_HW_2_1_1_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" |
111 | #define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" | 122 | #define AR6003_HW_2_1_1_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin" |
112 | #define AR6003_REV3_DEFAULT_BOARD_DATA_FILE \ | 123 | #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" |
113 | "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" | 124 | #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ |
125 | "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" | ||
114 | 126 | ||
115 | /* AR6004 1.0 definitions */ | 127 | /* AR6004 1.0 definitions */ |
116 | #define AR6004_REV1_VERSION 0x30000623 | 128 | #define AR6004_HW_1_0_VERSION 0x30000623 |
117 | #define AR6004_REV1_FIRMWARE_FILE "ath6k/AR6004/hw6.1/fw.ram.bin" | 129 | #define AR6004_HW_1_0_FIRMWARE_2_FILE "ath6k/AR6004/hw1.0/fw-2.bin" |
118 | #define AR6004_REV1_FIRMWARE_2_FILE "ath6k/AR6004/hw6.1/fw-2.bin" | 130 | #define AR6004_HW_1_0_FIRMWARE_FILE "ath6k/AR6004/hw1.0/fw.ram.bin" |
119 | #define AR6004_REV1_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.bin" | 131 | #define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin" |
120 | #define AR6004_REV1_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw6.1/bdata.DB132.bin" | 132 | #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ |
121 | #define AR6004_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6004/hw6.1/endpointping.bin" | 133 | "ath6k/AR6004/hw1.0/bdata.DB132.bin" |
134 | |||
135 | /* AR6004 1.1 definitions */ | ||
136 | #define AR6004_HW_1_1_VERSION 0x30000001 | ||
137 | #define AR6004_HW_1_1_FIRMWARE_2_FILE "ath6k/AR6004/hw1.1/fw-2.bin" | ||
138 | #define AR6004_HW_1_1_FIRMWARE_FILE "ath6k/AR6004/hw1.1/fw.ram.bin" | ||
139 | #define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin" | ||
140 | #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ | ||
141 | "ath6k/AR6004/hw1.1/bdata.DB132.bin" | ||
122 | 142 | ||
123 | /* Per STA data, used in AP mode */ | 143 | /* Per STA data, used in AP mode */ |
124 | #define STA_PS_AWAKE BIT(0) | 144 | #define STA_PS_AWAKE BIT(0) |
@@ -272,6 +292,8 @@ struct ath6kl_bmi { | |||
272 | u32 cmd_credits; | 292 | u32 cmd_credits; |
273 | bool done_sent; | 293 | bool done_sent; |
274 | u8 *cmd_buf; | 294 | u8 *cmd_buf; |
295 | u32 max_data_size; | ||
296 | u32 max_cmd_size; | ||
275 | }; | 297 | }; |
276 | 298 | ||
277 | struct target_stats { | 299 | struct target_stats { |
@@ -381,7 +403,16 @@ struct ath6kl_req_key { | |||
381 | u8 key_len; | 403 | u8 key_len; |
382 | }; | 404 | }; |
383 | 405 | ||
384 | #define MAX_NUM_VIF 1 | 406 | enum ath6kl_hif_type { |
407 | ATH6KL_HIF_TYPE_SDIO, | ||
408 | ATH6KL_HIF_TYPE_USB, | ||
409 | }; | ||
410 | |||
411 | /* | ||
412 | * Driver's maximum limit, note that some firmwares support only one vif | ||
413 | * and the runtime (current) limit must be checked from ar->vif_max. | ||
414 | */ | ||
415 | #define ATH6KL_VIF_MAX 3 | ||
385 | 416 | ||
386 | /* vif flags info */ | 417 | /* vif flags info */ |
387 | enum ath6kl_vif_state { | 418 | enum ath6kl_vif_state { |
@@ -424,7 +455,10 @@ struct ath6kl_vif { | |||
424 | struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1]; | 455 | struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1]; |
425 | struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1]; | 456 | struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1]; |
426 | struct aggr_info *aggr_cntxt; | 457 | struct aggr_info *aggr_cntxt; |
458 | |||
427 | struct timer_list disconnect_timer; | 459 | struct timer_list disconnect_timer; |
460 | struct timer_list sched_scan_timer; | ||
461 | |||
428 | struct cfg80211_scan_request *scan_req; | 462 | struct cfg80211_scan_request *scan_req; |
429 | enum sme_state sme_state; | 463 | enum sme_state sme_state; |
430 | int reconnect_flag; | 464 | int reconnect_flag; |
@@ -442,6 +476,8 @@ struct ath6kl_vif { | |||
442 | #define WOW_LIST_ID 0 | 476 | #define WOW_LIST_ID 0 |
443 | #define WOW_HOST_REQ_DELAY 500 /* ms */ | 477 | #define WOW_HOST_REQ_DELAY 500 /* ms */ |
444 | 478 | ||
479 | #define ATH6KL_SCHED_SCAN_RESULT_DELAY 5000 /* ms */ | ||
480 | |||
445 | /* Flag info */ | 481 | /* Flag info */ |
446 | enum ath6kl_dev_state { | 482 | enum ath6kl_dev_state { |
447 | WMI_ENABLED, | 483 | WMI_ENABLED, |
@@ -460,6 +496,7 @@ enum ath6kl_state { | |||
460 | ATH6KL_STATE_DEEPSLEEP, | 496 | ATH6KL_STATE_DEEPSLEEP, |
461 | ATH6KL_STATE_CUTPOWER, | 497 | ATH6KL_STATE_CUTPOWER, |
462 | ATH6KL_STATE_WOW, | 498 | ATH6KL_STATE_WOW, |
499 | ATH6KL_STATE_SCHED_SCAN, | ||
463 | }; | 500 | }; |
464 | 501 | ||
465 | struct ath6kl { | 502 | struct ath6kl { |
@@ -474,11 +511,13 @@ struct ath6kl { | |||
474 | int tx_pending[ENDPOINT_MAX]; | 511 | int tx_pending[ENDPOINT_MAX]; |
475 | int total_tx_data_pend; | 512 | int total_tx_data_pend; |
476 | struct htc_target *htc_target; | 513 | struct htc_target *htc_target; |
514 | enum ath6kl_hif_type hif_type; | ||
477 | void *hif_priv; | 515 | void *hif_priv; |
478 | struct list_head vif_list; | 516 | struct list_head vif_list; |
479 | /* Lock to avoid race in vif_list entries among add/del/traverse */ | 517 | /* Lock to avoid race in vif_list entries among add/del/traverse */ |
480 | spinlock_t list_lock; | 518 | spinlock_t list_lock; |
481 | u8 num_vif; | 519 | u8 num_vif; |
520 | unsigned int vif_max; | ||
482 | u8 max_norm_iface; | 521 | u8 max_norm_iface; |
483 | u8 avail_idx_map; | 522 | u8 avail_idx_map; |
484 | spinlock_t lock; | 523 | spinlock_t lock; |
@@ -517,7 +556,6 @@ struct ath6kl { | |||
517 | struct list_head amsdu_rx_buffer_queue; | 556 | struct list_head amsdu_rx_buffer_queue; |
518 | u8 rx_meta_ver; | 557 | u8 rx_meta_ver; |
519 | enum wlan_low_pwr_state wlan_pwr_state; | 558 | enum wlan_low_pwr_state wlan_pwr_state; |
520 | struct wmi_scan_params_cmd sc_params; | ||
521 | u8 mac_addr[ETH_ALEN]; | 559 | u8 mac_addr[ETH_ALEN]; |
522 | #define AR_MCAST_FILTER_MAC_ADDR_SIZE 4 | 560 | #define AR_MCAST_FILTER_MAC_ADDR_SIZE 4 |
523 | struct { | 561 | struct { |
@@ -525,12 +563,25 @@ struct ath6kl { | |||
525 | size_t rx_report_len; | 563 | size_t rx_report_len; |
526 | } tm; | 564 | } tm; |
527 | 565 | ||
528 | struct { | 566 | struct ath6kl_hw { |
567 | u32 id; | ||
568 | const char *name; | ||
529 | u32 dataset_patch_addr; | 569 | u32 dataset_patch_addr; |
530 | u32 app_load_addr; | 570 | u32 app_load_addr; |
531 | u32 app_start_override_addr; | 571 | u32 app_start_override_addr; |
532 | u32 board_ext_data_addr; | 572 | u32 board_ext_data_addr; |
533 | u32 reserved_ram_size; | 573 | u32 reserved_ram_size; |
574 | u32 board_addr; | ||
575 | u32 refclk_hz; | ||
576 | u32 uarttx_pin; | ||
577 | |||
578 | const char *fw_otp; | ||
579 | const char *fw; | ||
580 | const char *fw_tcmd; | ||
581 | const char *fw_patch; | ||
582 | const char *fw_api2; | ||
583 | const char *fw_board; | ||
584 | const char *fw_default_board; | ||
534 | } hw; | 585 | } hw; |
535 | 586 | ||
536 | u16 conf_flags; | 587 | u16 conf_flags; |
@@ -583,7 +634,7 @@ struct ath6kl { | |||
583 | #endif /* CONFIG_ATH6KL_DEBUG */ | 634 | #endif /* CONFIG_ATH6KL_DEBUG */ |
584 | }; | 635 | }; |
585 | 636 | ||
586 | static inline void *ath6kl_priv(struct net_device *dev) | 637 | static inline struct ath6kl *ath6kl_priv(struct net_device *dev) |
587 | { | 638 | { |
588 | return ((struct ath6kl_vif *) netdev_priv(dev))->ar; | 639 | return ((struct ath6kl_vif *) netdev_priv(dev))->ar; |
589 | } | 640 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 9eff0d010bb1..eb808b46f94c 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c | |||
@@ -1551,10 +1551,10 @@ static ssize_t ath6kl_listen_int_read(struct file *file, | |||
1551 | size_t count, loff_t *ppos) | 1551 | size_t count, loff_t *ppos) |
1552 | { | 1552 | { |
1553 | struct ath6kl *ar = file->private_data; | 1553 | struct ath6kl *ar = file->private_data; |
1554 | char buf[16]; | 1554 | char buf[32]; |
1555 | int len; | 1555 | int len; |
1556 | 1556 | ||
1557 | len = snprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t, | 1557 | len = scnprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t, |
1558 | ar->listen_intvl_b); | 1558 | ar->listen_intvl_b); |
1559 | 1559 | ||
1560 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 1560 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 9853c9c125c1..e569c652e35c 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h | |||
@@ -41,6 +41,7 @@ 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), | ||
44 | ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ | 45 | ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ |
45 | }; | 46 | }; |
46 | 47 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h index eed22870448b..2fe1dadfc77a 100644 --- a/drivers/net/wireless/ath/ath6kl/hif-ops.h +++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h | |||
@@ -91,6 +91,36 @@ static inline int ath6kl_hif_suspend(struct ath6kl *ar, | |||
91 | return ar->hif_ops->suspend(ar, wow); | 91 | return ar->hif_ops->suspend(ar, wow); |
92 | } | 92 | } |
93 | 93 | ||
94 | /* | ||
95 | * Read from the ATH6KL through its diagnostic window. No cooperation from | ||
96 | * the Target is required for this. | ||
97 | */ | ||
98 | static inline int ath6kl_hif_diag_read32(struct ath6kl *ar, u32 address, | ||
99 | u32 *value) | ||
100 | { | ||
101 | return ar->hif_ops->diag_read32(ar, address, value); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Write to the ATH6KL through its diagnostic window. No cooperation from | ||
106 | * the Target is required for this. | ||
107 | */ | ||
108 | static inline int ath6kl_hif_diag_write32(struct ath6kl *ar, u32 address, | ||
109 | __le32 value) | ||
110 | { | ||
111 | return ar->hif_ops->diag_write32(ar, address, value); | ||
112 | } | ||
113 | |||
114 | static inline int ath6kl_hif_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) | ||
115 | { | ||
116 | return ar->hif_ops->bmi_read(ar, buf, len); | ||
117 | } | ||
118 | |||
119 | static inline int ath6kl_hif_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) | ||
120 | { | ||
121 | return ar->hif_ops->bmi_write(ar, buf, len); | ||
122 | } | ||
123 | |||
94 | static inline int ath6kl_hif_resume(struct ath6kl *ar) | 124 | static inline int ath6kl_hif_resume(struct ath6kl *ar) |
95 | { | 125 | { |
96 | ath6kl_dbg(ATH6KL_DBG_HIF, "hif resume\n"); | 126 | ath6kl_dbg(ATH6KL_DBG_HIF, "hif resume\n"); |
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index e57da35e59fa..0772ef650174 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c | |||
@@ -689,6 +689,11 @@ 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 | |||
692 | status = ath6kl_hif_disable_intrs(dev); | 697 | status = ath6kl_hif_disable_intrs(dev); |
693 | 698 | ||
694 | fail_setup: | 699 | fail_setup: |
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h index f2dc3bcdae4a..699a036f3a44 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.h +++ b/drivers/net/wireless/ath/ath6kl/hif.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #define MAX_SCATTER_REQ_TRANSFER_SIZE (32 * 1024) | 35 | #define MAX_SCATTER_REQ_TRANSFER_SIZE (32 * 1024) |
36 | 36 | ||
37 | #define MANUFACTURER_ID_AR6003_BASE 0x300 | 37 | #define MANUFACTURER_ID_AR6003_BASE 0x300 |
38 | #define MANUFACTURER_ID_AR6004_BASE 0x400 | ||
38 | /* SDIO manufacturer ID and Codes */ | 39 | /* SDIO manufacturer ID and Codes */ |
39 | #define MANUFACTURER_ID_ATH6KL_BASE_MASK 0xFF00 | 40 | #define MANUFACTURER_ID_ATH6KL_BASE_MASK 0xFF00 |
40 | #define MANUFACTURER_CODE 0x271 /* Atheros */ | 41 | #define MANUFACTURER_CODE 0x271 /* Atheros */ |
@@ -244,6 +245,10 @@ struct ath6kl_hif_ops { | |||
244 | void (*cleanup_scatter)(struct ath6kl *ar); | 245 | void (*cleanup_scatter)(struct ath6kl *ar); |
245 | int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow); | 246 | int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow); |
246 | int (*resume)(struct ath6kl *ar); | 247 | int (*resume)(struct ath6kl *ar); |
248 | int (*diag_read32)(struct ath6kl *ar, u32 address, u32 *value); | ||
249 | int (*diag_write32)(struct ath6kl *ar, u32 address, __le32 value); | ||
250 | int (*bmi_read)(struct ath6kl *ar, u8 *buf, u32 len); | ||
251 | int (*bmi_write)(struct ath6kl *ar, u8 *buf, u32 len); | ||
247 | int (*power_on)(struct ath6kl *ar); | 252 | int (*power_on)(struct ath6kl *ar); |
248 | int (*power_off)(struct ath6kl *ar); | 253 | int (*power_off)(struct ath6kl *ar); |
249 | void (*stop)(struct ath6kl *ar); | 254 | void (*stop)(struct ath6kl *ar); |
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index f3b63ca25c7e..b01702258faf 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c | |||
@@ -2543,6 +2543,12 @@ 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 | |||
2546 | /* we should be getting 1 control message that the target is ready */ | 2552 | /* we should be getting 1 control message that the target is ready */ |
2547 | packet = htc_wait_for_ctrl_msg(target); | 2553 | packet = htc_wait_for_ctrl_msg(target); |
2548 | 2554 | ||
@@ -2772,7 +2778,9 @@ void ath6kl_htc_cleanup(struct htc_target *target) | |||
2772 | { | 2778 | { |
2773 | struct htc_packet *packet, *tmp_packet; | 2779 | struct htc_packet *packet, *tmp_packet; |
2774 | 2780 | ||
2775 | ath6kl_hif_cleanup_scatter(target->dev->ar); | 2781 | /* FIXME: remove check once USB support is implemented */ |
2782 | if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB) | ||
2783 | ath6kl_hif_cleanup_scatter(target->dev->ar); | ||
2776 | 2784 | ||
2777 | list_for_each_entry_safe(packet, tmp_packet, | 2785 | list_for_each_entry_safe(packet, tmp_packet, |
2778 | &target->free_ctrl_txbuf, list) { | 2786 | &target->free_ctrl_txbuf, list) { |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 5acb4a4b93bf..7f55be3092d1 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -33,6 +33,80 @@ module_param(debug_mask, uint, 0644); | |||
33 | module_param(testmode, uint, 0644); | 33 | module_param(testmode, uint, 0644); |
34 | module_param(suspend_cutpower, bool, 0444); | 34 | module_param(suspend_cutpower, bool, 0444); |
35 | 35 | ||
36 | static const struct ath6kl_hw hw_list[] = { | ||
37 | { | ||
38 | .id = AR6003_HW_2_0_VERSION, | ||
39 | .name = "ar6003 hw 2.0", | ||
40 | .dataset_patch_addr = 0x57e884, | ||
41 | .app_load_addr = 0x543180, | ||
42 | .board_ext_data_addr = 0x57e500, | ||
43 | .reserved_ram_size = 6912, | ||
44 | .refclk_hz = 26000000, | ||
45 | .uarttx_pin = 8, | ||
46 | |||
47 | /* hw2.0 needs override address hardcoded */ | ||
48 | .app_start_override_addr = 0x944C00, | ||
49 | |||
50 | .fw_otp = AR6003_HW_2_0_OTP_FILE, | ||
51 | .fw = AR6003_HW_2_0_FIRMWARE_FILE, | ||
52 | .fw_tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, | ||
53 | .fw_patch = AR6003_HW_2_0_PATCH_FILE, | ||
54 | .fw_api2 = AR6003_HW_2_0_FIRMWARE_2_FILE, | ||
55 | .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE, | ||
56 | .fw_default_board = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE, | ||
57 | }, | ||
58 | { | ||
59 | .id = AR6003_HW_2_1_1_VERSION, | ||
60 | .name = "ar6003 hw 2.1.1", | ||
61 | .dataset_patch_addr = 0x57ff74, | ||
62 | .app_load_addr = 0x1234, | ||
63 | .board_ext_data_addr = 0x542330, | ||
64 | .reserved_ram_size = 512, | ||
65 | .refclk_hz = 26000000, | ||
66 | .uarttx_pin = 8, | ||
67 | |||
68 | .fw_otp = AR6003_HW_2_1_1_OTP_FILE, | ||
69 | .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, | ||
70 | .fw_tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, | ||
71 | .fw_patch = AR6003_HW_2_1_1_PATCH_FILE, | ||
72 | .fw_api2 = AR6003_HW_2_1_1_FIRMWARE_2_FILE, | ||
73 | .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, | ||
74 | .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, | ||
75 | }, | ||
76 | { | ||
77 | .id = AR6004_HW_1_0_VERSION, | ||
78 | .name = "ar6004 hw 1.0", | ||
79 | .dataset_patch_addr = 0x57e884, | ||
80 | .app_load_addr = 0x1234, | ||
81 | .board_ext_data_addr = 0x437000, | ||
82 | .reserved_ram_size = 19456, | ||
83 | .board_addr = 0x433900, | ||
84 | .refclk_hz = 26000000, | ||
85 | .uarttx_pin = 11, | ||
86 | |||
87 | .fw = AR6004_HW_1_0_FIRMWARE_FILE, | ||
88 | .fw_api2 = AR6004_HW_1_0_FIRMWARE_2_FILE, | ||
89 | .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE, | ||
90 | .fw_default_board = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE, | ||
91 | }, | ||
92 | { | ||
93 | .id = AR6004_HW_1_1_VERSION, | ||
94 | .name = "ar6004 hw 1.1", | ||
95 | .dataset_patch_addr = 0x57e884, | ||
96 | .app_load_addr = 0x1234, | ||
97 | .board_ext_data_addr = 0x437000, | ||
98 | .reserved_ram_size = 11264, | ||
99 | .board_addr = 0x43d400, | ||
100 | .refclk_hz = 40000000, | ||
101 | .uarttx_pin = 11, | ||
102 | |||
103 | .fw = AR6004_HW_1_1_FIRMWARE_FILE, | ||
104 | .fw_api2 = AR6004_HW_1_1_FIRMWARE_2_FILE, | ||
105 | .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, | ||
106 | .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, | ||
107 | }, | ||
108 | }; | ||
109 | |||
36 | /* | 110 | /* |
37 | * Include definitions here that can be used to tune the WLAN module | 111 | * Include definitions here that can be used to tune the WLAN module |
38 | * behavior. Different customers can tune the behavior as per their needs, | 112 | * behavior. Different customers can tune the behavior as per their needs, |
@@ -58,7 +132,6 @@ module_param(suspend_cutpower, bool, 0444); | |||
58 | */ | 132 | */ |
59 | #define WLAN_CONFIG_DISCONNECT_TIMEOUT 10 | 133 | #define WLAN_CONFIG_DISCONNECT_TIMEOUT 10 |
60 | 134 | ||
61 | #define CONFIG_AR600x_DEBUG_UART_TX_PIN 8 | ||
62 | 135 | ||
63 | #define ATH6KL_DATA_OFFSET 64 | 136 | #define ATH6KL_DATA_OFFSET 64 |
64 | struct sk_buff *ath6kl_buf_alloc(int size) | 137 | struct sk_buff *ath6kl_buf_alloc(int size) |
@@ -348,11 +421,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) | |||
348 | status = -EIO; | 421 | status = -EIO; |
349 | } | 422 | } |
350 | 423 | ||
351 | /* | 424 | if (ar->p2p && (ar->vif_max == 1 || idx)) { |
352 | * FIXME: Make sure p2p configurations are not applied to | ||
353 | * non-p2p capable interfaces when multivif support is enabled. | ||
354 | */ | ||
355 | if (ar->p2p) { | ||
356 | ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx, | 425 | ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx, |
357 | P2P_FLAG_CAPABILITIES_REQ | | 426 | P2P_FLAG_CAPABILITIES_REQ | |
358 | P2P_FLAG_MACADDR_REQ | | 427 | P2P_FLAG_MACADDR_REQ | |
@@ -365,11 +434,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) | |||
365 | } | 434 | } |
366 | } | 435 | } |
367 | 436 | ||
368 | /* | 437 | if (ar->p2p && (ar->vif_max == 1 || idx)) { |
369 | * FIXME: Make sure p2p configurations are not applied to | ||
370 | * non-p2p capable interfaces when multivif support is enabled. | ||
371 | */ | ||
372 | if (ar->p2p) { | ||
373 | /* Enable Probe Request reporting for P2P */ | 438 | /* Enable Probe Request reporting for P2P */ |
374 | ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true); | 439 | ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true); |
375 | if (ret) { | 440 | if (ret) { |
@@ -385,7 +450,7 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
385 | { | 450 | { |
386 | u32 param, ram_reserved_size; | 451 | u32 param, ram_reserved_size; |
387 | u8 fw_iftype, fw_mode = 0, fw_submode = 0; | 452 | u8 fw_iftype, fw_mode = 0, fw_submode = 0; |
388 | int i; | 453 | int i, status; |
389 | 454 | ||
390 | /* | 455 | /* |
391 | * Note: Even though the firmware interface type is | 456 | * Note: Even though the firmware interface type is |
@@ -397,7 +462,7 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
397 | */ | 462 | */ |
398 | fw_iftype = HI_OPTION_FW_MODE_BSS_STA; | 463 | fw_iftype = HI_OPTION_FW_MODE_BSS_STA; |
399 | 464 | ||
400 | for (i = 0; i < MAX_NUM_VIF; i++) | 465 | for (i = 0; i < ar->vif_max; i++) |
401 | fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS); | 466 | fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS); |
402 | 467 | ||
403 | /* | 468 | /* |
@@ -411,15 +476,11 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
411 | fw_submode |= HI_OPTION_FW_SUBMODE_NONE << | 476 | fw_submode |= HI_OPTION_FW_SUBMODE_NONE << |
412 | (i * HI_OPTION_FW_SUBMODE_BITS); | 477 | (i * HI_OPTION_FW_SUBMODE_BITS); |
413 | 478 | ||
414 | for (i = ar->max_norm_iface; i < MAX_NUM_VIF; i++) | 479 | for (i = ar->max_norm_iface; i < ar->vif_max; i++) |
415 | fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV << | 480 | fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV << |
416 | (i * HI_OPTION_FW_SUBMODE_BITS); | 481 | (i * HI_OPTION_FW_SUBMODE_BITS); |
417 | 482 | ||
418 | /* | 483 | if (ar->p2p && ar->vif_max == 1) |
419 | * FIXME: This needs to be removed once the multivif | ||
420 | * support is enabled. | ||
421 | */ | ||
422 | if (ar->p2p) | ||
423 | fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; | 484 | fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; |
424 | 485 | ||
425 | param = HTC_PROTOCOL_VERSION; | 486 | param = HTC_PROTOCOL_VERSION; |
@@ -442,7 +503,7 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
442 | return -EIO; | 503 | return -EIO; |
443 | } | 504 | } |
444 | 505 | ||
445 | param |= (MAX_NUM_VIF << HI_OPTION_NUM_DEV_SHIFT); | 506 | param |= (ar->vif_max << HI_OPTION_NUM_DEV_SHIFT); |
446 | param |= fw_mode << HI_OPTION_FW_MODE_SHIFT; | 507 | param |= fw_mode << HI_OPTION_FW_MODE_SHIFT; |
447 | param |= fw_submode << HI_OPTION_FW_SUBMODE_SHIFT; | 508 | param |= fw_submode << HI_OPTION_FW_SUBMODE_SHIFT; |
448 | 509 | ||
@@ -491,6 +552,24 @@ int ath6kl_configure_target(struct ath6kl *ar) | |||
491 | /* use default number of control buffers */ | 552 | /* use default number of control buffers */ |
492 | return -EIO; | 553 | return -EIO; |
493 | 554 | ||
555 | /* Configure GPIO AR600x UART */ | ||
556 | param = ar->hw.uarttx_pin; | ||
557 | status = ath6kl_bmi_write(ar, | ||
558 | ath6kl_get_hi_item_addr(ar, | ||
559 | HI_ITEM(hi_dbg_uart_txpin)), | ||
560 | (u8 *)¶m, 4); | ||
561 | if (status) | ||
562 | return status; | ||
563 | |||
564 | /* Configure target refclk_hz */ | ||
565 | param = ar->hw.refclk_hz; | ||
566 | status = ath6kl_bmi_write(ar, | ||
567 | ath6kl_get_hi_item_addr(ar, | ||
568 | HI_ITEM(hi_refclk_hz)), | ||
569 | (u8 *)¶m, 4); | ||
570 | if (status) | ||
571 | return status; | ||
572 | |||
494 | return 0; | 573 | return 0; |
495 | } | 574 | } |
496 | 575 | ||
@@ -550,11 +629,11 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, | |||
550 | static const char *get_target_ver_dir(const struct ath6kl *ar) | 629 | static const char *get_target_ver_dir(const struct ath6kl *ar) |
551 | { | 630 | { |
552 | switch (ar->version.target_ver) { | 631 | switch (ar->version.target_ver) { |
553 | case AR6003_REV1_VERSION: | 632 | case AR6003_HW_1_0_VERSION: |
554 | return "ath6k/AR6003/hw1.0"; | 633 | return "ath6k/AR6003/hw1.0"; |
555 | case AR6003_REV2_VERSION: | 634 | case AR6003_HW_2_0_VERSION: |
556 | return "ath6k/AR6003/hw2.0"; | 635 | return "ath6k/AR6003/hw2.0"; |
557 | case AR6003_REV3_VERSION: | 636 | case AR6003_HW_2_1_1_VERSION: |
558 | return "ath6k/AR6003/hw2.1.1"; | 637 | return "ath6k/AR6003/hw2.1.1"; |
559 | } | 638 | } |
560 | ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__, | 639 | ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__, |
@@ -612,17 +691,10 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar) | |||
612 | if (ar->fw_board != NULL) | 691 | if (ar->fw_board != NULL) |
613 | return 0; | 692 | return 0; |
614 | 693 | ||
615 | switch (ar->version.target_ver) { | 694 | if (WARN_ON(ar->hw.fw_board == NULL)) |
616 | case AR6003_REV2_VERSION: | 695 | return -EINVAL; |
617 | filename = AR6003_REV2_BOARD_DATA_FILE; | 696 | |
618 | break; | 697 | filename = ar->hw.fw_board; |
619 | case AR6004_REV1_VERSION: | ||
620 | filename = AR6004_REV1_BOARD_DATA_FILE; | ||
621 | break; | ||
622 | default: | ||
623 | filename = AR6003_REV3_BOARD_DATA_FILE; | ||
624 | break; | ||
625 | } | ||
626 | 698 | ||
627 | ret = ath6kl_get_fw(ar, filename, &ar->fw_board, | 699 | ret = ath6kl_get_fw(ar, filename, &ar->fw_board, |
628 | &ar->fw_board_len); | 700 | &ar->fw_board_len); |
@@ -640,17 +712,7 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar) | |||
640 | ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n", | 712 | ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n", |
641 | filename, ret); | 713 | filename, ret); |
642 | 714 | ||
643 | switch (ar->version.target_ver) { | 715 | filename = ar->hw.fw_default_board; |
644 | case AR6003_REV2_VERSION: | ||
645 | filename = AR6003_REV2_DEFAULT_BOARD_DATA_FILE; | ||
646 | break; | ||
647 | case AR6004_REV1_VERSION: | ||
648 | filename = AR6004_REV1_DEFAULT_BOARD_DATA_FILE; | ||
649 | break; | ||
650 | default: | ||
651 | filename = AR6003_REV3_DEFAULT_BOARD_DATA_FILE; | ||
652 | break; | ||
653 | } | ||
654 | 716 | ||
655 | ret = ath6kl_get_fw(ar, filename, &ar->fw_board, | 717 | ret = ath6kl_get_fw(ar, filename, &ar->fw_board, |
656 | &ar->fw_board_len); | 718 | &ar->fw_board_len); |
@@ -674,19 +736,14 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar) | |||
674 | if (ar->fw_otp != NULL) | 736 | if (ar->fw_otp != NULL) |
675 | return 0; | 737 | return 0; |
676 | 738 | ||
677 | switch (ar->version.target_ver) { | 739 | if (ar->hw.fw_otp == NULL) { |
678 | case AR6003_REV2_VERSION: | 740 | ath6kl_dbg(ATH6KL_DBG_BOOT, |
679 | filename = AR6003_REV2_OTP_FILE; | 741 | "no OTP file configured for this hw\n"); |
680 | break; | ||
681 | case AR6004_REV1_VERSION: | ||
682 | ath6kl_dbg(ATH6KL_DBG_TRC, "AR6004 doesn't need OTP file\n"); | ||
683 | return 0; | 742 | return 0; |
684 | break; | ||
685 | default: | ||
686 | filename = AR6003_REV3_OTP_FILE; | ||
687 | break; | ||
688 | } | 743 | } |
689 | 744 | ||
745 | filename = ar->hw.fw_otp; | ||
746 | |||
690 | ret = ath6kl_get_fw(ar, filename, &ar->fw_otp, | 747 | ret = ath6kl_get_fw(ar, filename, &ar->fw_otp, |
691 | &ar->fw_otp_len); | 748 | &ar->fw_otp_len); |
692 | if (ret) { | 749 | if (ret) { |
@@ -707,38 +764,22 @@ static int ath6kl_fetch_fw_file(struct ath6kl *ar) | |||
707 | return 0; | 764 | return 0; |
708 | 765 | ||
709 | if (testmode) { | 766 | if (testmode) { |
710 | switch (ar->version.target_ver) { | 767 | if (ar->hw.fw_tcmd == NULL) { |
711 | case AR6003_REV2_VERSION: | 768 | ath6kl_warn("testmode not supported\n"); |
712 | filename = AR6003_REV2_TCMD_FIRMWARE_FILE; | ||
713 | break; | ||
714 | case AR6003_REV3_VERSION: | ||
715 | filename = AR6003_REV3_TCMD_FIRMWARE_FILE; | ||
716 | break; | ||
717 | case AR6004_REV1_VERSION: | ||
718 | ath6kl_warn("testmode not supported with ar6004\n"); | ||
719 | return -EOPNOTSUPP; | 769 | return -EOPNOTSUPP; |
720 | default: | ||
721 | ath6kl_warn("unknown target version: 0x%x\n", | ||
722 | ar->version.target_ver); | ||
723 | return -EINVAL; | ||
724 | } | 770 | } |
725 | 771 | ||
772 | filename = ar->hw.fw_tcmd; | ||
773 | |||
726 | set_bit(TESTMODE, &ar->flag); | 774 | set_bit(TESTMODE, &ar->flag); |
727 | 775 | ||
728 | goto get_fw; | 776 | goto get_fw; |
729 | } | 777 | } |
730 | 778 | ||
731 | switch (ar->version.target_ver) { | 779 | if (WARN_ON(ar->hw.fw == NULL)) |
732 | case AR6003_REV2_VERSION: | 780 | return -EINVAL; |
733 | filename = AR6003_REV2_FIRMWARE_FILE; | 781 | |
734 | break; | 782 | filename = ar->hw.fw; |
735 | case AR6004_REV1_VERSION: | ||
736 | filename = AR6004_REV1_FIRMWARE_FILE; | ||
737 | break; | ||
738 | default: | ||
739 | filename = AR6003_REV3_FIRMWARE_FILE; | ||
740 | break; | ||
741 | } | ||
742 | 783 | ||
743 | get_fw: | 784 | get_fw: |
744 | ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); | 785 | ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); |
@@ -756,27 +797,20 @@ static int ath6kl_fetch_patch_file(struct ath6kl *ar) | |||
756 | const char *filename; | 797 | const char *filename; |
757 | int ret; | 798 | int ret; |
758 | 799 | ||
759 | switch (ar->version.target_ver) { | 800 | if (ar->fw_patch != NULL) |
760 | case AR6003_REV2_VERSION: | ||
761 | filename = AR6003_REV2_PATCH_FILE; | ||
762 | break; | ||
763 | case AR6004_REV1_VERSION: | ||
764 | /* FIXME: implement for AR6004 */ | ||
765 | return 0; | 801 | return 0; |
766 | break; | ||
767 | default: | ||
768 | filename = AR6003_REV3_PATCH_FILE; | ||
769 | break; | ||
770 | } | ||
771 | 802 | ||
772 | if (ar->fw_patch == NULL) { | 803 | if (ar->hw.fw_patch == NULL) |
773 | ret = ath6kl_get_fw(ar, filename, &ar->fw_patch, | 804 | return 0; |
774 | &ar->fw_patch_len); | 805 | |
775 | if (ret) { | 806 | filename = ar->hw.fw_patch; |
776 | ath6kl_err("Failed to get patch file %s: %d\n", | 807 | |
777 | filename, ret); | 808 | ret = ath6kl_get_fw(ar, filename, &ar->fw_patch, |
778 | return ret; | 809 | &ar->fw_patch_len); |
779 | } | 810 | if (ret) { |
811 | ath6kl_err("Failed to get patch file %s: %d\n", | ||
812 | filename, ret); | ||
813 | return ret; | ||
780 | } | 814 | } |
781 | 815 | ||
782 | return 0; | 816 | return 0; |
@@ -811,19 +845,10 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) | |||
811 | int ret, ie_id, i, index, bit; | 845 | int ret, ie_id, i, index, bit; |
812 | __le32 *val; | 846 | __le32 *val; |
813 | 847 | ||
814 | switch (ar->version.target_ver) { | 848 | if (ar->hw.fw_api2 == NULL) |
815 | case AR6003_REV2_VERSION: | ||
816 | filename = AR6003_REV2_FIRMWARE_2_FILE; | ||
817 | break; | ||
818 | case AR6003_REV3_VERSION: | ||
819 | filename = AR6003_REV3_FIRMWARE_2_FILE; | ||
820 | break; | ||
821 | case AR6004_REV1_VERSION: | ||
822 | filename = AR6004_REV1_FIRMWARE_2_FILE; | ||
823 | break; | ||
824 | default: | ||
825 | return -EOPNOTSUPP; | 849 | return -EOPNOTSUPP; |
826 | } | 850 | |
851 | filename = ar->hw.fw_api2; | ||
827 | 852 | ||
828 | ret = request_firmware(&fw, filename, ar->dev); | 853 | ret = request_firmware(&fw, filename, ar->dev); |
829 | if (ret) | 854 | if (ret) |
@@ -913,12 +938,15 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) | |||
913 | ar->hw.reserved_ram_size); | 938 | ar->hw.reserved_ram_size); |
914 | break; | 939 | break; |
915 | case ATH6KL_FW_IE_CAPABILITIES: | 940 | case ATH6KL_FW_IE_CAPABILITIES: |
941 | if (ie_len < DIV_ROUND_UP(ATH6KL_FW_CAPABILITY_MAX, 8)) | ||
942 | break; | ||
943 | |||
916 | ath6kl_dbg(ATH6KL_DBG_BOOT, | 944 | ath6kl_dbg(ATH6KL_DBG_BOOT, |
917 | "found firmware capabilities ie (%zd B)\n", | 945 | "found firmware capabilities ie (%zd B)\n", |
918 | ie_len); | 946 | ie_len); |
919 | 947 | ||
920 | for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) { | 948 | for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) { |
921 | index = ALIGN(i, 8) / 8; | 949 | index = i / 8; |
922 | bit = i % 8; | 950 | bit = i % 8; |
923 | 951 | ||
924 | if (data[index] & (1 << bit)) | 952 | if (data[index] & (1 << bit)) |
@@ -937,9 +965,34 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) | |||
937 | ar->hw.dataset_patch_addr = le32_to_cpup(val); | 965 | ar->hw.dataset_patch_addr = le32_to_cpup(val); |
938 | 966 | ||
939 | ath6kl_dbg(ATH6KL_DBG_BOOT, | 967 | ath6kl_dbg(ATH6KL_DBG_BOOT, |
940 | "found patch address ie 0x%d\n", | 968 | "found patch address ie 0x%x\n", |
941 | ar->hw.dataset_patch_addr); | 969 | ar->hw.dataset_patch_addr); |
942 | break; | 970 | break; |
971 | case ATH6KL_FW_IE_BOARD_ADDR: | ||
972 | if (ie_len != sizeof(*val)) | ||
973 | break; | ||
974 | |||
975 | val = (__le32 *) data; | ||
976 | ar->hw.board_addr = le32_to_cpup(val); | ||
977 | |||
978 | ath6kl_dbg(ATH6KL_DBG_BOOT, | ||
979 | "found board address ie 0x%x\n", | ||
980 | ar->hw.board_addr); | ||
981 | break; | ||
982 | case ATH6KL_FW_IE_VIF_MAX: | ||
983 | if (ie_len != sizeof(*val)) | ||
984 | break; | ||
985 | |||
986 | val = (__le32 *) data; | ||
987 | ar->vif_max = min_t(unsigned int, le32_to_cpup(val), | ||
988 | ATH6KL_VIF_MAX); | ||
989 | |||
990 | if (ar->vif_max > 1 && !ar->p2p) | ||
991 | ar->max_norm_iface = 2; | ||
992 | |||
993 | ath6kl_dbg(ATH6KL_DBG_BOOT, | ||
994 | "found vif max ie %d\n", ar->vif_max); | ||
995 | break; | ||
943 | default: | 996 | default: |
944 | ath6kl_dbg(ATH6KL_DBG_BOOT, "Unknown fw ie: %u\n", | 997 | ath6kl_dbg(ATH6KL_DBG_BOOT, "Unknown fw ie: %u\n", |
945 | le32_to_cpup(&hdr->id)); | 998 | le32_to_cpup(&hdr->id)); |
@@ -994,8 +1047,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) | |||
994 | * For AR6004, host determine Target RAM address for | 1047 | * For AR6004, host determine Target RAM address for |
995 | * writing board data. | 1048 | * writing board data. |
996 | */ | 1049 | */ |
997 | if (ar->target_type == TARGET_TYPE_AR6004) { | 1050 | if (ar->hw.board_addr != 0) { |
998 | board_address = AR6004_REV1_BOARD_DATA_ADDRESS; | 1051 | board_address = ar->hw.board_addr; |
999 | ath6kl_bmi_write(ar, | 1052 | ath6kl_bmi_write(ar, |
1000 | ath6kl_get_hi_item_addr(ar, | 1053 | ath6kl_get_hi_item_addr(ar, |
1001 | HI_ITEM(hi_board_data)), | 1054 | HI_ITEM(hi_board_data)), |
@@ -1013,7 +1066,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) | |||
1013 | HI_ITEM(hi_board_ext_data)), | 1066 | HI_ITEM(hi_board_ext_data)), |
1014 | (u8 *) &board_ext_address, 4); | 1067 | (u8 *) &board_ext_address, 4); |
1015 | 1068 | ||
1016 | if (board_ext_address == 0) { | 1069 | if (ar->target_type == TARGET_TYPE_AR6003 && |
1070 | board_ext_address == 0) { | ||
1017 | ath6kl_err("Failed to get board file target address.\n"); | 1071 | ath6kl_err("Failed to get board file target address.\n"); |
1018 | return -EINVAL; | 1072 | return -EINVAL; |
1019 | } | 1073 | } |
@@ -1033,8 +1087,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) | |||
1033 | break; | 1087 | break; |
1034 | } | 1088 | } |
1035 | 1089 | ||
1036 | if (ar->fw_board_len == (board_data_size + | 1090 | if (board_ext_address && |
1037 | board_ext_data_size)) { | 1091 | ar->fw_board_len == (board_data_size + board_ext_data_size)) { |
1038 | 1092 | ||
1039 | /* write extended board data */ | 1093 | /* write extended board data */ |
1040 | ath6kl_dbg(ATH6KL_DBG_BOOT, | 1094 | ath6kl_dbg(ATH6KL_DBG_BOOT, |
@@ -1092,8 +1146,8 @@ static int ath6kl_upload_otp(struct ath6kl *ar) | |||
1092 | bool from_hw = false; | 1146 | bool from_hw = false; |
1093 | int ret; | 1147 | int ret; |
1094 | 1148 | ||
1095 | if (WARN_ON(ar->fw_otp == NULL)) | 1149 | if (ar->fw_otp == NULL) |
1096 | return -ENOENT; | 1150 | return 0; |
1097 | 1151 | ||
1098 | address = ar->hw.app_load_addr; | 1152 | address = ar->hw.app_load_addr; |
1099 | 1153 | ||
@@ -1142,7 +1196,7 @@ static int ath6kl_upload_firmware(struct ath6kl *ar) | |||
1142 | int ret; | 1196 | int ret; |
1143 | 1197 | ||
1144 | if (WARN_ON(ar->fw == NULL)) | 1198 | if (WARN_ON(ar->fw == NULL)) |
1145 | return -ENOENT; | 1199 | return 0; |
1146 | 1200 | ||
1147 | address = ar->hw.app_load_addr; | 1201 | address = ar->hw.app_load_addr; |
1148 | 1202 | ||
@@ -1172,8 +1226,8 @@ static int ath6kl_upload_patch(struct ath6kl *ar) | |||
1172 | u32 address, param; | 1226 | u32 address, param; |
1173 | int ret; | 1227 | int ret; |
1174 | 1228 | ||
1175 | if (WARN_ON(ar->fw_patch == NULL)) | 1229 | if (ar->fw_patch == NULL) |
1176 | return -ENOENT; | 1230 | return 0; |
1177 | 1231 | ||
1178 | address = ar->hw.dataset_patch_addr; | 1232 | address = ar->hw.dataset_patch_addr; |
1179 | 1233 | ||
@@ -1258,7 +1312,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) | |||
1258 | return status; | 1312 | return status; |
1259 | 1313 | ||
1260 | /* WAR to avoid SDIO CRC err */ | 1314 | /* WAR to avoid SDIO CRC err */ |
1261 | if (ar->version.target_ver == AR6003_REV2_VERSION) { | 1315 | if (ar->version.target_ver == AR6003_HW_2_0_VERSION) { |
1262 | ath6kl_err("temporary war to avoid sdio crc error\n"); | 1316 | ath6kl_err("temporary war to avoid sdio crc error\n"); |
1263 | 1317 | ||
1264 | param = 0x20; | 1318 | param = 0x20; |
@@ -1315,47 +1369,29 @@ static int ath6kl_init_upload(struct ath6kl *ar) | |||
1315 | if (status) | 1369 | if (status) |
1316 | return status; | 1370 | return status; |
1317 | 1371 | ||
1318 | /* Configure GPIO AR6003 UART */ | ||
1319 | param = CONFIG_AR600x_DEBUG_UART_TX_PIN; | ||
1320 | status = ath6kl_bmi_write(ar, | ||
1321 | ath6kl_get_hi_item_addr(ar, | ||
1322 | HI_ITEM(hi_dbg_uart_txpin)), | ||
1323 | (u8 *)¶m, 4); | ||
1324 | |||
1325 | return status; | 1372 | return status; |
1326 | } | 1373 | } |
1327 | 1374 | ||
1328 | static int ath6kl_init_hw_params(struct ath6kl *ar) | 1375 | static int ath6kl_init_hw_params(struct ath6kl *ar) |
1329 | { | 1376 | { |
1330 | switch (ar->version.target_ver) { | 1377 | const struct ath6kl_hw *hw; |
1331 | case AR6003_REV2_VERSION: | 1378 | int i; |
1332 | ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS; | ||
1333 | ar->hw.app_load_addr = AR6003_REV2_APP_LOAD_ADDRESS; | ||
1334 | ar->hw.board_ext_data_addr = AR6003_REV2_BOARD_EXT_DATA_ADDRESS; | ||
1335 | ar->hw.reserved_ram_size = AR6003_REV2_RAM_RESERVE_SIZE; | ||
1336 | 1379 | ||
1337 | /* hw2.0 needs override address hardcoded */ | 1380 | for (i = 0; i < ARRAY_SIZE(hw_list); i++) { |
1338 | ar->hw.app_start_override_addr = 0x944C00; | 1381 | hw = &hw_list[i]; |
1339 | 1382 | ||
1340 | break; | 1383 | if (hw->id == ar->version.target_ver) |
1341 | case AR6003_REV3_VERSION: | 1384 | break; |
1342 | ar->hw.dataset_patch_addr = AR6003_REV3_DATASET_PATCH_ADDRESS; | 1385 | } |
1343 | ar->hw.app_load_addr = 0x1234; | 1386 | |
1344 | ar->hw.board_ext_data_addr = AR6003_REV3_BOARD_EXT_DATA_ADDRESS; | 1387 | if (i == ARRAY_SIZE(hw_list)) { |
1345 | ar->hw.reserved_ram_size = AR6003_REV3_RAM_RESERVE_SIZE; | ||
1346 | break; | ||
1347 | case AR6004_REV1_VERSION: | ||
1348 | ar->hw.dataset_patch_addr = AR6003_REV2_DATASET_PATCH_ADDRESS; | ||
1349 | ar->hw.app_load_addr = AR6003_REV3_APP_LOAD_ADDRESS; | ||
1350 | ar->hw.board_ext_data_addr = AR6004_REV1_BOARD_EXT_DATA_ADDRESS; | ||
1351 | ar->hw.reserved_ram_size = AR6004_REV1_RAM_RESERVE_SIZE; | ||
1352 | break; | ||
1353 | default: | ||
1354 | ath6kl_err("Unsupported hardware version: 0x%x\n", | 1388 | ath6kl_err("Unsupported hardware version: 0x%x\n", |
1355 | ar->version.target_ver); | 1389 | ar->version.target_ver); |
1356 | return -EINVAL; | 1390 | return -EINVAL; |
1357 | } | 1391 | } |
1358 | 1392 | ||
1393 | ar->hw = *hw; | ||
1394 | |||
1359 | ath6kl_dbg(ATH6KL_DBG_BOOT, | 1395 | ath6kl_dbg(ATH6KL_DBG_BOOT, |
1360 | "target_ver 0x%x target_type 0x%x dataset_patch 0x%x app_load_addr 0x%x\n", | 1396 | "target_ver 0x%x target_type 0x%x dataset_patch 0x%x app_load_addr 0x%x\n", |
1361 | ar->version.target_ver, ar->target_type, | 1397 | ar->version.target_ver, ar->target_type, |
@@ -1364,10 +1400,25 @@ static int ath6kl_init_hw_params(struct ath6kl *ar) | |||
1364 | "app_start_override_addr 0x%x board_ext_data_addr 0x%x reserved_ram_size 0x%x", | 1400 | "app_start_override_addr 0x%x board_ext_data_addr 0x%x reserved_ram_size 0x%x", |
1365 | ar->hw.app_start_override_addr, ar->hw.board_ext_data_addr, | 1401 | ar->hw.app_start_override_addr, ar->hw.board_ext_data_addr, |
1366 | ar->hw.reserved_ram_size); | 1402 | ar->hw.reserved_ram_size); |
1403 | ath6kl_dbg(ATH6KL_DBG_BOOT, | ||
1404 | "refclk_hz %d uarttx_pin %d", | ||
1405 | ar->hw.refclk_hz, ar->hw.uarttx_pin); | ||
1367 | 1406 | ||
1368 | return 0; | 1407 | return 0; |
1369 | } | 1408 | } |
1370 | 1409 | ||
1410 | static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type) | ||
1411 | { | ||
1412 | switch (type) { | ||
1413 | case ATH6KL_HIF_TYPE_SDIO: | ||
1414 | return "sdio"; | ||
1415 | case ATH6KL_HIF_TYPE_USB: | ||
1416 | return "usb"; | ||
1417 | } | ||
1418 | |||
1419 | return NULL; | ||
1420 | } | ||
1421 | |||
1371 | int ath6kl_init_hw_start(struct ath6kl *ar) | 1422 | int ath6kl_init_hw_start(struct ath6kl *ar) |
1372 | { | 1423 | { |
1373 | long timeleft; | 1424 | long timeleft; |
@@ -1428,6 +1479,15 @@ int ath6kl_init_hw_start(struct ath6kl *ar) | |||
1428 | 1479 | ||
1429 | ath6kl_dbg(ATH6KL_DBG_BOOT, "firmware booted\n"); | 1480 | ath6kl_dbg(ATH6KL_DBG_BOOT, "firmware booted\n"); |
1430 | 1481 | ||
1482 | |||
1483 | if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) { | ||
1484 | ath6kl_info("%s %s fw %s%s\n", | ||
1485 | ar->hw.name, | ||
1486 | ath6kl_init_get_hif_name(ar->hif_type), | ||
1487 | ar->wiphy->fw_version, | ||
1488 | test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); | ||
1489 | } | ||
1490 | |||
1431 | if (ar->version.abi_ver != ATH6KL_ABI_VERSION) { | 1491 | if (ar->version.abi_ver != ATH6KL_ABI_VERSION) { |
1432 | ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n", | 1492 | ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n", |
1433 | ATH6KL_ABI_VERSION, ar->version.abi_ver); | 1493 | ATH6KL_ABI_VERSION, ar->version.abi_ver); |
@@ -1448,7 +1508,7 @@ int ath6kl_init_hw_start(struct ath6kl *ar) | |||
1448 | if ((ath6kl_set_host_app_area(ar)) != 0) | 1508 | if ((ath6kl_set_host_app_area(ar)) != 0) |
1449 | ath6kl_err("unable to set the host app area\n"); | 1509 | ath6kl_err("unable to set the host app area\n"); |
1450 | 1510 | ||
1451 | for (i = 0; i < MAX_NUM_VIF; i++) { | 1511 | for (i = 0; i < ar->vif_max; i++) { |
1452 | ret = ath6kl_target_config_wlan_params(ar, i); | 1512 | ret = ath6kl_target_config_wlan_params(ar, i); |
1453 | if (ret) | 1513 | if (ret) |
1454 | goto err_htc_stop; | 1514 | goto err_htc_stop; |
@@ -1558,7 +1618,7 @@ int ath6kl_core_init(struct ath6kl *ar) | |||
1558 | goto err_node_cleanup; | 1618 | goto err_node_cleanup; |
1559 | } | 1619 | } |
1560 | 1620 | ||
1561 | for (i = 0; i < MAX_NUM_VIF; i++) | 1621 | for (i = 0; i < ar->vif_max; i++) |
1562 | ar->avail_idx_map |= BIT(i); | 1622 | ar->avail_idx_map |= BIT(i); |
1563 | 1623 | ||
1564 | rtnl_lock(); | 1624 | rtnl_lock(); |
@@ -1603,7 +1663,17 @@ int ath6kl_core_init(struct ath6kl *ar) | |||
1603 | 1663 | ||
1604 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | | 1664 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | |
1605 | WIPHY_FLAG_HAVE_AP_SME | | 1665 | WIPHY_FLAG_HAVE_AP_SME | |
1606 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 1666 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | |
1667 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; | ||
1668 | |||
1669 | if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) | ||
1670 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | ||
1671 | |||
1672 | ar->wiphy->probe_resp_offload = | ||
1673 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | | ||
1674 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | | ||
1675 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | | ||
1676 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; | ||
1607 | 1677 | ||
1608 | set_bit(FIRST_BOOT, &ar->flag); | 1678 | set_bit(FIRST_BOOT, &ar->flag); |
1609 | 1679 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 5e5f4ca8f3f0..eea3c747653e 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -175,64 +175,6 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie) | |||
175 | ar->cookie_count++; | 175 | ar->cookie_count++; |
176 | } | 176 | } |
177 | 177 | ||
178 | /* set the window address register (using 4-byte register access ). */ | ||
179 | static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) | ||
180 | { | ||
181 | int status; | ||
182 | s32 i; | ||
183 | __le32 addr_val; | ||
184 | |||
185 | /* | ||
186 | * Write bytes 1,2,3 of the register to set the upper address bytes, | ||
187 | * the LSB is written last to initiate the access cycle | ||
188 | */ | ||
189 | |||
190 | for (i = 1; i <= 3; i++) { | ||
191 | /* | ||
192 | * Fill the buffer with the address byte value we want to | ||
193 | * hit 4 times. No need to worry about endianness as the | ||
194 | * same byte is copied to all four bytes of addr_val at | ||
195 | * any time. | ||
196 | */ | ||
197 | memset((u8 *)&addr_val, ((u8 *)&addr)[i], 4); | ||
198 | |||
199 | /* | ||
200 | * Hit each byte of the register address with a 4-byte | ||
201 | * write operation to the same address, this is a harmless | ||
202 | * operation. | ||
203 | */ | ||
204 | status = hif_read_write_sync(ar, reg_addr + i, (u8 *)&addr_val, | ||
205 | 4, HIF_WR_SYNC_BYTE_FIX); | ||
206 | if (status) | ||
207 | break; | ||
208 | } | ||
209 | |||
210 | if (status) { | ||
211 | ath6kl_err("failed to write initial bytes of 0x%x to window reg: 0x%X\n", | ||
212 | addr, reg_addr); | ||
213 | return status; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Write the address register again, this time write the whole | ||
218 | * 4-byte value. The effect here is that the LSB write causes the | ||
219 | * cycle to start, the extra 3 byte write to bytes 1,2,3 has no | ||
220 | * effect since we are writing the same values again | ||
221 | */ | ||
222 | addr_val = cpu_to_le32(addr); | ||
223 | status = hif_read_write_sync(ar, reg_addr, | ||
224 | (u8 *)&(addr_val), | ||
225 | 4, HIF_WR_SYNC_BYTE_INC); | ||
226 | |||
227 | if (status) { | ||
228 | ath6kl_err("failed to write 0x%x to window reg: 0x%X\n", | ||
229 | addr, reg_addr); | ||
230 | return status; | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | /* | 178 | /* |
237 | * Read from the hardware through its diagnostic window. No cooperation | 179 | * Read from the hardware through its diagnostic window. No cooperation |
238 | * from the firmware is required for this. | 180 | * from the firmware is required for this. |
@@ -241,14 +183,7 @@ int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value) | |||
241 | { | 183 | { |
242 | int ret; | 184 | int ret; |
243 | 185 | ||
244 | /* set window register to start read cycle */ | 186 | ret = ath6kl_hif_diag_read32(ar, address, value); |
245 | ret = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS, address); | ||
246 | if (ret) | ||
247 | return ret; | ||
248 | |||
249 | /* read the data */ | ||
250 | ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) value, | ||
251 | sizeof(*value), HIF_RD_SYNC_BYTE_INC); | ||
252 | if (ret) { | 187 | if (ret) { |
253 | ath6kl_warn("failed to read32 through diagnose window: %d\n", | 188 | ath6kl_warn("failed to read32 through diagnose window: %d\n", |
254 | ret); | 189 | ret); |
@@ -266,18 +201,15 @@ int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value) | |||
266 | { | 201 | { |
267 | int ret; | 202 | int ret; |
268 | 203 | ||
269 | /* set write data */ | 204 | ret = ath6kl_hif_diag_write32(ar, address, value); |
270 | ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) &value, | 205 | |
271 | sizeof(value), HIF_WR_SYNC_BYTE_INC); | ||
272 | if (ret) { | 206 | if (ret) { |
273 | ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n", | 207 | ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n", |
274 | address, value); | 208 | address, value); |
275 | return ret; | 209 | return ret; |
276 | } | 210 | } |
277 | 211 | ||
278 | /* set window register, which starts the write cycle */ | 212 | return 0; |
279 | return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS, | ||
280 | address); | ||
281 | } | 213 | } |
282 | 214 | ||
283 | int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length) | 215 | int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length) |
@@ -465,7 +397,9 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) | |||
465 | case NONE_AUTH: | 397 | case NONE_AUTH: |
466 | if (vif->prwise_crypto == WEP_CRYPT) | 398 | if (vif->prwise_crypto == WEP_CRYPT) |
467 | ath6kl_install_static_wep_keys(vif); | 399 | ath6kl_install_static_wep_keys(vif); |
468 | break; | 400 | if (!ik->valid || ik->key_type != WAPI_CRYPT) |
401 | break; | ||
402 | /* for WAPI, we need to set the delayed group key, continue: */ | ||
469 | case WPA_PSK_AUTH: | 403 | case WPA_PSK_AUTH: |
470 | case WPA2_PSK_AUTH: | 404 | case WPA2_PSK_AUTH: |
471 | case (WPA_PSK_AUTH | WPA2_PSK_AUTH): | 405 | case (WPA_PSK_AUTH | WPA2_PSK_AUTH): |
@@ -534,6 +468,18 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, | |||
534 | wpa_ie = pos; /* WPS IE */ | 468 | wpa_ie = pos; /* WPS IE */ |
535 | break; /* overrides WPA/RSN IE */ | 469 | break; /* overrides WPA/RSN IE */ |
536 | } | 470 | } |
471 | } else if (pos[0] == 0x44 && wpa_ie == NULL) { | ||
472 | /* | ||
473 | * Note: WAPI Parameter Set IE re-uses Element ID that | ||
474 | * was officially allocated for BSS AC Access Delay. As | ||
475 | * such, we need to be a bit more careful on when | ||
476 | * parsing the frame. However, BSS AC Access Delay | ||
477 | * element is not supposed to be included in | ||
478 | * (Re)Association Request frames, so this should not | ||
479 | * cause problems. | ||
480 | */ | ||
481 | wpa_ie = pos; /* WAPI IE */ | ||
482 | break; | ||
537 | } | 483 | } |
538 | pos += 2 + pos[1]; | 484 | pos += 2 + pos[1]; |
539 | } | 485 | } |
@@ -581,20 +527,6 @@ void ath6kl_disconnect(struct ath6kl_vif *vif) | |||
581 | 527 | ||
582 | /* WMI Event handlers */ | 528 | /* WMI Event handlers */ |
583 | 529 | ||
584 | static const char *get_hw_id_string(u32 id) | ||
585 | { | ||
586 | switch (id) { | ||
587 | case AR6003_REV1_VERSION: | ||
588 | return "1.0"; | ||
589 | case AR6003_REV2_VERSION: | ||
590 | return "2.0"; | ||
591 | case AR6003_REV3_VERSION: | ||
592 | return "2.1.1"; | ||
593 | default: | ||
594 | return "unknown"; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) | 530 | void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) |
599 | { | 531 | { |
600 | struct ath6kl *ar = devt; | 532 | struct ath6kl *ar = devt; |
@@ -617,13 +549,6 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver) | |||
617 | /* indicate to the waiting thread that the ready event was received */ | 549 | /* indicate to the waiting thread that the ready event was received */ |
618 | set_bit(WMI_READY, &ar->flag); | 550 | set_bit(WMI_READY, &ar->flag); |
619 | wake_up(&ar->event_wq); | 551 | wake_up(&ar->event_wq); |
620 | |||
621 | if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) { | ||
622 | ath6kl_info("hw %s fw %s%s\n", | ||
623 | get_hw_id_string(ar->wiphy->hw_version), | ||
624 | ar->wiphy->fw_version, | ||
625 | test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); | ||
626 | } | ||
627 | } | 552 | } |
628 | 553 | ||
629 | void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status) | 554 | void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status) |
@@ -1077,21 +1002,11 @@ static int ath6kl_open(struct net_device *dev) | |||
1077 | 1002 | ||
1078 | static int ath6kl_close(struct net_device *dev) | 1003 | static int ath6kl_close(struct net_device *dev) |
1079 | { | 1004 | { |
1080 | struct ath6kl *ar = ath6kl_priv(dev); | ||
1081 | struct ath6kl_vif *vif = netdev_priv(dev); | 1005 | struct ath6kl_vif *vif = netdev_priv(dev); |
1082 | 1006 | ||
1083 | netif_stop_queue(dev); | 1007 | netif_stop_queue(dev); |
1084 | 1008 | ||
1085 | ath6kl_disconnect(vif); | 1009 | ath6kl_cfg80211_stop(vif); |
1086 | |||
1087 | if (test_bit(WMI_READY, &ar->flag)) { | ||
1088 | if (ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF, | ||
1089 | 0, 0, 0, 0, 0, 0, 0, 0, 0)) | ||
1090 | return -EIO; | ||
1091 | |||
1092 | } | ||
1093 | |||
1094 | ath6kl_cfg80211_scan_complete_event(vif, true); | ||
1095 | 1010 | ||
1096 | clear_bit(WLAN_ENABLED, &vif->flags); | 1011 | clear_bit(WLAN_ENABLED, &vif->flags); |
1097 | 1012 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index e69ca5ee5bb1..15c3f56caf4f 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c | |||
@@ -40,8 +40,12 @@ struct ath6kl_sdio { | |||
40 | struct bus_request bus_req[BUS_REQUEST_MAX_NUM]; | 40 | struct bus_request bus_req[BUS_REQUEST_MAX_NUM]; |
41 | 41 | ||
42 | struct ath6kl *ar; | 42 | struct ath6kl *ar; |
43 | |||
43 | u8 *dma_buffer; | 44 | u8 *dma_buffer; |
44 | 45 | ||
46 | /* protects access to dma_buffer */ | ||
47 | struct mutex dma_buffer_mutex; | ||
48 | |||
45 | /* scatter request list head */ | 49 | /* scatter request list head */ |
46 | struct list_head scat_req; | 50 | struct list_head scat_req; |
47 | 51 | ||
@@ -396,6 +400,7 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, | |||
396 | if (buf_needs_bounce(buf)) { | 400 | if (buf_needs_bounce(buf)) { |
397 | if (!ar_sdio->dma_buffer) | 401 | if (!ar_sdio->dma_buffer) |
398 | return -ENOMEM; | 402 | return -ENOMEM; |
403 | mutex_lock(&ar_sdio->dma_buffer_mutex); | ||
399 | tbuf = ar_sdio->dma_buffer; | 404 | tbuf = ar_sdio->dma_buffer; |
400 | memcpy(tbuf, buf, len); | 405 | memcpy(tbuf, buf, len); |
401 | bounced = true; | 406 | bounced = true; |
@@ -406,6 +411,9 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, | |||
406 | if ((request & HIF_READ) && bounced) | 411 | if ((request & HIF_READ) && bounced) |
407 | memcpy(buf, tbuf, len); | 412 | memcpy(buf, tbuf, len); |
408 | 413 | ||
414 | if (bounced) | ||
415 | mutex_unlock(&ar_sdio->dma_buffer_mutex); | ||
416 | |||
409 | return ret; | 417 | return ret; |
410 | } | 418 | } |
411 | 419 | ||
@@ -799,7 +807,28 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
799 | return ret; | 807 | return ret; |
800 | } | 808 | } |
801 | 809 | ||
802 | if ((flags & MMC_PM_WAKE_SDIO_IRQ) && wow) { | 810 | if (!(flags & MMC_PM_WAKE_SDIO_IRQ)) |
811 | goto deepsleep; | ||
812 | |||
813 | /* sdio irq wakes up host */ | ||
814 | |||
815 | if (ar->state == ATH6KL_STATE_SCHED_SCAN) { | ||
816 | ret = ath6kl_cfg80211_suspend(ar, | ||
817 | ATH6KL_CFG_SUSPEND_SCHED_SCAN, | ||
818 | NULL); | ||
819 | if (ret) { | ||
820 | ath6kl_warn("Schedule scan suspend failed: %d", ret); | ||
821 | return ret; | ||
822 | } | ||
823 | |||
824 | ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); | ||
825 | if (ret) | ||
826 | ath6kl_warn("set sdio wake irq flag failed: %d\n", ret); | ||
827 | |||
828 | return ret; | ||
829 | } | ||
830 | |||
831 | if (wow) { | ||
803 | /* | 832 | /* |
804 | * The host sdio controller is capable of keep power and | 833 | * The host sdio controller is capable of keep power and |
805 | * sdio irq wake up at this point. It's fine to continue | 834 | * sdio irq wake up at this point. It's fine to continue |
@@ -816,6 +845,7 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
816 | return ret; | 845 | return ret; |
817 | } | 846 | } |
818 | 847 | ||
848 | deepsleep: | ||
819 | return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); | 849 | return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); |
820 | } | 850 | } |
821 | 851 | ||
@@ -839,6 +869,8 @@ static int ath6kl_sdio_resume(struct ath6kl *ar) | |||
839 | 869 | ||
840 | case ATH6KL_STATE_WOW: | 870 | case ATH6KL_STATE_WOW: |
841 | break; | 871 | break; |
872 | case ATH6KL_STATE_SCHED_SCAN: | ||
873 | break; | ||
842 | } | 874 | } |
843 | 875 | ||
844 | ath6kl_cfg80211_resume(ar); | 876 | ath6kl_cfg80211_resume(ar); |
@@ -846,6 +878,264 @@ static int ath6kl_sdio_resume(struct ath6kl *ar) | |||
846 | return 0; | 878 | return 0; |
847 | } | 879 | } |
848 | 880 | ||
881 | /* set the window address register (using 4-byte register access ). */ | ||
882 | static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr) | ||
883 | { | ||
884 | int status; | ||
885 | u8 addr_val[4]; | ||
886 | s32 i; | ||
887 | |||
888 | /* | ||
889 | * Write bytes 1,2,3 of the register to set the upper address bytes, | ||
890 | * the LSB is written last to initiate the access cycle | ||
891 | */ | ||
892 | |||
893 | for (i = 1; i <= 3; i++) { | ||
894 | /* | ||
895 | * Fill the buffer with the address byte value we want to | ||
896 | * hit 4 times. | ||
897 | */ | ||
898 | memset(addr_val, ((u8 *)&addr)[i], 4); | ||
899 | |||
900 | /* | ||
901 | * Hit each byte of the register address with a 4-byte | ||
902 | * write operation to the same address, this is a harmless | ||
903 | * operation. | ||
904 | */ | ||
905 | status = ath6kl_sdio_read_write_sync(ar, reg_addr + i, addr_val, | ||
906 | 4, HIF_WR_SYNC_BYTE_FIX); | ||
907 | if (status) | ||
908 | break; | ||
909 | } | ||
910 | |||
911 | if (status) { | ||
912 | ath6kl_err("%s: failed to write initial bytes of 0x%x " | ||
913 | "to window reg: 0x%X\n", __func__, | ||
914 | addr, reg_addr); | ||
915 | return status; | ||
916 | } | ||
917 | |||
918 | /* | ||
919 | * Write the address register again, this time write the whole | ||
920 | * 4-byte value. The effect here is that the LSB write causes the | ||
921 | * cycle to start, the extra 3 byte write to bytes 1,2,3 has no | ||
922 | * effect since we are writing the same values again | ||
923 | */ | ||
924 | status = ath6kl_sdio_read_write_sync(ar, reg_addr, (u8 *)(&addr), | ||
925 | 4, HIF_WR_SYNC_BYTE_INC); | ||
926 | |||
927 | if (status) { | ||
928 | ath6kl_err("%s: failed to write 0x%x to window reg: 0x%X\n", | ||
929 | __func__, addr, reg_addr); | ||
930 | return status; | ||
931 | } | ||
932 | |||
933 | return 0; | ||
934 | } | ||
935 | |||
936 | static int ath6kl_sdio_diag_read32(struct ath6kl *ar, u32 address, u32 *data) | ||
937 | { | ||
938 | int status; | ||
939 | |||
940 | /* set window register to start read cycle */ | ||
941 | status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS, | ||
942 | address); | ||
943 | |||
944 | if (status) | ||
945 | return status; | ||
946 | |||
947 | /* read the data */ | ||
948 | status = ath6kl_sdio_read_write_sync(ar, WINDOW_DATA_ADDRESS, | ||
949 | (u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC); | ||
950 | if (status) { | ||
951 | ath6kl_err("%s: failed to read from window data addr\n", | ||
952 | __func__); | ||
953 | return status; | ||
954 | } | ||
955 | |||
956 | return status; | ||
957 | } | ||
958 | |||
959 | static int ath6kl_sdio_diag_write32(struct ath6kl *ar, u32 address, | ||
960 | __le32 data) | ||
961 | { | ||
962 | int status; | ||
963 | u32 val = (__force u32) data; | ||
964 | |||
965 | /* set write data */ | ||
966 | status = ath6kl_sdio_read_write_sync(ar, WINDOW_DATA_ADDRESS, | ||
967 | (u8 *) &val, sizeof(u32), HIF_WR_SYNC_BYTE_INC); | ||
968 | if (status) { | ||
969 | ath6kl_err("%s: failed to write 0x%x to window data addr\n", | ||
970 | __func__, data); | ||
971 | return status; | ||
972 | } | ||
973 | |||
974 | /* set window register, which starts the write cycle */ | ||
975 | return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS, | ||
976 | address); | ||
977 | } | ||
978 | |||
979 | static int ath6kl_sdio_bmi_credits(struct ath6kl *ar) | ||
980 | { | ||
981 | u32 addr; | ||
982 | unsigned long timeout; | ||
983 | int ret; | ||
984 | |||
985 | ar->bmi.cmd_credits = 0; | ||
986 | |||
987 | /* Read the counter register to get the command credits */ | ||
988 | addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4; | ||
989 | |||
990 | timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT); | ||
991 | while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) { | ||
992 | |||
993 | /* | ||
994 | * Hit the credit counter with a 4-byte access, the first byte | ||
995 | * read will hit the counter and cause a decrement, while the | ||
996 | * remaining 3 bytes has no effect. The rationale behind this | ||
997 | * is to make all HIF accesses 4-byte aligned. | ||
998 | */ | ||
999 | ret = ath6kl_sdio_read_write_sync(ar, addr, | ||
1000 | (u8 *)&ar->bmi.cmd_credits, 4, | ||
1001 | HIF_RD_SYNC_BYTE_INC); | ||
1002 | if (ret) { | ||
1003 | ath6kl_err("Unable to decrement the command credit " | ||
1004 | "count register: %d\n", ret); | ||
1005 | return ret; | ||
1006 | } | ||
1007 | |||
1008 | /* The counter is only 8 bits. | ||
1009 | * Ignore anything in the upper 3 bytes | ||
1010 | */ | ||
1011 | ar->bmi.cmd_credits &= 0xFF; | ||
1012 | } | ||
1013 | |||
1014 | if (!ar->bmi.cmd_credits) { | ||
1015 | ath6kl_err("bmi communication timeout\n"); | ||
1016 | return -ETIMEDOUT; | ||
1017 | } | ||
1018 | |||
1019 | return 0; | ||
1020 | } | ||
1021 | |||
1022 | static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar) | ||
1023 | { | ||
1024 | unsigned long timeout; | ||
1025 | u32 rx_word = 0; | ||
1026 | int ret = 0; | ||
1027 | |||
1028 | timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT); | ||
1029 | while ((time_before(jiffies, timeout)) && !rx_word) { | ||
1030 | ret = ath6kl_sdio_read_write_sync(ar, | ||
1031 | RX_LOOKAHEAD_VALID_ADDRESS, | ||
1032 | (u8 *)&rx_word, sizeof(rx_word), | ||
1033 | HIF_RD_SYNC_BYTE_INC); | ||
1034 | if (ret) { | ||
1035 | ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n"); | ||
1036 | return ret; | ||
1037 | } | ||
1038 | |||
1039 | /* all we really want is one bit */ | ||
1040 | rx_word &= (1 << ENDPOINT1); | ||
1041 | } | ||
1042 | |||
1043 | if (!rx_word) { | ||
1044 | ath6kl_err("bmi_recv_buf FIFO empty\n"); | ||
1045 | return -EINVAL; | ||
1046 | } | ||
1047 | |||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | static int ath6kl_sdio_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) | ||
1052 | { | ||
1053 | int ret; | ||
1054 | u32 addr; | ||
1055 | |||
1056 | ret = ath6kl_sdio_bmi_credits(ar); | ||
1057 | if (ret) | ||
1058 | return ret; | ||
1059 | |||
1060 | addr = ar->mbox_info.htc_addr; | ||
1061 | |||
1062 | ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len, | ||
1063 | HIF_WR_SYNC_BYTE_INC); | ||
1064 | if (ret) | ||
1065 | ath6kl_err("unable to send the bmi data to the device\n"); | ||
1066 | |||
1067 | return ret; | ||
1068 | } | ||
1069 | |||
1070 | static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) | ||
1071 | { | ||
1072 | int ret; | ||
1073 | u32 addr; | ||
1074 | |||
1075 | /* | ||
1076 | * During normal bootup, small reads may be required. | ||
1077 | * Rather than issue an HIF Read and then wait as the Target | ||
1078 | * adds successive bytes to the FIFO, we wait here until | ||
1079 | * we know that response data is available. | ||
1080 | * | ||
1081 | * This allows us to cleanly timeout on an unexpected | ||
1082 | * Target failure rather than risk problems at the HIF level. | ||
1083 | * In particular, this avoids SDIO timeouts and possibly garbage | ||
1084 | * data on some host controllers. And on an interconnect | ||
1085 | * such as Compact Flash (as well as some SDIO masters) which | ||
1086 | * does not provide any indication on data timeout, it avoids | ||
1087 | * a potential hang or garbage response. | ||
1088 | * | ||
1089 | * Synchronization is more difficult for reads larger than the | ||
1090 | * size of the MBOX FIFO (128B), because the Target is unable | ||
1091 | * to push the 129th byte of data until AFTER the Host posts an | ||
1092 | * HIF Read and removes some FIFO data. So for large reads the | ||
1093 | * Host proceeds to post an HIF Read BEFORE all the data is | ||
1094 | * actually available to read. Fortunately, large BMI reads do | ||
1095 | * not occur in practice -- they're supported for debug/development. | ||
1096 | * | ||
1097 | * So Host/Target BMI synchronization is divided into these cases: | ||
1098 | * CASE 1: length < 4 | ||
1099 | * Should not happen | ||
1100 | * | ||
1101 | * CASE 2: 4 <= length <= 128 | ||
1102 | * Wait for first 4 bytes to be in FIFO | ||
1103 | * If CONSERVATIVE_BMI_READ is enabled, also wait for | ||
1104 | * a BMI command credit, which indicates that the ENTIRE | ||
1105 | * response is available in the the FIFO | ||
1106 | * | ||
1107 | * CASE 3: length > 128 | ||
1108 | * Wait for the first 4 bytes to be in FIFO | ||
1109 | * | ||
1110 | * For most uses, a small timeout should be sufficient and we will | ||
1111 | * usually see a response quickly; but there may be some unusual | ||
1112 | * (debug) cases of BMI_EXECUTE where we want an larger timeout. | ||
1113 | * For now, we use an unbounded busy loop while waiting for | ||
1114 | * BMI_EXECUTE. | ||
1115 | * | ||
1116 | * If BMI_EXECUTE ever needs to support longer-latency execution, | ||
1117 | * especially in production, this code needs to be enhanced to sleep | ||
1118 | * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently | ||
1119 | * a function of Host processor speed. | ||
1120 | */ | ||
1121 | if (len >= 4) { /* NB: Currently, always true */ | ||
1122 | ret = ath6kl_bmi_get_rx_lkahd(ar); | ||
1123 | if (ret) | ||
1124 | return ret; | ||
1125 | } | ||
1126 | |||
1127 | addr = ar->mbox_info.htc_addr; | ||
1128 | ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len, | ||
1129 | HIF_RD_SYNC_BYTE_INC); | ||
1130 | if (ret) { | ||
1131 | ath6kl_err("Unable to read the bmi data from the device: %d\n", | ||
1132 | ret); | ||
1133 | return ret; | ||
1134 | } | ||
1135 | |||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
849 | static void ath6kl_sdio_stop(struct ath6kl *ar) | 1139 | static void ath6kl_sdio_stop(struct ath6kl *ar) |
850 | { | 1140 | { |
851 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); | 1141 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); |
@@ -890,6 +1180,10 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = { | |||
890 | .cleanup_scatter = ath6kl_sdio_cleanup_scatter, | 1180 | .cleanup_scatter = ath6kl_sdio_cleanup_scatter, |
891 | .suspend = ath6kl_sdio_suspend, | 1181 | .suspend = ath6kl_sdio_suspend, |
892 | .resume = ath6kl_sdio_resume, | 1182 | .resume = ath6kl_sdio_resume, |
1183 | .diag_read32 = ath6kl_sdio_diag_read32, | ||
1184 | .diag_write32 = ath6kl_sdio_diag_write32, | ||
1185 | .bmi_read = ath6kl_sdio_bmi_read, | ||
1186 | .bmi_write = ath6kl_sdio_bmi_write, | ||
893 | .power_on = ath6kl_sdio_power_on, | 1187 | .power_on = ath6kl_sdio_power_on, |
894 | .power_off = ath6kl_sdio_power_off, | 1188 | .power_off = ath6kl_sdio_power_off, |
895 | .stop = ath6kl_sdio_stop, | 1189 | .stop = ath6kl_sdio_stop, |
@@ -958,6 +1252,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, | |||
958 | spin_lock_init(&ar_sdio->lock); | 1252 | spin_lock_init(&ar_sdio->lock); |
959 | spin_lock_init(&ar_sdio->scat_lock); | 1253 | spin_lock_init(&ar_sdio->scat_lock); |
960 | spin_lock_init(&ar_sdio->wr_async_lock); | 1254 | spin_lock_init(&ar_sdio->wr_async_lock); |
1255 | mutex_init(&ar_sdio->dma_buffer_mutex); | ||
961 | 1256 | ||
962 | INIT_LIST_HEAD(&ar_sdio->scat_req); | 1257 | INIT_LIST_HEAD(&ar_sdio->scat_req); |
963 | INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); | 1258 | INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); |
@@ -976,8 +1271,10 @@ static int ath6kl_sdio_probe(struct sdio_func *func, | |||
976 | } | 1271 | } |
977 | 1272 | ||
978 | ar_sdio->ar = ar; | 1273 | ar_sdio->ar = ar; |
1274 | ar->hif_type = ATH6KL_HIF_TYPE_SDIO; | ||
979 | ar->hif_priv = ar_sdio; | 1275 | ar->hif_priv = ar_sdio; |
980 | ar->hif_ops = &ath6kl_sdio_ops; | 1276 | ar->hif_ops = &ath6kl_sdio_ops; |
1277 | ar->bmi.max_data_size = 256; | ||
981 | 1278 | ||
982 | ath6kl_sdio_set_mbox_info(ar); | 1279 | ath6kl_sdio_set_mbox_info(ar); |
983 | 1280 | ||
@@ -1027,13 +1324,15 @@ static void ath6kl_sdio_remove(struct sdio_func *func) | |||
1027 | static const struct sdio_device_id ath6kl_sdio_devices[] = { | 1324 | static const struct sdio_device_id ath6kl_sdio_devices[] = { |
1028 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0))}, | 1325 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0))}, |
1029 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))}, | 1326 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))}, |
1327 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x0))}, | ||
1328 | {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x1))}, | ||
1030 | {}, | 1329 | {}, |
1031 | }; | 1330 | }; |
1032 | 1331 | ||
1033 | MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); | 1332 | MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); |
1034 | 1333 | ||
1035 | static struct sdio_driver ath6kl_sdio_driver = { | 1334 | static struct sdio_driver ath6kl_sdio_driver = { |
1036 | .name = "ath6kl", | 1335 | .name = "ath6kl_sdio", |
1037 | .id_table = ath6kl_sdio_devices, | 1336 | .id_table = ath6kl_sdio_devices, |
1038 | .probe = ath6kl_sdio_probe, | 1337 | .probe = ath6kl_sdio_probe, |
1039 | .remove = ath6kl_sdio_remove, | 1338 | .remove = ath6kl_sdio_remove, |
@@ -1063,13 +1362,19 @@ MODULE_AUTHOR("Atheros Communications, Inc."); | |||
1063 | MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices"); | 1362 | MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices"); |
1064 | MODULE_LICENSE("Dual BSD/GPL"); | 1363 | MODULE_LICENSE("Dual BSD/GPL"); |
1065 | 1364 | ||
1066 | MODULE_FIRMWARE(AR6003_REV2_OTP_FILE); | 1365 | MODULE_FIRMWARE(AR6003_HW_2_0_OTP_FILE); |
1067 | MODULE_FIRMWARE(AR6003_REV2_FIRMWARE_FILE); | 1366 | MODULE_FIRMWARE(AR6003_HW_2_0_FIRMWARE_FILE); |
1068 | MODULE_FIRMWARE(AR6003_REV2_PATCH_FILE); | 1367 | MODULE_FIRMWARE(AR6003_HW_2_0_PATCH_FILE); |
1069 | MODULE_FIRMWARE(AR6003_REV2_BOARD_DATA_FILE); | 1368 | MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE); |
1070 | MODULE_FIRMWARE(AR6003_REV2_DEFAULT_BOARD_DATA_FILE); | 1369 | MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE); |
1071 | MODULE_FIRMWARE(AR6003_REV3_OTP_FILE); | 1370 | MODULE_FIRMWARE(AR6003_HW_2_1_1_OTP_FILE); |
1072 | MODULE_FIRMWARE(AR6003_REV3_FIRMWARE_FILE); | 1371 | MODULE_FIRMWARE(AR6003_HW_2_1_1_FIRMWARE_FILE); |
1073 | MODULE_FIRMWARE(AR6003_REV3_PATCH_FILE); | 1372 | MODULE_FIRMWARE(AR6003_HW_2_1_1_PATCH_FILE); |
1074 | MODULE_FIRMWARE(AR6003_REV3_BOARD_DATA_FILE); | 1373 | MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE); |
1075 | MODULE_FIRMWARE(AR6003_REV3_DEFAULT_BOARD_DATA_FILE); | 1374 | MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE); |
1375 | MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); | ||
1376 | MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); | ||
1377 | MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); | ||
1378 | MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); | ||
1379 | MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); | ||
1380 | MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); | ||
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h index 687e2b350e8f..108a723a1085 100644 --- a/drivers/net/wireless/ath/ath6kl/target.h +++ b/drivers/net/wireless/ath/ath6kl/target.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #define AR6003_BOARD_DATA_SZ 1024 | 20 | #define AR6003_BOARD_DATA_SZ 1024 |
21 | #define AR6003_BOARD_EXT_DATA_SZ 768 | 21 | #define AR6003_BOARD_EXT_DATA_SZ 768 |
22 | 22 | ||
23 | #define AR6004_BOARD_DATA_SZ 7168 | 23 | #define AR6004_BOARD_DATA_SZ 6144 |
24 | #define AR6004_BOARD_EXT_DATA_SZ 0 | 24 | #define AR6004_BOARD_EXT_DATA_SZ 0 |
25 | 25 | ||
26 | #define RESET_CONTROL_ADDRESS 0x00000000 | 26 | #define RESET_CONTROL_ADDRESS 0x00000000 |
@@ -334,20 +334,6 @@ struct host_interest { | |||
334 | (((target_type) == TARGET_TYPE_AR6003) ? AR6003_VTOP(vaddr) : \ | 334 | (((target_type) == TARGET_TYPE_AR6003) ? AR6003_VTOP(vaddr) : \ |
335 | (((target_type) == TARGET_TYPE_AR6004) ? AR6004_VTOP(vaddr) : 0)) | 335 | (((target_type) == TARGET_TYPE_AR6004) ? AR6004_VTOP(vaddr) : 0)) |
336 | 336 | ||
337 | #define AR6003_REV2_APP_LOAD_ADDRESS 0x543180 | ||
338 | #define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500 | ||
339 | #define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884 | ||
340 | #define AR6003_REV2_RAM_RESERVE_SIZE 6912 | ||
341 | |||
342 | #define AR6003_REV3_APP_LOAD_ADDRESS 0x545000 | ||
343 | #define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330 | ||
344 | #define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74 | ||
345 | #define AR6003_REV3_RAM_RESERVE_SIZE 512 | ||
346 | |||
347 | #define AR6004_REV1_BOARD_DATA_ADDRESS 0x435400 | ||
348 | #define AR6004_REV1_BOARD_EXT_DATA_ADDRESS 0x437000 | ||
349 | #define AR6004_REV1_RAM_RESERVE_SIZE 11264 | ||
350 | |||
351 | #define ATH6KL_FWLOG_PAYLOAD_SIZE 1500 | 337 | #define ATH6KL_FWLOG_PAYLOAD_SIZE 1500 |
352 | 338 | ||
353 | struct ath6kl_dbglog_buf { | 339 | struct ath6kl_dbglog_buf { |
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index d9cff2b950b1..506a3031a885 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c | |||
@@ -453,11 +453,11 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, | |||
453 | set_bit(WMI_CTRL_EP_FULL, &ar->flag); | 453 | set_bit(WMI_CTRL_EP_FULL, &ar->flag); |
454 | spin_unlock_bh(&ar->lock); | 454 | spin_unlock_bh(&ar->lock); |
455 | ath6kl_err("wmi ctrl ep is full\n"); | 455 | ath6kl_err("wmi ctrl ep is full\n"); |
456 | goto stop_adhoc_netq; | 456 | return action; |
457 | } | 457 | } |
458 | 458 | ||
459 | if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG) | 459 | if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG) |
460 | goto stop_adhoc_netq; | 460 | return action; |
461 | 461 | ||
462 | /* | 462 | /* |
463 | * The last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for | 463 | * The last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for |
@@ -465,20 +465,18 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, | |||
465 | */ | 465 | */ |
466 | if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] < | 466 | if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] < |
467 | ar->hiac_stream_active_pri && | 467 | ar->hiac_stream_active_pri && |
468 | ar->cookie_count <= MAX_HI_COOKIE_NUM) { | 468 | ar->cookie_count <= MAX_HI_COOKIE_NUM) |
469 | /* | 469 | /* |
470 | * Give preference to the highest priority stream by | 470 | * Give preference to the highest priority stream by |
471 | * dropping the packets which overflowed. | 471 | * dropping the packets which overflowed. |
472 | */ | 472 | */ |
473 | action = HTC_SEND_FULL_DROP; | 473 | action = HTC_SEND_FULL_DROP; |
474 | goto stop_adhoc_netq; | ||
475 | } | ||
476 | 474 | ||
477 | stop_adhoc_netq: | ||
478 | /* FIXME: Locking */ | 475 | /* FIXME: Locking */ |
479 | spin_lock_bh(&ar->list_lock); | 476 | spin_lock_bh(&ar->list_lock); |
480 | list_for_each_entry(vif, &ar->vif_list, list) { | 477 | list_for_each_entry(vif, &ar->vif_list, list) { |
481 | if (vif->nw_type == ADHOC_NETWORK) { | 478 | if (vif->nw_type == ADHOC_NETWORK || |
479 | action != HTC_SEND_FULL_DROP) { | ||
482 | spin_unlock_bh(&ar->list_lock); | 480 | spin_unlock_bh(&ar->list_lock); |
483 | 481 | ||
484 | spin_lock_bh(&vif->if_lock); | 482 | spin_lock_bh(&vif->if_lock); |
@@ -543,7 +541,7 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue) | |||
543 | int status; | 541 | int status; |
544 | enum htc_endpoint_id eid; | 542 | enum htc_endpoint_id eid; |
545 | bool wake_event = false; | 543 | bool wake_event = false; |
546 | bool flushing[MAX_NUM_VIF] = {false}; | 544 | bool flushing[ATH6KL_VIF_MAX] = {false}; |
547 | u8 if_idx; | 545 | u8 if_idx; |
548 | struct ath6kl_vif *vif; | 546 | struct ath6kl_vif *vif; |
549 | 547 | ||
@@ -571,8 +569,6 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue) | |||
571 | if (!skb || !skb->data) | 569 | if (!skb || !skb->data) |
572 | goto fatal; | 570 | goto fatal; |
573 | 571 | ||
574 | packet->buf = skb->data; | ||
575 | |||
576 | __skb_queue_tail(&skb_queue, skb); | 572 | __skb_queue_tail(&skb_queue, skb); |
577 | 573 | ||
578 | if (!status && (packet->act_len != skb->len)) | 574 | if (!status && (packet->act_len != skb->len)) |
@@ -593,10 +589,10 @@ void ath6kl_tx_complete(void *context, struct list_head *packet_queue) | |||
593 | 589 | ||
594 | if (eid == ar->ctrl_ep) { | 590 | if (eid == ar->ctrl_ep) { |
595 | if_idx = wmi_cmd_hdr_get_if_idx( | 591 | if_idx = wmi_cmd_hdr_get_if_idx( |
596 | (struct wmi_cmd_hdr *) skb->data); | 592 | (struct wmi_cmd_hdr *) packet->buf); |
597 | } else { | 593 | } else { |
598 | if_idx = wmi_data_hdr_get_if_idx( | 594 | if_idx = wmi_data_hdr_get_if_idx( |
599 | (struct wmi_data_hdr *) skb->data); | 595 | (struct wmi_data_hdr *) packet->buf); |
600 | } | 596 | } |
601 | 597 | ||
602 | vif = ath6kl_get_vif_by_index(ar, if_idx); | 598 | vif = ath6kl_get_vif_by_index(ar, if_idx); |
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c new file mode 100644 index 000000000000..e3cf397fcafe --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/usb.c | |||
@@ -0,0 +1,431 @@ | |||
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 */ | ||
24 | struct 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 | |||
41 | struct ath6kl_usb_ctrl_diag_cmd_write { | ||
42 | __le32 cmd; | ||
43 | __le32 address; | ||
44 | __le32 value; | ||
45 | __le32 _pad[1]; | ||
46 | } __packed; | ||
47 | |||
48 | struct ath6kl_usb_ctrl_diag_cmd_read { | ||
49 | __le32 cmd; | ||
50 | __le32 address; | ||
51 | } __packed; | ||
52 | |||
53 | struct 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 | |||
60 | static 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 | |||
70 | static 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 | |||
98 | fail_ath6kl_usb_create: | ||
99 | if (status != 0) { | ||
100 | ath6kl_usb_destroy(ar_usb); | ||
101 | ar_usb = NULL; | ||
102 | } | ||
103 | return ar_usb; | ||
104 | } | ||
105 | |||
106 | static 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 | |||
121 | static 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 | |||
154 | static 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 | |||
187 | static 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 | |||
212 | static 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 | |||
245 | static 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 | |||
265 | static 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 | |||
283 | static 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 | |||
301 | static int ath6kl_usb_power_on(struct ath6kl *ar) | ||
302 | { | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static int ath6kl_usb_power_off(struct ath6kl *ar) | ||
307 | { | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static 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 */ | ||
321 | static 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 | |||
378 | err_core_free: | ||
379 | ath6kl_core_free(ar); | ||
380 | err_usb_destroy: | ||
381 | ath6kl_usb_destroy(ar_usb); | ||
382 | err_usb_put: | ||
383 | usb_put_dev(dev); | ||
384 | |||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | static 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 */ | ||
395 | static struct usb_device_id ath6kl_usb_ids[] = { | ||
396 | {USB_DEVICE(0x0cf3, 0x9374)}, | ||
397 | { /* Terminating entry */ }, | ||
398 | }; | ||
399 | |||
400 | MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids); | ||
401 | |||
402 | static 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 | |||
409 | static int ath6kl_usb_init(void) | ||
410 | { | ||
411 | usb_register(&ath6kl_usb_driver); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static void ath6kl_usb_exit(void) | ||
416 | { | ||
417 | usb_deregister(&ath6kl_usb_driver); | ||
418 | } | ||
419 | |||
420 | module_init(ath6kl_usb_init); | ||
421 | module_exit(ath6kl_usb_exit); | ||
422 | |||
423 | MODULE_AUTHOR("Atheros Communications, Inc."); | ||
424 | MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); | ||
425 | MODULE_LICENSE("Dual BSD/GPL"); | ||
426 | MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); | ||
427 | MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); | ||
428 | MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); | ||
429 | MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); | ||
430 | MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); | ||
431 | MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); | ||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 922344d3b262..f6f2aa27fc20 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -85,7 +85,7 @@ struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx) | |||
85 | { | 85 | { |
86 | struct ath6kl_vif *vif, *found = NULL; | 86 | struct ath6kl_vif *vif, *found = NULL; |
87 | 87 | ||
88 | if (WARN_ON(if_idx > (MAX_NUM_VIF - 1))) | 88 | if (WARN_ON(if_idx > (ar->vif_max - 1))) |
89 | return NULL; | 89 | return NULL; |
90 | 90 | ||
91 | /* FIXME: Locking */ | 91 | /* FIXME: Locking */ |
@@ -187,7 +187,7 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, | |||
187 | struct wmi_data_hdr *data_hdr; | 187 | struct wmi_data_hdr *data_hdr; |
188 | int ret; | 188 | int ret; |
189 | 189 | ||
190 | if (WARN_ON(skb == NULL || (if_idx > MAX_NUM_VIF - 1))) | 190 | if (WARN_ON(skb == NULL || (if_idx > wmi->parent_dev->vif_max - 1))) |
191 | return -EINVAL; | 191 | return -EINVAL; |
192 | 192 | ||
193 | if (tx_meta_info) { | 193 | if (tx_meta_info) { |
@@ -977,6 +977,13 @@ static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
977 | return 0; | 977 | return 0; |
978 | } | 978 | } |
979 | 979 | ||
980 | void ath6kl_wmi_sscan_timer(unsigned long ptr) | ||
981 | { | ||
982 | struct ath6kl_vif *vif = (struct ath6kl_vif *) ptr; | ||
983 | |||
984 | cfg80211_sched_scan_results(vif->ar->wiphy); | ||
985 | } | ||
986 | |||
980 | static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, | 987 | static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, |
981 | struct ath6kl_vif *vif) | 988 | struct ath6kl_vif *vif) |
982 | { | 989 | { |
@@ -1066,6 +1073,21 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
1066 | return -ENOMEM; | 1073 | return -ENOMEM; |
1067 | cfg80211_put_bss(bss); | 1074 | cfg80211_put_bss(bss); |
1068 | 1075 | ||
1076 | /* | ||
1077 | * Firmware doesn't return any event when scheduled scan has | ||
1078 | * finished, so we need to use a timer to find out when there are | ||
1079 | * no more results. | ||
1080 | * | ||
1081 | * The timer is started from the first bss info received, otherwise | ||
1082 | * the timer would not ever fire if the scan interval is short | ||
1083 | * enough. | ||
1084 | */ | ||
1085 | if (ar->state == ATH6KL_STATE_SCHED_SCAN && | ||
1086 | !timer_pending(&vif->sched_scan_timer)) { | ||
1087 | mod_timer(&vif->sched_scan_timer, jiffies + | ||
1088 | msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY)); | ||
1089 | } | ||
1090 | |||
1069 | return 0; | 1091 | return 0; |
1070 | } | 1092 | } |
1071 | 1093 | ||
@@ -1620,7 +1642,7 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, | |||
1620 | int ret; | 1642 | int ret; |
1621 | u16 info1; | 1643 | u16 info1; |
1622 | 1644 | ||
1623 | if (WARN_ON(skb == NULL || (if_idx > (MAX_NUM_VIF - 1)))) | 1645 | if (WARN_ON(skb == NULL || (if_idx > (wmi->parent_dev->vif_max - 1)))) |
1624 | return -EINVAL; | 1646 | return -EINVAL; |
1625 | 1647 | ||
1626 | ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n", | 1648 | ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n", |
@@ -1682,7 +1704,8 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, | |||
1682 | u8 pairwise_crypto_len, | 1704 | u8 pairwise_crypto_len, |
1683 | enum crypto_type group_crypto, | 1705 | enum crypto_type group_crypto, |
1684 | u8 group_crypto_len, int ssid_len, u8 *ssid, | 1706 | u8 group_crypto_len, int ssid_len, u8 *ssid, |
1685 | u8 *bssid, u16 channel, u32 ctrl_flags) | 1707 | u8 *bssid, u16 channel, u32 ctrl_flags, |
1708 | u8 nw_subtype) | ||
1686 | { | 1709 | { |
1687 | struct sk_buff *skb; | 1710 | struct sk_buff *skb; |
1688 | struct wmi_connect_cmd *cc; | 1711 | struct wmi_connect_cmd *cc; |
@@ -1722,6 +1745,7 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, | |||
1722 | cc->grp_crypto_len = group_crypto_len; | 1745 | cc->grp_crypto_len = group_crypto_len; |
1723 | cc->ch = cpu_to_le16(channel); | 1746 | cc->ch = cpu_to_le16(channel); |
1724 | cc->ctrl_flags = cpu_to_le32(ctrl_flags); | 1747 | cc->ctrl_flags = cpu_to_le32(ctrl_flags); |
1748 | cc->nw_subtype = nw_subtype; | ||
1725 | 1749 | ||
1726 | if (bssid != NULL) | 1750 | if (bssid != NULL) |
1727 | memcpy(cc->bssid, bssid, ETH_ALEN); | 1751 | memcpy(cc->bssid, bssid, ETH_ALEN); |
@@ -1774,6 +1798,72 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx) | |||
1774 | return ret; | 1798 | return ret; |
1775 | } | 1799 | } |
1776 | 1800 | ||
1801 | int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | ||
1802 | enum wmi_scan_type scan_type, | ||
1803 | u32 force_fgscan, u32 is_legacy, | ||
1804 | u32 home_dwell_time, u32 force_scan_interval, | ||
1805 | s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates) | ||
1806 | { | ||
1807 | struct sk_buff *skb; | ||
1808 | struct wmi_begin_scan_cmd *sc; | ||
1809 | s8 size; | ||
1810 | int i, band, ret; | ||
1811 | struct ath6kl *ar = wmi->parent_dev; | ||
1812 | int num_rates; | ||
1813 | |||
1814 | size = sizeof(struct wmi_begin_scan_cmd); | ||
1815 | |||
1816 | if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) | ||
1817 | return -EINVAL; | ||
1818 | |||
1819 | if (num_chan > WMI_MAX_CHANNELS) | ||
1820 | return -EINVAL; | ||
1821 | |||
1822 | if (num_chan) | ||
1823 | size += sizeof(u16) * (num_chan - 1); | ||
1824 | |||
1825 | skb = ath6kl_wmi_get_new_buf(size); | ||
1826 | if (!skb) | ||
1827 | return -ENOMEM; | ||
1828 | |||
1829 | sc = (struct wmi_begin_scan_cmd *) skb->data; | ||
1830 | sc->scan_type = scan_type; | ||
1831 | sc->force_fg_scan = cpu_to_le32(force_fgscan); | ||
1832 | sc->is_legacy = cpu_to_le32(is_legacy); | ||
1833 | sc->home_dwell_time = cpu_to_le32(home_dwell_time); | ||
1834 | sc->force_scan_intvl = cpu_to_le32(force_scan_interval); | ||
1835 | sc->no_cck = cpu_to_le32(no_cck); | ||
1836 | sc->num_ch = num_chan; | ||
1837 | |||
1838 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
1839 | struct ieee80211_supported_band *sband = | ||
1840 | ar->wiphy->bands[band]; | ||
1841 | u32 ratemask = rates[band]; | ||
1842 | u8 *supp_rates = sc->supp_rates[band].rates; | ||
1843 | num_rates = 0; | ||
1844 | |||
1845 | for (i = 0; i < sband->n_bitrates; i++) { | ||
1846 | if ((BIT(i) & ratemask) == 0) | ||
1847 | continue; /* skip rate */ | ||
1848 | supp_rates[num_rates++] = | ||
1849 | (u8) (sband->bitrates[i].bitrate / 5); | ||
1850 | } | ||
1851 | sc->supp_rates[band].nrates = num_rates; | ||
1852 | } | ||
1853 | |||
1854 | for (i = 0; i < num_chan; i++) | ||
1855 | sc->ch_list[i] = cpu_to_le16(ch_list[i]); | ||
1856 | |||
1857 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_BEGIN_SCAN_CMDID, | ||
1858 | NO_SYNC_WMIFLAG); | ||
1859 | |||
1860 | return ret; | ||
1861 | } | ||
1862 | |||
1863 | /* ath6kl_wmi_start_scan_cmd is to be deprecated. Use | ||
1864 | * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P | ||
1865 | * mgmt operations using station interface. | ||
1866 | */ | ||
1777 | int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, | 1867 | int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, |
1778 | enum wmi_scan_type scan_type, | 1868 | enum wmi_scan_type scan_type, |
1779 | u32 force_fgscan, u32 is_legacy, | 1869 | u32 force_fgscan, u32 is_legacy, |
@@ -2940,7 +3030,10 @@ int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, | |||
2940 | p = (struct wmi_set_appie_cmd *) skb->data; | 3030 | p = (struct wmi_set_appie_cmd *) skb->data; |
2941 | p->mgmt_frm_type = mgmt_frm_type; | 3031 | p->mgmt_frm_type = mgmt_frm_type; |
2942 | p->ie_len = ie_len; | 3032 | p->ie_len = ie_len; |
2943 | memcpy(p->ie_info, ie, ie_len); | 3033 | |
3034 | if (ie != NULL && ie_len > 0) | ||
3035 | memcpy(p->ie_info, ie, ie_len); | ||
3036 | |||
2944 | return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_APPIE_CMDID, | 3037 | return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_APPIE_CMDID, |
2945 | NO_SYNC_WMIFLAG); | 3038 | NO_SYNC_WMIFLAG); |
2946 | } | 3039 | } |
@@ -2981,6 +3074,10 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur) | |||
2981 | NO_SYNC_WMIFLAG); | 3074 | NO_SYNC_WMIFLAG); |
2982 | } | 3075 | } |
2983 | 3076 | ||
3077 | /* ath6kl_wmi_send_action_cmd is to be deprecated. Use | ||
3078 | * ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P | ||
3079 | * mgmt operations using station interface. | ||
3080 | */ | ||
2984 | int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | 3081 | int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, |
2985 | u32 wait, const u8 *data, u16 data_len) | 3082 | u32 wait, const u8 *data, u16 data_len) |
2986 | { | 3083 | { |
@@ -3018,14 +3115,57 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | |||
3018 | NO_SYNC_WMIFLAG); | 3115 | NO_SYNC_WMIFLAG); |
3019 | } | 3116 | } |
3020 | 3117 | ||
3118 | int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | ||
3119 | u32 wait, const u8 *data, u16 data_len, | ||
3120 | u32 no_cck) | ||
3121 | { | ||
3122 | struct sk_buff *skb; | ||
3123 | struct wmi_send_mgmt_cmd *p; | ||
3124 | u8 *buf; | ||
3125 | |||
3126 | if (wait) | ||
3127 | return -EINVAL; /* Offload for wait not supported */ | ||
3128 | |||
3129 | buf = kmalloc(data_len, GFP_KERNEL); | ||
3130 | if (!buf) | ||
3131 | return -ENOMEM; | ||
3132 | |||
3133 | skb = ath6kl_wmi_get_new_buf(sizeof(*p) + data_len); | ||
3134 | if (!skb) { | ||
3135 | kfree(buf); | ||
3136 | return -ENOMEM; | ||
3137 | } | ||
3138 | |||
3139 | kfree(wmi->last_mgmt_tx_frame); | ||
3140 | memcpy(buf, data, data_len); | ||
3141 | wmi->last_mgmt_tx_frame = buf; | ||
3142 | wmi->last_mgmt_tx_frame_len = data_len; | ||
3143 | |||
3144 | ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u " | ||
3145 | "len=%u\n", id, freq, wait, data_len); | ||
3146 | p = (struct wmi_send_mgmt_cmd *) skb->data; | ||
3147 | p->id = cpu_to_le32(id); | ||
3148 | p->freq = cpu_to_le32(freq); | ||
3149 | p->wait = cpu_to_le32(wait); | ||
3150 | p->no_cck = cpu_to_le32(no_cck); | ||
3151 | p->len = cpu_to_le16(data_len); | ||
3152 | memcpy(p->data, data, data_len); | ||
3153 | return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_MGMT_CMDID, | ||
3154 | NO_SYNC_WMIFLAG); | ||
3155 | } | ||
3156 | |||
3021 | int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, | 3157 | int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, |
3022 | const u8 *dst, const u8 *data, | 3158 | const u8 *dst, const u8 *data, |
3023 | u16 data_len) | 3159 | u16 data_len) |
3024 | { | 3160 | { |
3025 | struct sk_buff *skb; | 3161 | struct sk_buff *skb; |
3026 | struct wmi_p2p_probe_response_cmd *p; | 3162 | struct wmi_p2p_probe_response_cmd *p; |
3163 | size_t cmd_len = sizeof(*p) + data_len; | ||
3027 | 3164 | ||
3028 | skb = ath6kl_wmi_get_new_buf(sizeof(*p) + data_len); | 3165 | if (data_len == 0) |
3166 | cmd_len++; /* work around target minimum length requirement */ | ||
3167 | |||
3168 | skb = ath6kl_wmi_get_new_buf(cmd_len); | ||
3029 | if (!skb) | 3169 | if (!skb) |
3030 | return -ENOMEM; | 3170 | return -ENOMEM; |
3031 | 3171 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 76342d5a1906..42ac311eda4e 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h | |||
@@ -329,6 +329,10 @@ enum wmi_cmd_id { | |||
329 | WMI_SYNCHRONIZE_CMDID, | 329 | WMI_SYNCHRONIZE_CMDID, |
330 | WMI_CREATE_PSTREAM_CMDID, | 330 | WMI_CREATE_PSTREAM_CMDID, |
331 | WMI_DELETE_PSTREAM_CMDID, | 331 | WMI_DELETE_PSTREAM_CMDID, |
332 | /* WMI_START_SCAN_CMDID is to be deprecated. Use | ||
333 | * WMI_BEGIN_SCAN_CMDID instead. The new cmd supports P2P mgmt | ||
334 | * operations using station interface. | ||
335 | */ | ||
332 | WMI_START_SCAN_CMDID, | 336 | WMI_START_SCAN_CMDID, |
333 | WMI_SET_SCAN_PARAMS_CMDID, | 337 | WMI_SET_SCAN_PARAMS_CMDID, |
334 | WMI_SET_BSS_FILTER_CMDID, | 338 | WMI_SET_BSS_FILTER_CMDID, |
@@ -542,12 +546,61 @@ enum wmi_cmd_id { | |||
542 | WMI_GTK_OFFLOAD_OP_CMDID, | 546 | WMI_GTK_OFFLOAD_OP_CMDID, |
543 | WMI_REMAIN_ON_CHNL_CMDID, | 547 | WMI_REMAIN_ON_CHNL_CMDID, |
544 | WMI_CANCEL_REMAIN_ON_CHNL_CMDID, | 548 | WMI_CANCEL_REMAIN_ON_CHNL_CMDID, |
549 | /* WMI_SEND_ACTION_CMDID is to be deprecated. Use | ||
550 | * WMI_SEND_MGMT_CMDID instead. The new cmd supports P2P mgmt | ||
551 | * operations using station interface. | ||
552 | */ | ||
545 | WMI_SEND_ACTION_CMDID, | 553 | WMI_SEND_ACTION_CMDID, |
546 | WMI_PROBE_REQ_REPORT_CMDID, | 554 | WMI_PROBE_REQ_REPORT_CMDID, |
547 | WMI_DISABLE_11B_RATES_CMDID, | 555 | WMI_DISABLE_11B_RATES_CMDID, |
548 | WMI_SEND_PROBE_RESPONSE_CMDID, | 556 | WMI_SEND_PROBE_RESPONSE_CMDID, |
549 | WMI_GET_P2P_INFO_CMDID, | 557 | WMI_GET_P2P_INFO_CMDID, |
550 | WMI_AP_JOIN_BSS_CMDID, | 558 | WMI_AP_JOIN_BSS_CMDID, |
559 | |||
560 | WMI_SMPS_ENABLE_CMDID, | ||
561 | WMI_SMPS_CONFIG_CMDID, | ||
562 | WMI_SET_RATECTRL_PARM_CMDID, | ||
563 | /* LPL specific commands*/ | ||
564 | WMI_LPL_FORCE_ENABLE_CMDID, | ||
565 | WMI_LPL_SET_POLICY_CMDID, | ||
566 | WMI_LPL_GET_POLICY_CMDID, | ||
567 | WMI_LPL_GET_HWSTATE_CMDID, | ||
568 | WMI_LPL_SET_PARAMS_CMDID, | ||
569 | WMI_LPL_GET_PARAMS_CMDID, | ||
570 | |||
571 | WMI_SET_BUNDLE_PARAM_CMDID, | ||
572 | |||
573 | /*GreenTx specific commands*/ | ||
574 | |||
575 | WMI_GREENTX_PARAMS_CMDID, | ||
576 | |||
577 | WMI_RTT_MEASREQ_CMDID, | ||
578 | WMI_RTT_CAPREQ_CMDID, | ||
579 | WMI_RTT_STATUSREQ_CMDID, | ||
580 | |||
581 | /* WPS Commands */ | ||
582 | WMI_WPS_START_CMDID, | ||
583 | WMI_GET_WPS_STATUS_CMDID, | ||
584 | |||
585 | /* More P2P commands */ | ||
586 | WMI_SET_NOA_CMDID, | ||
587 | WMI_GET_NOA_CMDID, | ||
588 | WMI_SET_OPPPS_CMDID, | ||
589 | WMI_GET_OPPPS_CMDID, | ||
590 | WMI_ADD_PORT_CMDID, | ||
591 | WMI_DEL_PORT_CMDID, | ||
592 | |||
593 | /* 802.11w cmd */ | ||
594 | WMI_SET_RSN_CAP_CMDID, | ||
595 | WMI_GET_RSN_CAP_CMDID, | ||
596 | WMI_SET_IGTK_CMDID, | ||
597 | |||
598 | WMI_RX_FILTER_COALESCE_FILTER_OP_CMDID, | ||
599 | WMI_RX_FILTER_SET_FRAME_TEST_LIST_CMDID, | ||
600 | |||
601 | WMI_SEND_MGMT_CMDID, | ||
602 | WMI_BEGIN_SCAN_CMDID, | ||
603 | |||
551 | }; | 604 | }; |
552 | 605 | ||
553 | enum wmi_mgmt_frame_type { | 606 | enum wmi_mgmt_frame_type { |
@@ -567,6 +620,14 @@ enum network_type { | |||
567 | AP_NETWORK = 0x10, | 620 | AP_NETWORK = 0x10, |
568 | }; | 621 | }; |
569 | 622 | ||
623 | enum network_subtype { | ||
624 | SUBTYPE_NONE, | ||
625 | SUBTYPE_BT, | ||
626 | SUBTYPE_P2PDEV, | ||
627 | SUBTYPE_P2PCLIENT, | ||
628 | SUBTYPE_P2PGO, | ||
629 | }; | ||
630 | |||
570 | enum dot11_auth_mode { | 631 | enum dot11_auth_mode { |
571 | OPEN_AUTH = 0x01, | 632 | OPEN_AUTH = 0x01, |
572 | SHARED_AUTH = 0x02, | 633 | SHARED_AUTH = 0x02, |
@@ -639,6 +700,7 @@ struct wmi_connect_cmd { | |||
639 | __le16 ch; | 700 | __le16 ch; |
640 | u8 bssid[ETH_ALEN]; | 701 | u8 bssid[ETH_ALEN]; |
641 | __le32 ctrl_flags; | 702 | __le32 ctrl_flags; |
703 | u8 nw_subtype; | ||
642 | } __packed; | 704 | } __packed; |
643 | 705 | ||
644 | /* WMI_RECONNECT_CMDID */ | 706 | /* WMI_RECONNECT_CMDID */ |
@@ -726,7 +788,12 @@ enum wmi_scan_type { | |||
726 | WMI_SHORT_SCAN = 1, | 788 | WMI_SHORT_SCAN = 1, |
727 | }; | 789 | }; |
728 | 790 | ||
729 | struct wmi_start_scan_cmd { | 791 | struct wmi_supp_rates { |
792 | u8 nrates; | ||
793 | u8 rates[ATH6KL_RATE_MAXSIZE]; | ||
794 | }; | ||
795 | |||
796 | struct wmi_begin_scan_cmd { | ||
730 | __le32 force_fg_scan; | 797 | __le32 force_fg_scan; |
731 | 798 | ||
732 | /* for legacy cisco AP compatibility */ | 799 | /* for legacy cisco AP compatibility */ |
@@ -738,9 +805,15 @@ struct wmi_start_scan_cmd { | |||
738 | /* time interval between scans (msec) */ | 805 | /* time interval between scans (msec) */ |
739 | __le32 force_scan_intvl; | 806 | __le32 force_scan_intvl; |
740 | 807 | ||
808 | /* no CCK rates */ | ||
809 | __le32 no_cck; | ||
810 | |||
741 | /* enum wmi_scan_type */ | 811 | /* enum wmi_scan_type */ |
742 | u8 scan_type; | 812 | u8 scan_type; |
743 | 813 | ||
814 | /* Supported rates to advertise in the probe request frames */ | ||
815 | struct wmi_supp_rates supp_rates[IEEE80211_NUM_BANDS]; | ||
816 | |||
744 | /* how many channels follow */ | 817 | /* how many channels follow */ |
745 | u8 num_ch; | 818 | u8 num_ch; |
746 | 819 | ||
@@ -748,8 +821,31 @@ struct wmi_start_scan_cmd { | |||
748 | __le16 ch_list[1]; | 821 | __le16 ch_list[1]; |
749 | } __packed; | 822 | } __packed; |
750 | 823 | ||
751 | /* WMI_SET_SCAN_PARAMS_CMDID */ | 824 | /* wmi_start_scan_cmd is to be deprecated. Use |
752 | #define WMI_SHORTSCANRATIO_DEFAULT 3 | 825 | * wmi_begin_scan_cmd instead. The new structure supports P2P mgmt |
826 | * operations using station interface. | ||
827 | */ | ||
828 | struct wmi_start_scan_cmd { | ||
829 | __le32 force_fg_scan; | ||
830 | |||
831 | /* for legacy cisco AP compatibility */ | ||
832 | __le32 is_legacy; | ||
833 | |||
834 | /* max duration in the home channel(msec) */ | ||
835 | __le32 home_dwell_time; | ||
836 | |||
837 | /* time interval between scans (msec) */ | ||
838 | __le32 force_scan_intvl; | ||
839 | |||
840 | /* enum wmi_scan_type */ | ||
841 | u8 scan_type; | ||
842 | |||
843 | /* how many channels follow */ | ||
844 | u8 num_ch; | ||
845 | |||
846 | /* channels in Mhz */ | ||
847 | __le16 ch_list[1]; | ||
848 | } __packed; | ||
753 | 849 | ||
754 | /* | 850 | /* |
755 | * Warning: scan control flag value of 0xFF is used to disable | 851 | * Warning: scan control flag value of 0xFF is used to disable |
@@ -783,13 +879,6 @@ enum wmi_scan_ctrl_flags_bits { | |||
783 | ENABLE_SCAN_ABORT_EVENT = 0x40 | 879 | ENABLE_SCAN_ABORT_EVENT = 0x40 |
784 | }; | 880 | }; |
785 | 881 | ||
786 | #define DEFAULT_SCAN_CTRL_FLAGS \ | ||
787 | (CONNECT_SCAN_CTRL_FLAGS | \ | ||
788 | SCAN_CONNECTED_CTRL_FLAGS | \ | ||
789 | ACTIVE_SCAN_CTRL_FLAGS | \ | ||
790 | ROAM_SCAN_CTRL_FLAGS | \ | ||
791 | ENABLE_AUTO_CTRL_FLAGS) | ||
792 | |||
793 | struct wmi_scan_params_cmd { | 882 | struct wmi_scan_params_cmd { |
794 | /* sec */ | 883 | /* sec */ |
795 | __le16 fg_start_period; | 884 | __le16 fg_start_period; |
@@ -1818,7 +1907,7 @@ struct wmi_set_ip_cmd { | |||
1818 | } __packed; | 1907 | } __packed; |
1819 | 1908 | ||
1820 | enum ath6kl_wow_filters { | 1909 | enum ath6kl_wow_filters { |
1821 | WOW_FILTER_SSID = BIT(0), | 1910 | WOW_FILTER_SSID = BIT(1), |
1822 | WOW_FILTER_OPTION_MAGIC_PACKET = BIT(2), | 1911 | WOW_FILTER_OPTION_MAGIC_PACKET = BIT(2), |
1823 | WOW_FILTER_OPTION_EAP_REQ = BIT(3), | 1912 | WOW_FILTER_OPTION_EAP_REQ = BIT(3), |
1824 | WOW_FILTER_OPTION_PATTERNS = BIT(4), | 1913 | WOW_FILTER_OPTION_PATTERNS = BIT(4), |
@@ -1963,7 +2052,7 @@ struct wmi_tx_complete_event { | |||
1963 | * !!! Warning !!! | 2052 | * !!! Warning !!! |
1964 | * -Changing the following values needs compilation of both driver and firmware | 2053 | * -Changing the following values needs compilation of both driver and firmware |
1965 | */ | 2054 | */ |
1966 | #define AP_MAX_NUM_STA 8 | 2055 | #define AP_MAX_NUM_STA 10 |
1967 | 2056 | ||
1968 | /* Spl. AID used to set DTIM flag in the beacons */ | 2057 | /* Spl. AID used to set DTIM flag in the beacons */ |
1969 | #define MCAST_AID 0xFF | 2058 | #define MCAST_AID 0xFF |
@@ -2046,6 +2135,10 @@ struct wmi_remain_on_chnl_cmd { | |||
2046 | __le32 duration; | 2135 | __le32 duration; |
2047 | } __packed; | 2136 | } __packed; |
2048 | 2137 | ||
2138 | /* wmi_send_action_cmd is to be deprecated. Use | ||
2139 | * wmi_send_mgmt_cmd instead. The new structure supports P2P mgmt | ||
2140 | * operations using station interface. | ||
2141 | */ | ||
2049 | struct wmi_send_action_cmd { | 2142 | struct wmi_send_action_cmd { |
2050 | __le32 id; | 2143 | __le32 id; |
2051 | __le32 freq; | 2144 | __le32 freq; |
@@ -2054,6 +2147,15 @@ struct wmi_send_action_cmd { | |||
2054 | u8 data[0]; | 2147 | u8 data[0]; |
2055 | } __packed; | 2148 | } __packed; |
2056 | 2149 | ||
2150 | struct wmi_send_mgmt_cmd { | ||
2151 | __le32 id; | ||
2152 | __le32 freq; | ||
2153 | __le32 wait; | ||
2154 | __le32 no_cck; | ||
2155 | __le16 len; | ||
2156 | u8 data[0]; | ||
2157 | } __packed; | ||
2158 | |||
2057 | struct wmi_tx_status_event { | 2159 | struct wmi_tx_status_event { |
2058 | __le32 id; | 2160 | __le32 id; |
2059 | u8 ack_status; | 2161 | u8 ack_status; |
@@ -2242,7 +2344,8 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, | |||
2242 | u8 pairwise_crypto_len, | 2344 | u8 pairwise_crypto_len, |
2243 | enum crypto_type group_crypto, | 2345 | enum crypto_type group_crypto, |
2244 | u8 group_crypto_len, int ssid_len, u8 *ssid, | 2346 | u8 group_crypto_len, int ssid_len, u8 *ssid, |
2245 | u8 *bssid, u16 channel, u32 ctrl_flags); | 2347 | u8 *bssid, u16 channel, u32 ctrl_flags, |
2348 | u8 nw_subtype); | ||
2246 | 2349 | ||
2247 | int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, | 2350 | int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, |
2248 | u16 channel); | 2351 | u16 channel); |
@@ -2252,6 +2355,14 @@ int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, | |||
2252 | u32 force_fgscan, u32 is_legacy, | 2355 | u32 force_fgscan, u32 is_legacy, |
2253 | u32 home_dwell_time, u32 force_scan_interval, | 2356 | u32 home_dwell_time, u32 force_scan_interval, |
2254 | s8 num_chan, u16 *ch_list); | 2357 | s8 num_chan, u16 *ch_list); |
2358 | |||
2359 | int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | ||
2360 | enum wmi_scan_type scan_type, | ||
2361 | u32 force_fgscan, u32 is_legacy, | ||
2362 | u32 home_dwell_time, u32 force_scan_interval, | ||
2363 | s8 num_chan, u16 *ch_list, u32 no_cck, | ||
2364 | u32 *rates); | ||
2365 | |||
2255 | int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec, | 2366 | int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec, |
2256 | u16 fg_end_sec, u16 bg_sec, | 2367 | u16 fg_end_sec, u16 bg_sec, |
2257 | u16 minact_chdw_msec, u16 maxact_chdw_msec, | 2368 | u16 minact_chdw_msec, u16 maxact_chdw_msec, |
@@ -2346,6 +2457,10 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, | |||
2346 | int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | 2457 | int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, |
2347 | u32 wait, const u8 *data, u16 data_len); | 2458 | u32 wait, const u8 *data, u16 data_len); |
2348 | 2459 | ||
2460 | int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | ||
2461 | u32 wait, const u8 *data, u16 data_len, | ||
2462 | u32 no_cck); | ||
2463 | |||
2349 | int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, | 2464 | int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, |
2350 | const u8 *dst, const u8 *data, | 2465 | const u8 *dst, const u8 *data, |
2351 | u16 data_len); | 2466 | u16 data_len); |
@@ -2359,6 +2474,8 @@ int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx); | |||
2359 | int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, | 2474 | int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type, |
2360 | const u8 *ie, u8 ie_len); | 2475 | const u8 *ie, u8 ie_len); |
2361 | 2476 | ||
2477 | void ath6kl_wmi_sscan_timer(unsigned long ptr); | ||
2478 | |||
2362 | struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx); | 2479 | struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx); |
2363 | void *ath6kl_wmi_init(struct ath6kl *devt); | 2480 | void *ath6kl_wmi_init(struct ath6kl *devt); |
2364 | void ath6kl_wmi_shutdown(struct wmi *wmi); | 2481 | void ath6kl_wmi_shutdown(struct wmi *wmi); |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 1b4786ae00ac..dc6be4afe8eb 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -81,6 +81,14 @@ config ATH9K_RATE_CONTROL | |||
81 | Say Y, if you want to use the ath9k specific rate control | 81 | Say Y, if you want to use the ath9k specific rate control |
82 | module instead of minstrel_ht. | 82 | module instead of minstrel_ht. |
83 | 83 | ||
84 | config ATH9K_BTCOEX_SUPPORT | ||
85 | bool "Atheros ath9k bluetooth coexistence support" | ||
86 | depends on ATH9K | ||
87 | default y | ||
88 | ---help--- | ||
89 | Say Y, if you want to use the ath9k radios together with | ||
90 | Bluetooth modules in the same system. | ||
91 | |||
84 | config ATH9K_HTC | 92 | config ATH9K_HTC |
85 | tristate "Atheros HTC based wireless cards support" | 93 | tristate "Atheros HTC based wireless cards support" |
86 | depends on USB && MAC80211 | 94 | depends on USB && MAC80211 |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index a639b94f7643..bc56f57b393b 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -136,8 +136,8 @@ static void ath9k_ani_restart(struct ath_hw *ah) | |||
136 | cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; | 136 | cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; |
137 | } | 137 | } |
138 | 138 | ||
139 | ath_dbg(common, ATH_DBG_ANI, | 139 | ath_dbg(common, ANI, "Writing ofdmbase=%u cckbase=%u\n", |
140 | "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base); | 140 | ofdm_base, cck_base); |
141 | 141 | ||
142 | ENABLE_REGWRITE_BUFFER(ah); | 142 | ENABLE_REGWRITE_BUFFER(ah); |
143 | 143 | ||
@@ -268,8 +268,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) | |||
268 | 268 | ||
269 | aniState->noiseFloor = BEACON_RSSI(ah); | 269 | aniState->noiseFloor = BEACON_RSSI(ah); |
270 | 270 | ||
271 | ath_dbg(common, ATH_DBG_ANI, | 271 | ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", |
272 | "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", | ||
273 | aniState->ofdmNoiseImmunityLevel, | 272 | aniState->ofdmNoiseImmunityLevel, |
274 | immunityLevel, aniState->noiseFloor, | 273 | immunityLevel, aniState->noiseFloor, |
275 | aniState->rssiThrLow, aniState->rssiThrHigh); | 274 | aniState->rssiThrLow, aniState->rssiThrHigh); |
@@ -336,8 +335,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) | |||
336 | const struct ani_cck_level_entry *entry_cck; | 335 | const struct ani_cck_level_entry *entry_cck; |
337 | 336 | ||
338 | aniState->noiseFloor = BEACON_RSSI(ah); | 337 | aniState->noiseFloor = BEACON_RSSI(ah); |
339 | ath_dbg(common, ATH_DBG_ANI, | 338 | ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", |
340 | "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", | ||
341 | aniState->cckNoiseImmunityLevel, immunityLevel, | 339 | aniState->cckNoiseImmunityLevel, immunityLevel, |
342 | aniState->noiseFloor, aniState->rssiThrLow, | 340 | aniState->noiseFloor, aniState->rssiThrLow, |
343 | aniState->rssiThrHigh); | 341 | aniState->rssiThrHigh); |
@@ -481,8 +479,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) | |||
481 | 479 | ||
482 | if (ah->opmode != NL80211_IFTYPE_STATION | 480 | if (ah->opmode != NL80211_IFTYPE_STATION |
483 | && ah->opmode != NL80211_IFTYPE_ADHOC) { | 481 | && ah->opmode != NL80211_IFTYPE_ADHOC) { |
484 | ath_dbg(common, ATH_DBG_ANI, | 482 | ath_dbg(common, ANI, "Reset ANI state opmode %u\n", ah->opmode); |
485 | "Reset ANI state opmode %u\n", ah->opmode); | ||
486 | ah->stats.ast_ani_reset++; | 483 | ah->stats.ast_ani_reset++; |
487 | 484 | ||
488 | if (ah->opmode == NL80211_IFTYPE_AP) { | 485 | if (ah->opmode == NL80211_IFTYPE_AP) { |
@@ -582,7 +579,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) | |||
582 | ATH9K_ANI_OFDM_DEF_LEVEL || | 579 | ATH9K_ANI_OFDM_DEF_LEVEL || |
583 | aniState->cckNoiseImmunityLevel != | 580 | aniState->cckNoiseImmunityLevel != |
584 | ATH9K_ANI_CCK_DEF_LEVEL) { | 581 | ATH9K_ANI_CCK_DEF_LEVEL) { |
585 | ath_dbg(common, ATH_DBG_ANI, | 582 | ath_dbg(common, ANI, |
586 | "Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n", | 583 | "Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n", |
587 | ah->opmode, | 584 | ah->opmode, |
588 | chan->channel, | 585 | chan->channel, |
@@ -599,7 +596,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) | |||
599 | /* | 596 | /* |
600 | * restore historical levels for this channel | 597 | * restore historical levels for this channel |
601 | */ | 598 | */ |
602 | ath_dbg(common, ATH_DBG_ANI, | 599 | ath_dbg(common, ANI, |
603 | "Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n", | 600 | "Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n", |
604 | ah->opmode, | 601 | ah->opmode, |
605 | chan->channel, | 602 | chan->channel, |
@@ -662,7 +659,7 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) | |||
662 | 659 | ||
663 | if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { | 660 | if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { |
664 | if (phyCnt1 < ofdm_base) { | 661 | if (phyCnt1 < ofdm_base) { |
665 | ath_dbg(common, ATH_DBG_ANI, | 662 | ath_dbg(common, ANI, |
666 | "phyCnt1 0x%x, resetting counter value to 0x%x\n", | 663 | "phyCnt1 0x%x, resetting counter value to 0x%x\n", |
667 | phyCnt1, ofdm_base); | 664 | phyCnt1, ofdm_base); |
668 | REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); | 665 | REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); |
@@ -670,7 +667,7 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) | |||
670 | AR_PHY_ERR_OFDM_TIMING); | 667 | AR_PHY_ERR_OFDM_TIMING); |
671 | } | 668 | } |
672 | if (phyCnt2 < cck_base) { | 669 | if (phyCnt2 < cck_base) { |
673 | ath_dbg(common, ATH_DBG_ANI, | 670 | ath_dbg(common, ANI, |
674 | "phyCnt2 0x%x, resetting counter value to 0x%x\n", | 671 | "phyCnt2 0x%x, resetting counter value to 0x%x\n", |
675 | phyCnt2, cck_base); | 672 | phyCnt2, cck_base); |
676 | REG_WRITE(ah, AR_PHY_ERR_2, cck_base); | 673 | REG_WRITE(ah, AR_PHY_ERR_2, cck_base); |
@@ -713,7 +710,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) | |||
713 | cckPhyErrRate = aniState->cckPhyErrCount * 1000 / | 710 | cckPhyErrRate = aniState->cckPhyErrCount * 1000 / |
714 | aniState->listenTime; | 711 | aniState->listenTime; |
715 | 712 | ||
716 | ath_dbg(common, ATH_DBG_ANI, | 713 | ath_dbg(common, ANI, |
717 | "listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n", | 714 | "listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n", |
718 | aniState->listenTime, | 715 | aniState->listenTime, |
719 | aniState->ofdmNoiseImmunityLevel, | 716 | aniState->ofdmNoiseImmunityLevel, |
@@ -748,7 +745,7 @@ void ath9k_enable_mib_counters(struct ath_hw *ah) | |||
748 | { | 745 | { |
749 | struct ath_common *common = ath9k_hw_common(ah); | 746 | struct ath_common *common = ath9k_hw_common(ah); |
750 | 747 | ||
751 | ath_dbg(common, ATH_DBG_ANI, "Enable MIB counters\n"); | 748 | ath_dbg(common, ANI, "Enable MIB counters\n"); |
752 | 749 | ||
753 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | 750 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); |
754 | 751 | ||
@@ -770,7 +767,7 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) | |||
770 | { | 767 | { |
771 | struct ath_common *common = ath9k_hw_common(ah); | 768 | struct ath_common *common = ath9k_hw_common(ah); |
772 | 769 | ||
773 | ath_dbg(common, ATH_DBG_ANI, "Disable MIB counters\n"); | 770 | ath_dbg(common, ANI, "Disable MIB counters\n"); |
774 | 771 | ||
775 | REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); | 772 | REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); |
776 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | 773 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); |
@@ -845,7 +842,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah) | |||
845 | struct ath_common *common = ath9k_hw_common(ah); | 842 | struct ath_common *common = ath9k_hw_common(ah); |
846 | int i; | 843 | int i; |
847 | 844 | ||
848 | ath_dbg(common, ATH_DBG_ANI, "Initialize ANI\n"); | 845 | ath_dbg(common, ANI, "Initialize ANI\n"); |
849 | 846 | ||
850 | if (use_new_ani(ah)) { | 847 | if (use_new_ani(ah)) { |
851 | ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; | 848 | ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index f199e9e25149..f901a17f76ba 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -158,7 +158,7 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) | |||
158 | /* pre-reverse this field */ | 158 | /* pre-reverse this field */ |
159 | tmp_reg = ath9k_hw_reverse_bits(new_bias, 3); | 159 | tmp_reg = ath9k_hw_reverse_bits(new_bias, 3); |
160 | 160 | ||
161 | ath_dbg(common, ATH_DBG_CONFIG, "Force rf_pwd_icsyndiv to %1d on %4d\n", | 161 | ath_dbg(common, CONFIG, "Force rf_pwd_icsyndiv to %1d on %4d\n", |
162 | new_bias, synth_freq); | 162 | new_bias, synth_freq); |
163 | 163 | ||
164 | /* swizzle rf_pwd_icsyndiv */ | 164 | /* swizzle rf_pwd_icsyndiv */ |
@@ -1053,8 +1053,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, | |||
1053 | u32 level = param; | 1053 | u32 level = param; |
1054 | 1054 | ||
1055 | if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { | 1055 | if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { |
1056 | ath_dbg(common, ATH_DBG_ANI, | 1056 | ath_dbg(common, ANI, "level out of range (%u > %zu)\n", |
1057 | "level out of range (%u > %zu)\n", | ||
1058 | level, ARRAY_SIZE(ah->totalSizeDesired)); | 1057 | level, ARRAY_SIZE(ah->totalSizeDesired)); |
1059 | return false; | 1058 | return false; |
1060 | } | 1059 | } |
@@ -1157,8 +1156,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, | |||
1157 | u32 level = param; | 1156 | u32 level = param; |
1158 | 1157 | ||
1159 | if (level >= ARRAY_SIZE(firstep)) { | 1158 | if (level >= ARRAY_SIZE(firstep)) { |
1160 | ath_dbg(common, ATH_DBG_ANI, | 1159 | ath_dbg(common, ANI, "level out of range (%u > %zu)\n", |
1161 | "level out of range (%u > %zu)\n", | ||
1162 | level, ARRAY_SIZE(firstep)); | 1160 | level, ARRAY_SIZE(firstep)); |
1163 | return false; | 1161 | return false; |
1164 | } | 1162 | } |
@@ -1177,8 +1175,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, | |||
1177 | u32 level = param; | 1175 | u32 level = param; |
1178 | 1176 | ||
1179 | if (level >= ARRAY_SIZE(cycpwrThr1)) { | 1177 | if (level >= ARRAY_SIZE(cycpwrThr1)) { |
1180 | ath_dbg(common, ATH_DBG_ANI, | 1178 | ath_dbg(common, ANI, "level out of range (%u > %zu)\n", |
1181 | "level out of range (%u > %zu)\n", | ||
1182 | level, ARRAY_SIZE(cycpwrThr1)); | 1179 | level, ARRAY_SIZE(cycpwrThr1)); |
1183 | return false; | 1180 | return false; |
1184 | } | 1181 | } |
@@ -1195,23 +1192,22 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, | |||
1195 | case ATH9K_ANI_PRESENT: | 1192 | case ATH9K_ANI_PRESENT: |
1196 | break; | 1193 | break; |
1197 | default: | 1194 | default: |
1198 | ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd); | 1195 | ath_dbg(common, ANI, "invalid cmd %u\n", cmd); |
1199 | return false; | 1196 | return false; |
1200 | } | 1197 | } |
1201 | 1198 | ||
1202 | ath_dbg(common, ATH_DBG_ANI, "ANI parameters:\n"); | 1199 | ath_dbg(common, ANI, "ANI parameters:\n"); |
1203 | ath_dbg(common, ATH_DBG_ANI, | 1200 | ath_dbg(common, ANI, |
1204 | "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n", | 1201 | "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n", |
1205 | aniState->noiseImmunityLevel, | 1202 | aniState->noiseImmunityLevel, |
1206 | aniState->spurImmunityLevel, | 1203 | aniState->spurImmunityLevel, |
1207 | !aniState->ofdmWeakSigDetectOff); | 1204 | !aniState->ofdmWeakSigDetectOff); |
1208 | ath_dbg(common, ATH_DBG_ANI, | 1205 | ath_dbg(common, ANI, |
1209 | "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n", | 1206 | "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n", |
1210 | aniState->cckWeakSigThreshold, | 1207 | aniState->cckWeakSigThreshold, |
1211 | aniState->firstepLevel, | 1208 | aniState->firstepLevel, |
1212 | aniState->listenTime); | 1209 | aniState->listenTime); |
1213 | ath_dbg(common, ATH_DBG_ANI, | 1210 | ath_dbg(common, ANI, "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", |
1214 | "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", | ||
1215 | aniState->ofdmPhyErrCount, | 1211 | aniState->ofdmPhyErrCount, |
1216 | aniState->cckPhyErrCount); | 1212 | aniState->cckPhyErrCount); |
1217 | 1213 | ||
@@ -1295,7 +1291,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1295 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | 1291 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); |
1296 | 1292 | ||
1297 | if (!on != aniState->ofdmWeakSigDetectOff) { | 1293 | if (!on != aniState->ofdmWeakSigDetectOff) { |
1298 | ath_dbg(common, ATH_DBG_ANI, | 1294 | ath_dbg(common, ANI, |
1299 | "** ch %d: ofdm weak signal: %s=>%s\n", | 1295 | "** ch %d: ofdm weak signal: %s=>%s\n", |
1300 | chan->channel, | 1296 | chan->channel, |
1301 | !aniState->ofdmWeakSigDetectOff ? | 1297 | !aniState->ofdmWeakSigDetectOff ? |
@@ -1313,7 +1309,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1313 | u32 level = param; | 1309 | u32 level = param; |
1314 | 1310 | ||
1315 | if (level >= ARRAY_SIZE(firstep_table)) { | 1311 | if (level >= ARRAY_SIZE(firstep_table)) { |
1316 | ath_dbg(common, ATH_DBG_ANI, | 1312 | ath_dbg(common, ANI, |
1317 | "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n", | 1313 | "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n", |
1318 | level, ARRAY_SIZE(firstep_table)); | 1314 | level, ARRAY_SIZE(firstep_table)); |
1319 | return false; | 1315 | return false; |
@@ -1350,7 +1346,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1350 | AR_PHY_FIND_SIG_FIRSTEP_LOW, value2); | 1346 | AR_PHY_FIND_SIG_FIRSTEP_LOW, value2); |
1351 | 1347 | ||
1352 | if (level != aniState->firstepLevel) { | 1348 | if (level != aniState->firstepLevel) { |
1353 | ath_dbg(common, ATH_DBG_ANI, | 1349 | ath_dbg(common, ANI, |
1354 | "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n", | 1350 | "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n", |
1355 | chan->channel, | 1351 | chan->channel, |
1356 | aniState->firstepLevel, | 1352 | aniState->firstepLevel, |
@@ -1358,7 +1354,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1358 | ATH9K_ANI_FIRSTEP_LVL_NEW, | 1354 | ATH9K_ANI_FIRSTEP_LVL_NEW, |
1359 | value, | 1355 | value, |
1360 | aniState->iniDef.firstep); | 1356 | aniState->iniDef.firstep); |
1361 | ath_dbg(common, ATH_DBG_ANI, | 1357 | ath_dbg(common, ANI, |
1362 | "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n", | 1358 | "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n", |
1363 | chan->channel, | 1359 | chan->channel, |
1364 | aniState->firstepLevel, | 1360 | aniState->firstepLevel, |
@@ -1378,7 +1374,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1378 | u32 level = param; | 1374 | u32 level = param; |
1379 | 1375 | ||
1380 | if (level >= ARRAY_SIZE(cycpwrThr1_table)) { | 1376 | if (level >= ARRAY_SIZE(cycpwrThr1_table)) { |
1381 | ath_dbg(common, ATH_DBG_ANI, | 1377 | ath_dbg(common, ANI, |
1382 | "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n", | 1378 | "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n", |
1383 | level, ARRAY_SIZE(cycpwrThr1_table)); | 1379 | level, ARRAY_SIZE(cycpwrThr1_table)); |
1384 | return false; | 1380 | return false; |
@@ -1414,7 +1410,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1414 | AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2); | 1410 | AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2); |
1415 | 1411 | ||
1416 | if (level != aniState->spurImmunityLevel) { | 1412 | if (level != aniState->spurImmunityLevel) { |
1417 | ath_dbg(common, ATH_DBG_ANI, | 1413 | ath_dbg(common, ANI, |
1418 | "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n", | 1414 | "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n", |
1419 | chan->channel, | 1415 | chan->channel, |
1420 | aniState->spurImmunityLevel, | 1416 | aniState->spurImmunityLevel, |
@@ -1422,7 +1418,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1422 | ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, | 1418 | ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, |
1423 | value, | 1419 | value, |
1424 | aniState->iniDef.cycpwrThr1); | 1420 | aniState->iniDef.cycpwrThr1); |
1425 | ath_dbg(common, ATH_DBG_ANI, | 1421 | ath_dbg(common, ANI, |
1426 | "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n", | 1422 | "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n", |
1427 | chan->channel, | 1423 | chan->channel, |
1428 | aniState->spurImmunityLevel, | 1424 | aniState->spurImmunityLevel, |
@@ -1448,11 +1444,11 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, | |||
1448 | case ATH9K_ANI_PRESENT: | 1444 | case ATH9K_ANI_PRESENT: |
1449 | break; | 1445 | break; |
1450 | default: | 1446 | default: |
1451 | ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd); | 1447 | ath_dbg(common, ANI, "invalid cmd %u\n", cmd); |
1452 | return false; | 1448 | return false; |
1453 | } | 1449 | } |
1454 | 1450 | ||
1455 | ath_dbg(common, ATH_DBG_ANI, | 1451 | ath_dbg(common, ANI, |
1456 | "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", | 1452 | "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", |
1457 | aniState->spurImmunityLevel, | 1453 | aniState->spurImmunityLevel, |
1458 | !aniState->ofdmWeakSigDetectOff ? "on" : "off", | 1454 | !aniState->ofdmWeakSigDetectOff ? "on" : "off", |
@@ -1506,7 +1502,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) | |||
1506 | 1502 | ||
1507 | iniDef = &aniState->iniDef; | 1503 | iniDef = &aniState->iniDef; |
1508 | 1504 | ||
1509 | ath_dbg(common, ATH_DBG_ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n", | 1505 | ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n", |
1510 | ah->hw_version.macVersion, | 1506 | ah->hw_version.macVersion, |
1511 | ah->hw_version.macRev, | 1507 | ah->hw_version.macRev, |
1512 | ah->opmode, | 1508 | ah->opmode, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 157337febc2b..c55e5bbafc46 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c | |||
@@ -61,18 +61,16 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah, | |||
61 | switch (currCal->calData->calType) { | 61 | switch (currCal->calData->calType) { |
62 | case IQ_MISMATCH_CAL: | 62 | case IQ_MISMATCH_CAL: |
63 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | 63 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); |
64 | ath_dbg(common, ATH_DBG_CALIBRATE, | 64 | ath_dbg(common, CALIBRATE, |
65 | "starting IQ Mismatch Calibration\n"); | 65 | "starting IQ Mismatch Calibration\n"); |
66 | break; | 66 | break; |
67 | case ADC_GAIN_CAL: | 67 | case ADC_GAIN_CAL: |
68 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); | 68 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); |
69 | ath_dbg(common, ATH_DBG_CALIBRATE, | 69 | ath_dbg(common, CALIBRATE, "starting ADC Gain Calibration\n"); |
70 | "starting ADC Gain Calibration\n"); | ||
71 | break; | 70 | break; |
72 | case ADC_DC_CAL: | 71 | case ADC_DC_CAL: |
73 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); | 72 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); |
74 | ath_dbg(common, ATH_DBG_CALIBRATE, | 73 | ath_dbg(common, CALIBRATE, "starting ADC DC Calibration\n"); |
75 | "starting ADC DC Calibration\n"); | ||
76 | break; | 74 | break; |
77 | } | 75 | } |
78 | 76 | ||
@@ -129,7 +127,7 @@ static void ar9002_hw_iqcal_collect(struct ath_hw *ah) | |||
129 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | 127 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); |
130 | ah->totalIqCorrMeas[i] += | 128 | ah->totalIqCorrMeas[i] += |
131 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | 129 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); |
132 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | 130 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, |
133 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | 131 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", |
134 | ah->cal_samples, i, ah->totalPowerMeasI[i], | 132 | ah->cal_samples, i, ah->totalPowerMeasI[i], |
135 | ah->totalPowerMeasQ[i], | 133 | ah->totalPowerMeasQ[i], |
@@ -151,7 +149,7 @@ static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah) | |||
151 | ah->totalAdcQEvenPhase[i] += | 149 | ah->totalAdcQEvenPhase[i] += |
152 | REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | 150 | REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); |
153 | 151 | ||
154 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | 152 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, |
155 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n", | 153 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n", |
156 | ah->cal_samples, i, | 154 | ah->cal_samples, i, |
157 | ah->totalAdcIOddPhase[i], | 155 | ah->totalAdcIOddPhase[i], |
@@ -175,7 +173,7 @@ static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah) | |||
175 | ah->totalAdcDcOffsetQEvenPhase[i] += | 173 | ah->totalAdcDcOffsetQEvenPhase[i] += |
176 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | 174 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); |
177 | 175 | ||
178 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | 176 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, |
179 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n", | 177 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; oddq=0x%08x; evenq=0x%08x;\n", |
180 | ah->cal_samples, i, | 178 | ah->cal_samples, i, |
181 | ah->totalAdcDcOffsetIOddPhase[i], | 179 | ah->totalAdcDcOffsetIOddPhase[i], |
@@ -198,11 +196,11 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
198 | powerMeasQ = ah->totalPowerMeasQ[i]; | 196 | powerMeasQ = ah->totalPowerMeasQ[i]; |
199 | iqCorrMeas = ah->totalIqCorrMeas[i]; | 197 | iqCorrMeas = ah->totalIqCorrMeas[i]; |
200 | 198 | ||
201 | ath_dbg(common, ATH_DBG_CALIBRATE, | 199 | ath_dbg(common, CALIBRATE, |
202 | "Starting IQ Cal and Correction for Chain %d\n", | 200 | "Starting IQ Cal and Correction for Chain %d\n", |
203 | i); | 201 | i); |
204 | 202 | ||
205 | ath_dbg(common, ATH_DBG_CALIBRATE, | 203 | ath_dbg(common, CALIBRATE, |
206 | "Original: Chn %d iq_corr_meas = 0x%08x\n", | 204 | "Original: Chn %d iq_corr_meas = 0x%08x\n", |
207 | i, ah->totalIqCorrMeas[i]); | 205 | i, ah->totalIqCorrMeas[i]); |
208 | 206 | ||
@@ -213,12 +211,11 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
213 | iqCorrNeg = 1; | 211 | iqCorrNeg = 1; |
214 | } | 212 | } |
215 | 213 | ||
216 | ath_dbg(common, ATH_DBG_CALIBRATE, | 214 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_i = 0x%08x\n", |
217 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); | 215 | i, powerMeasI); |
218 | ath_dbg(common, ATH_DBG_CALIBRATE, | 216 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_q = 0x%08x\n", |
219 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); | 217 | i, powerMeasQ); |
220 | ath_dbg(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", | 218 | ath_dbg(common, CALIBRATE, "iqCorrNeg is 0x%08x\n", iqCorrNeg); |
221 | iqCorrNeg); | ||
222 | 219 | ||
223 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; | 220 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; |
224 | qCoffDenom = powerMeasQ / 64; | 221 | qCoffDenom = powerMeasQ / 64; |
@@ -227,13 +224,13 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
227 | (qCoffDenom != 0)) { | 224 | (qCoffDenom != 0)) { |
228 | iCoff = iqCorrMeas / iCoffDenom; | 225 | iCoff = iqCorrMeas / iCoffDenom; |
229 | qCoff = powerMeasI / qCoffDenom - 64; | 226 | qCoff = powerMeasI / qCoffDenom - 64; |
230 | ath_dbg(common, ATH_DBG_CALIBRATE, | 227 | ath_dbg(common, CALIBRATE, "Chn %d iCoff = 0x%08x\n", |
231 | "Chn %d iCoff = 0x%08x\n", i, iCoff); | 228 | i, iCoff); |
232 | ath_dbg(common, ATH_DBG_CALIBRATE, | 229 | ath_dbg(common, CALIBRATE, "Chn %d qCoff = 0x%08x\n", |
233 | "Chn %d qCoff = 0x%08x\n", i, qCoff); | 230 | i, qCoff); |
234 | 231 | ||
235 | iCoff = iCoff & 0x3f; | 232 | iCoff = iCoff & 0x3f; |
236 | ath_dbg(common, ATH_DBG_CALIBRATE, | 233 | ath_dbg(common, CALIBRATE, |
237 | "New: Chn %d iCoff = 0x%08x\n", i, iCoff); | 234 | "New: Chn %d iCoff = 0x%08x\n", i, iCoff); |
238 | if (iqCorrNeg == 0x0) | 235 | if (iqCorrNeg == 0x0) |
239 | iCoff = 0x40 - iCoff; | 236 | iCoff = 0x40 - iCoff; |
@@ -243,7 +240,7 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
243 | else if (qCoff <= -16) | 240 | else if (qCoff <= -16) |
244 | qCoff = -16; | 241 | qCoff = -16; |
245 | 242 | ||
246 | ath_dbg(common, ATH_DBG_CALIBRATE, | 243 | ath_dbg(common, CALIBRATE, |
247 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", | 244 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", |
248 | i, iCoff, qCoff); | 245 | i, iCoff, qCoff); |
249 | 246 | ||
@@ -253,7 +250,7 @@ static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
253 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | 250 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), |
254 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, | 251 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, |
255 | qCoff); | 252 | qCoff); |
256 | ath_dbg(common, ATH_DBG_CALIBRATE, | 253 | ath_dbg(common, CALIBRATE, |
257 | "IQ Cal and Correction done for Chain %d\n", | 254 | "IQ Cal and Correction done for Chain %d\n", |
258 | i); | 255 | i); |
259 | } | 256 | } |
@@ -275,21 +272,17 @@ static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | |||
275 | qOddMeasOffset = ah->totalAdcQOddPhase[i]; | 272 | qOddMeasOffset = ah->totalAdcQOddPhase[i]; |
276 | qEvenMeasOffset = ah->totalAdcQEvenPhase[i]; | 273 | qEvenMeasOffset = ah->totalAdcQEvenPhase[i]; |
277 | 274 | ||
278 | ath_dbg(common, ATH_DBG_CALIBRATE, | 275 | ath_dbg(common, CALIBRATE, |
279 | "Starting ADC Gain Cal for Chain %d\n", i); | 276 | "Starting ADC Gain Cal for Chain %d\n", i); |
280 | 277 | ||
281 | ath_dbg(common, ATH_DBG_CALIBRATE, | 278 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_i = 0x%08x\n", |
282 | "Chn %d pwr_meas_odd_i = 0x%08x\n", i, | 279 | i, iOddMeasOffset); |
283 | iOddMeasOffset); | 280 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_i = 0x%08x\n", |
284 | ath_dbg(common, ATH_DBG_CALIBRATE, | 281 | i, iEvenMeasOffset); |
285 | "Chn %d pwr_meas_even_i = 0x%08x\n", i, | 282 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_q = 0x%08x\n", |
286 | iEvenMeasOffset); | 283 | i, qOddMeasOffset); |
287 | ath_dbg(common, ATH_DBG_CALIBRATE, | 284 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_q = 0x%08x\n", |
288 | "Chn %d pwr_meas_odd_q = 0x%08x\n", i, | 285 | i, qEvenMeasOffset); |
289 | qOddMeasOffset); | ||
290 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
291 | "Chn %d pwr_meas_even_q = 0x%08x\n", i, | ||
292 | qEvenMeasOffset); | ||
293 | 286 | ||
294 | if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { | 287 | if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { |
295 | iGainMismatch = | 288 | iGainMismatch = |
@@ -299,19 +292,19 @@ static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | |||
299 | ((qOddMeasOffset * 32) / | 292 | ((qOddMeasOffset * 32) / |
300 | qEvenMeasOffset) & 0x3f; | 293 | qEvenMeasOffset) & 0x3f; |
301 | 294 | ||
302 | ath_dbg(common, ATH_DBG_CALIBRATE, | 295 | ath_dbg(common, CALIBRATE, |
303 | "Chn %d gain_mismatch_i = 0x%08x\n", i, | 296 | "Chn %d gain_mismatch_i = 0x%08x\n", |
304 | iGainMismatch); | 297 | i, iGainMismatch); |
305 | ath_dbg(common, ATH_DBG_CALIBRATE, | 298 | ath_dbg(common, CALIBRATE, |
306 | "Chn %d gain_mismatch_q = 0x%08x\n", i, | 299 | "Chn %d gain_mismatch_q = 0x%08x\n", |
307 | qGainMismatch); | 300 | i, qGainMismatch); |
308 | 301 | ||
309 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | 302 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); |
310 | val &= 0xfffff000; | 303 | val &= 0xfffff000; |
311 | val |= (qGainMismatch) | (iGainMismatch << 6); | 304 | val |= (qGainMismatch) | (iGainMismatch << 6); |
312 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | 305 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); |
313 | 306 | ||
314 | ath_dbg(common, ATH_DBG_CALIBRATE, | 307 | ath_dbg(common, CALIBRATE, |
315 | "ADC Gain Cal done for Chain %d\n", i); | 308 | "ADC Gain Cal done for Chain %d\n", i); |
316 | } | 309 | } |
317 | } | 310 | } |
@@ -337,40 +330,36 @@ static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) | |||
337 | qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i]; | 330 | qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i]; |
338 | qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i]; | 331 | qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i]; |
339 | 332 | ||
340 | ath_dbg(common, ATH_DBG_CALIBRATE, | 333 | ath_dbg(common, CALIBRATE, |
341 | "Starting ADC DC Offset Cal for Chain %d\n", i); | 334 | "Starting ADC DC Offset Cal for Chain %d\n", i); |
342 | 335 | ||
343 | ath_dbg(common, ATH_DBG_CALIBRATE, | 336 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_i = %d\n", |
344 | "Chn %d pwr_meas_odd_i = %d\n", i, | 337 | i, iOddMeasOffset); |
345 | iOddMeasOffset); | 338 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_i = %d\n", |
346 | ath_dbg(common, ATH_DBG_CALIBRATE, | 339 | i, iEvenMeasOffset); |
347 | "Chn %d pwr_meas_even_i = %d\n", i, | 340 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_odd_q = %d\n", |
348 | iEvenMeasOffset); | 341 | i, qOddMeasOffset); |
349 | ath_dbg(common, ATH_DBG_CALIBRATE, | 342 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_even_q = %d\n", |
350 | "Chn %d pwr_meas_odd_q = %d\n", i, | 343 | i, qEvenMeasOffset); |
351 | qOddMeasOffset); | ||
352 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
353 | "Chn %d pwr_meas_even_q = %d\n", i, | ||
354 | qEvenMeasOffset); | ||
355 | 344 | ||
356 | iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / | 345 | iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / |
357 | numSamples) & 0x1ff; | 346 | numSamples) & 0x1ff; |
358 | qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / | 347 | qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / |
359 | numSamples) & 0x1ff; | 348 | numSamples) & 0x1ff; |
360 | 349 | ||
361 | ath_dbg(common, ATH_DBG_CALIBRATE, | 350 | ath_dbg(common, CALIBRATE, |
362 | "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, | 351 | "Chn %d dc_offset_mismatch_i = 0x%08x\n", |
363 | iDcMismatch); | 352 | i, iDcMismatch); |
364 | ath_dbg(common, ATH_DBG_CALIBRATE, | 353 | ath_dbg(common, CALIBRATE, |
365 | "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, | 354 | "Chn %d dc_offset_mismatch_q = 0x%08x\n", |
366 | qDcMismatch); | 355 | i, qDcMismatch); |
367 | 356 | ||
368 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | 357 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); |
369 | val &= 0xc0000fff; | 358 | val &= 0xc0000fff; |
370 | val |= (qDcMismatch << 12) | (iDcMismatch << 21); | 359 | val |= (qDcMismatch << 12) | (iDcMismatch << 21); |
371 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | 360 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); |
372 | 361 | ||
373 | ath_dbg(common, ATH_DBG_CALIBRATE, | 362 | ath_dbg(common, CALIBRATE, |
374 | "ADC DC Offset Cal done for Chain %d\n", i); | 363 | "ADC DC Offset Cal done for Chain %d\n", i); |
375 | } | 364 | } |
376 | 365 | ||
@@ -560,7 +549,7 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) | |||
560 | { 0x7838, 0 }, | 549 | { 0x7838, 0 }, |
561 | }; | 550 | }; |
562 | 551 | ||
563 | ath_dbg(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n"); | 552 | ath_dbg(common, CALIBRATE, "Running PA Calibration\n"); |
564 | 553 | ||
565 | /* PA CAL is not needed for high power solution */ | 554 | /* PA CAL is not needed for high power solution */ |
566 | if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == | 555 | if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == |
@@ -741,7 +730,7 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
741 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | 730 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); |
742 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | 731 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, |
743 | AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { | 732 | AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { |
744 | ath_dbg(common, ATH_DBG_CALIBRATE, | 733 | ath_dbg(common, CALIBRATE, |
745 | "offset calibration failed to complete in 1ms; noisy environment?\n"); | 734 | "offset calibration failed to complete in 1ms; noisy environment?\n"); |
746 | return false; | 735 | return false; |
747 | } | 736 | } |
@@ -755,7 +744,7 @@ static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
755 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | 744 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); |
756 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, | 745 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, |
757 | 0, AH_WAIT_TIMEOUT)) { | 746 | 0, AH_WAIT_TIMEOUT)) { |
758 | ath_dbg(common, ATH_DBG_CALIBRATE, | 747 | ath_dbg(common, CALIBRATE, |
759 | "offset calibration failed to complete in 1ms; noisy environment?\n"); | 748 | "offset calibration failed to complete in 1ms; noisy environment?\n"); |
760 | return false; | 749 | return false; |
761 | } | 750 | } |
@@ -851,7 +840,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
851 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | 840 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, |
852 | AR_PHY_AGC_CONTROL_CAL, | 841 | AR_PHY_AGC_CONTROL_CAL, |
853 | 0, AH_WAIT_TIMEOUT)) { | 842 | 0, AH_WAIT_TIMEOUT)) { |
854 | ath_dbg(common, ATH_DBG_CALIBRATE, | 843 | ath_dbg(common, CALIBRATE, |
855 | "offset calibration failed to complete in 1ms; noisy environment?\n"); | 844 | "offset calibration failed to complete in 1ms; noisy environment?\n"); |
856 | return false; | 845 | return false; |
857 | } | 846 | } |
@@ -886,22 +875,21 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
886 | if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) { | 875 | if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) { |
887 | INIT_CAL(&ah->adcgain_caldata); | 876 | INIT_CAL(&ah->adcgain_caldata); |
888 | INSERT_CAL(ah, &ah->adcgain_caldata); | 877 | INSERT_CAL(ah, &ah->adcgain_caldata); |
889 | ath_dbg(common, ATH_DBG_CALIBRATE, | 878 | ath_dbg(common, CALIBRATE, |
890 | "enabling ADC Gain Calibration.\n"); | 879 | "enabling ADC Gain Calibration\n"); |
891 | } | 880 | } |
892 | 881 | ||
893 | if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) { | 882 | if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) { |
894 | INIT_CAL(&ah->adcdc_caldata); | 883 | INIT_CAL(&ah->adcdc_caldata); |
895 | INSERT_CAL(ah, &ah->adcdc_caldata); | 884 | INSERT_CAL(ah, &ah->adcdc_caldata); |
896 | ath_dbg(common, ATH_DBG_CALIBRATE, | 885 | ath_dbg(common, CALIBRATE, |
897 | "enabling ADC DC Calibration.\n"); | 886 | "enabling ADC DC Calibration\n"); |
898 | } | 887 | } |
899 | 888 | ||
900 | if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) { | 889 | if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) { |
901 | INIT_CAL(&ah->iq_caldata); | 890 | INIT_CAL(&ah->iq_caldata); |
902 | INSERT_CAL(ah, &ah->iq_caldata); | 891 | INSERT_CAL(ah, &ah->iq_caldata); |
903 | ath_dbg(common, ATH_DBG_CALIBRATE, | 892 | ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); |
904 | "enabling IQ Calibration.\n"); | ||
905 | } | 893 | } |
906 | 894 | ||
907 | ah->cal_list_curr = ah->cal_list; | 895 | ah->cal_list_curr = ah->cal_list; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index b5920168606d..7b6417b5212e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -107,7 +107,7 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | if (isr & AR_ISR_RXORN) { | 109 | if (isr & AR_ISR_RXORN) { |
110 | ath_dbg(common, ATH_DBG_INTERRUPT, | 110 | ath_dbg(common, INTERRUPT, |
111 | "receive FIFO overrun interrupt\n"); | 111 | "receive FIFO overrun interrupt\n"); |
112 | } | 112 | } |
113 | 113 | ||
@@ -143,24 +143,24 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
143 | 143 | ||
144 | if (fatal_int) { | 144 | if (fatal_int) { |
145 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { | 145 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { |
146 | ath_dbg(common, ATH_DBG_ANY, | 146 | ath_dbg(common, ANY, |
147 | "received PCI FATAL interrupt\n"); | 147 | "received PCI FATAL interrupt\n"); |
148 | } | 148 | } |
149 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { | 149 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { |
150 | ath_dbg(common, ATH_DBG_ANY, | 150 | ath_dbg(common, ANY, |
151 | "received PCI PERR interrupt\n"); | 151 | "received PCI PERR interrupt\n"); |
152 | } | 152 | } |
153 | *masked |= ATH9K_INT_FATAL; | 153 | *masked |= ATH9K_INT_FATAL; |
154 | } | 154 | } |
155 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | 155 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { |
156 | ath_dbg(common, ATH_DBG_INTERRUPT, | 156 | ath_dbg(common, INTERRUPT, |
157 | "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); | 157 | "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); |
158 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | 158 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); |
159 | REG_WRITE(ah, AR_RC, 0); | 159 | REG_WRITE(ah, AR_RC, 0); |
160 | *masked |= ATH9K_INT_FATAL; | 160 | *masked |= ATH9K_INT_FATAL; |
161 | } | 161 | } |
162 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { | 162 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { |
163 | ath_dbg(common, ATH_DBG_INTERRUPT, | 163 | ath_dbg(common, INTERRUPT, |
164 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); | 164 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); |
165 | } | 165 | } |
166 | 166 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 23b3a6c57800..8e70f0bc073e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -52,7 +52,7 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, | |||
52 | currCal->calData->calCountMax); | 52 | currCal->calData->calCountMax); |
53 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | 53 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); |
54 | 54 | ||
55 | ath_dbg(common, ATH_DBG_CALIBRATE, | 55 | ath_dbg(common, CALIBRATE, |
56 | "starting IQ Mismatch Calibration\n"); | 56 | "starting IQ Mismatch Calibration\n"); |
57 | 57 | ||
58 | /* Kick-off cal */ | 58 | /* Kick-off cal */ |
@@ -64,7 +64,7 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, | |||
64 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, | 64 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, |
65 | AR_PHY_65NM_CH0_THERM_START, 1); | 65 | AR_PHY_65NM_CH0_THERM_START, 1); |
66 | 66 | ||
67 | ath_dbg(common, ATH_DBG_CALIBRATE, | 67 | ath_dbg(common, CALIBRATE, |
68 | "starting Temperature Compensation Calibration\n"); | 68 | "starting Temperature Compensation Calibration\n"); |
69 | break; | 69 | break; |
70 | } | 70 | } |
@@ -194,7 +194,7 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah) | |||
194 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | 194 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); |
195 | ah->totalIqCorrMeas[i] += | 195 | ah->totalIqCorrMeas[i] += |
196 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | 196 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); |
197 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | 197 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, |
198 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | 198 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", |
199 | ah->cal_samples, i, ah->totalPowerMeasI[i], | 199 | ah->cal_samples, i, ah->totalPowerMeasI[i], |
200 | ah->totalPowerMeasQ[i], | 200 | ah->totalPowerMeasQ[i], |
@@ -221,11 +221,10 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
221 | powerMeasQ = ah->totalPowerMeasQ[i]; | 221 | powerMeasQ = ah->totalPowerMeasQ[i]; |
222 | iqCorrMeas = ah->totalIqCorrMeas[i]; | 222 | iqCorrMeas = ah->totalIqCorrMeas[i]; |
223 | 223 | ||
224 | ath_dbg(common, ATH_DBG_CALIBRATE, | 224 | ath_dbg(common, CALIBRATE, |
225 | "Starting IQ Cal and Correction for Chain %d\n", | 225 | "Starting IQ Cal and Correction for Chain %d\n", i); |
226 | i); | ||
227 | 226 | ||
228 | ath_dbg(common, ATH_DBG_CALIBRATE, | 227 | ath_dbg(common, CALIBRATE, |
229 | "Original: Chn %d iq_corr_meas = 0x%08x\n", | 228 | "Original: Chn %d iq_corr_meas = 0x%08x\n", |
230 | i, ah->totalIqCorrMeas[i]); | 229 | i, ah->totalIqCorrMeas[i]); |
231 | 230 | ||
@@ -236,12 +235,11 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
236 | iqCorrNeg = 1; | 235 | iqCorrNeg = 1; |
237 | } | 236 | } |
238 | 237 | ||
239 | ath_dbg(common, ATH_DBG_CALIBRATE, | 238 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_i = 0x%08x\n", |
240 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); | 239 | i, powerMeasI); |
241 | ath_dbg(common, ATH_DBG_CALIBRATE, | 240 | ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_q = 0x%08x\n", |
242 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); | 241 | i, powerMeasQ); |
243 | ath_dbg(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", | 242 | ath_dbg(common, CALIBRATE, "iqCorrNeg is 0x%08x\n", iqCorrNeg); |
244 | iqCorrNeg); | ||
245 | 243 | ||
246 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256; | 244 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256; |
247 | qCoffDenom = powerMeasQ / 64; | 245 | qCoffDenom = powerMeasQ / 64; |
@@ -249,10 +247,10 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
249 | if ((iCoffDenom != 0) && (qCoffDenom != 0)) { | 247 | if ((iCoffDenom != 0) && (qCoffDenom != 0)) { |
250 | iCoff = iqCorrMeas / iCoffDenom; | 248 | iCoff = iqCorrMeas / iCoffDenom; |
251 | qCoff = powerMeasI / qCoffDenom - 64; | 249 | qCoff = powerMeasI / qCoffDenom - 64; |
252 | ath_dbg(common, ATH_DBG_CALIBRATE, | 250 | ath_dbg(common, CALIBRATE, "Chn %d iCoff = 0x%08x\n", |
253 | "Chn %d iCoff = 0x%08x\n", i, iCoff); | 251 | i, iCoff); |
254 | ath_dbg(common, ATH_DBG_CALIBRATE, | 252 | ath_dbg(common, CALIBRATE, "Chn %d qCoff = 0x%08x\n", |
255 | "Chn %d qCoff = 0x%08x\n", i, qCoff); | 253 | i, qCoff); |
256 | 254 | ||
257 | /* Force bounds on iCoff */ | 255 | /* Force bounds on iCoff */ |
258 | if (iCoff >= 63) | 256 | if (iCoff >= 63) |
@@ -273,10 +271,10 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
273 | iCoff = iCoff & 0x7f; | 271 | iCoff = iCoff & 0x7f; |
274 | qCoff = qCoff & 0x7f; | 272 | qCoff = qCoff & 0x7f; |
275 | 273 | ||
276 | ath_dbg(common, ATH_DBG_CALIBRATE, | 274 | ath_dbg(common, CALIBRATE, |
277 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", | 275 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", |
278 | i, iCoff, qCoff); | 276 | i, iCoff, qCoff); |
279 | ath_dbg(common, ATH_DBG_CALIBRATE, | 277 | ath_dbg(common, CALIBRATE, |
280 | "Register offset (0x%04x) before update = 0x%x\n", | 278 | "Register offset (0x%04x) before update = 0x%x\n", |
281 | offset_array[i], | 279 | offset_array[i], |
282 | REG_READ(ah, offset_array[i])); | 280 | REG_READ(ah, offset_array[i])); |
@@ -287,25 +285,25 @@ static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | |||
287 | REG_RMW_FIELD(ah, offset_array[i], | 285 | REG_RMW_FIELD(ah, offset_array[i], |
288 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, | 286 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, |
289 | qCoff); | 287 | qCoff); |
290 | ath_dbg(common, ATH_DBG_CALIBRATE, | 288 | ath_dbg(common, CALIBRATE, |
291 | "Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n", | 289 | "Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n", |
292 | offset_array[i], | 290 | offset_array[i], |
293 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, | 291 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, |
294 | REG_READ(ah, offset_array[i])); | 292 | REG_READ(ah, offset_array[i])); |
295 | ath_dbg(common, ATH_DBG_CALIBRATE, | 293 | ath_dbg(common, CALIBRATE, |
296 | "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n", | 294 | "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n", |
297 | offset_array[i], | 295 | offset_array[i], |
298 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, | 296 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, |
299 | REG_READ(ah, offset_array[i])); | 297 | REG_READ(ah, offset_array[i])); |
300 | 298 | ||
301 | ath_dbg(common, ATH_DBG_CALIBRATE, | 299 | ath_dbg(common, CALIBRATE, |
302 | "IQ Cal and Correction done for Chain %d\n", i); | 300 | "IQ Cal and Correction done for Chain %d\n", i); |
303 | } | 301 | } |
304 | } | 302 | } |
305 | 303 | ||
306 | REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0, | 304 | REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0, |
307 | AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE); | 305 | AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE); |
308 | ath_dbg(common, ATH_DBG_CALIBRATE, | 306 | ath_dbg(common, CALIBRATE, |
309 | "IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n", | 307 | "IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n", |
310 | (unsigned) (AR_PHY_RX_IQCAL_CORR_B0), | 308 | (unsigned) (AR_PHY_RX_IQCAL_CORR_B0), |
311 | AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE, | 309 | AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE, |
@@ -349,7 +347,7 @@ static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah, | |||
349 | f2 = (f1 * f1 + f3 * f3) / result_shift; | 347 | f2 = (f1 * f1 + f3 * f3) / result_shift; |
350 | 348 | ||
351 | if (!f2) { | 349 | if (!f2) { |
352 | ath_dbg(common, ATH_DBG_CALIBRATE, "Divide by 0\n"); | 350 | ath_dbg(common, CALIBRATE, "Divide by 0\n"); |
353 | return false; | 351 | return false; |
354 | } | 352 | } |
355 | 353 | ||
@@ -470,7 +468,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
470 | 468 | ||
471 | if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) || | 469 | if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) || |
472 | (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) { | 470 | (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) { |
473 | ath_dbg(common, ATH_DBG_CALIBRATE, | 471 | ath_dbg(common, CALIBRATE, |
474 | "Divide by 0:\n" | 472 | "Divide by 0:\n" |
475 | "a0_d0=%d\n" | 473 | "a0_d0=%d\n" |
476 | "a0_d1=%d\n" | 474 | "a0_d1=%d\n" |
@@ -510,8 +508,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
510 | mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2); | 508 | mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2); |
511 | 509 | ||
512 | if ((mag1 == 0) || (mag2 == 0)) { | 510 | if ((mag1 == 0) || (mag2 == 0)) { |
513 | ath_dbg(common, ATH_DBG_CALIBRATE, | 511 | ath_dbg(common, CALIBRATE, "Divide by 0: mag1=%d, mag2=%d\n", |
514 | "Divide by 0: mag1=%d, mag2=%d\n", | ||
515 | mag1, mag2); | 512 | mag1, mag2); |
516 | return false; | 513 | return false; |
517 | } | 514 | } |
@@ -529,8 +526,8 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
529 | mag_a0_d0, phs_a0_d0, | 526 | mag_a0_d0, phs_a0_d0, |
530 | mag_a1_d0, | 527 | mag_a1_d0, |
531 | phs_a1_d0, solved_eq)) { | 528 | phs_a1_d0, solved_eq)) { |
532 | ath_dbg(common, ATH_DBG_CALIBRATE, | 529 | ath_dbg(common, CALIBRATE, |
533 | "Call to ar9003_hw_solve_iq_cal() failed.\n"); | 530 | "Call to ar9003_hw_solve_iq_cal() failed\n"); |
534 | return false; | 531 | return false; |
535 | } | 532 | } |
536 | 533 | ||
@@ -539,12 +536,12 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
539 | mag_rx = solved_eq[2]; | 536 | mag_rx = solved_eq[2]; |
540 | phs_rx = solved_eq[3]; | 537 | phs_rx = solved_eq[3]; |
541 | 538 | ||
542 | ath_dbg(common, ATH_DBG_CALIBRATE, | 539 | ath_dbg(common, CALIBRATE, |
543 | "chain %d: mag mismatch=%d phase mismatch=%d\n", | 540 | "chain %d: mag mismatch=%d phase mismatch=%d\n", |
544 | chain_idx, mag_tx/res_scale, phs_tx/res_scale); | 541 | chain_idx, mag_tx/res_scale, phs_tx/res_scale); |
545 | 542 | ||
546 | if (res_scale == mag_tx) { | 543 | if (res_scale == mag_tx) { |
547 | ath_dbg(common, ATH_DBG_CALIBRATE, | 544 | ath_dbg(common, CALIBRATE, |
548 | "Divide by 0: mag_tx=%d, res_scale=%d\n", | 545 | "Divide by 0: mag_tx=%d, res_scale=%d\n", |
549 | mag_tx, res_scale); | 546 | mag_tx, res_scale); |
550 | return false; | 547 | return false; |
@@ -557,8 +554,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
557 | q_q_coff = (mag_corr_tx * 128 / res_scale); | 554 | q_q_coff = (mag_corr_tx * 128 / res_scale); |
558 | q_i_coff = (phs_corr_tx * 256 / res_scale); | 555 | q_i_coff = (phs_corr_tx * 256 / res_scale); |
559 | 556 | ||
560 | ath_dbg(common, ATH_DBG_CALIBRATE, | 557 | ath_dbg(common, CALIBRATE, "tx chain %d: mag corr=%d phase corr=%d\n", |
561 | "tx chain %d: mag corr=%d phase corr=%d\n", | ||
562 | chain_idx, q_q_coff, q_i_coff); | 558 | chain_idx, q_q_coff, q_i_coff); |
563 | 559 | ||
564 | if (q_i_coff < -63) | 560 | if (q_i_coff < -63) |
@@ -572,12 +568,11 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
572 | 568 | ||
573 | iqc_coeff[0] = (q_q_coff * 128) + q_i_coff; | 569 | iqc_coeff[0] = (q_q_coff * 128) + q_i_coff; |
574 | 570 | ||
575 | ath_dbg(common, ATH_DBG_CALIBRATE, | 571 | ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n", |
576 | "tx chain %d: iq corr coeff=%x\n", | ||
577 | chain_idx, iqc_coeff[0]); | 572 | chain_idx, iqc_coeff[0]); |
578 | 573 | ||
579 | if (-mag_rx == res_scale) { | 574 | if (-mag_rx == res_scale) { |
580 | ath_dbg(common, ATH_DBG_CALIBRATE, | 575 | ath_dbg(common, CALIBRATE, |
581 | "Divide by 0: mag_rx=%d, res_scale=%d\n", | 576 | "Divide by 0: mag_rx=%d, res_scale=%d\n", |
582 | mag_rx, res_scale); | 577 | mag_rx, res_scale); |
583 | return false; | 578 | return false; |
@@ -590,8 +585,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
590 | q_q_coff = (mag_corr_rx * 128 / res_scale); | 585 | q_q_coff = (mag_corr_rx * 128 / res_scale); |
591 | q_i_coff = (phs_corr_rx * 256 / res_scale); | 586 | q_i_coff = (phs_corr_rx * 256 / res_scale); |
592 | 587 | ||
593 | ath_dbg(common, ATH_DBG_CALIBRATE, | 588 | ath_dbg(common, CALIBRATE, "rx chain %d: mag corr=%d phase corr=%d\n", |
594 | "rx chain %d: mag corr=%d phase corr=%d\n", | ||
595 | chain_idx, q_q_coff, q_i_coff); | 589 | chain_idx, q_q_coff, q_i_coff); |
596 | 590 | ||
597 | if (q_i_coff < -63) | 591 | if (q_i_coff < -63) |
@@ -605,8 +599,7 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
605 | 599 | ||
606 | iqc_coeff[1] = (q_q_coff * 128) + q_i_coff; | 600 | iqc_coeff[1] = (q_q_coff * 128) + q_i_coff; |
607 | 601 | ||
608 | ath_dbg(common, ATH_DBG_CALIBRATE, | 602 | ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n", |
609 | "rx chain %d: iq corr coeff=%x\n", | ||
610 | chain_idx, iqc_coeff[1]); | 603 | chain_idx, iqc_coeff[1]); |
611 | 604 | ||
612 | return true; | 605 | return true; |
@@ -753,8 +746,7 @@ static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) | |||
753 | if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, | 746 | if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, |
754 | AR_PHY_TX_IQCAL_START_DO_CAL, 0, | 747 | AR_PHY_TX_IQCAL_START_DO_CAL, 0, |
755 | AH_WAIT_TIMEOUT)) { | 748 | AH_WAIT_TIMEOUT)) { |
756 | ath_dbg(common, ATH_DBG_CALIBRATE, | 749 | ath_dbg(common, CALIBRATE, "Tx IQ Cal is not completed\n"); |
757 | "Tx IQ Cal is not completed.\n"); | ||
758 | return false; | 750 | return false; |
759 | } | 751 | } |
760 | return true; | 752 | return true; |
@@ -792,13 +784,13 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
792 | nmeasurement = MAX_MEASUREMENT; | 784 | nmeasurement = MAX_MEASUREMENT; |
793 | 785 | ||
794 | for (im = 0; im < nmeasurement; im++) { | 786 | for (im = 0; im < nmeasurement; im++) { |
795 | ath_dbg(common, ATH_DBG_CALIBRATE, | 787 | ath_dbg(common, CALIBRATE, |
796 | "Doing Tx IQ Cal for chain %d.\n", i); | 788 | "Doing Tx IQ Cal for chain %d\n", i); |
797 | 789 | ||
798 | if (REG_READ(ah, txiqcal_status[i]) & | 790 | if (REG_READ(ah, txiqcal_status[i]) & |
799 | AR_PHY_TX_IQCAL_STATUS_FAILED) { | 791 | AR_PHY_TX_IQCAL_STATUS_FAILED) { |
800 | ath_dbg(common, ATH_DBG_CALIBRATE, | 792 | ath_dbg(common, CALIBRATE, |
801 | "Tx IQ Cal failed for chain %d.\n", i); | 793 | "Tx IQ Cal failed for chain %d\n", i); |
802 | goto tx_iqcal_fail; | 794 | goto tx_iqcal_fail; |
803 | } | 795 | } |
804 | 796 | ||
@@ -824,18 +816,16 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
824 | iq_res[idx + 1] = 0xffff & REG_READ(ah, | 816 | iq_res[idx + 1] = 0xffff & REG_READ(ah, |
825 | chan_info_tab[i] + offset); | 817 | chan_info_tab[i] + offset); |
826 | 818 | ||
827 | ath_dbg(common, ATH_DBG_CALIBRATE, | 819 | ath_dbg(common, CALIBRATE, |
828 | "IQ_RES[%d]=0x%x " | 820 | "IQ_RES[%d]=0x%x IQ_RES[%d]=0x%x\n", |
829 | "IQ_RES[%d]=0x%x\n", | ||
830 | idx, iq_res[idx], idx + 1, | 821 | idx, iq_res[idx], idx + 1, |
831 | iq_res[idx + 1]); | 822 | iq_res[idx + 1]); |
832 | } | 823 | } |
833 | 824 | ||
834 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, | 825 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, |
835 | coeff.iqc_coeff)) { | 826 | coeff.iqc_coeff)) { |
836 | ath_dbg(common, ATH_DBG_CALIBRATE, | 827 | ath_dbg(common, CALIBRATE, |
837 | "Failed in calculation of \ | 828 | "Failed in calculation of IQ correction\n"); |
838 | IQ correction.\n"); | ||
839 | goto tx_iqcal_fail; | 829 | goto tx_iqcal_fail; |
840 | } | 830 | } |
841 | 831 | ||
@@ -855,7 +845,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
855 | return; | 845 | return; |
856 | 846 | ||
857 | tx_iqcal_fail: | 847 | tx_iqcal_fail: |
858 | ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); | 848 | ath_dbg(common, CALIBRATE, "Tx IQ Cal failed\n"); |
859 | return; | 849 | return; |
860 | } | 850 | } |
861 | 851 | ||
@@ -953,7 +943,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
953 | if (!ar9003_hw_rtt_restore(ah, chan)) | 943 | if (!ar9003_hw_rtt_restore(ah, chan)) |
954 | run_rtt_cal = true; | 944 | run_rtt_cal = true; |
955 | 945 | ||
956 | ath_dbg(common, ATH_DBG_CALIBRATE, "RTT restore %s\n", | 946 | ath_dbg(common, CALIBRATE, "RTT restore %s\n", |
957 | run_rtt_cal ? "failed" : "succeed"); | 947 | run_rtt_cal ? "failed" : "succeed"); |
958 | } | 948 | } |
959 | run_agc_cal = run_rtt_cal; | 949 | run_agc_cal = run_rtt_cal; |
@@ -1016,20 +1006,20 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
1016 | u32 pld[4] = {0, 0, 0, 0}; | 1006 | u32 pld[4] = {0, 0, 0, 0}; |
1017 | 1007 | ||
1018 | /* send CAL_REQ only when BT is AWAKE. */ | 1008 | /* send CAL_REQ only when BT is AWAKE. */ |
1019 | ath_dbg(common, ATH_DBG_MCI, "MCI send WLAN_CAL_REQ 0x%x\n", | 1009 | ath_dbg(common, MCI, "MCI send WLAN_CAL_REQ 0x%x\n", |
1020 | mci_hw->wlan_cal_seq); | 1010 | mci_hw->wlan_cal_seq); |
1021 | MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ); | 1011 | MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ); |
1022 | pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++; | 1012 | pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++; |
1023 | ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); | 1013 | ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); |
1024 | 1014 | ||
1025 | /* Wait BT_CAL_GRANT for 50ms */ | 1015 | /* Wait BT_CAL_GRANT for 50ms */ |
1026 | ath_dbg(common, ATH_DBG_MCI, "MCI wait for BT_CAL_GRANT"); | 1016 | ath_dbg(common, MCI, "MCI wait for BT_CAL_GRANT\n"); |
1027 | 1017 | ||
1028 | if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) | 1018 | if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) |
1029 | ath_dbg(common, ATH_DBG_MCI, "MCI got BT_CAL_GRANT"); | 1019 | ath_dbg(common, MCI, "MCI got BT_CAL_GRANT\n"); |
1030 | else { | 1020 | else { |
1031 | is_reusable = false; | 1021 | is_reusable = false; |
1032 | ath_dbg(common, ATH_DBG_MCI, "\nMCI BT is not responding"); | 1022 | ath_dbg(common, MCI, "\nMCI BT is not responding\n"); |
1033 | } | 1023 | } |
1034 | } | 1024 | } |
1035 | 1025 | ||
@@ -1058,7 +1048,7 @@ skip_tx_iqcal: | |||
1058 | 1048 | ||
1059 | u32 pld[4] = {0, 0, 0, 0}; | 1049 | u32 pld[4] = {0, 0, 0, 0}; |
1060 | 1050 | ||
1061 | ath_dbg(common, ATH_DBG_MCI, "MCI Send WLAN_CAL_DONE 0x%x\n", | 1051 | ath_dbg(common, MCI, "MCI Send WLAN_CAL_DONE 0x%x\n", |
1062 | mci_hw->wlan_cal_done); | 1052 | mci_hw->wlan_cal_done); |
1063 | MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE); | 1053 | MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE); |
1064 | pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++; | 1054 | pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++; |
@@ -1074,9 +1064,8 @@ skip_tx_iqcal: | |||
1074 | if (run_rtt_cal) | 1064 | if (run_rtt_cal) |
1075 | ar9003_hw_rtt_disable(ah); | 1065 | ar9003_hw_rtt_disable(ah); |
1076 | 1066 | ||
1077 | ath_dbg(common, ATH_DBG_CALIBRATE, | 1067 | ath_dbg(common, CALIBRATE, |
1078 | "offset calibration failed to complete in 1ms;" | 1068 | "offset calibration failed to complete in 1ms; noisy environment?\n"); |
1079 | "noisy environment?\n"); | ||
1080 | return false; | 1069 | return false; |
1081 | } | 1070 | } |
1082 | 1071 | ||
@@ -1135,15 +1124,14 @@ skip_tx_iqcal: | |||
1135 | if (ah->supp_cals & IQ_MISMATCH_CAL) { | 1124 | if (ah->supp_cals & IQ_MISMATCH_CAL) { |
1136 | INIT_CAL(&ah->iq_caldata); | 1125 | INIT_CAL(&ah->iq_caldata); |
1137 | INSERT_CAL(ah, &ah->iq_caldata); | 1126 | INSERT_CAL(ah, &ah->iq_caldata); |
1138 | ath_dbg(common, ATH_DBG_CALIBRATE, | 1127 | ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); |
1139 | "enabling IQ Calibration.\n"); | ||
1140 | } | 1128 | } |
1141 | 1129 | ||
1142 | if (ah->supp_cals & TEMP_COMP_CAL) { | 1130 | if (ah->supp_cals & TEMP_COMP_CAL) { |
1143 | INIT_CAL(&ah->tempCompCalData); | 1131 | INIT_CAL(&ah->tempCompCalData); |
1144 | INSERT_CAL(ah, &ah->tempCompCalData); | 1132 | INSERT_CAL(ah, &ah->tempCompCalData); |
1145 | ath_dbg(common, ATH_DBG_CALIBRATE, | 1133 | ath_dbg(common, CALIBRATE, |
1146 | "enabling Temperature Compensation Calibration.\n"); | 1134 | "enabling Temperature Compensation Calibration\n"); |
1147 | } | 1135 | } |
1148 | 1136 | ||
1149 | /* Initialize current pointer to first element in list */ | 1137 | /* Initialize current pointer to first element in list */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 4ba6f52943a8..391def99314c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -3043,8 +3043,7 @@ static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer, | |||
3043 | int i; | 3043 | int i; |
3044 | 3044 | ||
3045 | if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) { | 3045 | if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) { |
3046 | ath_dbg(common, ATH_DBG_EEPROM, | 3046 | ath_dbg(common, EEPROM, "eeprom address not in range\n"); |
3047 | "eeprom address not in range\n"); | ||
3048 | return false; | 3047 | return false; |
3049 | } | 3048 | } |
3050 | 3049 | ||
@@ -3075,8 +3074,8 @@ static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer, | |||
3075 | return true; | 3074 | return true; |
3076 | 3075 | ||
3077 | error: | 3076 | error: |
3078 | ath_dbg(common, ATH_DBG_EEPROM, | 3077 | ath_dbg(common, EEPROM, "unable to read eeprom region at offset %d\n", |
3079 | "unable to read eeprom region at offset %d\n", address); | 3078 | address); |
3080 | return false; | 3079 | return false; |
3081 | } | 3080 | } |
3082 | 3081 | ||
@@ -3160,13 +3159,13 @@ static bool ar9300_uncompress_block(struct ath_hw *ah, | |||
3160 | length &= 0xff; | 3159 | length &= 0xff; |
3161 | 3160 | ||
3162 | if (length > 0 && spot >= 0 && spot+length <= mdataSize) { | 3161 | if (length > 0 && spot >= 0 && spot+length <= mdataSize) { |
3163 | ath_dbg(common, ATH_DBG_EEPROM, | 3162 | ath_dbg(common, EEPROM, |
3164 | "Restore at %d: spot=%d offset=%d length=%d\n", | 3163 | "Restore at %d: spot=%d offset=%d length=%d\n", |
3165 | it, spot, offset, length); | 3164 | it, spot, offset, length); |
3166 | memcpy(&mptr[spot], &block[it+2], length); | 3165 | memcpy(&mptr[spot], &block[it+2], length); |
3167 | spot += length; | 3166 | spot += length; |
3168 | } else if (length > 0) { | 3167 | } else if (length > 0) { |
3169 | ath_dbg(common, ATH_DBG_EEPROM, | 3168 | ath_dbg(common, EEPROM, |
3170 | "Bad restore at %d: spot=%d offset=%d length=%d\n", | 3169 | "Bad restore at %d: spot=%d offset=%d length=%d\n", |
3171 | it, spot, offset, length); | 3170 | it, spot, offset, length); |
3172 | return false; | 3171 | return false; |
@@ -3188,13 +3187,13 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
3188 | switch (code) { | 3187 | switch (code) { |
3189 | case _CompressNone: | 3188 | case _CompressNone: |
3190 | if (length != mdata_size) { | 3189 | if (length != mdata_size) { |
3191 | ath_dbg(common, ATH_DBG_EEPROM, | 3190 | ath_dbg(common, EEPROM, |
3192 | "EEPROM structure size mismatch memory=%d eeprom=%d\n", | 3191 | "EEPROM structure size mismatch memory=%d eeprom=%d\n", |
3193 | mdata_size, length); | 3192 | mdata_size, length); |
3194 | return -1; | 3193 | return -1; |
3195 | } | 3194 | } |
3196 | memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length); | 3195 | memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length); |
3197 | ath_dbg(common, ATH_DBG_EEPROM, | 3196 | ath_dbg(common, EEPROM, |
3198 | "restored eeprom %d: uncompressed, length %d\n", | 3197 | "restored eeprom %d: uncompressed, length %d\n", |
3199 | it, length); | 3198 | it, length); |
3200 | break; | 3199 | break; |
@@ -3203,22 +3202,21 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
3203 | } else { | 3202 | } else { |
3204 | eep = ar9003_eeprom_struct_find_by_id(reference); | 3203 | eep = ar9003_eeprom_struct_find_by_id(reference); |
3205 | if (eep == NULL) { | 3204 | if (eep == NULL) { |
3206 | ath_dbg(common, ATH_DBG_EEPROM, | 3205 | ath_dbg(common, EEPROM, |
3207 | "can't find reference eeprom struct %d\n", | 3206 | "can't find reference eeprom struct %d\n", |
3208 | reference); | 3207 | reference); |
3209 | return -1; | 3208 | return -1; |
3210 | } | 3209 | } |
3211 | memcpy(mptr, eep, mdata_size); | 3210 | memcpy(mptr, eep, mdata_size); |
3212 | } | 3211 | } |
3213 | ath_dbg(common, ATH_DBG_EEPROM, | 3212 | ath_dbg(common, EEPROM, |
3214 | "restore eeprom %d: block, reference %d, length %d\n", | 3213 | "restore eeprom %d: block, reference %d, length %d\n", |
3215 | it, reference, length); | 3214 | it, reference, length); |
3216 | ar9300_uncompress_block(ah, mptr, mdata_size, | 3215 | ar9300_uncompress_block(ah, mptr, mdata_size, |
3217 | (u8 *) (word + COMP_HDR_LEN), length); | 3216 | (u8 *) (word + COMP_HDR_LEN), length); |
3218 | break; | 3217 | break; |
3219 | default: | 3218 | default: |
3220 | ath_dbg(common, ATH_DBG_EEPROM, | 3219 | ath_dbg(common, EEPROM, "unknown compression code %d\n", code); |
3221 | "unknown compression code %d\n", code); | ||
3222 | return -1; | 3220 | return -1; |
3223 | } | 3221 | } |
3224 | return 0; | 3222 | return 0; |
@@ -3294,34 +3292,32 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, | |||
3294 | cptr = AR9300_BASE_ADDR_512; | 3292 | cptr = AR9300_BASE_ADDR_512; |
3295 | else | 3293 | else |
3296 | cptr = AR9300_BASE_ADDR; | 3294 | cptr = AR9300_BASE_ADDR; |
3297 | ath_dbg(common, ATH_DBG_EEPROM, | 3295 | ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n", |
3298 | "Trying EEPROM access at Address 0x%04x\n", cptr); | 3296 | cptr); |
3299 | if (ar9300_check_eeprom_header(ah, read, cptr)) | 3297 | if (ar9300_check_eeprom_header(ah, read, cptr)) |
3300 | goto found; | 3298 | goto found; |
3301 | 3299 | ||
3302 | cptr = AR9300_BASE_ADDR_512; | 3300 | cptr = AR9300_BASE_ADDR_512; |
3303 | ath_dbg(common, ATH_DBG_EEPROM, | 3301 | ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n", |
3304 | "Trying EEPROM access at Address 0x%04x\n", cptr); | 3302 | cptr); |
3305 | if (ar9300_check_eeprom_header(ah, read, cptr)) | 3303 | if (ar9300_check_eeprom_header(ah, read, cptr)) |
3306 | goto found; | 3304 | goto found; |
3307 | 3305 | ||
3308 | read = ar9300_read_otp; | 3306 | read = ar9300_read_otp; |
3309 | cptr = AR9300_BASE_ADDR; | 3307 | cptr = AR9300_BASE_ADDR; |
3310 | ath_dbg(common, ATH_DBG_EEPROM, | 3308 | ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr); |
3311 | "Trying OTP access at Address 0x%04x\n", cptr); | ||
3312 | if (ar9300_check_eeprom_header(ah, read, cptr)) | 3309 | if (ar9300_check_eeprom_header(ah, read, cptr)) |
3313 | goto found; | 3310 | goto found; |
3314 | 3311 | ||
3315 | cptr = AR9300_BASE_ADDR_512; | 3312 | cptr = AR9300_BASE_ADDR_512; |
3316 | ath_dbg(common, ATH_DBG_EEPROM, | 3313 | ath_dbg(common, EEPROM, "Trying OTP access at Address 0x%04x\n", cptr); |
3317 | "Trying OTP access at Address 0x%04x\n", cptr); | ||
3318 | if (ar9300_check_eeprom_header(ah, read, cptr)) | 3314 | if (ar9300_check_eeprom_header(ah, read, cptr)) |
3319 | goto found; | 3315 | goto found; |
3320 | 3316 | ||
3321 | goto fail; | 3317 | goto fail; |
3322 | 3318 | ||
3323 | found: | 3319 | found: |
3324 | ath_dbg(common, ATH_DBG_EEPROM, "Found valid EEPROM data\n"); | 3320 | ath_dbg(common, EEPROM, "Found valid EEPROM data\n"); |
3325 | 3321 | ||
3326 | for (it = 0; it < MSTATE; it++) { | 3322 | for (it = 0; it < MSTATE; it++) { |
3327 | if (!read(ah, cptr, word, COMP_HDR_LEN)) | 3323 | if (!read(ah, cptr, word, COMP_HDR_LEN)) |
@@ -3332,13 +3328,12 @@ found: | |||
3332 | 3328 | ||
3333 | ar9300_comp_hdr_unpack(word, &code, &reference, | 3329 | ar9300_comp_hdr_unpack(word, &code, &reference, |
3334 | &length, &major, &minor); | 3330 | &length, &major, &minor); |
3335 | ath_dbg(common, ATH_DBG_EEPROM, | 3331 | ath_dbg(common, EEPROM, |
3336 | "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n", | 3332 | "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n", |
3337 | cptr, code, reference, length, major, minor); | 3333 | cptr, code, reference, length, major, minor); |
3338 | if ((!AR_SREV_9485(ah) && length >= 1024) || | 3334 | if ((!AR_SREV_9485(ah) && length >= 1024) || |
3339 | (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) { | 3335 | (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) { |
3340 | ath_dbg(common, ATH_DBG_EEPROM, | 3336 | ath_dbg(common, EEPROM, "Skipping bad header\n"); |
3341 | "Skipping bad header\n"); | ||
3342 | cptr -= COMP_HDR_LEN; | 3337 | cptr -= COMP_HDR_LEN; |
3343 | continue; | 3338 | continue; |
3344 | } | 3339 | } |
@@ -3347,13 +3342,13 @@ found: | |||
3347 | read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN); | 3342 | read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN); |
3348 | checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); | 3343 | checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); |
3349 | mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]); | 3344 | mchecksum = get_unaligned_le16(&word[COMP_HDR_LEN + osize]); |
3350 | ath_dbg(common, ATH_DBG_EEPROM, | 3345 | ath_dbg(common, EEPROM, "checksum %x %x\n", |
3351 | "checksum %x %x\n", checksum, mchecksum); | 3346 | checksum, mchecksum); |
3352 | if (checksum == mchecksum) { | 3347 | if (checksum == mchecksum) { |
3353 | ar9300_compress_decision(ah, it, code, reference, mptr, | 3348 | ar9300_compress_decision(ah, it, code, reference, mptr, |
3354 | word, length, mdata_size); | 3349 | word, length, mdata_size); |
3355 | } else { | 3350 | } else { |
3356 | ath_dbg(common, ATH_DBG_EEPROM, | 3351 | ath_dbg(common, EEPROM, |
3357 | "skipping block with bad checksum\n"); | 3352 | "skipping block with bad checksum\n"); |
3358 | } | 3353 | } |
3359 | cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN); | 3354 | cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN); |
@@ -4424,8 +4419,8 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, | |||
4424 | is2GHz) + ht40PowerIncForPdadc; | 4419 | is2GHz) + ht40PowerIncForPdadc; |
4425 | 4420 | ||
4426 | for (i = 0; i < ar9300RateSize; i++) { | 4421 | for (i = 0; i < ar9300RateSize; i++) { |
4427 | ath_dbg(common, ATH_DBG_EEPROM, | 4422 | ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n", |
4428 | "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); | 4423 | i, targetPowerValT2[i]); |
4429 | } | 4424 | } |
4430 | } | 4425 | } |
4431 | 4426 | ||
@@ -4444,7 +4439,7 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | |||
4444 | struct ath_common *common = ath9k_hw_common(ah); | 4439 | struct ath_common *common = ath9k_hw_common(ah); |
4445 | 4440 | ||
4446 | if (ichain >= AR9300_MAX_CHAINS) { | 4441 | if (ichain >= AR9300_MAX_CHAINS) { |
4447 | ath_dbg(common, ATH_DBG_EEPROM, | 4442 | ath_dbg(common, EEPROM, |
4448 | "Invalid chain index, must be less than %d\n", | 4443 | "Invalid chain index, must be less than %d\n", |
4449 | AR9300_MAX_CHAINS); | 4444 | AR9300_MAX_CHAINS); |
4450 | return -1; | 4445 | return -1; |
@@ -4452,7 +4447,7 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | |||
4452 | 4447 | ||
4453 | if (mode) { /* 5GHz */ | 4448 | if (mode) { /* 5GHz */ |
4454 | if (ipier >= AR9300_NUM_5G_CAL_PIERS) { | 4449 | if (ipier >= AR9300_NUM_5G_CAL_PIERS) { |
4455 | ath_dbg(common, ATH_DBG_EEPROM, | 4450 | ath_dbg(common, EEPROM, |
4456 | "Invalid 5GHz cal pier index, must be less than %d\n", | 4451 | "Invalid 5GHz cal pier index, must be less than %d\n", |
4457 | AR9300_NUM_5G_CAL_PIERS); | 4452 | AR9300_NUM_5G_CAL_PIERS); |
4458 | return -1; | 4453 | return -1; |
@@ -4462,7 +4457,7 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | |||
4462 | is2GHz = 0; | 4457 | is2GHz = 0; |
4463 | } else { | 4458 | } else { |
4464 | if (ipier >= AR9300_NUM_2G_CAL_PIERS) { | 4459 | if (ipier >= AR9300_NUM_2G_CAL_PIERS) { |
4465 | ath_dbg(common, ATH_DBG_EEPROM, | 4460 | ath_dbg(common, EEPROM, |
4466 | "Invalid 2GHz cal pier index, must be less than %d\n", | 4461 | "Invalid 2GHz cal pier index, must be less than %d\n", |
4467 | AR9300_NUM_2G_CAL_PIERS); | 4462 | AR9300_NUM_2G_CAL_PIERS); |
4468 | return -1; | 4463 | return -1; |
@@ -4624,8 +4619,7 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) | |||
4624 | 4619 | ||
4625 | /* interpolate */ | 4620 | /* interpolate */ |
4626 | for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { | 4621 | for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { |
4627 | ath_dbg(common, ATH_DBG_EEPROM, | 4622 | ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n", |
4628 | "ch=%d f=%d low=%d %d h=%d %d\n", | ||
4629 | ichain, frequency, lfrequency[ichain], | 4623 | ichain, frequency, lfrequency[ichain], |
4630 | lcorrection[ichain], hfrequency[ichain], | 4624 | lcorrection[ichain], hfrequency[ichain], |
4631 | hcorrection[ichain]); | 4625 | hcorrection[ichain]); |
@@ -4680,7 +4674,7 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) | |||
4680 | ar9003_hw_power_control_override(ah, frequency, correction, voltage, | 4674 | ar9003_hw_power_control_override(ah, frequency, correction, voltage, |
4681 | temperature); | 4675 | temperature); |
4682 | 4676 | ||
4683 | ath_dbg(common, ATH_DBG_EEPROM, | 4677 | ath_dbg(common, EEPROM, |
4684 | "for frequency=%d, calibration correction = %d %d %d\n", | 4678 | "for frequency=%d, calibration correction = %d %d %d\n", |
4685 | frequency, correction[0], correction[1], correction[2]); | 4679 | frequency, correction[0], correction[1], correction[2]); |
4686 | 4680 | ||
@@ -4866,7 +4860,7 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, | |||
4866 | else | 4860 | else |
4867 | freq = centers.ctl_center; | 4861 | freq = centers.ctl_center; |
4868 | 4862 | ||
4869 | ath_dbg(common, ATH_DBG_REGULATORY, | 4863 | ath_dbg(common, REGULATORY, |
4870 | "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n", | 4864 | "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, EXT_ADDITIVE %d\n", |
4871 | ctlMode, numCtlModes, isHt40CtlMode, | 4865 | ctlMode, numCtlModes, isHt40CtlMode, |
4872 | (pCtlMode[ctlMode] & EXT_ADDITIVE)); | 4866 | (pCtlMode[ctlMode] & EXT_ADDITIVE)); |
@@ -4882,7 +4876,7 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, | |||
4882 | 4876 | ||
4883 | twiceMaxEdgePower = MAX_RATE_POWER; | 4877 | twiceMaxEdgePower = MAX_RATE_POWER; |
4884 | for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) { | 4878 | for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) { |
4885 | ath_dbg(common, ATH_DBG_REGULATORY, | 4879 | ath_dbg(common, REGULATORY, |
4886 | "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n", | 4880 | "LOOP-Ctlidx %d: cfgCtl 0x%2.2x pCtlMode 0x%2.2x ctlIndex 0x%2.2x chan %d\n", |
4887 | i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i], | 4881 | i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i], |
4888 | chan->channel); | 4882 | chan->channel); |
@@ -4924,7 +4918,7 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, | |||
4924 | 4918 | ||
4925 | minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); | 4919 | minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); |
4926 | 4920 | ||
4927 | ath_dbg(common, ATH_DBG_REGULATORY, | 4921 | ath_dbg(common, REGULATORY, |
4928 | "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n", | 4922 | "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d sP %d minCtlPwr %d\n", |
4929 | ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, | 4923 | ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, |
4930 | scaledPower, minCtlPower); | 4924 | scaledPower, minCtlPower); |
@@ -5048,7 +5042,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | |||
5048 | target_power_val_t2_eep[i]) > | 5042 | target_power_val_t2_eep[i]) > |
5049 | paprd_scale_factor)) { | 5043 | paprd_scale_factor)) { |
5050 | ah->paprd_ratemask &= ~(1 << i); | 5044 | ah->paprd_ratemask &= ~(1 << i); |
5051 | ath_dbg(common, ATH_DBG_EEPROM, | 5045 | ath_dbg(common, EEPROM, |
5052 | "paprd disabled for mcs %d\n", i); | 5046 | "paprd disabled for mcs %d\n", i); |
5053 | } | 5047 | } |
5054 | } | 5048 | } |
@@ -5066,8 +5060,8 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | |||
5066 | return; | 5060 | return; |
5067 | 5061 | ||
5068 | for (i = 0; i < ar9300RateSize; i++) { | 5062 | for (i = 0; i < ar9300RateSize; i++) { |
5069 | ath_dbg(common, ATH_DBG_EEPROM, | 5063 | ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n", |
5070 | "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); | 5064 | i, targetPowerValT2[i]); |
5071 | } | 5065 | } |
5072 | 5066 | ||
5073 | ah->txpower_limit = regulatory->max_power_level; | 5067 | ah->txpower_limit = regulatory->max_power_level; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 631fe4f2e495..4a315155d779 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -305,10 +305,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
305 | raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW); | 305 | raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW); |
306 | 306 | ||
307 | if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef)) | 307 | if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef)) |
308 | ath_dbg(common, ATH_DBG_MCI, | 308 | ath_dbg(common, MCI, |
309 | "MCI gets 0xdeadbeef during MCI int processing" | 309 | "MCI gets 0xdeadbeef during MCI int processing new raw_intr=0x%08x, new rx_msg_raw=0x%08x, raw_intr=0x%08x, rx_msg_raw=0x%08x\n", |
310 | "new raw_intr=0x%08x, new rx_msg_raw=0x%08x, " | ||
311 | "raw_intr=0x%08x, rx_msg_raw=0x%08x\n", | ||
312 | raw_intr, rx_msg_intr, mci->raw_intr, | 310 | raw_intr, rx_msg_intr, mci->raw_intr, |
313 | mci->rx_msg_intr); | 311 | mci->rx_msg_intr); |
314 | else { | 312 | else { |
@@ -322,7 +320,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
322 | 320 | ||
323 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr); | 321 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr); |
324 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr); | 322 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr); |
325 | ath_dbg(common, ATH_DBG_MCI, "AR_INTR_SYNC_MCI\n"); | 323 | ath_dbg(common, MCI, "AR_INTR_SYNC_MCI\n"); |
326 | 324 | ||
327 | } | 325 | } |
328 | } | 326 | } |
@@ -335,7 +333,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | |||
335 | } | 333 | } |
336 | 334 | ||
337 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) | 335 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) |
338 | ath_dbg(common, ATH_DBG_INTERRUPT, | 336 | ath_dbg(common, INTERRUPT, |
339 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); | 337 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); |
340 | 338 | ||
341 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); | 339 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); |
@@ -366,7 +364,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
366 | 364 | ||
367 | if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || | 365 | if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || |
368 | (MS(ads->ds_info, AR_TxRxDesc) != 1)) { | 366 | (MS(ads->ds_info, AR_TxRxDesc) != 1)) { |
369 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT, | 367 | ath_dbg(ath9k_hw_common(ah), XMIT, |
370 | "Tx Descriptor error %x\n", ads->ds_info); | 368 | "Tx Descriptor error %x\n", ads->ds_info); |
371 | memset(ads, 0, sizeof(*ads)); | 369 | memset(ads, 0, sizeof(*ads)); |
372 | return -EIO; | 370 | return -EIO; |
@@ -574,7 +572,7 @@ void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah) | |||
574 | memset((void *) ah->ts_ring, 0, | 572 | memset((void *) ah->ts_ring, 0, |
575 | ah->ts_size * sizeof(struct ar9003_txs)); | 573 | ah->ts_size * sizeof(struct ar9003_txs)); |
576 | 574 | ||
577 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT, | 575 | ath_dbg(ath9k_hw_common(ah), XMIT, |
578 | "TS Start 0x%x End 0x%x Virt %p, Size %d\n", | 576 | "TS Start 0x%x End 0x%x Virt %p, Size %d\n", |
579 | ah->ts_paddr_start, ah->ts_paddr_end, | 577 | ah->ts_paddr_start, ah->ts_paddr_end, |
580 | ah->ts_ring, ah->ts_size); | 578 | ah->ts_ring, ah->ts_size); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 8599822dc83f..709520c6835b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c | |||
@@ -68,11 +68,11 @@ static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address, | |||
68 | } | 68 | } |
69 | 69 | ||
70 | if (time_out <= 0) { | 70 | if (time_out <= 0) { |
71 | ath_dbg(common, ATH_DBG_MCI, | 71 | ath_dbg(common, MCI, |
72 | "MCI Wait for Reg 0x%08x = 0x%08x timeout.\n", | 72 | "MCI Wait for Reg 0x%08x = 0x%08x timeout\n", |
73 | address, bit_position); | 73 | address, bit_position); |
74 | ath_dbg(common, ATH_DBG_MCI, | 74 | ath_dbg(common, MCI, |
75 | "MCI INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x", | 75 | "MCI INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n", |
76 | REG_READ(ah, AR_MCI_INTERRUPT_RAW), | 76 | REG_READ(ah, AR_MCI_INTERRUPT_RAW), |
77 | REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW)); | 77 | REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW)); |
78 | time_out = 0; | 78 | time_out = 0; |
@@ -85,6 +85,9 @@ void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done) | |||
85 | { | 85 | { |
86 | u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00}; | 86 | u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00}; |
87 | 87 | ||
88 | if (!ATH9K_HW_CAP_MCI) | ||
89 | return; | ||
90 | |||
88 | ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16, | 91 | ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16, |
89 | wait_done, false); | 92 | wait_done, false); |
90 | udelay(5); | 93 | udelay(5); |
@@ -94,6 +97,9 @@ void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done) | |||
94 | { | 97 | { |
95 | u32 payload = 0x00000000; | 98 | u32 payload = 0x00000000; |
96 | 99 | ||
100 | if (!ATH9K_HW_CAP_MCI) | ||
101 | return; | ||
102 | |||
97 | ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1, | 103 | ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1, |
98 | wait_done, false); | 104 | wait_done, false); |
99 | } | 105 | } |
@@ -107,6 +113,9 @@ static void ar9003_mci_send_req_wake(struct ath_hw *ah, bool wait_done) | |||
107 | 113 | ||
108 | void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done) | 114 | void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done) |
109 | { | 115 | { |
116 | if (!ATH9K_HW_CAP_MCI) | ||
117 | return; | ||
118 | |||
110 | ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP, | 119 | ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP, |
111 | NULL, 0, wait_done, false); | 120 | NULL, 0, wait_done, false); |
112 | } | 121 | } |
@@ -135,7 +144,7 @@ static void ar9003_mci_send_coex_version_query(struct ath_hw *ah, | |||
135 | 144 | ||
136 | if (!mci->bt_version_known && | 145 | if (!mci->bt_version_known && |
137 | (mci->bt_state != MCI_BT_SLEEP)) { | 146 | (mci->bt_state != MCI_BT_SLEEP)) { |
138 | ath_dbg(common, ATH_DBG_MCI, "MCI Send Coex version query\n"); | 147 | ath_dbg(common, MCI, "MCI Send Coex version query\n"); |
139 | MCI_GPM_SET_TYPE_OPCODE(payload, | 148 | MCI_GPM_SET_TYPE_OPCODE(payload, |
140 | MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_QUERY); | 149 | MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_QUERY); |
141 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | 150 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, |
@@ -150,7 +159,7 @@ static void ar9003_mci_send_coex_version_response(struct ath_hw *ah, | |||
150 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 159 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
151 | u32 payload[4] = {0, 0, 0, 0}; | 160 | u32 payload[4] = {0, 0, 0, 0}; |
152 | 161 | ||
153 | ath_dbg(common, ATH_DBG_MCI, "MCI Send Coex version response\n"); | 162 | ath_dbg(common, MCI, "MCI Send Coex version response\n"); |
154 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, | 163 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, |
155 | MCI_GPM_COEX_VERSION_RESPONSE); | 164 | MCI_GPM_COEX_VERSION_RESPONSE); |
156 | *(((u8 *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) = | 165 | *(((u8 *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) = |
@@ -187,8 +196,8 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, | |||
187 | 196 | ||
188 | if (mci->bt_state != MCI_BT_SLEEP) { | 197 | if (mci->bt_state != MCI_BT_SLEEP) { |
189 | 198 | ||
190 | ath_dbg(common, ATH_DBG_MCI, | 199 | ath_dbg(common, MCI, "MCI Send Coex BT Status Query 0x%02X\n", |
191 | "MCI Send Coex BT Status Query 0x%02X\n", query_type); | 200 | query_type); |
192 | 201 | ||
193 | MCI_GPM_SET_TYPE_OPCODE(payload, | 202 | MCI_GPM_SET_TYPE_OPCODE(payload, |
194 | MCI_GPM_COEX_AGENT, MCI_GPM_COEX_STATUS_QUERY); | 203 | MCI_GPM_COEX_AGENT, MCI_GPM_COEX_STATUS_QUERY); |
@@ -203,9 +212,8 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, | |||
203 | if (query_btinfo) { | 212 | if (query_btinfo) { |
204 | mci->need_flush_btinfo = true; | 213 | mci->need_flush_btinfo = true; |
205 | 214 | ||
206 | ath_dbg(common, ATH_DBG_MCI, | 215 | ath_dbg(common, MCI, |
207 | "MCI send bt_status_query fail, " | 216 | "MCI send bt_status_query fail, set flush flag again\n"); |
208 | "set flush flag again\n"); | ||
209 | } | 217 | } |
210 | } | 218 | } |
211 | 219 | ||
@@ -221,7 +229,10 @@ void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, | |||
221 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 229 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
222 | u32 payload[4] = {0, 0, 0, 0}; | 230 | u32 payload[4] = {0, 0, 0, 0}; |
223 | 231 | ||
224 | ath_dbg(common, ATH_DBG_MCI, "MCI Send Coex %s BT GPM.\n", | 232 | if (!ATH9K_HW_CAP_MCI) |
233 | return; | ||
234 | |||
235 | ath_dbg(common, MCI, "MCI Send Coex %s BT GPM\n", | ||
225 | (halt) ? "halt" : "unhalt"); | 236 | (halt) ? "halt" : "unhalt"); |
226 | 237 | ||
227 | MCI_GPM_SET_TYPE_OPCODE(payload, | 238 | MCI_GPM_SET_TYPE_OPCODE(payload, |
@@ -259,8 +270,8 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) | |||
259 | REG_READ(ah, AR_MCI_INTERRUPT_RAW)); | 270 | REG_READ(ah, AR_MCI_INTERRUPT_RAW)); |
260 | 271 | ||
261 | /* Remote Reset */ | 272 | /* Remote Reset */ |
262 | ath_dbg(common, ATH_DBG_MCI, "MCI Reset sequence start\n"); | 273 | ath_dbg(common, MCI, "MCI Reset sequence start\n"); |
263 | ath_dbg(common, ATH_DBG_MCI, "MCI send REMOTE_RESET\n"); | 274 | ath_dbg(common, MCI, "MCI send REMOTE_RESET\n"); |
264 | ar9003_mci_remote_reset(ah, true); | 275 | ar9003_mci_remote_reset(ah, true); |
265 | 276 | ||
266 | /* | 277 | /* |
@@ -271,14 +282,13 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) | |||
271 | if (AR_SREV_9462_10(ah)) | 282 | if (AR_SREV_9462_10(ah)) |
272 | udelay(252); | 283 | udelay(252); |
273 | 284 | ||
274 | ath_dbg(common, ATH_DBG_MCI, "MCI Send REQ_WAKE to remoter(BT)\n"); | 285 | ath_dbg(common, MCI, "MCI Send REQ_WAKE to remoter(BT)\n"); |
275 | ar9003_mci_send_req_wake(ah, true); | 286 | ar9003_mci_send_req_wake(ah, true); |
276 | 287 | ||
277 | if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 288 | if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
278 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) { | 289 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) { |
279 | 290 | ||
280 | ath_dbg(common, ATH_DBG_MCI, | 291 | ath_dbg(common, MCI, "MCI SYS_WAKING from remote(BT)\n"); |
281 | "MCI SYS_WAKING from remote(BT)\n"); | ||
282 | mci->bt_state = MCI_BT_AWAKE; | 292 | mci->bt_state = MCI_BT_AWAKE; |
283 | 293 | ||
284 | if (AR_SREV_9462_10(ah)) | 294 | if (AR_SREV_9462_10(ah)) |
@@ -302,8 +312,7 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) | |||
302 | 312 | ||
303 | /* Send SYS_WAKING to BT */ | 313 | /* Send SYS_WAKING to BT */ |
304 | 314 | ||
305 | ath_dbg(common, ATH_DBG_MCI, | 315 | ath_dbg(common, MCI, "MCI send SW SYS_WAKING to remote BT\n"); |
306 | "MCI send SW SYS_WAKING to remote BT\n"); | ||
307 | 316 | ||
308 | ar9003_mci_send_sys_waking(ah, true); | 317 | ar9003_mci_send_sys_waking(ah, true); |
309 | udelay(10); | 318 | udelay(10); |
@@ -332,8 +341,7 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) | |||
332 | 341 | ||
333 | if (AR_SREV_9462_10(ah) || mci->is_2g) { | 342 | if (AR_SREV_9462_10(ah) || mci->is_2g) { |
334 | /* Send LNA_TRANS */ | 343 | /* Send LNA_TRANS */ |
335 | ath_dbg(common, ATH_DBG_MCI, | 344 | ath_dbg(common, MCI, "MCI send LNA_TRANS to BT\n"); |
336 | "MCI send LNA_TRANS to BT\n"); | ||
337 | ar9003_mci_send_lna_transfer(ah, true); | 345 | ar9003_mci_send_lna_transfer(ah, true); |
338 | udelay(5); | 346 | udelay(5); |
339 | } | 347 | } |
@@ -344,20 +352,17 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) | |||
344 | AR_MCI_INTERRUPT_RX_MSG_RAW, | 352 | AR_MCI_INTERRUPT_RX_MSG_RAW, |
345 | AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, | 353 | AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, |
346 | mci_timeout)) | 354 | mci_timeout)) |
347 | ath_dbg(common, ATH_DBG_MCI, | 355 | ath_dbg(common, MCI, |
348 | "MCI WLAN has control over the LNA & " | 356 | "MCI WLAN has control over the LNA & BT obeys it\n"); |
349 | "BT obeys it\n"); | ||
350 | else | 357 | else |
351 | ath_dbg(common, ATH_DBG_MCI, | 358 | ath_dbg(common, MCI, |
352 | "MCI BT didn't respond to" | 359 | "MCI BT didn't respond to LNA_TRANS\n"); |
353 | "LNA_TRANS\n"); | ||
354 | } | 360 | } |
355 | 361 | ||
356 | if (AR_SREV_9462_10(ah)) { | 362 | if (AR_SREV_9462_10(ah)) { |
357 | /* Send another remote_reset to deassert BT clk_req. */ | 363 | /* Send another remote_reset to deassert BT clk_req. */ |
358 | ath_dbg(common, ATH_DBG_MCI, | 364 | ath_dbg(common, MCI, |
359 | "MCI another remote_reset to " | 365 | "MCI another remote_reset to deassert clk_req\n"); |
360 | "deassert clk_req\n"); | ||
361 | ar9003_mci_remote_reset(ah, true); | 366 | ar9003_mci_remote_reset(ah, true); |
362 | udelay(252); | 367 | udelay(252); |
363 | } | 368 | } |
@@ -381,12 +386,17 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) | |||
381 | 386 | ||
382 | void ar9003_mci_disable_interrupt(struct ath_hw *ah) | 387 | void ar9003_mci_disable_interrupt(struct ath_hw *ah) |
383 | { | 388 | { |
389 | if (!ATH9K_HW_CAP_MCI) | ||
390 | return; | ||
391 | |||
384 | REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0); | 392 | REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0); |
385 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); | 393 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); |
386 | } | 394 | } |
387 | 395 | ||
388 | void ar9003_mci_enable_interrupt(struct ath_hw *ah) | 396 | void ar9003_mci_enable_interrupt(struct ath_hw *ah) |
389 | { | 397 | { |
398 | if (!ATH9K_HW_CAP_MCI) | ||
399 | return; | ||
390 | 400 | ||
391 | REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT); | 401 | REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT); |
392 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, | 402 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, |
@@ -397,6 +407,9 @@ bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints) | |||
397 | { | 407 | { |
398 | u32 intr; | 408 | u32 intr; |
399 | 409 | ||
410 | if (!ATH9K_HW_CAP_MCI) | ||
411 | return false; | ||
412 | |||
400 | intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW); | 413 | intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW); |
401 | return ((intr & ints) == ints); | 414 | return ((intr & ints) == ints); |
402 | } | 415 | } |
@@ -405,6 +418,10 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, | |||
405 | u32 *rx_msg_intr) | 418 | u32 *rx_msg_intr) |
406 | { | 419 | { |
407 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 420 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
421 | |||
422 | if (!ATH9K_HW_CAP_MCI) | ||
423 | return; | ||
424 | |||
408 | *raw_intr = mci->raw_intr; | 425 | *raw_intr = mci->raw_intr; |
409 | *rx_msg_intr = mci->rx_msg_intr; | 426 | *rx_msg_intr = mci->rx_msg_intr; |
410 | 427 | ||
@@ -418,6 +435,9 @@ void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g) | |||
418 | { | 435 | { |
419 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 436 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
420 | 437 | ||
438 | if (!ATH9K_HW_CAP_MCI) | ||
439 | return; | ||
440 | |||
421 | if (!mci->update_2g5g && | 441 | if (!mci->update_2g5g && |
422 | (mci->is_2g != is_2g)) | 442 | (mci->is_2g != is_2g)) |
423 | mci->update_2g5g = true; | 443 | mci->update_2g5g = true; |
@@ -441,7 +461,7 @@ static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index) | |||
441 | recv_type = MCI_GPM_TYPE(payload); | 461 | recv_type = MCI_GPM_TYPE(payload); |
442 | 462 | ||
443 | if (recv_type == MCI_GPM_RSVD_PATTERN) { | 463 | if (recv_type == MCI_GPM_RSVD_PATTERN) { |
444 | ath_dbg(common, ATH_DBG_MCI, "MCI Skip RSVD GPM\n"); | 464 | ath_dbg(common, MCI, "MCI Skip RSVD GPM\n"); |
445 | return false; | 465 | return false; |
446 | } | 466 | } |
447 | 467 | ||
@@ -514,11 +534,11 @@ static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done, | |||
514 | *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = (bt_flags >> 16) & 0xFF; | 534 | *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = (bt_flags >> 16) & 0xFF; |
515 | *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = (bt_flags >> 24) & 0xFF; | 535 | *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = (bt_flags >> 24) & 0xFF; |
516 | 536 | ||
517 | ath_dbg(common, ATH_DBG_MCI, | 537 | ath_dbg(common, MCI, |
518 | "MCI BT_MCI_FLAGS: Send Coex BT Update Flags %s 0x%08x\n", | 538 | "MCI BT_MCI_FLAGS: Send Coex BT Update Flags %s 0x%08x\n", |
519 | (opcode == MCI_GPM_COEX_BT_FLAGS_READ) ? "READ" : | 539 | opcode == MCI_GPM_COEX_BT_FLAGS_READ ? "READ" : |
520 | ((opcode == MCI_GPM_COEX_BT_FLAGS_SET) ? "SET" : "CLEAR"), | 540 | opcode == MCI_GPM_COEX_BT_FLAGS_SET ? "SET" : "CLEAR", |
521 | bt_flags); | 541 | bt_flags); |
522 | 542 | ||
523 | return ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, | 543 | return ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, |
524 | wait_done, true); | 544 | wait_done, true); |
@@ -531,7 +551,10 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | |||
531 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 551 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
532 | u32 regval, thresh; | 552 | u32 regval, thresh; |
533 | 553 | ||
534 | ath_dbg(common, ATH_DBG_MCI, "MCI full_sleep = %d, is_2g = %d\n", | 554 | if (!ATH9K_HW_CAP_MCI) |
555 | return; | ||
556 | |||
557 | ath_dbg(common, MCI, "MCI full_sleep = %d, is_2g = %d\n", | ||
535 | is_full_sleep, is_2g); | 558 | is_full_sleep, is_2g); |
536 | 559 | ||
537 | /* | 560 | /* |
@@ -539,14 +562,13 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | |||
539 | */ | 562 | */ |
540 | 563 | ||
541 | if (!mci->gpm_addr && !mci->sched_addr) { | 564 | if (!mci->gpm_addr && !mci->sched_addr) { |
542 | ath_dbg(common, ATH_DBG_MCI, | 565 | ath_dbg(common, MCI, |
543 | "MCI GPM and schedule buffers are not allocated"); | 566 | "MCI GPM and schedule buffers are not allocated\n"); |
544 | return; | 567 | return; |
545 | } | 568 | } |
546 | 569 | ||
547 | if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { | 570 | if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { |
548 | ath_dbg(common, ATH_DBG_MCI, | 571 | ath_dbg(common, MCI, "MCI it's deadbeef, quit mci_reset\n"); |
549 | "MCI it's deadbeef, quit mci_reset\n"); | ||
550 | return; | 572 | return; |
551 | } | 573 | } |
552 | 574 | ||
@@ -574,8 +596,7 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | |||
574 | !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) { | 596 | !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) { |
575 | 597 | ||
576 | regval |= SM(1, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | 598 | regval |= SM(1, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); |
577 | ath_dbg(common, ATH_DBG_MCI, | 599 | ath_dbg(common, MCI, "MCI sched one step look ahead\n"); |
578 | "MCI sched one step look ahead\n"); | ||
579 | 600 | ||
580 | if (!(mci->config & | 601 | if (!(mci->config & |
581 | ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { | 602 | ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { |
@@ -593,11 +614,9 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | |||
593 | AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); | 614 | AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); |
594 | 615 | ||
595 | } else | 616 | } else |
596 | ath_dbg(common, ATH_DBG_MCI, | 617 | ath_dbg(common, MCI, "MCI sched aggr thresh: off\n"); |
597 | "MCI sched aggr thresh: off\n"); | ||
598 | } else | 618 | } else |
599 | ath_dbg(common, ATH_DBG_MCI, | 619 | ath_dbg(common, MCI, "MCI SCHED one step look ahead off\n"); |
600 | "MCI SCHED one step look ahead off\n"); | ||
601 | 620 | ||
602 | if (AR_SREV_9462_10(ah)) | 621 | if (AR_SREV_9462_10(ah)) |
603 | regval |= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10); | 622 | regval |= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10); |
@@ -661,6 +680,9 @@ void ar9003_mci_mute_bt(struct ath_hw *ah) | |||
661 | { | 680 | { |
662 | struct ath_common *common = ath9k_hw_common(ah); | 681 | struct ath_common *common = ath9k_hw_common(ah); |
663 | 682 | ||
683 | if (!ATH9K_HW_CAP_MCI) | ||
684 | return; | ||
685 | |||
664 | /* disable all MCI messages */ | 686 | /* disable all MCI messages */ |
665 | REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); | 687 | REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); |
666 | REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff); | 688 | REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff); |
@@ -678,12 +700,12 @@ void ar9003_mci_mute_bt(struct ath_hw *ah) | |||
678 | * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment | 700 | * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment |
679 | */ | 701 | */ |
680 | 702 | ||
681 | ath_dbg(common, ATH_DBG_MCI, "MCI Send LNA take\n"); | 703 | ath_dbg(common, MCI, "MCI Send LNA take\n"); |
682 | ar9003_mci_send_lna_take(ah, true); | 704 | ar9003_mci_send_lna_take(ah, true); |
683 | 705 | ||
684 | udelay(5); | 706 | udelay(5); |
685 | 707 | ||
686 | ath_dbg(common, ATH_DBG_MCI, "MCI Send sys sleeping\n"); | 708 | ath_dbg(common, MCI, "MCI Send sys sleeping\n"); |
687 | ar9003_mci_send_sys_sleeping(ah, true); | 709 | ar9003_mci_send_sys_sleeping(ah, true); |
688 | } | 710 | } |
689 | 711 | ||
@@ -693,10 +715,13 @@ void ar9003_mci_sync_bt_state(struct ath_hw *ah) | |||
693 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 715 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
694 | u32 cur_bt_state; | 716 | u32 cur_bt_state; |
695 | 717 | ||
718 | if (!ATH9K_HW_CAP_MCI) | ||
719 | return; | ||
720 | |||
696 | cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); | 721 | cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); |
697 | 722 | ||
698 | if (mci->bt_state != cur_bt_state) { | 723 | if (mci->bt_state != cur_bt_state) { |
699 | ath_dbg(common, ATH_DBG_MCI, | 724 | ath_dbg(common, MCI, |
700 | "MCI BT state mismatches. old: %d, new: %d\n", | 725 | "MCI BT state mismatches. old: %d, new: %d\n", |
701 | mci->bt_state, cur_bt_state); | 726 | mci->bt_state, cur_bt_state); |
702 | mci->bt_state = cur_bt_state; | 727 | mci->bt_state = cur_bt_state; |
@@ -708,7 +733,7 @@ void ar9003_mci_sync_bt_state(struct ath_hw *ah) | |||
708 | ar9003_mci_send_coex_wlan_channels(ah, true); | 733 | ar9003_mci_send_coex_wlan_channels(ah, true); |
709 | 734 | ||
710 | if (mci->unhalt_bt_gpm == true) { | 735 | if (mci->unhalt_bt_gpm == true) { |
711 | ath_dbg(common, ATH_DBG_MCI, "MCI unhalt BT GPM"); | 736 | ath_dbg(common, MCI, "MCI unhalt BT GPM\n"); |
712 | ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); | 737 | ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); |
713 | } | 738 | } |
714 | } | 739 | } |
@@ -734,7 +759,7 @@ static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done) | |||
734 | to_set = MCI_5G_FLAGS_SET_MASK; | 759 | to_set = MCI_5G_FLAGS_SET_MASK; |
735 | } | 760 | } |
736 | 761 | ||
737 | ath_dbg(common, ATH_DBG_MCI, | 762 | ath_dbg(common, MCI, |
738 | "MCI BT_MCI_FLAGS: %s 0x%08x clr=0x%08x, set=0x%08x\n", | 763 | "MCI BT_MCI_FLAGS: %s 0x%08x clr=0x%08x, set=0x%08x\n", |
739 | mci->is_2g ? "2G" : "5G", new_flags, to_clear, to_set); | 764 | mci->is_2g ? "2G" : "5G", new_flags, to_clear, to_set); |
740 | 765 | ||
@@ -761,15 +786,15 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, | |||
761 | if (queue) { | 786 | if (queue) { |
762 | 787 | ||
763 | if (payload) | 788 | if (payload) |
764 | ath_dbg(common, ATH_DBG_MCI, | 789 | ath_dbg(common, MCI, |
765 | "MCI ERROR: Send fail: %02x: %02x %02x %02x\n", | 790 | "MCI ERROR: Send fail: %02x: %02x %02x %02x\n", |
766 | header, | 791 | header, |
767 | *(((u8 *)payload) + 4), | 792 | *(((u8 *)payload) + 4), |
768 | *(((u8 *)payload) + 5), | 793 | *(((u8 *)payload) + 5), |
769 | *(((u8 *)payload) + 6)); | 794 | *(((u8 *)payload) + 6)); |
770 | else | 795 | else |
771 | ath_dbg(common, ATH_DBG_MCI, | 796 | ath_dbg(common, MCI, "MCI ERROR: Send fail: %02x\n", |
772 | "MCI ERROR: Send fail: %02x\n", header); | 797 | header); |
773 | } | 798 | } |
774 | 799 | ||
775 | /* check if the message is to be queued */ | 800 | /* check if the message is to be queued */ |
@@ -795,12 +820,12 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, | |||
795 | mci->update_2g5g = queue; | 820 | mci->update_2g5g = queue; |
796 | 821 | ||
797 | if (queue) | 822 | if (queue) |
798 | ath_dbg(common, ATH_DBG_MCI, | 823 | ath_dbg(common, MCI, |
799 | "MCI BT_MCI_FLAGS: 2G5G status <queued> %s.\n", | 824 | "MCI BT_MCI_FLAGS: 2G5G status <queued> %s\n", |
800 | mci->is_2g ? "2G" : "5G"); | 825 | mci->is_2g ? "2G" : "5G"); |
801 | else | 826 | else |
802 | ath_dbg(common, ATH_DBG_MCI, | 827 | ath_dbg(common, MCI, |
803 | "MCI BT_MCI_FLAGS: 2G5G status <sent> %s.\n", | 828 | "MCI BT_MCI_FLAGS: 2G5G status <sent> %s\n", |
804 | mci->is_2g ? "2G" : "5G"); | 829 | mci->is_2g ? "2G" : "5G"); |
805 | 830 | ||
806 | break; | 831 | break; |
@@ -809,11 +834,9 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, | |||
809 | 834 | ||
810 | mci->wlan_channels_update = queue; | 835 | mci->wlan_channels_update = queue; |
811 | if (queue) | 836 | if (queue) |
812 | ath_dbg(common, ATH_DBG_MCI, | 837 | ath_dbg(common, MCI, "MCI WLAN channel map <queued>\n"); |
813 | "MCI WLAN channel map <queued>\n"); | ||
814 | else | 838 | else |
815 | ath_dbg(common, ATH_DBG_MCI, | 839 | ath_dbg(common, MCI, "MCI WLAN channel map <sent>\n"); |
816 | "MCI WLAN channel map <sent>\n"); | ||
817 | break; | 840 | break; |
818 | 841 | ||
819 | case MCI_GPM_COEX_HALT_BT_GPM: | 842 | case MCI_GPM_COEX_HALT_BT_GPM: |
@@ -824,11 +847,11 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, | |||
824 | mci->unhalt_bt_gpm = queue; | 847 | mci->unhalt_bt_gpm = queue; |
825 | 848 | ||
826 | if (queue) | 849 | if (queue) |
827 | ath_dbg(common, ATH_DBG_MCI, | 850 | ath_dbg(common, MCI, |
828 | "MCI UNHALT BT GPM <queued>\n"); | 851 | "MCI UNHALT BT GPM <queued>\n"); |
829 | else { | 852 | else { |
830 | mci->halted_bt_gpm = false; | 853 | mci->halted_bt_gpm = false; |
831 | ath_dbg(common, ATH_DBG_MCI, | 854 | ath_dbg(common, MCI, |
832 | "MCI UNHALT BT GPM <sent>\n"); | 855 | "MCI UNHALT BT GPM <sent>\n"); |
833 | } | 856 | } |
834 | } | 857 | } |
@@ -839,10 +862,10 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, | |||
839 | mci->halted_bt_gpm = !queue; | 862 | mci->halted_bt_gpm = !queue; |
840 | 863 | ||
841 | if (queue) | 864 | if (queue) |
842 | ath_dbg(common, ATH_DBG_MCI, | 865 | ath_dbg(common, MCI, |
843 | "MCI HALT BT GPM <not sent>\n"); | 866 | "MCI HALT BT GPM <not sent>\n"); |
844 | else | 867 | else |
845 | ath_dbg(common, ATH_DBG_MCI, | 868 | ath_dbg(common, MCI, |
846 | "MCI UNHALT BT GPM <sent>\n"); | 869 | "MCI UNHALT BT GPM <sent>\n"); |
847 | } | 870 | } |
848 | 871 | ||
@@ -857,11 +880,14 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) | |||
857 | struct ath_common *common = ath9k_hw_common(ah); | 880 | struct ath_common *common = ath9k_hw_common(ah); |
858 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 881 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
859 | 882 | ||
883 | if (!ATH9K_HW_CAP_MCI) | ||
884 | return; | ||
885 | |||
860 | if (mci->update_2g5g) { | 886 | if (mci->update_2g5g) { |
861 | if (mci->is_2g) { | 887 | if (mci->is_2g) { |
862 | 888 | ||
863 | ar9003_mci_send_2g5g_status(ah, true); | 889 | ar9003_mci_send_2g5g_status(ah, true); |
864 | ath_dbg(common, ATH_DBG_MCI, "MCI Send LNA trans\n"); | 890 | ath_dbg(common, MCI, "MCI Send LNA trans\n"); |
865 | ar9003_mci_send_lna_transfer(ah, true); | 891 | ar9003_mci_send_lna_transfer(ah, true); |
866 | udelay(5); | 892 | udelay(5); |
867 | 893 | ||
@@ -878,7 +904,7 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) | |||
878 | } | 904 | } |
879 | } | 905 | } |
880 | } else { | 906 | } else { |
881 | ath_dbg(common, ATH_DBG_MCI, "MCI Send LNA take\n"); | 907 | ath_dbg(common, MCI, "MCI Send LNA take\n"); |
882 | ar9003_mci_send_lna_take(ah, true); | 908 | ar9003_mci_send_lna_take(ah, true); |
883 | udelay(5); | 909 | udelay(5); |
884 | 910 | ||
@@ -908,14 +934,17 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, | |||
908 | u32 saved_mci_int_en; | 934 | u32 saved_mci_int_en; |
909 | int i; | 935 | int i; |
910 | 936 | ||
937 | if (!ATH9K_HW_CAP_MCI) | ||
938 | return false; | ||
939 | |||
911 | saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN); | 940 | saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN); |
912 | regval = REG_READ(ah, AR_BTCOEX_CTRL); | 941 | regval = REG_READ(ah, AR_BTCOEX_CTRL); |
913 | 942 | ||
914 | if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) { | 943 | if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) { |
915 | 944 | ||
916 | ath_dbg(common, ATH_DBG_MCI, | 945 | ath_dbg(common, MCI, |
917 | "MCI Not sending 0x%x. MCI is not enabled. " | 946 | "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n", |
918 | "full_sleep = %d\n", header, | 947 | header, |
919 | (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0); | 948 | (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0); |
920 | 949 | ||
921 | ar9003_mci_queue_unsent_gpm(ah, header, payload, true); | 950 | ar9003_mci_queue_unsent_gpm(ah, header, payload, true); |
@@ -923,8 +952,9 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, | |||
923 | 952 | ||
924 | } else if (check_bt && (mci->bt_state == MCI_BT_SLEEP)) { | 953 | } else if (check_bt && (mci->bt_state == MCI_BT_SLEEP)) { |
925 | 954 | ||
926 | ath_dbg(common, ATH_DBG_MCI, | 955 | ath_dbg(common, MCI, |
927 | "MCI Don't send message 0x%x. BT is in sleep state\n", header); | 956 | "MCI Don't send message 0x%x. BT is in sleep state\n", |
957 | header); | ||
928 | 958 | ||
929 | ar9003_mci_queue_unsent_gpm(ah, header, payload, true); | 959 | ar9003_mci_queue_unsent_gpm(ah, header, payload, true); |
930 | return false; | 960 | return false; |
@@ -973,6 +1003,9 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, | |||
973 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 1003 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
974 | void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr)); | 1004 | void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr)); |
975 | 1005 | ||
1006 | if (!ATH9K_HW_CAP_MCI) | ||
1007 | return; | ||
1008 | |||
976 | mci->gpm_addr = gpm_addr; | 1009 | mci->gpm_addr = gpm_addr; |
977 | mci->gpm_buf = gpm_buf; | 1010 | mci->gpm_buf = gpm_buf; |
978 | mci->gpm_len = len; | 1011 | mci->gpm_len = len; |
@@ -987,9 +1020,12 @@ void ar9003_mci_cleanup(struct ath_hw *ah) | |||
987 | { | 1020 | { |
988 | struct ath_common *common = ath9k_hw_common(ah); | 1021 | struct ath_common *common = ath9k_hw_common(ah); |
989 | 1022 | ||
1023 | if (!ATH9K_HW_CAP_MCI) | ||
1024 | return; | ||
1025 | |||
990 | /* Turn off MCI and Jupiter mode. */ | 1026 | /* Turn off MCI and Jupiter mode. */ |
991 | REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00); | 1027 | REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00); |
992 | ath_dbg(common, ATH_DBG_MCI, "MCI ar9003_mci_cleanup\n"); | 1028 | ath_dbg(common, MCI, "MCI ar9003_mci_cleanup\n"); |
993 | ar9003_mci_disable_interrupt(ah); | 1029 | ar9003_mci_disable_interrupt(ah); |
994 | } | 1030 | } |
995 | EXPORT_SYMBOL(ar9003_mci_cleanup); | 1031 | EXPORT_SYMBOL(ar9003_mci_cleanup); |
@@ -1006,40 +1042,35 @@ static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type, | |||
1006 | 1042 | ||
1007 | switch (gpm_opcode) { | 1043 | switch (gpm_opcode) { |
1008 | case MCI_GPM_COEX_VERSION_QUERY: | 1044 | case MCI_GPM_COEX_VERSION_QUERY: |
1009 | ath_dbg(common, ATH_DBG_MCI, | 1045 | ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n"); |
1010 | "MCI Recv GPM COEX Version Query\n"); | ||
1011 | ar9003_mci_send_coex_version_response(ah, true); | 1046 | ar9003_mci_send_coex_version_response(ah, true); |
1012 | break; | 1047 | break; |
1013 | case MCI_GPM_COEX_VERSION_RESPONSE: | 1048 | case MCI_GPM_COEX_VERSION_RESPONSE: |
1014 | ath_dbg(common, ATH_DBG_MCI, | 1049 | ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n"); |
1015 | "MCI Recv GPM COEX Version Response\n"); | ||
1016 | mci->bt_ver_major = | 1050 | mci->bt_ver_major = |
1017 | *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION); | 1051 | *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION); |
1018 | mci->bt_ver_minor = | 1052 | mci->bt_ver_minor = |
1019 | *(p_data + MCI_GPM_COEX_B_MINOR_VERSION); | 1053 | *(p_data + MCI_GPM_COEX_B_MINOR_VERSION); |
1020 | mci->bt_version_known = true; | 1054 | mci->bt_version_known = true; |
1021 | ath_dbg(common, ATH_DBG_MCI, | 1055 | ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n", |
1022 | "MCI BT Coex version: %d.%d\n", | 1056 | mci->bt_ver_major, mci->bt_ver_minor); |
1023 | mci->bt_ver_major, | ||
1024 | mci->bt_ver_minor); | ||
1025 | break; | 1057 | break; |
1026 | case MCI_GPM_COEX_STATUS_QUERY: | 1058 | case MCI_GPM_COEX_STATUS_QUERY: |
1027 | ath_dbg(common, ATH_DBG_MCI, | 1059 | ath_dbg(common, MCI, |
1028 | "MCI Recv GPM COEX Status Query = 0x%02X.\n", | 1060 | "MCI Recv GPM COEX Status Query = 0x%02X\n", |
1029 | *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP)); | 1061 | *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP)); |
1030 | mci->wlan_channels_update = true; | 1062 | mci->wlan_channels_update = true; |
1031 | ar9003_mci_send_coex_wlan_channels(ah, true); | 1063 | ar9003_mci_send_coex_wlan_channels(ah, true); |
1032 | break; | 1064 | break; |
1033 | case MCI_GPM_COEX_BT_PROFILE_INFO: | 1065 | case MCI_GPM_COEX_BT_PROFILE_INFO: |
1034 | mci->query_bt = true; | 1066 | mci->query_bt = true; |
1035 | ath_dbg(common, ATH_DBG_MCI, | 1067 | ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n"); |
1036 | "MCI Recv GPM COEX BT_Profile_Info\n"); | ||
1037 | break; | 1068 | break; |
1038 | case MCI_GPM_COEX_BT_STATUS_UPDATE: | 1069 | case MCI_GPM_COEX_BT_STATUS_UPDATE: |
1039 | mci->query_bt = true; | 1070 | mci->query_bt = true; |
1040 | ath_dbg(common, ATH_DBG_MCI, | 1071 | ath_dbg(common, MCI, |
1041 | "MCI Recv GPM COEX BT_Status_Update " | 1072 | "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n", |
1042 | "SEQ=%d (drop&query)\n", *(p_gpm + 3)); | 1073 | *(p_gpm + 3)); |
1043 | break; | 1074 | break; |
1044 | default: | 1075 | default: |
1045 | break; | 1076 | break; |
@@ -1056,6 +1087,9 @@ u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
1056 | u8 recv_type = 0, recv_opcode = 0; | 1087 | u8 recv_type = 0, recv_opcode = 0; |
1057 | bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE); | 1088 | bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE); |
1058 | 1089 | ||
1090 | if (!ATH9K_HW_CAP_MCI) | ||
1091 | return 0; | ||
1092 | |||
1059 | more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE; | 1093 | more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE; |
1060 | 1094 | ||
1061 | while (time_out > 0) { | 1095 | while (time_out > 0) { |
@@ -1090,9 +1124,8 @@ u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
1090 | if ((gpm_type == MCI_GPM_BT_CAL_DONE) && | 1124 | if ((gpm_type == MCI_GPM_BT_CAL_DONE) && |
1091 | !b_is_bt_cal_done) { | 1125 | !b_is_bt_cal_done) { |
1092 | gpm_type = MCI_GPM_BT_CAL_GRANT; | 1126 | gpm_type = MCI_GPM_BT_CAL_GRANT; |
1093 | ath_dbg(common, ATH_DBG_MCI, | 1127 | ath_dbg(common, MCI, |
1094 | "MCI Recv BT_CAL_DONE" | 1128 | "MCI Recv BT_CAL_DONE wait BT_CAL_GRANT\n"); |
1095 | "wait BT_CAL_GRANT\n"); | ||
1096 | continue; | 1129 | continue; |
1097 | } | 1130 | } |
1098 | 1131 | ||
@@ -1123,7 +1156,7 @@ u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
1123 | u32 payload[4] = {0, 0, 0, 0}; | 1156 | u32 payload[4] = {0, 0, 0, 0}; |
1124 | 1157 | ||
1125 | gpm_type = MCI_GPM_BT_CAL_DONE; | 1158 | gpm_type = MCI_GPM_BT_CAL_DONE; |
1126 | ath_dbg(common, ATH_DBG_MCI, | 1159 | ath_dbg(common, MCI, |
1127 | "MCI Rcv BT_CAL_REQ, send WLAN_CAL_GRANT\n"); | 1160 | "MCI Rcv BT_CAL_REQ, send WLAN_CAL_GRANT\n"); |
1128 | 1161 | ||
1129 | MCI_GPM_SET_CAL_TYPE(payload, | 1162 | MCI_GPM_SET_CAL_TYPE(payload, |
@@ -1132,13 +1165,12 @@ u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
1132 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | 1165 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, |
1133 | false, false); | 1166 | false, false); |
1134 | 1167 | ||
1135 | ath_dbg(common, ATH_DBG_MCI, | 1168 | ath_dbg(common, MCI, "MCI now wait for BT_CAL_DONE\n"); |
1136 | "MCI now wait for BT_CAL_DONE\n"); | ||
1137 | 1169 | ||
1138 | continue; | 1170 | continue; |
1139 | } else { | 1171 | } else { |
1140 | ath_dbg(common, ATH_DBG_MCI, "MCI GPM subtype" | 1172 | ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n", |
1141 | "not match 0x%x\n", *(p_gpm + 1)); | 1173 | *(p_gpm + 1)); |
1142 | mismatch++; | 1174 | mismatch++; |
1143 | ar9003_mci_process_gpm_extra(ah, recv_type, | 1175 | ar9003_mci_process_gpm_extra(ah, recv_type, |
1144 | recv_opcode, p_gpm); | 1176 | recv_opcode, p_gpm); |
@@ -1151,16 +1183,15 @@ u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
1151 | 1183 | ||
1152 | if (time_out <= 0) { | 1184 | if (time_out <= 0) { |
1153 | time_out = 0; | 1185 | time_out = 0; |
1154 | ath_dbg(common, ATH_DBG_MCI, | 1186 | ath_dbg(common, MCI, |
1155 | "MCI GPM received timeout, mismatch = %d\n", mismatch); | 1187 | "MCI GPM received timeout, mismatch = %d\n", mismatch); |
1156 | } else | 1188 | } else |
1157 | ath_dbg(common, ATH_DBG_MCI, | 1189 | ath_dbg(common, MCI, "MCI Receive GPM type=0x%x, code=0x%x\n", |
1158 | "MCI Receive GPM type=0x%x, code=0x%x\n", | ||
1159 | gpm_type, gpm_opcode); | 1190 | gpm_type, gpm_opcode); |
1160 | 1191 | ||
1161 | while (more_data == MCI_GPM_MORE) { | 1192 | while (more_data == MCI_GPM_MORE) { |
1162 | 1193 | ||
1163 | ath_dbg(common, ATH_DBG_MCI, "MCI discard remaining GPM\n"); | 1194 | ath_dbg(common, MCI, "MCI discard remaining GPM\n"); |
1164 | offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, | 1195 | offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, |
1165 | &more_data); | 1196 | &more_data); |
1166 | 1197 | ||
@@ -1188,6 +1219,9 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1188 | u32 value = 0, more_gpm = 0, gpm_ptr; | 1219 | u32 value = 0, more_gpm = 0, gpm_ptr; |
1189 | u8 query_type; | 1220 | u8 query_type; |
1190 | 1221 | ||
1222 | if (!ATH9K_HW_CAP_MCI) | ||
1223 | return 0; | ||
1224 | |||
1191 | switch (state_type) { | 1225 | switch (state_type) { |
1192 | case MCI_STATE_ENABLE: | 1226 | case MCI_STATE_ENABLE: |
1193 | if (mci->ready) { | 1227 | if (mci->ready) { |
@@ -1201,8 +1235,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1201 | break; | 1235 | break; |
1202 | case MCI_STATE_INIT_GPM_OFFSET: | 1236 | case MCI_STATE_INIT_GPM_OFFSET: |
1203 | value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); | 1237 | value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); |
1204 | ath_dbg(common, ATH_DBG_MCI, | 1238 | ath_dbg(common, MCI, "MCI GPM initial WRITE_PTR=%d\n", value); |
1205 | "MCI GPM initial WRITE_PTR=%d\n", value); | ||
1206 | mci->gpm_idx = value; | 1239 | mci->gpm_idx = value; |
1207 | break; | 1240 | break; |
1208 | case MCI_STATE_NEXT_GPM_OFFSET: | 1241 | case MCI_STATE_NEXT_GPM_OFFSET: |
@@ -1227,8 +1260,8 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1227 | else if (value >= mci->gpm_len) { | 1260 | else if (value >= mci->gpm_len) { |
1228 | if (value != 0xFFFF) { | 1261 | if (value != 0xFFFF) { |
1229 | value = 0; | 1262 | value = 0; |
1230 | ath_dbg(common, ATH_DBG_MCI, "MCI GPM offset" | 1263 | ath_dbg(common, MCI, |
1231 | "out of range\n"); | 1264 | "MCI GPM offset out of range\n"); |
1232 | } | 1265 | } |
1233 | } else | 1266 | } else |
1234 | value--; | 1267 | value--; |
@@ -1236,8 +1269,8 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1236 | if (value == 0xFFFF) { | 1269 | if (value == 0xFFFF) { |
1237 | value = MCI_GPM_INVALID; | 1270 | value = MCI_GPM_INVALID; |
1238 | more_gpm = MCI_GPM_NOMORE; | 1271 | more_gpm = MCI_GPM_NOMORE; |
1239 | ath_dbg(common, ATH_DBG_MCI, "MCI GPM ptr invalid" | 1272 | ath_dbg(common, MCI, |
1240 | "@ptr=%d, offset=%d, more=GPM_NOMORE\n", | 1273 | "MCI GPM ptr invalid @ptr=%d, offset=%d, more=GPM_NOMORE\n", |
1241 | gpm_ptr, value); | 1274 | gpm_ptr, value); |
1242 | } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) { | 1275 | } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) { |
1243 | 1276 | ||
@@ -1245,9 +1278,9 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1245 | value = MCI_GPM_INVALID; | 1278 | value = MCI_GPM_INVALID; |
1246 | more_gpm = MCI_GPM_NOMORE; | 1279 | more_gpm = MCI_GPM_NOMORE; |
1247 | 1280 | ||
1248 | ath_dbg(common, ATH_DBG_MCI, "MCI GPM message" | 1281 | ath_dbg(common, MCI, |
1249 | "not available @ptr=%d, @offset=%d," | 1282 | "MCI GPM message not available @ptr=%d, @offset=%d, more=GPM_NOMORE\n", |
1250 | "more=GPM_NOMORE\n", gpm_ptr, value); | 1283 | gpm_ptr, value); |
1251 | } else { | 1284 | } else { |
1252 | for (;;) { | 1285 | for (;;) { |
1253 | 1286 | ||
@@ -1267,9 +1300,8 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1267 | mci->gpm_len) | 1300 | mci->gpm_len) |
1268 | mci->gpm_idx = 0; | 1301 | mci->gpm_idx = 0; |
1269 | 1302 | ||
1270 | ath_dbg(common, ATH_DBG_MCI, | 1303 | ath_dbg(common, MCI, |
1271 | "MCI GPM message got ptr=%d," | 1304 | "MCI GPM message got ptr=%d, @offset=%d, more=%d\n", |
1272 | "@offset=%d, more=%d\n", | ||
1273 | gpm_ptr, temp_index, | 1305 | gpm_ptr, temp_index, |
1274 | (more_gpm == MCI_GPM_MORE)); | 1306 | (more_gpm == MCI_GPM_MORE)); |
1275 | 1307 | ||
@@ -1333,8 +1365,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1333 | 1365 | ||
1334 | if (mci->unhalt_bt_gpm) { | 1366 | if (mci->unhalt_bt_gpm) { |
1335 | 1367 | ||
1336 | ath_dbg(common, ATH_DBG_MCI, | 1368 | ath_dbg(common, MCI, "MCI unhalt BT GPM\n"); |
1337 | "MCI unhalt BT GPM\n"); | ||
1338 | ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); | 1369 | ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); |
1339 | } | 1370 | } |
1340 | 1371 | ||
@@ -1360,8 +1391,8 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1360 | ATH_MCI_CONFIG_MCI_OBS_GPIO) != | 1391 | ATH_MCI_CONFIG_MCI_OBS_GPIO) != |
1361 | ATH_MCI_CONFIG_MCI_OBS_GPIO) { | 1392 | ATH_MCI_CONFIG_MCI_OBS_GPIO) { |
1362 | 1393 | ||
1363 | ath_dbg(common, ATH_DBG_MCI, | 1394 | ath_dbg(common, MCI, |
1364 | "MCI reconfigure observation"); | 1395 | "MCI reconfigure observation\n"); |
1365 | ar9003_mci_observation_set_up(ah); | 1396 | ar9003_mci_observation_set_up(ah); |
1366 | } | 1397 | } |
1367 | } | 1398 | } |
@@ -1374,16 +1405,14 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1374 | case MCI_STATE_SET_BT_COEX_VERSION: | 1405 | case MCI_STATE_SET_BT_COEX_VERSION: |
1375 | 1406 | ||
1376 | if (!p_data) | 1407 | if (!p_data) |
1377 | ath_dbg(common, ATH_DBG_MCI, | 1408 | ath_dbg(common, MCI, |
1378 | "MCI Set BT Coex version with NULL data!!\n"); | 1409 | "MCI Set BT Coex version with NULL data!!\n"); |
1379 | else { | 1410 | else { |
1380 | mci->bt_ver_major = (*p_data >> 8) & 0xff; | 1411 | mci->bt_ver_major = (*p_data >> 8) & 0xff; |
1381 | mci->bt_ver_minor = (*p_data) & 0xff; | 1412 | mci->bt_ver_minor = (*p_data) & 0xff; |
1382 | mci->bt_version_known = true; | 1413 | mci->bt_version_known = true; |
1383 | ath_dbg(common, ATH_DBG_MCI, | 1414 | ath_dbg(common, MCI, "MCI BT version set: %d.%d\n", |
1384 | "MCI BT version set: %d.%d\n", | 1415 | mci->bt_ver_major, mci->bt_ver_minor); |
1385 | mci->bt_ver_major, | ||
1386 | mci->bt_ver_minor); | ||
1387 | } | 1416 | } |
1388 | break; | 1417 | break; |
1389 | 1418 | ||
@@ -1438,7 +1467,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1438 | 1467 | ||
1439 | case MCI_STATE_RECOVER_RX: | 1468 | case MCI_STATE_RECOVER_RX: |
1440 | 1469 | ||
1441 | ath_dbg(common, ATH_DBG_MCI, "MCI hw RECOVER_RX\n"); | 1470 | ath_dbg(common, MCI, "MCI hw RECOVER_RX\n"); |
1442 | ar9003_mci_prep_interface(ah); | 1471 | ar9003_mci_prep_interface(ah); |
1443 | mci->query_bt = true; | 1472 | mci->query_bt = true; |
1444 | mci->need_flush_btinfo = true; | 1473 | mci->need_flush_btinfo = true; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index a4450cba0653..59647a3ceb7f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
@@ -119,8 +119,8 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah) | |||
119 | break; | 119 | break; |
120 | default: | 120 | default: |
121 | delta = 0; | 121 | delta = 0; |
122 | ath_dbg(common, ATH_DBG_CALIBRATE, | 122 | ath_dbg(common, CALIBRATE, "Invalid tx-chainmask: %u\n", |
123 | "Invalid tx-chainmask: %u\n", ah->txchainmask); | 123 | ah->txchainmask); |
124 | } | 124 | } |
125 | 125 | ||
126 | power += delta; | 126 | power += delta; |
@@ -148,13 +148,12 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
148 | else | 148 | else |
149 | training_power = ar9003_get_training_power_5g(ah); | 149 | training_power = ar9003_get_training_power_5g(ah); |
150 | 150 | ||
151 | ath_dbg(common, ATH_DBG_CALIBRATE, | 151 | ath_dbg(common, CALIBRATE, "Training power: %d, Target power: %d\n", |
152 | "Training power: %d, Target power: %d\n", | ||
153 | training_power, ah->paprd_target_power); | 152 | training_power, ah->paprd_target_power); |
154 | 153 | ||
155 | if (training_power < 0) { | 154 | if (training_power < 0) { |
156 | ath_dbg(common, ATH_DBG_CALIBRATE, | 155 | ath_dbg(common, CALIBRATE, |
157 | "PAPRD target power delta out of range"); | 156 | "PAPRD target power delta out of range\n"); |
158 | return -ERANGE; | 157 | return -ERANGE; |
159 | } | 158 | } |
160 | ah->paprd_training_power = training_power; | 159 | ah->paprd_training_power = training_power; |
@@ -311,8 +310,8 @@ static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, | |||
311 | reg_cl_gain = AR_PHY_CL_TAB_2; | 310 | reg_cl_gain = AR_PHY_CL_TAB_2; |
312 | break; | 311 | break; |
313 | default: | 312 | default: |
314 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | 313 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, |
315 | "Invalid chainmask: %d\n", chain); | 314 | "Invalid chainmask: %d\n", chain); |
316 | break; | 315 | break; |
317 | } | 316 | } |
318 | 317 | ||
@@ -850,7 +849,7 @@ bool ar9003_paprd_is_done(struct ath_hw *ah) | |||
850 | agc2_pwr = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 849 | agc2_pwr = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, |
851 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR); | 850 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR); |
852 | 851 | ||
853 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | 852 | ath_dbg(ath9k_hw_common(ah), CALIBRATE, |
854 | "AGC2_PWR = 0x%x training done = 0x%x\n", | 853 | "AGC2_PWR = 0x%x training done = 0x%x\n", |
855 | agc2_pwr, paprd_done); | 854 | agc2_pwr, paprd_done); |
856 | /* | 855 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index e41d26939ab8..2589b38b689a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -882,7 +882,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
882 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | 882 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); |
883 | 883 | ||
884 | if (!on != aniState->ofdmWeakSigDetectOff) { | 884 | if (!on != aniState->ofdmWeakSigDetectOff) { |
885 | ath_dbg(common, ATH_DBG_ANI, | 885 | ath_dbg(common, ANI, |
886 | "** ch %d: ofdm weak signal: %s=>%s\n", | 886 | "** ch %d: ofdm weak signal: %s=>%s\n", |
887 | chan->channel, | 887 | chan->channel, |
888 | !aniState->ofdmWeakSigDetectOff ? | 888 | !aniState->ofdmWeakSigDetectOff ? |
@@ -900,7 +900,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
900 | u32 level = param; | 900 | u32 level = param; |
901 | 901 | ||
902 | if (level >= ARRAY_SIZE(firstep_table)) { | 902 | if (level >= ARRAY_SIZE(firstep_table)) { |
903 | ath_dbg(common, ATH_DBG_ANI, | 903 | ath_dbg(common, ANI, |
904 | "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n", | 904 | "ATH9K_ANI_FIRSTEP_LEVEL: level out of range (%u > %zu)\n", |
905 | level, ARRAY_SIZE(firstep_table)); | 905 | level, ARRAY_SIZE(firstep_table)); |
906 | return false; | 906 | return false; |
@@ -937,7 +937,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
937 | AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2); | 937 | AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2); |
938 | 938 | ||
939 | if (level != aniState->firstepLevel) { | 939 | if (level != aniState->firstepLevel) { |
940 | ath_dbg(common, ATH_DBG_ANI, | 940 | ath_dbg(common, ANI, |
941 | "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n", | 941 | "** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n", |
942 | chan->channel, | 942 | chan->channel, |
943 | aniState->firstepLevel, | 943 | aniState->firstepLevel, |
@@ -945,7 +945,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
945 | ATH9K_ANI_FIRSTEP_LVL_NEW, | 945 | ATH9K_ANI_FIRSTEP_LVL_NEW, |
946 | value, | 946 | value, |
947 | aniState->iniDef.firstep); | 947 | aniState->iniDef.firstep); |
948 | ath_dbg(common, ATH_DBG_ANI, | 948 | ath_dbg(common, ANI, |
949 | "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n", | 949 | "** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n", |
950 | chan->channel, | 950 | chan->channel, |
951 | aniState->firstepLevel, | 951 | aniState->firstepLevel, |
@@ -965,7 +965,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
965 | u32 level = param; | 965 | u32 level = param; |
966 | 966 | ||
967 | if (level >= ARRAY_SIZE(cycpwrThr1_table)) { | 967 | if (level >= ARRAY_SIZE(cycpwrThr1_table)) { |
968 | ath_dbg(common, ATH_DBG_ANI, | 968 | ath_dbg(common, ANI, |
969 | "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n", | 969 | "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level out of range (%u > %zu)\n", |
970 | level, ARRAY_SIZE(cycpwrThr1_table)); | 970 | level, ARRAY_SIZE(cycpwrThr1_table)); |
971 | return false; | 971 | return false; |
@@ -1001,7 +1001,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
1001 | AR_PHY_EXT_CYCPWR_THR1, value2); | 1001 | AR_PHY_EXT_CYCPWR_THR1, value2); |
1002 | 1002 | ||
1003 | if (level != aniState->spurImmunityLevel) { | 1003 | if (level != aniState->spurImmunityLevel) { |
1004 | ath_dbg(common, ATH_DBG_ANI, | 1004 | ath_dbg(common, ANI, |
1005 | "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n", | 1005 | "** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n", |
1006 | chan->channel, | 1006 | chan->channel, |
1007 | aniState->spurImmunityLevel, | 1007 | aniState->spurImmunityLevel, |
@@ -1009,7 +1009,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
1009 | ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, | 1009 | ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, |
1010 | value, | 1010 | value, |
1011 | aniState->iniDef.cycpwrThr1); | 1011 | aniState->iniDef.cycpwrThr1); |
1012 | ath_dbg(common, ATH_DBG_ANI, | 1012 | ath_dbg(common, ANI, |
1013 | "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n", | 1013 | "** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n", |
1014 | chan->channel, | 1014 | chan->channel, |
1015 | aniState->spurImmunityLevel, | 1015 | aniState->spurImmunityLevel, |
@@ -1036,8 +1036,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
1036 | REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, | 1036 | REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, |
1037 | AR_PHY_MRC_CCK_MUX_REG, is_on); | 1037 | AR_PHY_MRC_CCK_MUX_REG, is_on); |
1038 | if (!is_on != aniState->mrcCCKOff) { | 1038 | if (!is_on != aniState->mrcCCKOff) { |
1039 | ath_dbg(common, ATH_DBG_ANI, | 1039 | ath_dbg(common, ANI, "** ch %d: MRC CCK: %s=>%s\n", |
1040 | "** ch %d: MRC CCK: %s=>%s\n", | ||
1041 | chan->channel, | 1040 | chan->channel, |
1042 | !aniState->mrcCCKOff ? "on" : "off", | 1041 | !aniState->mrcCCKOff ? "on" : "off", |
1043 | is_on ? "on" : "off"); | 1042 | is_on ? "on" : "off"); |
@@ -1052,11 +1051,11 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, | |||
1052 | case ATH9K_ANI_PRESENT: | 1051 | case ATH9K_ANI_PRESENT: |
1053 | break; | 1052 | break; |
1054 | default: | 1053 | default: |
1055 | ath_dbg(common, ATH_DBG_ANI, "invalid cmd %u\n", cmd); | 1054 | ath_dbg(common, ANI, "invalid cmd %u\n", cmd); |
1056 | return false; | 1055 | return false; |
1057 | } | 1056 | } |
1058 | 1057 | ||
1059 | ath_dbg(common, ATH_DBG_ANI, | 1058 | ath_dbg(common, ANI, |
1060 | "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", | 1059 | "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", |
1061 | aniState->spurImmunityLevel, | 1060 | aniState->spurImmunityLevel, |
1062 | !aniState->ofdmWeakSigDetectOff ? "on" : "off", | 1061 | !aniState->ofdmWeakSigDetectOff ? "on" : "off", |
@@ -1125,8 +1124,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) | |||
1125 | aniState = &ah->curchan->ani; | 1124 | aniState = &ah->curchan->ani; |
1126 | iniDef = &aniState->iniDef; | 1125 | iniDef = &aniState->iniDef; |
1127 | 1126 | ||
1128 | ath_dbg(common, ATH_DBG_ANI, | 1127 | ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n", |
1129 | "ver %d.%d opmode %u chan %d Mhz/0x%x\n", | ||
1130 | ah->hw_version.macVersion, | 1128 | ah->hw_version.macVersion, |
1131 | ah->hw_version.macRev, | 1129 | ah->hw_version.macRev, |
1132 | ah->opmode, | 1130 | ah->opmode, |
@@ -1388,7 +1386,7 @@ void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) | |||
1388 | ~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE | | 1386 | ~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE | |
1389 | AR_PHY_WATCHDOG_IDLE_ENABLE)); | 1387 | AR_PHY_WATCHDOG_IDLE_ENABLE)); |
1390 | 1388 | ||
1391 | ath_dbg(common, ATH_DBG_RESET, "Disabled BB Watchdog\n"); | 1389 | ath_dbg(common, RESET, "Disabled BB Watchdog\n"); |
1392 | return; | 1390 | return; |
1393 | } | 1391 | } |
1394 | 1392 | ||
@@ -1424,8 +1422,7 @@ void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) | |||
1424 | AR_PHY_WATCHDOG_IDLE_MASK | | 1422 | AR_PHY_WATCHDOG_IDLE_MASK | |
1425 | (AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2))); | 1423 | (AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2))); |
1426 | 1424 | ||
1427 | ath_dbg(common, ATH_DBG_RESET, | 1425 | ath_dbg(common, RESET, "Enabled BB Watchdog timeout (%u ms)\n", |
1428 | "Enabled BB Watchdog timeout (%u ms)\n", | ||
1429 | idle_tmo_ms); | 1426 | idle_tmo_ms); |
1430 | } | 1427 | } |
1431 | 1428 | ||
@@ -1454,9 +1451,9 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) | |||
1454 | return; | 1451 | return; |
1455 | 1452 | ||
1456 | status = ah->bb_watchdog_last_status; | 1453 | status = ah->bb_watchdog_last_status; |
1457 | ath_dbg(common, ATH_DBG_RESET, | 1454 | ath_dbg(common, RESET, |
1458 | "\n==== BB update: BB status=0x%08x ====\n", status); | 1455 | "\n==== BB update: BB status=0x%08x ====\n", status); |
1459 | ath_dbg(common, ATH_DBG_RESET, | 1456 | ath_dbg(common, RESET, |
1460 | "** BB state: wd=%u det=%u rdar=%u rOFDM=%d rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n", | 1457 | "** BB state: wd=%u det=%u rdar=%u rOFDM=%d rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n", |
1461 | MS(status, AR_PHY_WATCHDOG_INFO), | 1458 | MS(status, AR_PHY_WATCHDOG_INFO), |
1462 | MS(status, AR_PHY_WATCHDOG_DET_HANG), | 1459 | MS(status, AR_PHY_WATCHDOG_DET_HANG), |
@@ -1468,22 +1465,19 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) | |||
1468 | MS(status, AR_PHY_WATCHDOG_AGC_SM), | 1465 | MS(status, AR_PHY_WATCHDOG_AGC_SM), |
1469 | MS(status, AR_PHY_WATCHDOG_SRCH_SM)); | 1466 | MS(status, AR_PHY_WATCHDOG_SRCH_SM)); |
1470 | 1467 | ||
1471 | ath_dbg(common, ATH_DBG_RESET, | 1468 | ath_dbg(common, RESET, "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n", |
1472 | "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n", | ||
1473 | REG_READ(ah, AR_PHY_WATCHDOG_CTL_1), | 1469 | REG_READ(ah, AR_PHY_WATCHDOG_CTL_1), |
1474 | REG_READ(ah, AR_PHY_WATCHDOG_CTL_2)); | 1470 | REG_READ(ah, AR_PHY_WATCHDOG_CTL_2)); |
1475 | ath_dbg(common, ATH_DBG_RESET, | 1471 | ath_dbg(common, RESET, "** BB mode: BB_gen_controls=0x%08x **\n", |
1476 | "** BB mode: BB_gen_controls=0x%08x **\n", | ||
1477 | REG_READ(ah, AR_PHY_GEN_CTRL)); | 1472 | REG_READ(ah, AR_PHY_GEN_CTRL)); |
1478 | 1473 | ||
1479 | #define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles) | 1474 | #define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles) |
1480 | if (common->cc_survey.cycles) | 1475 | if (common->cc_survey.cycles) |
1481 | ath_dbg(common, ATH_DBG_RESET, | 1476 | ath_dbg(common, RESET, |
1482 | "** BB busy times: rx_clear=%d%%, rx_frame=%d%%, tx_frame=%d%% **\n", | 1477 | "** BB busy times: rx_clear=%d%%, rx_frame=%d%%, tx_frame=%d%% **\n", |
1483 | PCT(rx_busy), PCT(rx_frame), PCT(tx_frame)); | 1478 | PCT(rx_busy), PCT(rx_frame), PCT(tx_frame)); |
1484 | 1479 | ||
1485 | ath_dbg(common, ATH_DBG_RESET, | 1480 | ath_dbg(common, RESET, "==== BB update: done ====\n\n"); |
1486 | "==== BB update: done ====\n\n"); | ||
1487 | } | 1481 | } |
1488 | EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); | 1482 | EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); |
1489 | 1483 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 130e5dba9555..95276e914c1b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -196,6 +196,7 @@ struct ath_txq { | |||
196 | u8 txq_headidx; | 196 | u8 txq_headidx; |
197 | u8 txq_tailidx; | 197 | u8 txq_tailidx; |
198 | int pending_frames; | 198 | int pending_frames; |
199 | struct sk_buff_head complete_q; | ||
199 | }; | 200 | }; |
200 | 201 | ||
201 | struct ath_atx_ac { | 202 | struct ath_atx_ac { |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index a13cabb95435..dc5fd569690f 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -117,11 +117,10 @@ static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
117 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | 117 | memset(&txctl, 0, sizeof(struct ath_tx_control)); |
118 | txctl.txq = sc->beacon.cabq; | 118 | txctl.txq = sc->beacon.cabq; |
119 | 119 | ||
120 | ath_dbg(common, ATH_DBG_XMIT, | 120 | ath_dbg(common, XMIT, "transmitting CABQ packet, skb: %p\n", skb); |
121 | "transmitting CABQ packet, skb: %p\n", skb); | ||
122 | 121 | ||
123 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 122 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
124 | ath_dbg(common, ATH_DBG_XMIT, "CABQ TX failed\n"); | 123 | ath_dbg(common, XMIT, "CABQ TX failed\n"); |
125 | dev_kfree_skb_any(skb); | 124 | dev_kfree_skb_any(skb); |
126 | } | 125 | } |
127 | } | 126 | } |
@@ -204,7 +203,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
204 | 203 | ||
205 | if (skb && cabq_depth) { | 204 | if (skb && cabq_depth) { |
206 | if (sc->nvifs > 1) { | 205 | if (sc->nvifs > 1) { |
207 | ath_dbg(common, ATH_DBG_BEACON, | 206 | ath_dbg(common, BEACON, |
208 | "Flushing previous cabq traffic\n"); | 207 | "Flushing previous cabq traffic\n"); |
209 | ath_draintxq(sc, cabq, false); | 208 | ath_draintxq(sc, cabq, false); |
210 | } | 209 | } |
@@ -297,7 +296,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
297 | tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF; | 296 | tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF; |
298 | avp->tsf_adjust = cpu_to_le64(tsfadjust); | 297 | avp->tsf_adjust = cpu_to_le64(tsfadjust); |
299 | 298 | ||
300 | ath_dbg(common, ATH_DBG_BEACON, | 299 | ath_dbg(common, BEACON, |
301 | "stagger beacons, bslot %d intval %u tsfadjust %llu\n", | 300 | "stagger beacons, bslot %d intval %u tsfadjust %llu\n", |
302 | avp->av_bslot, intval, (unsigned long long)tsfadjust); | 301 | avp->av_bslot, intval, (unsigned long long)tsfadjust); |
303 | 302 | ||
@@ -371,15 +370,14 @@ void ath_beacon_tasklet(unsigned long data) | |||
371 | sc->beacon.bmisscnt++; | 370 | sc->beacon.bmisscnt++; |
372 | 371 | ||
373 | if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { | 372 | if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { |
374 | ath_dbg(common, ATH_DBG_BSTUCK, | 373 | ath_dbg(common, BSTUCK, |
375 | "missed %u consecutive beacons\n", | 374 | "missed %u consecutive beacons\n", |
376 | sc->beacon.bmisscnt); | 375 | sc->beacon.bmisscnt); |
377 | ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); | 376 | ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); |
378 | if (sc->beacon.bmisscnt > 3) | 377 | if (sc->beacon.bmisscnt > 3) |
379 | ath9k_hw_bstuck_nfcal(ah); | 378 | ath9k_hw_bstuck_nfcal(ah); |
380 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { | 379 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { |
381 | ath_dbg(common, ATH_DBG_BSTUCK, | 380 | ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); |
382 | "beacon is officially stuck\n"); | ||
383 | sc->sc_flags |= SC_OP_TSF_RESET; | 381 | sc->sc_flags |= SC_OP_TSF_RESET; |
384 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 382 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
385 | } | 383 | } |
@@ -406,7 +404,7 @@ void ath_beacon_tasklet(unsigned long data) | |||
406 | slot = (tsftu % (intval * ATH_BCBUF)) / intval; | 404 | slot = (tsftu % (intval * ATH_BCBUF)) / intval; |
407 | vif = sc->beacon.bslot[slot]; | 405 | vif = sc->beacon.bslot[slot]; |
408 | 406 | ||
409 | ath_dbg(common, ATH_DBG_BEACON, | 407 | ath_dbg(common, BEACON, |
410 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", | 408 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", |
411 | slot, tsf, tsftu / ATH_BCBUF, intval, vif); | 409 | slot, tsf, tsftu / ATH_BCBUF, intval, vif); |
412 | } else { | 410 | } else { |
@@ -424,7 +422,7 @@ void ath_beacon_tasklet(unsigned long data) | |||
424 | } | 422 | } |
425 | 423 | ||
426 | if (sc->beacon.bmisscnt != 0) { | 424 | if (sc->beacon.bmisscnt != 0) { |
427 | ath_dbg(common, ATH_DBG_BSTUCK, | 425 | ath_dbg(common, BSTUCK, |
428 | "resume beacon xmit after %u misses\n", | 426 | "resume beacon xmit after %u misses\n", |
429 | sc->beacon.bmisscnt); | 427 | sc->beacon.bmisscnt); |
430 | sc->beacon.bmisscnt = 0; | 428 | sc->beacon.bmisscnt = 0; |
@@ -541,7 +539,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
541 | 539 | ||
542 | /* No need to configure beacon if we are not associated */ | 540 | /* No need to configure beacon if we are not associated */ |
543 | if (!common->curaid) { | 541 | if (!common->curaid) { |
544 | ath_dbg(common, ATH_DBG_BEACON, | 542 | ath_dbg(common, BEACON, |
545 | "STA is not yet associated..skipping beacon config\n"); | 543 | "STA is not yet associated..skipping beacon config\n"); |
546 | return; | 544 | return; |
547 | } | 545 | } |
@@ -631,8 +629,8 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
631 | /* TSF out of range threshold fixed at 1 second */ | 629 | /* TSF out of range threshold fixed at 1 second */ |
632 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | 630 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; |
633 | 631 | ||
634 | ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); | 632 | ath_dbg(common, BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); |
635 | ath_dbg(common, ATH_DBG_BEACON, | 633 | ath_dbg(common, BEACON, |
636 | "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", | 634 | "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", |
637 | bs.bs_bmissthreshold, bs.bs_sleepduration, | 635 | bs.bs_bmissthreshold, bs.bs_sleepduration, |
638 | bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); | 636 | bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); |
@@ -660,8 +658,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
660 | tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); | 658 | tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); |
661 | nexttbtt = tsf + intval; | 659 | nexttbtt = tsf + intval; |
662 | 660 | ||
663 | ath_dbg(common, ATH_DBG_BEACON, | 661 | ath_dbg(common, BEACON, "IBSS nexttbtt %u intval %u (%u)\n", |
664 | "IBSS nexttbtt %u intval %u (%u)\n", | ||
665 | nexttbtt, intval, conf->beacon_interval); | 662 | nexttbtt, intval, conf->beacon_interval); |
666 | 663 | ||
667 | /* | 664 | /* |
@@ -699,9 +696,8 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc, | |||
699 | (sc->nbcnvifs > 1) && | 696 | (sc->nbcnvifs > 1) && |
700 | (vif->type == NL80211_IFTYPE_AP) && | 697 | (vif->type == NL80211_IFTYPE_AP) && |
701 | (cur_conf->beacon_interval != bss_conf->beacon_int)) { | 698 | (cur_conf->beacon_interval != bss_conf->beacon_int)) { |
702 | ath_dbg(common, ATH_DBG_CONFIG, | 699 | ath_dbg(common, CONFIG, |
703 | "Changing beacon interval of multiple \ | 700 | "Changing beacon interval of multiple AP interfaces !\n"); |
704 | AP interfaces !\n"); | ||
705 | return false; | 701 | return false; |
706 | } | 702 | } |
707 | /* | 703 | /* |
@@ -710,7 +706,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc, | |||
710 | */ | 706 | */ |
711 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && | 707 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && |
712 | (vif->type != NL80211_IFTYPE_AP)) { | 708 | (vif->type != NL80211_IFTYPE_AP)) { |
713 | ath_dbg(common, ATH_DBG_CONFIG, | 709 | ath_dbg(common, CONFIG, |
714 | "STA vif's beacon not allowed on AP mode\n"); | 710 | "STA vif's beacon not allowed on AP mode\n"); |
715 | return false; | 711 | return false; |
716 | } | 712 | } |
@@ -722,7 +718,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc, | |||
722 | (vif->type == NL80211_IFTYPE_STATION) && | 718 | (vif->type == NL80211_IFTYPE_STATION) && |
723 | (sc->sc_flags & SC_OP_BEACONS) && | 719 | (sc->sc_flags & SC_OP_BEACONS) && |
724 | !avp->primary_sta_vif) { | 720 | !avp->primary_sta_vif) { |
725 | ath_dbg(common, ATH_DBG_CONFIG, | 721 | ath_dbg(common, CONFIG, |
726 | "Beacon already configured for a station interface\n"); | 722 | "Beacon already configured for a station interface\n"); |
727 | return false; | 723 | return false; |
728 | } | 724 | } |
@@ -802,8 +798,7 @@ void ath_set_beacon(struct ath_softc *sc) | |||
802 | ath_beacon_config_sta(sc, cur_conf); | 798 | ath_beacon_config_sta(sc, cur_conf); |
803 | break; | 799 | break; |
804 | default: | 800 | default: |
805 | ath_dbg(common, ATH_DBG_CONFIG, | 801 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); |
806 | "Unsupported beaconing mode\n"); | ||
807 | return; | 802 | return; |
808 | } | 803 | } |
809 | 804 | ||
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index bbb20810ec10..a6712a95d76a 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -68,6 +68,9 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) | |||
68 | u32 i, idx; | 68 | u32 i, idx; |
69 | bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; | 69 | bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; |
70 | 70 | ||
71 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
72 | return; | ||
73 | |||
71 | if (AR_SREV_9300_20_OR_LATER(ah)) | 74 | if (AR_SREV_9300_20_OR_LATER(ah)) |
72 | rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; | 75 | rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; |
73 | 76 | ||
@@ -99,6 +102,9 @@ void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah) | |||
99 | { | 102 | { |
100 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 103 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
101 | 104 | ||
105 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
106 | return; | ||
107 | |||
102 | /* connect bt_active to baseband */ | 108 | /* connect bt_active to baseband */ |
103 | REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL, | 109 | REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL, |
104 | (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF | | 110 | (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF | |
@@ -121,6 +127,9 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah) | |||
121 | { | 127 | { |
122 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 128 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
123 | 129 | ||
130 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
131 | return; | ||
132 | |||
124 | /* btcoex 3-wire */ | 133 | /* btcoex 3-wire */ |
125 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | 134 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, |
126 | (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB | | 135 | (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB | |
@@ -147,6 +156,9 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah) | |||
147 | { | 156 | { |
148 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 157 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
149 | 158 | ||
159 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
160 | return; | ||
161 | |||
150 | /* Configure the desired GPIO port for TX_FRAME output */ | 162 | /* Configure the desired GPIO port for TX_FRAME output */ |
151 | ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, | 163 | ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, |
152 | AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); | 164 | AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); |
@@ -158,6 +170,9 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, | |||
158 | { | 170 | { |
159 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 171 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
160 | 172 | ||
173 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
174 | return; | ||
175 | |||
161 | btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) | | 176 | btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) | |
162 | SM(wlan_weight, AR_BTCOEX_WL_WGHT); | 177 | SM(wlan_weight, AR_BTCOEX_WL_WGHT); |
163 | } | 178 | } |
@@ -219,9 +234,9 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah) | |||
219 | { | 234 | { |
220 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 235 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
221 | 236 | ||
222 | switch (btcoex_hw->scheme) { | 237 | switch (ath9k_hw_get_btcoex_scheme(ah)) { |
223 | case ATH_BTCOEX_CFG_NONE: | 238 | case ATH_BTCOEX_CFG_NONE: |
224 | break; | 239 | return; |
225 | case ATH_BTCOEX_CFG_2WIRE: | 240 | case ATH_BTCOEX_CFG_2WIRE: |
226 | ath9k_hw_btcoex_enable_2wire(ah); | 241 | ath9k_hw_btcoex_enable_2wire(ah); |
227 | break; | 242 | break; |
@@ -246,6 +261,9 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) | |||
246 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 261 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
247 | int i; | 262 | int i; |
248 | 263 | ||
264 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
265 | return; | ||
266 | |||
249 | btcoex_hw->enabled = false; | 267 | btcoex_hw->enabled = false; |
250 | if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) { | 268 | if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) { |
251 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | 269 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
@@ -294,6 +312,9 @@ static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, | |||
294 | void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | 312 | void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, |
295 | enum ath_stomp_type stomp_type) | 313 | enum ath_stomp_type stomp_type) |
296 | { | 314 | { |
315 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
316 | return; | ||
317 | |||
297 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 318 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
298 | ar9003_btcoex_bt_stomp(ah, stomp_type); | 319 | ar9003_btcoex_bt_stomp(ah, stomp_type); |
299 | return; | 320 | return; |
@@ -313,8 +334,7 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | |||
313 | AR_STOMP_NONE_WLAN_WGHT); | 334 | AR_STOMP_NONE_WLAN_WGHT); |
314 | break; | 335 | break; |
315 | default: | 336 | default: |
316 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | 337 | ath_dbg(ath9k_hw_common(ah), BTCOEX, "Invalid Stomptype\n"); |
317 | "Invalid Stomptype\n"); | ||
318 | break; | 338 | break; |
319 | } | 339 | } |
320 | } | 340 | } |
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 99538810a312..172e33db7f4c 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -116,7 +116,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, | |||
116 | if (h[i].privNF > limit->max) { | 116 | if (h[i].privNF > limit->max) { |
117 | high_nf_mid = true; | 117 | high_nf_mid = true; |
118 | 118 | ||
119 | ath_dbg(common, ATH_DBG_CALIBRATE, | 119 | ath_dbg(common, CALIBRATE, |
120 | "NFmid[%d] (%d) > MAX (%d), %s\n", | 120 | "NFmid[%d] (%d) > MAX (%d), %s\n", |
121 | i, h[i].privNF, limit->max, | 121 | i, h[i].privNF, limit->max, |
122 | (cal->nfcal_interference ? | 122 | (cal->nfcal_interference ? |
@@ -199,8 +199,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | |||
199 | return true; | 199 | return true; |
200 | 200 | ||
201 | if (currCal->calState != CAL_DONE) { | 201 | if (currCal->calState != CAL_DONE) { |
202 | ath_dbg(common, ATH_DBG_CALIBRATE, | 202 | ath_dbg(common, CALIBRATE, "Calibration state incorrect, %d\n", |
203 | "Calibration state incorrect, %d\n", | ||
204 | currCal->calState); | 203 | currCal->calState); |
205 | return true; | 204 | return true; |
206 | } | 205 | } |
@@ -208,8 +207,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | |||
208 | if (!(ah->supp_cals & currCal->calData->calType)) | 207 | if (!(ah->supp_cals & currCal->calData->calType)) |
209 | return true; | 208 | return true; |
210 | 209 | ||
211 | ath_dbg(common, ATH_DBG_CALIBRATE, | 210 | ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n", |
212 | "Resetting Cal %d state for channel %u\n", | ||
213 | currCal->calData->calType, conf->channel->center_freq); | 211 | currCal->calData->calType, conf->channel->center_freq); |
214 | 212 | ||
215 | ah->caldata->CalValid &= ~currCal->calData->calType; | 213 | ah->caldata->CalValid &= ~currCal->calData->calType; |
@@ -302,7 +300,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
302 | * noisefloor until the next calibration timer. | 300 | * noisefloor until the next calibration timer. |
303 | */ | 301 | */ |
304 | if (j == 10000) { | 302 | if (j == 10000) { |
305 | ath_dbg(common, ATH_DBG_ANY, | 303 | ath_dbg(common, ANY, |
306 | "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n", | 304 | "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n", |
307 | REG_READ(ah, AR_PHY_AGC_CONTROL)); | 305 | REG_READ(ah, AR_PHY_AGC_CONTROL)); |
308 | return; | 306 | return; |
@@ -344,17 +342,17 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) | |||
344 | if (!nf[i]) | 342 | if (!nf[i]) |
345 | continue; | 343 | continue; |
346 | 344 | ||
347 | ath_dbg(common, ATH_DBG_CALIBRATE, | 345 | ath_dbg(common, CALIBRATE, |
348 | "NF calibrated [%s] [chain %d] is %d\n", | 346 | "NF calibrated [%s] [chain %d] is %d\n", |
349 | (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); | 347 | (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); |
350 | 348 | ||
351 | if (nf[i] > ATH9K_NF_TOO_HIGH) { | 349 | if (nf[i] > ATH9K_NF_TOO_HIGH) { |
352 | ath_dbg(common, ATH_DBG_CALIBRATE, | 350 | ath_dbg(common, CALIBRATE, |
353 | "NF[%d] (%d) > MAX (%d), correcting to MAX\n", | 351 | "NF[%d] (%d) > MAX (%d), correcting to MAX\n", |
354 | i, nf[i], ATH9K_NF_TOO_HIGH); | 352 | i, nf[i], ATH9K_NF_TOO_HIGH); |
355 | nf[i] = limit->max; | 353 | nf[i] = limit->max; |
356 | } else if (nf[i] < limit->min) { | 354 | } else if (nf[i] < limit->min) { |
357 | ath_dbg(common, ATH_DBG_CALIBRATE, | 355 | ath_dbg(common, CALIBRATE, |
358 | "NF[%d] (%d) < MIN (%d), correcting to NOM\n", | 356 | "NF[%d] (%d) < MIN (%d), correcting to NOM\n", |
359 | i, nf[i], limit->min); | 357 | i, nf[i], limit->min); |
360 | nf[i] = limit->nominal; | 358 | nf[i] = limit->nominal; |
@@ -373,7 +371,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
373 | 371 | ||
374 | chan->channelFlags &= (~CHANNEL_CW_INT); | 372 | chan->channelFlags &= (~CHANNEL_CW_INT); |
375 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { | 373 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { |
376 | ath_dbg(common, ATH_DBG_CALIBRATE, | 374 | ath_dbg(common, CALIBRATE, |
377 | "NF did not complete in calibration window\n"); | 375 | "NF did not complete in calibration window\n"); |
378 | return false; | 376 | return false; |
379 | } | 377 | } |
@@ -383,7 +381,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
383 | nf = nfarray[0]; | 381 | nf = nfarray[0]; |
384 | if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) | 382 | if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) |
385 | && nf > nfThresh) { | 383 | && nf > nfThresh) { |
386 | ath_dbg(common, ATH_DBG_CALIBRATE, | 384 | ath_dbg(common, CALIBRATE, |
387 | "noise floor failed detected; detected %d, threshold %d\n", | 385 | "noise floor failed detected; detected %d, threshold %d\n", |
388 | nf, nfThresh); | 386 | nf, nfThresh); |
389 | chan->channelFlags |= CHANNEL_CW_INT; | 387 | chan->channelFlags |= CHANNEL_CW_INT; |
diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c index e4e84a9e6273..f4f56aff1e9d 100644 --- a/drivers/net/wireless/ath/ath9k/dfs.c +++ b/drivers/net/wireless/ath/ath9k/dfs.c | |||
@@ -66,7 +66,7 @@ ath9k_postprocess_radar_event(struct ath_softc *sc, | |||
66 | u8 rssi; | 66 | u8 rssi; |
67 | u16 dur; | 67 | u16 dur; |
68 | 68 | ||
69 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_DFS, | 69 | ath_dbg(ath9k_hw_common(sc->sc_ah), DFS, |
70 | "pulse_bw_info=0x%x, pri,ext len/rssi=(%u/%u, %u/%u)\n", | 70 | "pulse_bw_info=0x%x, pri,ext len/rssi=(%u/%u, %u/%u)\n", |
71 | are->pulse_bw_info, | 71 | are->pulse_bw_info, |
72 | are->pulse_length_pri, are->rssi, | 72 | are->pulse_length_pri, are->rssi, |
@@ -161,7 +161,7 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data, | |||
161 | 161 | ||
162 | if ((!(rs->rs_phyerr != ATH9K_PHYERR_RADAR)) && | 162 | if ((!(rs->rs_phyerr != ATH9K_PHYERR_RADAR)) && |
163 | (!(rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT))) { | 163 | (!(rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT))) { |
164 | ath_dbg(common, ATH_DBG_DFS, | 164 | ath_dbg(common, DFS, |
165 | "Error: rs_phyer=0x%x not a radar error\n", | 165 | "Error: rs_phyer=0x%x not a radar error\n", |
166 | rs->rs_phyerr); | 166 | rs->rs_phyerr); |
167 | return; | 167 | return; |
@@ -190,7 +190,7 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data, | |||
190 | ard.pulse_length_ext = vdata_end[-2]; | 190 | ard.pulse_length_ext = vdata_end[-2]; |
191 | ard.pulse_length_pri = vdata_end[-3]; | 191 | ard.pulse_length_pri = vdata_end[-3]; |
192 | 192 | ||
193 | ath_dbg(common, ATH_DBG_DFS, | 193 | ath_dbg(common, DFS, |
194 | "bw_info=%d, length_pri=%d, length_ext=%d, " | 194 | "bw_info=%d, length_pri=%d, length_ext=%d, " |
195 | "rssi_pri=%d, rssi_ext=%d\n", | 195 | "rssi_pri=%d, rssi_ext=%d\n", |
196 | ard.pulse_bw_info, ard.pulse_length_pri, ard.pulse_length_ext, | 196 | ard.pulse_bw_info, ard.pulse_length_pri, ard.pulse_length_ext, |
@@ -200,7 +200,7 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data, | |||
200 | drp.ts = mactime; | 200 | drp.ts = mactime; |
201 | if (ath9k_postprocess_radar_event(sc, &ard, &drp)) { | 201 | if (ath9k_postprocess_radar_event(sc, &ard, &drp)) { |
202 | static u64 last_ts; | 202 | static u64 last_ts; |
203 | ath_dbg(common, ATH_DBG_DFS, | 203 | ath_dbg(common, DFS, |
204 | "ath9k_dfs_process_phyerr: channel=%d, ts=%llu, " | 204 | "ath9k_dfs_process_phyerr: channel=%d, ts=%llu, " |
205 | "width=%d, rssi=%d, delta_ts=%llu\n", | 205 | "width=%d, rssi=%d, delta_ts=%llu\n", |
206 | drp.freq, drp.ts, drp.width, drp.rssi, drp.ts-last_ts); | 206 | drp.freq, drp.ts, drp.width, drp.rssi, drp.ts-last_ts); |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.h b/drivers/net/wireless/ath/ath9k/dfs_debug.h index 6e1e2a71659e..4911724cb445 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_debug.h +++ b/drivers/net/wireless/ath/ath9k/dfs_debug.h | |||
@@ -16,8 +16,8 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | 18 | ||
19 | #ifndef DFS_DEBUG_H | 19 | #ifndef ATH9K_DFS_DEBUG_H |
20 | #define DFS_DEBUG_H | 20 | #define ATH9K_DFS_DEBUG_H |
21 | 21 | ||
22 | #include "hw.h" | 22 | #include "hw.h" |
23 | 23 | ||
@@ -54,4 +54,4 @@ static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { } | |||
54 | 54 | ||
55 | #endif /* CONFIG_ATH9K_DFS_DEBUGFS */ | 55 | #endif /* CONFIG_ATH9K_DFS_DEBUGFS */ |
56 | 56 | ||
57 | #endif /* DFS_DEBUG_H */ | 57 | #endif /* ATH9K_DFS_DEBUG_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index e46f751ab508..c43523233319 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -305,8 +305,7 @@ void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah) | |||
305 | regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; | 305 | regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; |
306 | break; | 306 | break; |
307 | default: | 307 | default: |
308 | ath_dbg(common, ATH_DBG_EEPROM, | 308 | ath_dbg(common, EEPROM, "Invalid chainmask configuration\n"); |
309 | "Invalid chainmask configuration\n"); | ||
310 | break; | 309 | break; |
311 | } | 310 | } |
312 | } | 311 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 61fcab0e2d76..4322ac80c203 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -38,7 +38,7 @@ static bool __ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) | |||
38 | 38 | ||
39 | for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { | 39 | for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { |
40 | if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { | 40 | if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { |
41 | ath_dbg(common, ATH_DBG_EEPROM, | 41 | ath_dbg(common, EEPROM, |
42 | "Unable to read eeprom region\n"); | 42 | "Unable to read eeprom region\n"); |
43 | return false; | 43 | return false; |
44 | } | 44 | } |
@@ -62,8 +62,7 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) | |||
62 | struct ath_common *common = ath9k_hw_common(ah); | 62 | struct ath_common *common = ath9k_hw_common(ah); |
63 | 63 | ||
64 | if (!ath9k_hw_use_flash(ah)) { | 64 | if (!ath9k_hw_use_flash(ah)) { |
65 | ath_dbg(common, ATH_DBG_EEPROM, | 65 | ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n"); |
66 | "Reading from EEPROM, not flash\n"); | ||
67 | } | 66 | } |
68 | 67 | ||
69 | if (common->bus_ops->ath_bus_type == ATH_USB) | 68 | if (common->bus_ops->ath_bus_type == ATH_USB) |
@@ -204,8 +203,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) | |||
204 | return false; | 203 | return false; |
205 | } | 204 | } |
206 | 205 | ||
207 | ath_dbg(common, ATH_DBG_EEPROM, | 206 | ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); |
208 | "Read Magic = 0x%04X\n", magic); | ||
209 | 207 | ||
210 | if (magic != AR5416_EEPROM_MAGIC) { | 208 | if (magic != AR5416_EEPROM_MAGIC) { |
211 | magic2 = swab16(magic); | 209 | magic2 = swab16(magic); |
@@ -227,7 +225,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) | |||
227 | } | 225 | } |
228 | } | 226 | } |
229 | 227 | ||
230 | ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n", | 228 | ath_dbg(common, EEPROM, "need_swap = %s\n", |
231 | need_swap ? "True" : "False"); | 229 | need_swap ? "True" : "False"); |
232 | 230 | ||
233 | if (need_swap) | 231 | if (need_swap) |
@@ -249,7 +247,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) | |||
249 | u32 integer; | 247 | u32 integer; |
250 | u16 word; | 248 | u16 word; |
251 | 249 | ||
252 | ath_dbg(common, ATH_DBG_EEPROM, | 250 | ath_dbg(common, EEPROM, |
253 | "EEPROM Endianness is not native.. Changing\n"); | 251 | "EEPROM Endianness is not native.. Changing\n"); |
254 | 252 | ||
255 | word = swab16(eep->baseEepHeader.length); | 253 | word = swab16(eep->baseEepHeader.length); |
@@ -435,11 +433,11 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, | |||
435 | reg32 = get_unaligned_le32(&pdadcValues[4 * j]); | 433 | reg32 = get_unaligned_le32(&pdadcValues[4 * j]); |
436 | REG_WRITE(ah, regOffset, reg32); | 434 | REG_WRITE(ah, regOffset, reg32); |
437 | 435 | ||
438 | ath_dbg(common, ATH_DBG_EEPROM, | 436 | ath_dbg(common, EEPROM, |
439 | "PDADC (%d,%4x): %4.4x %8.8x\n", | 437 | "PDADC (%d,%4x): %4.4x %8.8x\n", |
440 | i, regChainOffset, regOffset, | 438 | i, regChainOffset, regOffset, |
441 | reg32); | 439 | reg32); |
442 | ath_dbg(common, ATH_DBG_EEPROM, | 440 | ath_dbg(common, EEPROM, |
443 | "PDADC: Chain %d | " | 441 | "PDADC: Chain %d | " |
444 | "PDADC %3d Value %3d | " | 442 | "PDADC %3d Value %3d | " |
445 | "PDADC %3d Value %3d | " | 443 | "PDADC %3d Value %3d | " |
@@ -1079,8 +1077,7 @@ static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | |||
1079 | 1077 | ||
1080 | u16 spur_val = AR_NO_SPUR; | 1078 | u16 spur_val = AR_NO_SPUR; |
1081 | 1079 | ||
1082 | ath_dbg(common, ATH_DBG_ANI, | 1080 | ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n", |
1083 | "Getting spur idx:%d is2Ghz:%d val:%x\n", | ||
1084 | i, is2GHz, ah->config.spurchans[i][is2GHz]); | 1081 | i, is2GHz, ah->config.spurchans[i][is2GHz]); |
1085 | 1082 | ||
1086 | switch (ah->config.spurmode) { | 1083 | switch (ah->config.spurmode) { |
@@ -1088,8 +1085,8 @@ static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | |||
1088 | break; | 1085 | break; |
1089 | case SPUR_ENABLE_IOCTL: | 1086 | case SPUR_ENABLE_IOCTL: |
1090 | spur_val = ah->config.spurchans[i][is2GHz]; | 1087 | spur_val = ah->config.spurchans[i][is2GHz]; |
1091 | ath_dbg(common, ATH_DBG_ANI, | 1088 | ath_dbg(common, ANI, "Getting spur val from new loc. %d\n", |
1092 | "Getting spur val from new loc. %d\n", spur_val); | 1089 | spur_val); |
1093 | break; | 1090 | break; |
1094 | case SPUR_ENABLE_EEPROM: | 1091 | case SPUR_ENABLE_EEPROM: |
1095 | spur_val = EEP_MAP4K_SPURCHAN; | 1092 | spur_val = EEP_MAP4K_SPURCHAN; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 0981c073471d..f272236d8053 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -41,7 +41,7 @@ static bool __ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) | |||
41 | for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) { | 41 | for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) { |
42 | if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, | 42 | if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, |
43 | eep_data)) { | 43 | eep_data)) { |
44 | ath_dbg(common, ATH_DBG_EEPROM, | 44 | ath_dbg(common, EEPROM, |
45 | "Unable to read eeprom region\n"); | 45 | "Unable to read eeprom region\n"); |
46 | return false; | 46 | return false; |
47 | } | 47 | } |
@@ -66,8 +66,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) | |||
66 | struct ath_common *common = ath9k_hw_common(ah); | 66 | struct ath_common *common = ath9k_hw_common(ah); |
67 | 67 | ||
68 | if (!ath9k_hw_use_flash(ah)) { | 68 | if (!ath9k_hw_use_flash(ah)) { |
69 | ath_dbg(common, ATH_DBG_EEPROM, | 69 | ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n"); |
70 | "Reading from EEPROM, not flash\n"); | ||
71 | } | 70 | } |
72 | 71 | ||
73 | if (common->bus_ops->ath_bus_type == ATH_USB) | 72 | if (common->bus_ops->ath_bus_type == ATH_USB) |
@@ -197,8 +196,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) | |||
197 | return false; | 196 | return false; |
198 | } | 197 | } |
199 | 198 | ||
200 | ath_dbg(common, ATH_DBG_EEPROM, | 199 | ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); |
201 | "Read Magic = 0x%04X\n", magic); | ||
202 | 200 | ||
203 | if (magic != AR5416_EEPROM_MAGIC) { | 201 | if (magic != AR5416_EEPROM_MAGIC) { |
204 | magic2 = swab16(magic); | 202 | magic2 = swab16(magic); |
@@ -220,7 +218,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) | |||
220 | } | 218 | } |
221 | } | 219 | } |
222 | 220 | ||
223 | ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n", | 221 | ath_dbg(common, EEPROM, "need_swap = %s\n", |
224 | need_swap ? "True" : "False"); | 222 | need_swap ? "True" : "False"); |
225 | 223 | ||
226 | if (need_swap) | 224 | if (need_swap) |
@@ -1041,8 +1039,7 @@ static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, | |||
1041 | struct ath_common *common = ath9k_hw_common(ah); | 1039 | struct ath_common *common = ath9k_hw_common(ah); |
1042 | u16 spur_val = AR_NO_SPUR; | 1040 | u16 spur_val = AR_NO_SPUR; |
1043 | 1041 | ||
1044 | ath_dbg(common, ATH_DBG_ANI, | 1042 | ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n", |
1045 | "Getting spur idx:%d is2Ghz:%d val:%x\n", | ||
1046 | i, is2GHz, ah->config.spurchans[i][is2GHz]); | 1043 | i, is2GHz, ah->config.spurchans[i][is2GHz]); |
1047 | 1044 | ||
1048 | switch (ah->config.spurmode) { | 1045 | switch (ah->config.spurmode) { |
@@ -1050,8 +1047,8 @@ static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah, | |||
1050 | break; | 1047 | break; |
1051 | case SPUR_ENABLE_IOCTL: | 1048 | case SPUR_ENABLE_IOCTL: |
1052 | spur_val = ah->config.spurchans[i][is2GHz]; | 1049 | spur_val = ah->config.spurchans[i][is2GHz]; |
1053 | ath_dbg(common, ATH_DBG_ANI, | 1050 | ath_dbg(common, ANI, "Getting spur val from new loc. %d\n", |
1054 | "Getting spur val from new loc. %d\n", spur_val); | 1051 | spur_val); |
1055 | break; | 1052 | break; |
1056 | case SPUR_ENABLE_EEPROM: | 1053 | case SPUR_ENABLE_EEPROM: |
1057 | spur_val = EEP_MAP9287_SPURCHAN; | 1054 | spur_val = EEP_MAP9287_SPURCHAN; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 9681c099d0a5..619b95d764ff 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -121,8 +121,7 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) | |||
121 | struct ath_common *common = ath9k_hw_common(ah); | 121 | struct ath_common *common = ath9k_hw_common(ah); |
122 | 122 | ||
123 | if (!ath9k_hw_use_flash(ah)) { | 123 | if (!ath9k_hw_use_flash(ah)) { |
124 | ath_dbg(common, ATH_DBG_EEPROM, | 124 | ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n"); |
125 | "Reading from EEPROM, not flash\n"); | ||
126 | } | 125 | } |
127 | 126 | ||
128 | if (common->bus_ops->ath_bus_type == ATH_USB) | 127 | if (common->bus_ops->ath_bus_type == ATH_USB) |
@@ -279,8 +278,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
279 | } | 278 | } |
280 | 279 | ||
281 | if (!ath9k_hw_use_flash(ah)) { | 280 | if (!ath9k_hw_use_flash(ah)) { |
282 | ath_dbg(common, ATH_DBG_EEPROM, | 281 | ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); |
283 | "Read Magic = 0x%04X\n", magic); | ||
284 | 282 | ||
285 | if (magic != AR5416_EEPROM_MAGIC) { | 283 | if (magic != AR5416_EEPROM_MAGIC) { |
286 | magic2 = swab16(magic); | 284 | magic2 = swab16(magic); |
@@ -303,7 +301,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
303 | } | 301 | } |
304 | } | 302 | } |
305 | 303 | ||
306 | ath_dbg(common, ATH_DBG_EEPROM, "need_swap = %s.\n", | 304 | ath_dbg(common, EEPROM, "need_swap = %s\n", |
307 | need_swap ? "True" : "False"); | 305 | need_swap ? "True" : "False"); |
308 | 306 | ||
309 | if (need_swap) | 307 | if (need_swap) |
@@ -325,7 +323,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
325 | u32 integer, j; | 323 | u32 integer, j; |
326 | u16 word; | 324 | u16 word; |
327 | 325 | ||
328 | ath_dbg(common, ATH_DBG_EEPROM, | 326 | ath_dbg(common, EEPROM, |
329 | "EEPROM Endianness is not native.. Changing.\n"); | 327 | "EEPROM Endianness is not native.. Changing.\n"); |
330 | 328 | ||
331 | word = swab16(eep->baseEepHeader.length); | 329 | word = swab16(eep->baseEepHeader.length); |
@@ -965,15 +963,12 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, | |||
965 | reg32 = get_unaligned_le32(&pdadcValues[4 * j]); | 963 | reg32 = get_unaligned_le32(&pdadcValues[4 * j]); |
966 | REG_WRITE(ah, regOffset, reg32); | 964 | REG_WRITE(ah, regOffset, reg32); |
967 | 965 | ||
968 | ath_dbg(common, ATH_DBG_EEPROM, | 966 | ath_dbg(common, EEPROM, |
969 | "PDADC (%d,%4x): %4.4x %8.8x\n", | 967 | "PDADC (%d,%4x): %4.4x %8.8x\n", |
970 | i, regChainOffset, regOffset, | 968 | i, regChainOffset, regOffset, |
971 | reg32); | 969 | reg32); |
972 | ath_dbg(common, ATH_DBG_EEPROM, | 970 | ath_dbg(common, EEPROM, |
973 | "PDADC: Chain %d | PDADC %3d " | 971 | "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n", |
974 | "Value %3d | PDADC %3d Value %3d | " | ||
975 | "PDADC %3d Value %3d | PDADC %3d " | ||
976 | "Value %3d |\n", | ||
977 | i, 4 * j, pdadcValues[4 * j], | 972 | i, 4 * j, pdadcValues[4 * j], |
978 | 4 * j + 1, pdadcValues[4 * j + 1], | 973 | 4 * j + 1, pdadcValues[4 * j + 1], |
979 | 4 * j + 2, pdadcValues[4 * j + 2], | 974 | 4 * j + 2, pdadcValues[4 * j + 2], |
@@ -1278,7 +1273,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, | |||
1278 | regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; | 1273 | regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; |
1279 | break; | 1274 | break; |
1280 | default: | 1275 | default: |
1281 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_EEPROM, | 1276 | ath_dbg(ath9k_hw_common(ah), EEPROM, |
1282 | "Invalid chainmask configuration\n"); | 1277 | "Invalid chainmask configuration\n"); |
1283 | break; | 1278 | break; |
1284 | } | 1279 | } |
@@ -1396,8 +1391,7 @@ static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | |||
1396 | 1391 | ||
1397 | u16 spur_val = AR_NO_SPUR; | 1392 | u16 spur_val = AR_NO_SPUR; |
1398 | 1393 | ||
1399 | ath_dbg(common, ATH_DBG_ANI, | 1394 | ath_dbg(common, ANI, "Getting spur idx:%d is2Ghz:%d val:%x\n", |
1400 | "Getting spur idx:%d is2Ghz:%d val:%x\n", | ||
1401 | i, is2GHz, ah->config.spurchans[i][is2GHz]); | 1395 | i, is2GHz, ah->config.spurchans[i][is2GHz]); |
1402 | 1396 | ||
1403 | switch (ah->config.spurmode) { | 1397 | switch (ah->config.spurmode) { |
@@ -1405,8 +1399,8 @@ static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz) | |||
1405 | break; | 1399 | break; |
1406 | case SPUR_ENABLE_IOCTL: | 1400 | case SPUR_ENABLE_IOCTL: |
1407 | spur_val = ah->config.spurchans[i][is2GHz]; | 1401 | spur_val = ah->config.spurchans[i][is2GHz]; |
1408 | ath_dbg(common, ATH_DBG_ANI, | 1402 | ath_dbg(common, ANI, "Getting spur val from new loc. %d\n", |
1409 | "Getting spur val from new loc. %d\n", spur_val); | 1403 | spur_val); |
1410 | break; | 1404 | break; |
1411 | case SPUR_ENABLE_EEPROM: | 1405 | case SPUR_ENABLE_EEPROM: |
1412 | spur_val = EEP_DEF_SPURCHAN; | 1406 | spur_val = EEP_DEF_SPURCHAN; |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index e4ae08e07719..597c84e31adb 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -130,12 +130,12 @@ static void ath_detect_bt_priority(struct ath_softc *sc) | |||
130 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | 130 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); |
131 | /* Detect if colocated bt started scanning */ | 131 | /* Detect if colocated bt started scanning */ |
132 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { | 132 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { |
133 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, | 133 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, |
134 | "BT scan detected\n"); | 134 | "BT scan detected\n"); |
135 | sc->sc_flags |= (SC_OP_BT_SCAN | | 135 | sc->sc_flags |= (SC_OP_BT_SCAN | |
136 | SC_OP_BT_PRIORITY_DETECTED); | 136 | SC_OP_BT_PRIORITY_DETECTED); |
137 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | 137 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { |
138 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, | 138 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, |
139 | "BT priority traffic detected\n"); | 139 | "BT priority traffic detected\n"); |
140 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | 140 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; |
141 | } | 141 | } |
@@ -230,8 +230,7 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
230 | struct ath_common *common = ath9k_hw_common(ah); | 230 | struct ath_common *common = ath9k_hw_common(ah); |
231 | bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 231 | bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; |
232 | 232 | ||
233 | ath_dbg(common, ATH_DBG_BTCOEX, | 233 | ath_dbg(common, BTCOEX, "no stomp timer running\n"); |
234 | "no stomp timer running\n"); | ||
235 | 234 | ||
236 | ath9k_ps_wakeup(sc); | 235 | ath9k_ps_wakeup(sc); |
237 | spin_lock_bh(&btcoex->btcoex_lock); | 236 | spin_lock_bh(&btcoex->btcoex_lock); |
@@ -250,6 +249,9 @@ int ath_init_btcoex_timer(struct ath_softc *sc) | |||
250 | { | 249 | { |
251 | struct ath_btcoex *btcoex = &sc->btcoex; | 250 | struct ath_btcoex *btcoex = &sc->btcoex; |
252 | 251 | ||
252 | if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_NONE) | ||
253 | return 0; | ||
254 | |||
253 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; | 255 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; |
254 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | 256 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * |
255 | btcoex->btcoex_period / 100; | 257 | btcoex->btcoex_period / 100; |
@@ -280,8 +282,10 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) | |||
280 | struct ath_btcoex *btcoex = &sc->btcoex; | 282 | struct ath_btcoex *btcoex = &sc->btcoex; |
281 | struct ath_hw *ah = sc->sc_ah; | 283 | struct ath_hw *ah = sc->sc_ah; |
282 | 284 | ||
283 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | 285 | ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); |
284 | "Starting btcoex timers\n"); | 286 | |
287 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
288 | return; | ||
285 | 289 | ||
286 | /* make sure duty cycle timer is also stopped when resuming */ | 290 | /* make sure duty cycle timer is also stopped when resuming */ |
287 | if (btcoex->hw_timer_enabled) | 291 | if (btcoex->hw_timer_enabled) |
@@ -303,6 +307,9 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc) | |||
303 | struct ath_btcoex *btcoex = &sc->btcoex; | 307 | struct ath_btcoex *btcoex = &sc->btcoex; |
304 | struct ath_hw *ah = sc->sc_ah; | 308 | struct ath_hw *ah = sc->sc_ah; |
305 | 309 | ||
310 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) | ||
311 | return; | ||
312 | |||
306 | del_timer_sync(&btcoex->period_timer); | 313 | del_timer_sync(&btcoex->period_timer); |
307 | 314 | ||
308 | if (btcoex->hw_timer_enabled) | 315 | if (btcoex->hw_timer_enabled) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 57fe22b24247..2eadffb7971c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -167,9 +167,9 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | |||
167 | /* TSF out of range threshold fixed at 1 second */ | 167 | /* TSF out of range threshold fixed at 1 second */ |
168 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | 168 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; |
169 | 169 | ||
170 | ath_dbg(common, ATH_DBG_CONFIG, "intval: %u tsf: %llu tsftu: %u\n", | 170 | ath_dbg(common, CONFIG, "intval: %u tsf: %llu tsftu: %u\n", |
171 | intval, tsf, tsftu); | 171 | intval, tsf, tsftu); |
172 | ath_dbg(common, ATH_DBG_CONFIG, | 172 | ath_dbg(common, CONFIG, |
173 | "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", | 173 | "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", |
174 | bs.bs_bmissthreshold, bs.bs_sleepduration, | 174 | bs.bs_bmissthreshold, bs.bs_sleepduration, |
175 | bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); | 175 | bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); |
@@ -224,9 +224,8 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
224 | if (priv->op_flags & OP_ENABLE_BEACON) | 224 | if (priv->op_flags & OP_ENABLE_BEACON) |
225 | imask |= ATH9K_INT_SWBA; | 225 | imask |= ATH9K_INT_SWBA; |
226 | 226 | ||
227 | ath_dbg(common, ATH_DBG_CONFIG, | 227 | ath_dbg(common, CONFIG, |
228 | "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d " | 228 | "AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d imask: 0x%x\n", |
229 | "imask: 0x%x\n", | ||
230 | bss_conf->beacon_interval, nexttbtt, | 229 | bss_conf->beacon_interval, nexttbtt, |
231 | priv->ah->config.sw_beacon_response_time, imask); | 230 | priv->ah->config.sw_beacon_response_time, imask); |
232 | 231 | ||
@@ -273,9 +272,8 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
273 | if (priv->op_flags & OP_ENABLE_BEACON) | 272 | if (priv->op_flags & OP_ENABLE_BEACON) |
274 | imask |= ATH9K_INT_SWBA; | 273 | imask |= ATH9K_INT_SWBA; |
275 | 274 | ||
276 | ath_dbg(common, ATH_DBG_CONFIG, | 275 | ath_dbg(common, CONFIG, |
277 | "IBSS Beacon config, intval: %d, nexttbtt: %u, " | 276 | "IBSS Beacon config, intval: %d, nexttbtt: %u, resp_time: %d, imask: 0x%x\n", |
278 | "resp_time: %d, imask: 0x%x\n", | ||
279 | bss_conf->beacon_interval, nexttbtt, | 277 | bss_conf->beacon_interval, nexttbtt, |
280 | priv->ah->config.sw_beacon_response_time, imask); | 278 | priv->ah->config.sw_beacon_response_time, imask); |
281 | 279 | ||
@@ -323,7 +321,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, | |||
323 | 321 | ||
324 | tx_slot = ath9k_htc_tx_get_slot(priv); | 322 | tx_slot = ath9k_htc_tx_get_slot(priv); |
325 | if (tx_slot < 0) { | 323 | if (tx_slot < 0) { |
326 | ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n"); | 324 | ath_dbg(common, XMIT, "No free CAB slot\n"); |
327 | dev_kfree_skb_any(skb); | 325 | dev_kfree_skb_any(skb); |
328 | goto next; | 326 | goto next; |
329 | } | 327 | } |
@@ -333,8 +331,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, | |||
333 | ath9k_htc_tx_clear_slot(priv, tx_slot); | 331 | ath9k_htc_tx_clear_slot(priv, tx_slot); |
334 | dev_kfree_skb_any(skb); | 332 | dev_kfree_skb_any(skb); |
335 | 333 | ||
336 | ath_dbg(common, ATH_DBG_XMIT, | 334 | ath_dbg(common, XMIT, "Failed to send CAB frame\n"); |
337 | "Failed to send CAB frame\n"); | ||
338 | } else { | 335 | } else { |
339 | spin_lock_bh(&priv->tx.tx_lock); | 336 | spin_lock_bh(&priv->tx.tx_lock); |
340 | priv->tx.queued_cnt++; | 337 | priv->tx.queued_cnt++; |
@@ -409,7 +406,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, | |||
409 | ret = htc_send(priv->htc, beacon); | 406 | ret = htc_send(priv->htc, beacon); |
410 | if (ret != 0) { | 407 | if (ret != 0) { |
411 | if (ret == -ENOMEM) { | 408 | if (ret == -ENOMEM) { |
412 | ath_dbg(common, ATH_DBG_BSTUCK, | 409 | ath_dbg(common, BSTUCK, |
413 | "Failed to send beacon, no free TX buffer\n"); | 410 | "Failed to send beacon, no free TX buffer\n"); |
414 | } | 411 | } |
415 | dev_kfree_skb_any(beacon); | 412 | dev_kfree_skb_any(beacon); |
@@ -434,7 +431,7 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, | |||
434 | slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; | 431 | slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval; |
435 | slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; | 432 | slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1; |
436 | 433 | ||
437 | ath_dbg(common, ATH_DBG_BEACON, | 434 | ath_dbg(common, BEACON, |
438 | "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n", | 435 | "Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n", |
439 | slot, tsf, tsftu, intval); | 436 | slot, tsf, tsftu, intval); |
440 | 437 | ||
@@ -450,8 +447,7 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, | |||
450 | if (swba->beacon_pending != 0) { | 447 | if (swba->beacon_pending != 0) { |
451 | priv->cur_beacon_conf.bmiss_cnt++; | 448 | priv->cur_beacon_conf.bmiss_cnt++; |
452 | if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { | 449 | if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) { |
453 | ath_dbg(common, ATH_DBG_BSTUCK, | 450 | ath_dbg(common, BSTUCK, "Beacon stuck, HW reset\n"); |
454 | "Beacon stuck, HW reset\n"); | ||
455 | ieee80211_queue_work(priv->hw, | 451 | ieee80211_queue_work(priv->hw, |
456 | &priv->fatal_work); | 452 | &priv->fatal_work); |
457 | } | 453 | } |
@@ -459,7 +455,7 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, | |||
459 | } | 455 | } |
460 | 456 | ||
461 | if (priv->cur_beacon_conf.bmiss_cnt) { | 457 | if (priv->cur_beacon_conf.bmiss_cnt) { |
462 | ath_dbg(common, ATH_DBG_BSTUCK, | 458 | ath_dbg(common, BSTUCK, |
463 | "Resuming beacon xmit after %u misses\n", | 459 | "Resuming beacon xmit after %u misses\n", |
464 | priv->cur_beacon_conf.bmiss_cnt); | 460 | priv->cur_beacon_conf.bmiss_cnt); |
465 | priv->cur_beacon_conf.bmiss_cnt = 0; | 461 | priv->cur_beacon_conf.bmiss_cnt = 0; |
@@ -495,8 +491,8 @@ void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv, | |||
495 | priv->cur_beacon_conf.bslot[avp->bslot] = vif; | 491 | priv->cur_beacon_conf.bslot[avp->bslot] = vif; |
496 | spin_unlock_bh(&priv->beacon_lock); | 492 | spin_unlock_bh(&priv->beacon_lock); |
497 | 493 | ||
498 | ath_dbg(common, ATH_DBG_CONFIG, | 494 | ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", |
499 | "Added interface at beacon slot: %d\n", avp->bslot); | 495 | avp->bslot); |
500 | } | 496 | } |
501 | 497 | ||
502 | void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | 498 | void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, |
@@ -509,8 +505,8 @@ void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv, | |||
509 | priv->cur_beacon_conf.bslot[avp->bslot] = NULL; | 505 | priv->cur_beacon_conf.bslot[avp->bslot] = NULL; |
510 | spin_unlock_bh(&priv->beacon_lock); | 506 | spin_unlock_bh(&priv->beacon_lock); |
511 | 507 | ||
512 | ath_dbg(common, ATH_DBG_CONFIG, | 508 | ath_dbg(common, CONFIG, "Removed interface at beacon slot: %d\n", |
513 | "Removed interface at beacon slot: %d\n", avp->bslot); | 509 | avp->bslot); |
514 | } | 510 | } |
515 | 511 | ||
516 | /* | 512 | /* |
@@ -536,8 +532,7 @@ void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv, | |||
536 | tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF; | 532 | tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF; |
537 | avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); | 533 | avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); |
538 | 534 | ||
539 | ath_dbg(common, ATH_DBG_CONFIG, | 535 | ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n", |
540 | "tsfadjust is: %llu for bslot: %d\n", | ||
541 | (unsigned long long)tsfadjust, avp->bslot); | 536 | (unsigned long long)tsfadjust, avp->bslot); |
542 | } | 537 | } |
543 | 538 | ||
@@ -568,7 +563,7 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv, | |||
568 | (priv->num_ap_vif > 1) && | 563 | (priv->num_ap_vif > 1) && |
569 | (vif->type == NL80211_IFTYPE_AP) && | 564 | (vif->type == NL80211_IFTYPE_AP) && |
570 | (cur_conf->beacon_interval != bss_conf->beacon_int)) { | 565 | (cur_conf->beacon_interval != bss_conf->beacon_int)) { |
571 | ath_dbg(common, ATH_DBG_CONFIG, | 566 | ath_dbg(common, CONFIG, |
572 | "Changing beacon interval of multiple AP interfaces !\n"); | 567 | "Changing beacon interval of multiple AP interfaces !\n"); |
573 | return false; | 568 | return false; |
574 | } | 569 | } |
@@ -579,7 +574,7 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv, | |||
579 | */ | 574 | */ |
580 | if (priv->num_ap_vif && | 575 | if (priv->num_ap_vif && |
581 | (vif->type != NL80211_IFTYPE_AP)) { | 576 | (vif->type != NL80211_IFTYPE_AP)) { |
582 | ath_dbg(common, ATH_DBG_CONFIG, | 577 | ath_dbg(common, CONFIG, |
583 | "HW in AP mode, cannot set STA beacon parameters\n"); | 578 | "HW in AP mode, cannot set STA beacon parameters\n"); |
584 | return false; | 579 | return false; |
585 | } | 580 | } |
@@ -597,7 +592,7 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv, | |||
597 | &beacon_configured); | 592 | &beacon_configured); |
598 | 593 | ||
599 | if (beacon_configured) { | 594 | if (beacon_configured) { |
600 | ath_dbg(common, ATH_DBG_CONFIG, | 595 | ath_dbg(common, CONFIG, |
601 | "Beacon already configured for a station interface\n"); | 596 | "Beacon already configured for a station interface\n"); |
602 | return false; | 597 | return false; |
603 | } | 598 | } |
@@ -637,8 +632,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | |||
637 | ath9k_htc_beacon_config_ap(priv, cur_conf); | 632 | ath9k_htc_beacon_config_ap(priv, cur_conf); |
638 | break; | 633 | break; |
639 | default: | 634 | default: |
640 | ath_dbg(common, ATH_DBG_CONFIG, | 635 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); |
641 | "Unsupported beaconing mode\n"); | ||
642 | return; | 636 | return; |
643 | } | 637 | } |
644 | } | 638 | } |
@@ -659,8 +653,7 @@ void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv) | |||
659 | ath9k_htc_beacon_config_ap(priv, cur_conf); | 653 | ath9k_htc_beacon_config_ap(priv, cur_conf); |
660 | break; | 654 | break; |
661 | default: | 655 | default: |
662 | ath_dbg(common, ATH_DBG_CONFIG, | 656 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); |
663 | "Unsupported beaconing mode\n"); | ||
664 | return; | 657 | return; |
665 | } | 658 | } |
666 | } | 659 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index ce606b618e0b..6506e1fd5036 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | |||
@@ -36,12 +36,12 @@ static void ath_detect_bt_priority(struct ath9k_htc_priv *priv) | |||
36 | priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); | 36 | priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); |
37 | /* Detect if colocated bt started scanning */ | 37 | /* Detect if colocated bt started scanning */ |
38 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { | 38 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { |
39 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | 39 | ath_dbg(ath9k_hw_common(ah), BTCOEX, |
40 | "BT scan detected\n"); | 40 | "BT scan detected\n"); |
41 | priv->op_flags |= (OP_BT_SCAN | | 41 | priv->op_flags |= (OP_BT_SCAN | |
42 | OP_BT_PRIORITY_DETECTED); | 42 | OP_BT_PRIORITY_DETECTED); |
43 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | 43 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { |
44 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | 44 | ath_dbg(ath9k_hw_common(ah), BTCOEX, |
45 | "BT priority traffic detected\n"); | 45 | "BT priority traffic detected\n"); |
46 | priv->op_flags |= OP_BT_PRIORITY_DETECTED; | 46 | priv->op_flags |= OP_BT_PRIORITY_DETECTED; |
47 | } | 47 | } |
@@ -102,8 +102,7 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) | |||
102 | struct ath_common *common = ath9k_hw_common(ah); | 102 | struct ath_common *common = ath9k_hw_common(ah); |
103 | bool is_btscan = priv->op_flags & OP_BT_SCAN; | 103 | bool is_btscan = priv->op_flags & OP_BT_SCAN; |
104 | 104 | ||
105 | ath_dbg(common, ATH_DBG_BTCOEX, | 105 | ath_dbg(common, BTCOEX, "time slice work for bt and wlan\n"); |
106 | "time slice work for bt and wlan\n"); | ||
107 | 106 | ||
108 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | 107 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) |
109 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | 108 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
@@ -116,6 +115,9 @@ void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) | |||
116 | { | 115 | { |
117 | struct ath_btcoex *btcoex = &priv->btcoex; | 116 | struct ath_btcoex *btcoex = &priv->btcoex; |
118 | 117 | ||
118 | if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE) | ||
119 | return; | ||
120 | |||
119 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; | 121 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; |
120 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | 122 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * |
121 | btcoex->btcoex_period / 100; | 123 | btcoex->btcoex_period / 100; |
@@ -134,7 +136,10 @@ void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) | |||
134 | struct ath_btcoex *btcoex = &priv->btcoex; | 136 | struct ath_btcoex *btcoex = &priv->btcoex; |
135 | struct ath_hw *ah = priv->ah; | 137 | struct ath_hw *ah = priv->ah; |
136 | 138 | ||
137 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, "Starting btcoex work\n"); | 139 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) |
140 | return; | ||
141 | |||
142 | ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex work\n"); | ||
138 | 143 | ||
139 | btcoex->bt_priority_cnt = 0; | 144 | btcoex->bt_priority_cnt = 0; |
140 | btcoex->bt_priority_time = jiffies; | 145 | btcoex->bt_priority_time = jiffies; |
@@ -148,6 +153,9 @@ void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) | |||
148 | */ | 153 | */ |
149 | void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) | 154 | void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) |
150 | { | 155 | { |
156 | if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE) | ||
157 | return; | ||
158 | |||
151 | cancel_delayed_work_sync(&priv->coex_period_work); | 159 | cancel_delayed_work_sync(&priv->coex_period_work); |
152 | cancel_delayed_work_sync(&priv->duty_cycle_work); | 160 | cancel_delayed_work_sync(&priv->duty_cycle_work); |
153 | } | 161 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 966661c9e586..9be10a2da1c2 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -299,8 +299,7 @@ static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset) | |||
299 | (u8 *) &val, sizeof(val), | 299 | (u8 *) &val, sizeof(val), |
300 | 100); | 300 | 100); |
301 | if (unlikely(r)) { | 301 | if (unlikely(r)) { |
302 | ath_dbg(common, ATH_DBG_WMI, | 302 | ath_dbg(common, WMI, "REGISTER READ FAILED: (0x%04x, %d)\n", |
303 | "REGISTER READ FAILED: (0x%04x, %d)\n", | ||
304 | reg_offset, r); | 303 | reg_offset, r); |
305 | return -EIO; | 304 | return -EIO; |
306 | } | 305 | } |
@@ -327,7 +326,7 @@ static void ath9k_multi_regread(void *hw_priv, u32 *addr, | |||
327 | (u8 *)tmpval, sizeof(u32) * count, | 326 | (u8 *)tmpval, sizeof(u32) * count, |
328 | 100); | 327 | 100); |
329 | if (unlikely(ret)) { | 328 | if (unlikely(ret)) { |
330 | ath_dbg(common, ATH_DBG_WMI, | 329 | ath_dbg(common, WMI, |
331 | "Multiple REGISTER READ FAILED (count: %d)\n", count); | 330 | "Multiple REGISTER READ FAILED (count: %d)\n", count); |
332 | } | 331 | } |
333 | 332 | ||
@@ -352,8 +351,7 @@ static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) | |||
352 | (u8 *) &val, sizeof(val), | 351 | (u8 *) &val, sizeof(val), |
353 | 100); | 352 | 100); |
354 | if (unlikely(r)) { | 353 | if (unlikely(r)) { |
355 | ath_dbg(common, ATH_DBG_WMI, | 354 | ath_dbg(common, WMI, "REGISTER WRITE FAILED:(0x%04x, %d)\n", |
356 | "REGISTER WRITE FAILED:(0x%04x, %d)\n", | ||
357 | reg_offset, r); | 355 | reg_offset, r); |
358 | } | 356 | } |
359 | } | 357 | } |
@@ -384,7 +382,7 @@ static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset) | |||
384 | (u8 *) &rsp_status, sizeof(rsp_status), | 382 | (u8 *) &rsp_status, sizeof(rsp_status), |
385 | 100); | 383 | 100); |
386 | if (unlikely(r)) { | 384 | if (unlikely(r)) { |
387 | ath_dbg(common, ATH_DBG_WMI, | 385 | ath_dbg(common, WMI, |
388 | "REGISTER WRITE FAILED, multi len: %d\n", | 386 | "REGISTER WRITE FAILED, multi len: %d\n", |
389 | priv->wmi->multi_write_idx); | 387 | priv->wmi->multi_write_idx); |
390 | } | 388 | } |
@@ -434,7 +432,7 @@ static void ath9k_regwrite_flush(void *hw_priv) | |||
434 | (u8 *) &rsp_status, sizeof(rsp_status), | 432 | (u8 *) &rsp_status, sizeof(rsp_status), |
435 | 100); | 433 | 100); |
436 | if (unlikely(r)) { | 434 | if (unlikely(r)) { |
437 | ath_dbg(common, ATH_DBG_WMI, | 435 | ath_dbg(common, WMI, |
438 | "REGISTER WRITE FAILED, multi len: %d\n", | 436 | "REGISTER WRITE FAILED, multi len: %d\n", |
439 | priv->wmi->multi_write_idx); | 437 | priv->wmi->multi_write_idx); |
440 | } | 438 | } |
@@ -512,8 +510,7 @@ static void setup_ht_cap(struct ath9k_htc_priv *priv, | |||
512 | tx_streams = ath9k_cmn_count_streams(priv->ah->txchainmask, 2); | 510 | tx_streams = ath9k_cmn_count_streams(priv->ah->txchainmask, 2); |
513 | rx_streams = ath9k_cmn_count_streams(priv->ah->rxchainmask, 2); | 511 | rx_streams = ath9k_cmn_count_streams(priv->ah->rxchainmask, 2); |
514 | 512 | ||
515 | ath_dbg(common, ATH_DBG_CONFIG, | 513 | ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n", |
516 | "TX streams %d, RX streams: %d\n", | ||
517 | tx_streams, rx_streams); | 514 | tx_streams, rx_streams); |
518 | 515 | ||
519 | if (tx_streams != rx_streams) { | 516 | if (tx_streams != rx_streams) { |
@@ -610,7 +607,7 @@ static void ath9k_init_btcoex(struct ath9k_htc_priv *priv) | |||
610 | { | 607 | { |
611 | int qnum; | 608 | int qnum; |
612 | 609 | ||
613 | switch (priv->ah->btcoex_hw.scheme) { | 610 | switch (ath9k_hw_get_btcoex_scheme(priv->ah)) { |
614 | case ATH_BTCOEX_CFG_NONE: | 611 | case ATH_BTCOEX_CFG_NONE: |
615 | break; | 612 | break; |
616 | case ATH_BTCOEX_CFG_3WIRE: | 613 | case ATH_BTCOEX_CFG_3WIRE: |
@@ -704,7 +701,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
704 | 701 | ||
705 | if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { | 702 | if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { |
706 | ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; | 703 | ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; |
707 | ath9k_init_btcoex(priv); | 704 | if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) |
705 | ath9k_init_btcoex(priv); | ||
708 | } | 706 | } |
709 | 707 | ||
710 | return 0; | 708 | return 0; |
@@ -876,9 +874,8 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
876 | goto err_world; | 874 | goto err_world; |
877 | } | 875 | } |
878 | 876 | ||
879 | ath_dbg(common, ATH_DBG_CONFIG, | 877 | ath_dbg(common, CONFIG, |
880 | "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, " | 878 | "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, BE:%d, BK:%d, VI:%d, VO:%d\n", |
881 | "BE:%d, BK:%d, VI:%d, VO:%d\n", | ||
882 | priv->wmi_cmd_ep, | 879 | priv->wmi_cmd_ep, |
883 | priv->beacon_ep, | 880 | priv->beacon_ep, |
884 | priv->cab_ep, | 881 | priv->cab_ep, |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f8ce4ea6f65c..ef4c60661290 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -266,7 +266,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
266 | 266 | ||
267 | ath9k_wmi_event_drain(priv); | 267 | ath9k_wmi_event_drain(priv); |
268 | 268 | ||
269 | ath_dbg(common, ATH_DBG_CONFIG, | 269 | ath_dbg(common, CONFIG, |
270 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", | 270 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", |
271 | priv->ah->curchan->channel, | 271 | priv->ah->curchan->channel, |
272 | channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf), | 272 | channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf), |
@@ -415,7 +415,7 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | |||
415 | priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx; | 415 | priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx; |
416 | priv->ah->is_monitoring = true; | 416 | priv->ah->is_monitoring = true; |
417 | 417 | ||
418 | ath_dbg(common, ATH_DBG_CONFIG, | 418 | ath_dbg(common, CONFIG, |
419 | "Attached a monitor interface at idx: %d, sta idx: %d\n", | 419 | "Attached a monitor interface at idx: %d, sta idx: %d\n", |
420 | priv->mon_vif_idx, sta_idx); | 420 | priv->mon_vif_idx, sta_idx); |
421 | 421 | ||
@@ -427,7 +427,7 @@ err_sta: | |||
427 | */ | 427 | */ |
428 | __ath9k_htc_remove_monitor_interface(priv); | 428 | __ath9k_htc_remove_monitor_interface(priv); |
429 | err_vif: | 429 | err_vif: |
430 | ath_dbg(common, ATH_DBG_FATAL, "Unable to attach a monitor interface\n"); | 430 | ath_dbg(common, FATAL, "Unable to attach a monitor interface\n"); |
431 | 431 | ||
432 | return ret; | 432 | return ret; |
433 | } | 433 | } |
@@ -452,7 +452,7 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) | |||
452 | priv->nstations--; | 452 | priv->nstations--; |
453 | priv->ah->is_monitoring = false; | 453 | priv->ah->is_monitoring = false; |
454 | 454 | ||
455 | ath_dbg(common, ATH_DBG_CONFIG, | 455 | ath_dbg(common, CONFIG, |
456 | "Removed a monitor interface at idx: %d, sta idx: %d\n", | 456 | "Removed a monitor interface at idx: %d, sta idx: %d\n", |
457 | priv->mon_vif_idx, sta_idx); | 457 | priv->mon_vif_idx, sta_idx); |
458 | 458 | ||
@@ -512,11 +512,11 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
512 | } | 512 | } |
513 | 513 | ||
514 | if (sta) { | 514 | if (sta) { |
515 | ath_dbg(common, ATH_DBG_CONFIG, | 515 | ath_dbg(common, CONFIG, |
516 | "Added a station entry for: %pM (idx: %d)\n", | 516 | "Added a station entry for: %pM (idx: %d)\n", |
517 | sta->addr, tsta.sta_index); | 517 | sta->addr, tsta.sta_index); |
518 | } else { | 518 | } else { |
519 | ath_dbg(common, ATH_DBG_CONFIG, | 519 | ath_dbg(common, CONFIG, |
520 | "Added a station entry for VIF %d (idx: %d)\n", | 520 | "Added a station entry for VIF %d (idx: %d)\n", |
521 | avp->index, tsta.sta_index); | 521 | avp->index, tsta.sta_index); |
522 | } | 522 | } |
@@ -556,11 +556,11 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, | |||
556 | } | 556 | } |
557 | 557 | ||
558 | if (sta) { | 558 | if (sta) { |
559 | ath_dbg(common, ATH_DBG_CONFIG, | 559 | ath_dbg(common, CONFIG, |
560 | "Removed a station entry for: %pM (idx: %d)\n", | 560 | "Removed a station entry for: %pM (idx: %d)\n", |
561 | sta->addr, sta_idx); | 561 | sta->addr, sta_idx); |
562 | } else { | 562 | } else { |
563 | ath_dbg(common, ATH_DBG_CONFIG, | 563 | ath_dbg(common, CONFIG, |
564 | "Removed a station entry for VIF %d (idx: %d)\n", | 564 | "Removed a station entry for VIF %d (idx: %d)\n", |
565 | avp->index, sta_idx); | 565 | avp->index, sta_idx); |
566 | } | 566 | } |
@@ -665,7 +665,7 @@ static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv, | |||
665 | ath9k_htc_setup_rate(priv, sta, &trate); | 665 | ath9k_htc_setup_rate(priv, sta, &trate); |
666 | ret = ath9k_htc_send_rate_cmd(priv, &trate); | 666 | ret = ath9k_htc_send_rate_cmd(priv, &trate); |
667 | if (!ret) | 667 | if (!ret) |
668 | ath_dbg(common, ATH_DBG_CONFIG, | 668 | ath_dbg(common, CONFIG, |
669 | "Updated target sta: %pM, rate caps: 0x%X\n", | 669 | "Updated target sta: %pM, rate caps: 0x%X\n", |
670 | sta->addr, be32_to_cpu(trate.capflags)); | 670 | sta->addr, be32_to_cpu(trate.capflags)); |
671 | } | 671 | } |
@@ -692,7 +692,7 @@ static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv, | |||
692 | 692 | ||
693 | ret = ath9k_htc_send_rate_cmd(priv, &trate); | 693 | ret = ath9k_htc_send_rate_cmd(priv, &trate); |
694 | if (!ret) | 694 | if (!ret) |
695 | ath_dbg(common, ATH_DBG_CONFIG, | 695 | ath_dbg(common, CONFIG, |
696 | "Updated target sta: %pM, rate caps: 0x%X\n", | 696 | "Updated target sta: %pM, rate caps: 0x%X\n", |
697 | bss_conf->bssid, be32_to_cpu(trate.capflags)); | 697 | bss_conf->bssid, be32_to_cpu(trate.capflags)); |
698 | } | 698 | } |
@@ -721,11 +721,11 @@ static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv, | |||
721 | 721 | ||
722 | WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr); | 722 | WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr); |
723 | if (ret) | 723 | if (ret) |
724 | ath_dbg(common, ATH_DBG_CONFIG, | 724 | ath_dbg(common, CONFIG, |
725 | "Unable to %s TX aggregation for (%pM, %d)\n", | 725 | "Unable to %s TX aggregation for (%pM, %d)\n", |
726 | (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid); | 726 | (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid); |
727 | else | 727 | else |
728 | ath_dbg(common, ATH_DBG_CONFIG, | 728 | ath_dbg(common, CONFIG, |
729 | "%s TX aggregation for (%pM, %d)\n", | 729 | "%s TX aggregation for (%pM, %d)\n", |
730 | (aggr.aggr_enable) ? "Starting" : "Stopping", | 730 | (aggr.aggr_enable) ? "Starting" : "Stopping", |
731 | sta->addr, tid); | 731 | sta->addr, tid); |
@@ -784,7 +784,7 @@ void ath9k_htc_ani_work(struct work_struct *work) | |||
784 | /* Long calibration runs independently of short calibration. */ | 784 | /* Long calibration runs independently of short calibration. */ |
785 | if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { | 785 | if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { |
786 | longcal = true; | 786 | longcal = true; |
787 | ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); | 787 | ath_dbg(common, ANI, "longcal @%lu\n", jiffies); |
788 | common->ani.longcal_timer = timestamp; | 788 | common->ani.longcal_timer = timestamp; |
789 | } | 789 | } |
790 | 790 | ||
@@ -793,8 +793,7 @@ void ath9k_htc_ani_work(struct work_struct *work) | |||
793 | if ((timestamp - common->ani.shortcal_timer) >= | 793 | if ((timestamp - common->ani.shortcal_timer) >= |
794 | short_cal_interval) { | 794 | short_cal_interval) { |
795 | shortcal = true; | 795 | shortcal = true; |
796 | ath_dbg(common, ATH_DBG_ANI, | 796 | ath_dbg(common, ANI, "shortcal @%lu\n", jiffies); |
797 | "shortcal @%lu\n", jiffies); | ||
798 | common->ani.shortcal_timer = timestamp; | 797 | common->ani.shortcal_timer = timestamp; |
799 | common->ani.resetcal_timer = timestamp; | 798 | common->ani.resetcal_timer = timestamp; |
800 | } | 799 | } |
@@ -866,7 +865,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
866 | padsize = padpos & 3; | 865 | padsize = padpos & 3; |
867 | if (padsize && skb->len > padpos) { | 866 | if (padsize && skb->len > padpos) { |
868 | if (skb_headroom(skb) < padsize) { | 867 | if (skb_headroom(skb) < padsize) { |
869 | ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n"); | 868 | ath_dbg(common, XMIT, "No room for padding\n"); |
870 | goto fail_tx; | 869 | goto fail_tx; |
871 | } | 870 | } |
872 | skb_push(skb, padsize); | 871 | skb_push(skb, padsize); |
@@ -875,13 +874,13 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
875 | 874 | ||
876 | slot = ath9k_htc_tx_get_slot(priv); | 875 | slot = ath9k_htc_tx_get_slot(priv); |
877 | if (slot < 0) { | 876 | if (slot < 0) { |
878 | ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n"); | 877 | ath_dbg(common, XMIT, "No free TX slot\n"); |
879 | goto fail_tx; | 878 | goto fail_tx; |
880 | } | 879 | } |
881 | 880 | ||
882 | ret = ath9k_htc_tx_start(priv, skb, slot, false); | 881 | ret = ath9k_htc_tx_start(priv, skb, slot, false); |
883 | if (ret != 0) { | 882 | if (ret != 0) { |
884 | ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n"); | 883 | ath_dbg(common, XMIT, "Tx failed\n"); |
885 | goto clear_slot; | 884 | goto clear_slot; |
886 | } | 885 | } |
887 | 886 | ||
@@ -909,7 +908,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
909 | 908 | ||
910 | mutex_lock(&priv->mutex); | 909 | mutex_lock(&priv->mutex); |
911 | 910 | ||
912 | ath_dbg(common, ATH_DBG_CONFIG, | 911 | ath_dbg(common, CONFIG, |
913 | "Starting driver with initial channel: %d MHz\n", | 912 | "Starting driver with initial channel: %d MHz\n", |
914 | curchan->center_freq); | 913 | curchan->center_freq); |
915 | 914 | ||
@@ -943,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
943 | 942 | ||
944 | ret = ath9k_htc_update_cap_target(priv, 0); | 943 | ret = ath9k_htc_update_cap_target(priv, 0); |
945 | if (ret) | 944 | if (ret) |
946 | ath_dbg(common, ATH_DBG_CONFIG, | 945 | ath_dbg(common, CONFIG, |
947 | "Failed to update capability in target\n"); | 946 | "Failed to update capability in target\n"); |
948 | 947 | ||
949 | priv->op_flags &= ~OP_INVALID; | 948 | priv->op_flags &= ~OP_INVALID; |
@@ -958,7 +957,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
958 | mod_timer(&priv->tx.cleanup_timer, | 957 | mod_timer(&priv->tx.cleanup_timer, |
959 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); | 958 | jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); |
960 | 959 | ||
961 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { | 960 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) { |
962 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | 961 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
963 | AR_STOMP_LOW_WLAN_WGHT); | 962 | AR_STOMP_LOW_WLAN_WGHT); |
964 | ath9k_hw_btcoex_enable(ah); | 963 | ath9k_hw_btcoex_enable(ah); |
@@ -980,7 +979,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
980 | mutex_lock(&priv->mutex); | 979 | mutex_lock(&priv->mutex); |
981 | 980 | ||
982 | if (priv->op_flags & OP_INVALID) { | 981 | if (priv->op_flags & OP_INVALID) { |
983 | ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); | 982 | ath_dbg(common, ANY, "Device not present\n"); |
984 | mutex_unlock(&priv->mutex); | 983 | mutex_unlock(&priv->mutex); |
985 | return; | 984 | return; |
986 | } | 985 | } |
@@ -1010,7 +1009,8 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1010 | 1009 | ||
1011 | mutex_lock(&priv->mutex); | 1010 | mutex_lock(&priv->mutex); |
1012 | 1011 | ||
1013 | if (ah->btcoex_hw.enabled) { | 1012 | if (ah->btcoex_hw.enabled && |
1013 | ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { | ||
1014 | ath9k_hw_btcoex_disable(ah); | 1014 | ath9k_hw_btcoex_disable(ah); |
1015 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 1015 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) |
1016 | ath_htc_cancel_btcoex_work(priv); | 1016 | ath_htc_cancel_btcoex_work(priv); |
@@ -1027,7 +1027,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1027 | 1027 | ||
1028 | priv->op_flags |= OP_INVALID; | 1028 | priv->op_flags |= OP_INVALID; |
1029 | 1029 | ||
1030 | ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); | 1030 | ath_dbg(common, CONFIG, "Driver halt\n"); |
1031 | mutex_unlock(&priv->mutex); | 1031 | mutex_unlock(&priv->mutex); |
1032 | } | 1032 | } |
1033 | 1033 | ||
@@ -1120,8 +1120,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1120 | ath9k_htc_start_ani(priv); | 1120 | ath9k_htc_start_ani(priv); |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | ath_dbg(common, ATH_DBG_CONFIG, | 1123 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d at idx: %d\n", |
1124 | "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); | 1124 | vif->type, avp->index); |
1125 | 1125 | ||
1126 | out: | 1126 | out: |
1127 | ath9k_htc_ps_restore(priv); | 1127 | ath9k_htc_ps_restore(priv); |
@@ -1177,7 +1177,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1177 | ath9k_htc_stop_ani(priv); | 1177 | ath9k_htc_stop_ani(priv); |
1178 | } | 1178 | } |
1179 | 1179 | ||
1180 | ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index); | 1180 | ath_dbg(common, CONFIG, "Detach Interface at idx: %d\n", avp->index); |
1181 | 1181 | ||
1182 | ath9k_htc_ps_restore(priv); | 1182 | ath9k_htc_ps_restore(priv); |
1183 | mutex_unlock(&priv->mutex); | 1183 | mutex_unlock(&priv->mutex); |
@@ -1202,8 +1202,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
1202 | mutex_unlock(&priv->htc_pm_lock); | 1202 | mutex_unlock(&priv->htc_pm_lock); |
1203 | 1203 | ||
1204 | if (enable_radio) { | 1204 | if (enable_radio) { |
1205 | ath_dbg(common, ATH_DBG_CONFIG, | 1205 | ath_dbg(common, CONFIG, "not-idle: enabling radio\n"); |
1206 | "not-idle: enabling radio\n"); | ||
1207 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); | 1206 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); |
1208 | ath9k_htc_radio_enable(hw); | 1207 | ath9k_htc_radio_enable(hw); |
1209 | } | 1208 | } |
@@ -1225,7 +1224,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
1225 | struct ieee80211_channel *curchan = hw->conf.channel; | 1224 | struct ieee80211_channel *curchan = hw->conf.channel; |
1226 | int pos = curchan->hw_value; | 1225 | int pos = curchan->hw_value; |
1227 | 1226 | ||
1228 | ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 1227 | ath_dbg(common, CONFIG, "Set channel: %d MHz\n", |
1229 | curchan->center_freq); | 1228 | curchan->center_freq); |
1230 | 1229 | ||
1231 | ath9k_cmn_update_ichannel(&priv->ah->channels[pos], | 1230 | ath9k_cmn_update_ichannel(&priv->ah->channels[pos], |
@@ -1265,8 +1264,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
1265 | } | 1264 | } |
1266 | mutex_unlock(&priv->htc_pm_lock); | 1265 | mutex_unlock(&priv->htc_pm_lock); |
1267 | 1266 | ||
1268 | ath_dbg(common, ATH_DBG_CONFIG, | 1267 | ath_dbg(common, CONFIG, "idle: disabling radio\n"); |
1269 | "idle: disabling radio\n"); | ||
1270 | ath9k_htc_radio_disable(hw); | 1268 | ath9k_htc_radio_disable(hw); |
1271 | } | 1269 | } |
1272 | 1270 | ||
@@ -1298,7 +1296,7 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | |||
1298 | *total_flags &= SUPPORTED_FILTERS; | 1296 | *total_flags &= SUPPORTED_FILTERS; |
1299 | 1297 | ||
1300 | if (priv->op_flags & OP_INVALID) { | 1298 | if (priv->op_flags & OP_INVALID) { |
1301 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_ANY, | 1299 | ath_dbg(ath9k_hw_common(priv->ah), ANY, |
1302 | "Unable to configure filter on invalid state\n"); | 1300 | "Unable to configure filter on invalid state\n"); |
1303 | mutex_unlock(&priv->mutex); | 1301 | mutex_unlock(&priv->mutex); |
1304 | return; | 1302 | return; |
@@ -1309,8 +1307,8 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | |||
1309 | rfilt = ath9k_htc_calcrxfilter(priv); | 1307 | rfilt = ath9k_htc_calcrxfilter(priv); |
1310 | ath9k_hw_setrxfilter(priv->ah, rfilt); | 1308 | ath9k_hw_setrxfilter(priv->ah, rfilt); |
1311 | 1309 | ||
1312 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG, | 1310 | ath_dbg(ath9k_hw_common(priv->ah), CONFIG, "Set HW RX filter: 0x%x\n", |
1313 | "Set HW RX filter: 0x%x\n", rfilt); | 1311 | rfilt); |
1314 | 1312 | ||
1315 | ath9k_htc_ps_restore(priv); | 1313 | ath9k_htc_ps_restore(priv); |
1316 | mutex_unlock(&priv->mutex); | 1314 | mutex_unlock(&priv->mutex); |
@@ -1377,7 +1375,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, | |||
1377 | 1375 | ||
1378 | qnum = get_hw_qnum(queue, priv->hwq_map); | 1376 | qnum = get_hw_qnum(queue, priv->hwq_map); |
1379 | 1377 | ||
1380 | ath_dbg(common, ATH_DBG_CONFIG, | 1378 | ath_dbg(common, CONFIG, |
1381 | "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | 1379 | "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", |
1382 | queue, qnum, params->aifs, params->cw_min, | 1380 | queue, qnum, params->aifs, params->cw_min, |
1383 | params->cw_max, params->txop); | 1381 | params->cw_max, params->txop); |
@@ -1412,7 +1410,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, | |||
1412 | return -ENOSPC; | 1410 | return -ENOSPC; |
1413 | 1411 | ||
1414 | mutex_lock(&priv->mutex); | 1412 | mutex_lock(&priv->mutex); |
1415 | ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); | 1413 | ath_dbg(common, CONFIG, "Set HW Key\n"); |
1416 | ath9k_htc_ps_wakeup(priv); | 1414 | ath9k_htc_ps_wakeup(priv); |
1417 | 1415 | ||
1418 | switch (cmd) { | 1416 | switch (cmd) { |
@@ -1448,8 +1446,7 @@ static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv) | |||
1448 | struct ath_common *common = ath9k_hw_common(priv->ah); | 1446 | struct ath_common *common = ath9k_hw_common(priv->ah); |
1449 | 1447 | ||
1450 | ath9k_hw_write_associd(priv->ah); | 1448 | ath9k_hw_write_associd(priv->ah); |
1451 | ath_dbg(common, ATH_DBG_CONFIG, | 1449 | ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", |
1452 | "BSSID: %pM aid: 0x%x\n", | ||
1453 | common->curbssid, common->curaid); | 1450 | common->curbssid, common->curaid); |
1454 | } | 1451 | } |
1455 | 1452 | ||
@@ -1487,7 +1484,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1487 | ath9k_htc_ps_wakeup(priv); | 1484 | ath9k_htc_ps_wakeup(priv); |
1488 | 1485 | ||
1489 | if (changed & BSS_CHANGED_ASSOC) { | 1486 | if (changed & BSS_CHANGED_ASSOC) { |
1490 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | 1487 | ath_dbg(common, CONFIG, "BSS Changed ASSOC %d\n", |
1491 | bss_conf->assoc); | 1488 | bss_conf->assoc); |
1492 | 1489 | ||
1493 | bss_conf->assoc ? | 1490 | bss_conf->assoc ? |
@@ -1512,8 +1509,8 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1512 | } | 1509 | } |
1513 | 1510 | ||
1514 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { | 1511 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { |
1515 | ath_dbg(common, ATH_DBG_CONFIG, | 1512 | ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n", |
1516 | "Beacon enabled for BSS: %pM\n", bss_conf->bssid); | 1513 | bss_conf->bssid); |
1517 | ath9k_htc_set_tsfadjust(priv, vif); | 1514 | ath9k_htc_set_tsfadjust(priv, vif); |
1518 | priv->op_flags |= OP_ENABLE_BEACON; | 1515 | priv->op_flags |= OP_ENABLE_BEACON; |
1519 | ath9k_htc_beacon_config(priv, vif); | 1516 | ath9k_htc_beacon_config(priv, vif); |
@@ -1525,7 +1522,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1525 | * AP/IBSS interfaces. | 1522 | * AP/IBSS interfaces. |
1526 | */ | 1523 | */ |
1527 | if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) { | 1524 | if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) { |
1528 | ath_dbg(common, ATH_DBG_CONFIG, | 1525 | ath_dbg(common, CONFIG, |
1529 | "Beacon disabled for BSS: %pM\n", | 1526 | "Beacon disabled for BSS: %pM\n", |
1530 | bss_conf->bssid); | 1527 | bss_conf->bssid); |
1531 | priv->op_flags &= ~OP_ENABLE_BEACON; | 1528 | priv->op_flags &= ~OP_ENABLE_BEACON; |
@@ -1543,7 +1540,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1543 | (vif->type == NL80211_IFTYPE_AP)) { | 1540 | (vif->type == NL80211_IFTYPE_AP)) { |
1544 | priv->op_flags |= OP_TSF_RESET; | 1541 | priv->op_flags |= OP_TSF_RESET; |
1545 | } | 1542 | } |
1546 | ath_dbg(common, ATH_DBG_CONFIG, | 1543 | ath_dbg(common, CONFIG, |
1547 | "Beacon interval changed for BSS: %pM\n", | 1544 | "Beacon interval changed for BSS: %pM\n", |
1548 | bss_conf->bssid); | 1545 | bss_conf->bssid); |
1549 | ath9k_htc_beacon_config(priv, vif); | 1546 | ath9k_htc_beacon_config(priv, vif); |
@@ -1733,8 +1730,7 @@ static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw, | |||
1733 | goto out; | 1730 | goto out; |
1734 | } | 1731 | } |
1735 | 1732 | ||
1736 | ath_dbg(common, ATH_DBG_CONFIG, | 1733 | ath_dbg(common, CONFIG, "Set bitrate masks: 0x%x, 0x%x\n", |
1737 | "Set bitrate masks: 0x%x, 0x%x\n", | ||
1738 | mask->control[IEEE80211_BAND_2GHZ].legacy, | 1734 | mask->control[IEEE80211_BAND_2GHZ].legacy, |
1739 | mask->control[IEEE80211_BAND_5GHZ].legacy); | 1735 | mask->control[IEEE80211_BAND_5GHZ].legacy); |
1740 | out: | 1736 | out: |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 2d81c700e201..3e40a6461512 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -355,7 +355,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, | |||
355 | vif_idx = avp->index; | 355 | vif_idx = avp->index; |
356 | } else { | 356 | } else { |
357 | if (!priv->ah->is_monitoring) { | 357 | if (!priv->ah->is_monitoring) { |
358 | ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | 358 | ath_dbg(ath9k_hw_common(priv->ah), XMIT, |
359 | "VIF is null, but no monitor interface !\n"); | 359 | "VIF is null, but no monitor interface !\n"); |
360 | return -EINVAL; | 360 | return -EINVAL; |
361 | } | 361 | } |
@@ -620,8 +620,7 @@ static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv, | |||
620 | } | 620 | } |
621 | spin_unlock_irqrestore(&epid_queue->lock, flags); | 621 | spin_unlock_irqrestore(&epid_queue->lock, flags); |
622 | 622 | ||
623 | ath_dbg(common, ATH_DBG_XMIT, | 623 | ath_dbg(common, XMIT, "No matching packet for cookie: %d, epid: %d\n", |
624 | "No matching packet for cookie: %d, epid: %d\n", | ||
625 | txs->cookie, epid); | 624 | txs->cookie, epid); |
626 | 625 | ||
627 | return NULL; | 626 | return NULL; |
@@ -705,8 +704,7 @@ static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb | |||
705 | if (time_after(jiffies, | 704 | if (time_after(jiffies, |
706 | tx_ctl->timestamp + | 705 | tx_ctl->timestamp + |
707 | msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) { | 706 | msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) { |
708 | ath_dbg(common, ATH_DBG_XMIT, | 707 | ath_dbg(common, XMIT, "Dropping a packet due to TX timeout\n"); |
709 | "Dropping a packet due to TX timeout\n"); | ||
710 | return true; | 708 | return true; |
711 | } | 709 | } |
712 | 710 | ||
@@ -753,7 +751,7 @@ void ath9k_htc_tx_cleanup_timer(unsigned long data) | |||
753 | 751 | ||
754 | skb = ath9k_htc_tx_get_packet(priv, &event->txs); | 752 | skb = ath9k_htc_tx_get_packet(priv, &event->txs); |
755 | if (skb) { | 753 | if (skb) { |
756 | ath_dbg(common, ATH_DBG_XMIT, | 754 | ath_dbg(common, XMIT, |
757 | "Found packet for cookie: %d, epid: %d\n", | 755 | "Found packet for cookie: %d, epid: %d\n", |
758 | event->txs.cookie, | 756 | event->txs.cookie, |
759 | MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID)); | 757 | MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID)); |
@@ -1167,8 +1165,7 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, | |||
1167 | spin_unlock(&priv->rx.rxbuflock); | 1165 | spin_unlock(&priv->rx.rxbuflock); |
1168 | 1166 | ||
1169 | if (rxbuf == NULL) { | 1167 | if (rxbuf == NULL) { |
1170 | ath_dbg(common, ATH_DBG_ANY, | 1168 | ath_dbg(common, ANY, "No free RX buffer\n"); |
1171 | "No free RX buffer\n"); | ||
1172 | goto err; | 1169 | goto err; |
1173 | } | 1170 | } |
1174 | 1171 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8cda9a1513a7..ee7759575050 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -133,7 +133,7 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) | |||
133 | udelay(AH_TIME_QUANTUM); | 133 | udelay(AH_TIME_QUANTUM); |
134 | } | 134 | } |
135 | 135 | ||
136 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_ANY, | 136 | ath_dbg(ath9k_hw_common(ah), ANY, |
137 | "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", | 137 | "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", |
138 | timeout, reg, REG_READ(ah, reg), mask, val); | 138 | timeout, reg, REG_READ(ah, reg), mask, val); |
139 | 139 | ||
@@ -491,8 +491,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
491 | if (ecode != 0) | 491 | if (ecode != 0) |
492 | return ecode; | 492 | return ecode; |
493 | 493 | ||
494 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_CONFIG, | 494 | ath_dbg(ath9k_hw_common(ah), CONFIG, "Eeprom VER: %d, REV: %d\n", |
495 | "Eeprom VER: %d, REV: %d\n", | ||
496 | ah->eep_ops->get_eeprom_ver(ah), | 495 | ah->eep_ops->get_eeprom_ver(ah), |
497 | ah->eep_ops->get_eeprom_rev(ah)); | 496 | ah->eep_ops->get_eeprom_rev(ah)); |
498 | 497 | ||
@@ -567,7 +566,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
567 | } | 566 | } |
568 | } | 567 | } |
569 | 568 | ||
570 | ath_dbg(common, ATH_DBG_RESET, "serialize_regmode is %d\n", | 569 | ath_dbg(common, RESET, "serialize_regmode is %d\n", |
571 | ah->config.serialize_regmode); | 570 | ah->config.serialize_regmode); |
572 | 571 | ||
573 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | 572 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) |
@@ -958,8 +957,8 @@ static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) | |||
958 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) | 957 | static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) |
959 | { | 958 | { |
960 | if (tu > 0xFFFF) { | 959 | if (tu > 0xFFFF) { |
961 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_XMIT, | 960 | ath_dbg(ath9k_hw_common(ah), XMIT, "bad global tx timeout %u\n", |
962 | "bad global tx timeout %u\n", tu); | 961 | tu); |
963 | ah->globaltxtimeout = (u32) -1; | 962 | ah->globaltxtimeout = (u32) -1; |
964 | return false; | 963 | return false; |
965 | } else { | 964 | } else { |
@@ -980,7 +979,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
980 | int rx_lat = 0, tx_lat = 0, eifs = 0; | 979 | int rx_lat = 0, tx_lat = 0, eifs = 0; |
981 | u32 reg; | 980 | u32 reg; |
982 | 981 | ||
983 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", | 982 | ath_dbg(ath9k_hw_common(ah), RESET, "ah->misc_mode 0x%x\n", |
984 | ah->misc_mode); | 983 | ah->misc_mode); |
985 | 984 | ||
986 | if (!chan) | 985 | if (!chan) |
@@ -1275,7 +1274,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1275 | (npend || type == ATH9K_RESET_COLD)) { | 1274 | (npend || type == ATH9K_RESET_COLD)) { |
1276 | int reset_err = 0; | 1275 | int reset_err = 0; |
1277 | 1276 | ||
1278 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, | 1277 | ath_dbg(ath9k_hw_common(ah), RESET, |
1279 | "reset MAC via external reset\n"); | 1278 | "reset MAC via external reset\n"); |
1280 | 1279 | ||
1281 | reset_err = ah->external_reset(); | 1280 | reset_err = ah->external_reset(); |
@@ -1298,8 +1297,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1298 | 1297 | ||
1299 | REG_WRITE(ah, AR_RTC_RC, 0); | 1298 | REG_WRITE(ah, AR_RTC_RC, 0); |
1300 | if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) { | 1299 | if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) { |
1301 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, | 1300 | ath_dbg(ath9k_hw_common(ah), RESET, "RTC stuck in MAC reset\n"); |
1302 | "RTC stuck in MAC reset\n"); | ||
1303 | return false; | 1301 | return false; |
1304 | } | 1302 | } |
1305 | 1303 | ||
@@ -1344,8 +1342,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | |||
1344 | AR_RTC_STATUS_M, | 1342 | AR_RTC_STATUS_M, |
1345 | AR_RTC_STATUS_ON, | 1343 | AR_RTC_STATUS_ON, |
1346 | AH_WAIT_TIMEOUT)) { | 1344 | AH_WAIT_TIMEOUT)) { |
1347 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, | 1345 | ath_dbg(ath9k_hw_common(ah), RESET, "RTC not waking up\n"); |
1348 | "RTC not waking up\n"); | ||
1349 | return false; | 1346 | return false; |
1350 | } | 1347 | } |
1351 | 1348 | ||
@@ -1418,7 +1415,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1418 | 1415 | ||
1419 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { | 1416 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { |
1420 | if (ath9k_hw_numtxpending(ah, qnum)) { | 1417 | if (ath9k_hw_numtxpending(ah, qnum)) { |
1421 | ath_dbg(common, ATH_DBG_QUEUE, | 1418 | ath_dbg(common, QUEUE, |
1422 | "Transmit frames pending on queue %d\n", qnum); | 1419 | "Transmit frames pending on queue %d\n", qnum); |
1423 | return false; | 1420 | return false; |
1424 | } | 1421 | } |
@@ -1536,7 +1533,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1536 | if (mci_hw->bt_state == MCI_BT_CAL_START) { | 1533 | if (mci_hw->bt_state == MCI_BT_CAL_START) { |
1537 | u32 payload[4] = {0, 0, 0, 0}; | 1534 | u32 payload[4] = {0, 0, 0, 0}; |
1538 | 1535 | ||
1539 | ath_dbg(common, ATH_DBG_MCI, "MCI stop rx for BT CAL"); | 1536 | ath_dbg(common, MCI, "MCI stop rx for BT CAL\n"); |
1540 | 1537 | ||
1541 | mci_hw->bt_state = MCI_BT_CAL; | 1538 | mci_hw->bt_state = MCI_BT_CAL; |
1542 | 1539 | ||
@@ -1548,23 +1545,22 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1548 | 1545 | ||
1549 | ar9003_mci_disable_interrupt(ah); | 1546 | ar9003_mci_disable_interrupt(ah); |
1550 | 1547 | ||
1551 | ath_dbg(common, ATH_DBG_MCI, "send WLAN_CAL_GRANT"); | 1548 | ath_dbg(common, MCI, "send WLAN_CAL_GRANT\n"); |
1552 | MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT); | 1549 | MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT); |
1553 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, | 1550 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, |
1554 | 16, true, false); | 1551 | 16, true, false); |
1555 | 1552 | ||
1556 | ath_dbg(common, ATH_DBG_MCI, "\nMCI BT is calibrating"); | 1553 | ath_dbg(common, MCI, "\nMCI BT is calibrating\n"); |
1557 | 1554 | ||
1558 | /* Wait BT calibration to be completed for 25ms */ | 1555 | /* Wait BT calibration to be completed for 25ms */ |
1559 | 1556 | ||
1560 | if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, | 1557 | if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, |
1561 | 0, 25000)) | 1558 | 0, 25000)) |
1562 | ath_dbg(common, ATH_DBG_MCI, | 1559 | ath_dbg(common, MCI, |
1563 | "MCI got BT_CAL_DONE\n"); | 1560 | "MCI got BT_CAL_DONE\n"); |
1564 | else | 1561 | else |
1565 | ath_dbg(common, ATH_DBG_MCI, | 1562 | ath_dbg(common, MCI, |
1566 | "MCI ### BT cal takes to long, force" | 1563 | "MCI ### BT cal takes to long, force bt_state to be bt_awake\n"); |
1567 | "bt_state to be bt_awake\n"); | ||
1568 | mci_hw->bt_state = MCI_BT_AWAKE; | 1564 | mci_hw->bt_state = MCI_BT_AWAKE; |
1569 | /* MCI FIX: enable mci interrupt here */ | 1565 | /* MCI FIX: enable mci interrupt here */ |
1570 | ar9003_mci_enable_interrupt(ah); | 1566 | ar9003_mci_enable_interrupt(ah); |
@@ -1825,14 +1821,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1825 | * message exchanges again and recal. | 1821 | * message exchanges again and recal. |
1826 | */ | 1822 | */ |
1827 | 1823 | ||
1828 | ath_dbg(common, ATH_DBG_MCI, "MCI BT wakes up" | 1824 | ath_dbg(common, MCI, |
1829 | "during WLAN calibration\n"); | 1825 | "MCI BT wakes up during WLAN calibration\n"); |
1830 | 1826 | ||
1831 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 1827 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
1832 | AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | | 1828 | AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | |
1833 | AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); | 1829 | AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); |
1834 | ath_dbg(common, ATH_DBG_MCI, "MCI send" | 1830 | ath_dbg(common, MCI, "MCI send REMOTE_RESET\n"); |
1835 | "REMOTE_RESET\n"); | ||
1836 | ar9003_mci_remote_reset(ah, true); | 1831 | ar9003_mci_remote_reset(ah, true); |
1837 | ar9003_mci_send_sys_waking(ah, true); | 1832 | ar9003_mci_send_sys_waking(ah, true); |
1838 | udelay(1); | 1833 | udelay(1); |
@@ -1841,7 +1836,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1841 | 1836 | ||
1842 | mci_hw->bt_state = MCI_BT_AWAKE; | 1837 | mci_hw->bt_state = MCI_BT_AWAKE; |
1843 | 1838 | ||
1844 | ath_dbg(common, ATH_DBG_MCI, "MCI re-cal\n"); | 1839 | ath_dbg(common, MCI, "MCI re-cal\n"); |
1845 | 1840 | ||
1846 | if (caldata) { | 1841 | if (caldata) { |
1847 | caldata->done_txiqcal_once = false; | 1842 | caldata->done_txiqcal_once = false; |
@@ -1871,14 +1866,14 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1871 | u32 mask; | 1866 | u32 mask; |
1872 | mask = REG_READ(ah, AR_CFG); | 1867 | mask = REG_READ(ah, AR_CFG); |
1873 | if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { | 1868 | if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) { |
1874 | ath_dbg(common, ATH_DBG_RESET, | 1869 | ath_dbg(common, RESET, "CFG Byte Swap Set 0x%x\n", |
1875 | "CFG Byte Swap Set 0x%x\n", mask); | 1870 | mask); |
1876 | } else { | 1871 | } else { |
1877 | mask = | 1872 | mask = |
1878 | INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; | 1873 | INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB; |
1879 | REG_WRITE(ah, AR_CFG, mask); | 1874 | REG_WRITE(ah, AR_CFG, mask); |
1880 | ath_dbg(common, ATH_DBG_RESET, | 1875 | ath_dbg(common, RESET, "Setting CFG 0x%x\n", |
1881 | "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); | 1876 | REG_READ(ah, AR_CFG)); |
1882 | } | 1877 | } |
1883 | } else { | 1878 | } else { |
1884 | if (common->bus_ops->ath_bus_type == ATH_USB) { | 1879 | if (common->bus_ops->ath_bus_type == ATH_USB) { |
@@ -1896,7 +1891,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1896 | #endif | 1891 | #endif |
1897 | } | 1892 | } |
1898 | 1893 | ||
1899 | if (ah->btcoex_hw.enabled) | 1894 | if (ah->btcoex_hw.enabled && |
1895 | ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) | ||
1900 | ath9k_hw_btcoex_enable(ah); | 1896 | ath9k_hw_btcoex_enable(ah); |
1901 | 1897 | ||
1902 | if (mci && mci_hw->ready) { | 1898 | if (mci && mci_hw->ready) { |
@@ -2090,7 +2086,7 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | |||
2090 | if (ah->power_mode == mode) | 2086 | if (ah->power_mode == mode) |
2091 | return status; | 2087 | return status; |
2092 | 2088 | ||
2093 | ath_dbg(common, ATH_DBG_RESET, "%s -> %s\n", | 2089 | ath_dbg(common, RESET, "%s -> %s\n", |
2094 | modes[ah->power_mode], modes[mode]); | 2090 | modes[ah->power_mode], modes[mode]); |
2095 | 2091 | ||
2096 | switch (mode) { | 2092 | switch (mode) { |
@@ -2107,8 +2103,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | |||
2107 | if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) && | 2103 | if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) && |
2108 | (mci->bt_state != MCI_BT_SLEEP) && | 2104 | (mci->bt_state != MCI_BT_SLEEP) && |
2109 | !mci->halted_bt_gpm) { | 2105 | !mci->halted_bt_gpm) { |
2110 | ath_dbg(common, ATH_DBG_MCI, "MCI halt BT GPM" | 2106 | ath_dbg(common, MCI, |
2111 | "(full_sleep)"); | 2107 | "MCI halt BT GPM (full_sleep)\n"); |
2112 | ar9003_mci_send_coex_halt_bt_gpm(ah, | 2108 | ar9003_mci_send_coex_halt_bt_gpm(ah, |
2113 | true, true); | 2109 | true, true); |
2114 | } | 2110 | } |
@@ -2174,9 +2170,8 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) | |||
2174 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; | 2170 | AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; |
2175 | break; | 2171 | break; |
2176 | default: | 2172 | default: |
2177 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_BEACON, | 2173 | ath_dbg(ath9k_hw_common(ah), BEACON, |
2178 | "%s: unsupported opmode: %d\n", | 2174 | "%s: unsupported opmode: %d\n", __func__, ah->opmode); |
2179 | __func__, ah->opmode); | ||
2180 | return; | 2175 | return; |
2181 | break; | 2176 | break; |
2182 | } | 2177 | } |
@@ -2227,10 +2222,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
2227 | else | 2222 | else |
2228 | nextTbtt = bs->bs_nexttbtt; | 2223 | nextTbtt = bs->bs_nexttbtt; |
2229 | 2224 | ||
2230 | ath_dbg(common, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim); | 2225 | ath_dbg(common, BEACON, "next DTIM %d\n", bs->bs_nextdtim); |
2231 | ath_dbg(common, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt); | 2226 | ath_dbg(common, BEACON, "next beacon %d\n", nextTbtt); |
2232 | ath_dbg(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); | 2227 | ath_dbg(common, BEACON, "beacon period %d\n", beaconintval); |
2233 | ath_dbg(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); | 2228 | ath_dbg(common, BEACON, "DTIM period %d\n", dtimperiod); |
2234 | 2229 | ||
2235 | ENABLE_REGWRITE_BUFFER(ah); | 2230 | ENABLE_REGWRITE_BUFFER(ah); |
2236 | 2231 | ||
@@ -2322,8 +2317,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2322 | regulatory->current_rd += 5; | 2317 | regulatory->current_rd += 5; |
2323 | else if (regulatory->current_rd == 0x41) | 2318 | else if (regulatory->current_rd == 0x41) |
2324 | regulatory->current_rd = 0x43; | 2319 | regulatory->current_rd = 0x43; |
2325 | ath_dbg(common, ATH_DBG_REGULATORY, | 2320 | ath_dbg(common, REGULATORY, "regdomain mapped to 0x%x\n", |
2326 | "regdomain mapped to 0x%x\n", regulatory->current_rd); | 2321 | regulatory->current_rd); |
2327 | } | 2322 | } |
2328 | 2323 | ||
2329 | eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); | 2324 | eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); |
@@ -2848,7 +2843,7 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah) | |||
2848 | { | 2843 | { |
2849 | if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0, | 2844 | if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0, |
2850 | AH_TSF_WRITE_TIMEOUT)) | 2845 | AH_TSF_WRITE_TIMEOUT)) |
2851 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, | 2846 | ath_dbg(ath9k_hw_common(ah), RESET, |
2852 | "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); | 2847 | "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n"); |
2853 | 2848 | ||
2854 | REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); | 2849 | REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); |
@@ -2973,7 +2968,7 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, | |||
2973 | 2968 | ||
2974 | timer_next = tsf + trig_timeout; | 2969 | timer_next = tsf + trig_timeout; |
2975 | 2970 | ||
2976 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, | 2971 | ath_dbg(ath9k_hw_common(ah), HWTIMER, |
2977 | "current tsf %x period %x timer_next %x\n", | 2972 | "current tsf %x period %x timer_next %x\n", |
2978 | tsf, timer_period, timer_next); | 2973 | tsf, timer_period, timer_next); |
2979 | 2974 | ||
@@ -3062,8 +3057,8 @@ void ath_gen_timer_isr(struct ath_hw *ah) | |||
3062 | index = rightmost_index(timer_table, &thresh_mask); | 3057 | index = rightmost_index(timer_table, &thresh_mask); |
3063 | timer = timer_table->timers[index]; | 3058 | timer = timer_table->timers[index]; |
3064 | BUG_ON(!timer); | 3059 | BUG_ON(!timer); |
3065 | ath_dbg(common, ATH_DBG_HWTIMER, | 3060 | ath_dbg(common, HWTIMER, "TSF overflow for Gen timer %d\n", |
3066 | "TSF overflow for Gen timer %d\n", index); | 3061 | index); |
3067 | timer->overflow(timer->arg); | 3062 | timer->overflow(timer->arg); |
3068 | } | 3063 | } |
3069 | 3064 | ||
@@ -3071,7 +3066,7 @@ void ath_gen_timer_isr(struct ath_hw *ah) | |||
3071 | index = rightmost_index(timer_table, &trigger_mask); | 3066 | index = rightmost_index(timer_table, &trigger_mask); |
3072 | timer = timer_table->timers[index]; | 3067 | timer = timer_table->timers[index]; |
3073 | BUG_ON(!timer); | 3068 | BUG_ON(!timer); |
3074 | ath_dbg(common, ATH_DBG_HWTIMER, | 3069 | ath_dbg(common, HWTIMER, |
3075 | "Gen timer[%d] trigger\n", index); | 3070 | "Gen timer[%d] trigger\n", index); |
3076 | timer->trigger(timer->arg); | 3071 | timer->trigger(timer->arg); |
3077 | } | 3072 | } |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 615cc839f0de..48205c2960b5 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -209,7 +209,11 @@ enum ath9k_hw_caps { | |||
209 | ATH9K_HW_CAP_5GHZ = BIT(12), | 209 | ATH9K_HW_CAP_5GHZ = BIT(12), |
210 | ATH9K_HW_CAP_APM = BIT(13), | 210 | ATH9K_HW_CAP_APM = BIT(13), |
211 | ATH9K_HW_CAP_RTT = BIT(14), | 211 | ATH9K_HW_CAP_RTT = BIT(14), |
212 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | ||
212 | ATH9K_HW_CAP_MCI = BIT(15), | 213 | ATH9K_HW_CAP_MCI = BIT(15), |
214 | #else | ||
215 | ATH9K_HW_CAP_MCI = 0, | ||
216 | #endif | ||
213 | ATH9K_HW_CAP_DFS = BIT(16), | 217 | ATH9K_HW_CAP_DFS = BIT(16), |
214 | }; | 218 | }; |
215 | 219 | ||
@@ -1228,6 +1232,16 @@ void ar9003_mci_sync_bt_state(struct ath_hw *ah); | |||
1228 | void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, | 1232 | void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, |
1229 | u32 *rx_msg_intr); | 1233 | u32 *rx_msg_intr); |
1230 | 1234 | ||
1235 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | ||
1236 | static inline enum ath_btcoex_scheme | ||
1237 | ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) | ||
1238 | { | ||
1239 | return ah->btcoex_hw.scheme; | ||
1240 | } | ||
1241 | #else | ||
1242 | #define ath9k_hw_get_btcoex_scheme(...) ATH_BTCOEX_CFG_NONE | ||
1243 | #endif | ||
1244 | |||
1231 | #define ATH9K_CLOCK_RATE_CCK 22 | 1245 | #define ATH9K_CLOCK_RATE_CCK 22 |
1232 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 | 1246 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 |
1233 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 | 1247 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index c5df98139c4d..abf943557dee 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -276,8 +276,7 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
276 | tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams); | 276 | tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams); |
277 | rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams); | 277 | rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams); |
278 | 278 | ||
279 | ath_dbg(common, ATH_DBG_CONFIG, | 279 | ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n", |
280 | "TX streams %d, RX streams: %d\n", | ||
281 | tx_streams, rx_streams); | 280 | tx_streams, rx_streams); |
282 | 281 | ||
283 | if (tx_streams != rx_streams) { | 282 | if (tx_streams != rx_streams) { |
@@ -329,7 +328,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
329 | struct ath_buf *bf; | 328 | struct ath_buf *bf; |
330 | int i, bsize, error, desc_len; | 329 | int i, bsize, error, desc_len; |
331 | 330 | ||
332 | ath_dbg(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | 331 | ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n", |
333 | name, nbuf, ndesc); | 332 | name, nbuf, ndesc); |
334 | 333 | ||
335 | INIT_LIST_HEAD(head); | 334 | INIT_LIST_HEAD(head); |
@@ -375,7 +374,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
375 | goto fail; | 374 | goto fail; |
376 | } | 375 | } |
377 | ds = (u8 *) dd->dd_desc; | 376 | ds = (u8 *) dd->dd_desc; |
378 | ath_dbg(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | 377 | ath_dbg(common, CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", |
379 | name, ds, (u32) dd->dd_desc_len, | 378 | name, ds, (u32) dd->dd_desc_len, |
380 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | 379 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); |
381 | 380 | ||
@@ -426,7 +425,7 @@ static int ath9k_init_btcoex(struct ath_softc *sc) | |||
426 | struct ath_hw *ah = sc->sc_ah; | 425 | struct ath_hw *ah = sc->sc_ah; |
427 | int r; | 426 | int r; |
428 | 427 | ||
429 | switch (sc->sc_ah->btcoex_hw.scheme) { | 428 | switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) { |
430 | case ATH_BTCOEX_CFG_NONE: | 429 | case ATH_BTCOEX_CFG_NONE: |
431 | break; | 430 | break; |
432 | case ATH_BTCOEX_CFG_2WIRE: | 431 | case ATH_BTCOEX_CFG_2WIRE: |
@@ -881,10 +880,10 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
881 | kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); | 880 | kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); |
882 | 881 | ||
883 | if ((sc->btcoex.no_stomp_timer) && | 882 | if ((sc->btcoex.no_stomp_timer) && |
884 | sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 883 | ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE) |
885 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); | 884 | ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); |
886 | 885 | ||
887 | if (sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_MCI) | 886 | if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI) |
888 | ath_mci_cleanup(sc); | 887 | ath_mci_cleanup(sc); |
889 | 888 | ||
890 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 889 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 0e4fbb3bea33..fd3f19c2e550 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -21,7 +21,7 @@ | |||
21 | static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, | 21 | static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, |
22 | struct ath9k_tx_queue_info *qi) | 22 | struct ath9k_tx_queue_info *qi) |
23 | { | 23 | { |
24 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_INTERRUPT, | 24 | ath_dbg(ath9k_hw_common(ah), INTERRUPT, |
25 | "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", | 25 | "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", |
26 | ah->txok_interrupt_mask, ah->txerr_interrupt_mask, | 26 | ah->txok_interrupt_mask, ah->txerr_interrupt_mask, |
27 | ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, | 27 | ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, |
@@ -57,8 +57,7 @@ EXPORT_SYMBOL(ath9k_hw_puttxbuf); | |||
57 | 57 | ||
58 | void ath9k_hw_txstart(struct ath_hw *ah, u32 q) | 58 | void ath9k_hw_txstart(struct ath_hw *ah, u32 q) |
59 | { | 59 | { |
60 | ath_dbg(ath9k_hw_common(ah), ATH_DBG_QUEUE, | 60 | ath_dbg(ath9k_hw_common(ah), QUEUE, "Enable TXE on queue: %u\n", q); |
61 | "Enable TXE on queue: %u\n", q); | ||
62 | REG_WRITE(ah, AR_Q_TXE, 1 << q); | 61 | REG_WRITE(ah, AR_Q_TXE, 1 << q); |
63 | } | 62 | } |
64 | EXPORT_SYMBOL(ath9k_hw_txstart); | 63 | EXPORT_SYMBOL(ath9k_hw_txstart); |
@@ -202,12 +201,12 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, | |||
202 | 201 | ||
203 | qi = &ah->txq[q]; | 202 | qi = &ah->txq[q]; |
204 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 203 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
205 | ath_dbg(common, ATH_DBG_QUEUE, | 204 | ath_dbg(common, QUEUE, |
206 | "Set TXQ properties, inactive queue: %u\n", q); | 205 | "Set TXQ properties, inactive queue: %u\n", q); |
207 | return false; | 206 | return false; |
208 | } | 207 | } |
209 | 208 | ||
210 | ath_dbg(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q); | 209 | ath_dbg(common, QUEUE, "Set queue properties for: %u\n", q); |
211 | 210 | ||
212 | qi->tqi_ver = qinfo->tqi_ver; | 211 | qi->tqi_ver = qinfo->tqi_ver; |
213 | qi->tqi_subtype = qinfo->tqi_subtype; | 212 | qi->tqi_subtype = qinfo->tqi_subtype; |
@@ -266,7 +265,7 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, | |||
266 | 265 | ||
267 | qi = &ah->txq[q]; | 266 | qi = &ah->txq[q]; |
268 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 267 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
269 | ath_dbg(common, ATH_DBG_QUEUE, | 268 | ath_dbg(common, QUEUE, |
270 | "Get TXQ properties, inactive queue: %u\n", q); | 269 | "Get TXQ properties, inactive queue: %u\n", q); |
271 | return false; | 270 | return false; |
272 | } | 271 | } |
@@ -325,7 +324,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, | |||
325 | return -1; | 324 | return -1; |
326 | } | 325 | } |
327 | 326 | ||
328 | ath_dbg(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q); | 327 | ath_dbg(common, QUEUE, "Setup TX queue: %u\n", q); |
329 | 328 | ||
330 | qi = &ah->txq[q]; | 329 | qi = &ah->txq[q]; |
331 | if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { | 330 | if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { |
@@ -348,12 +347,11 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) | |||
348 | 347 | ||
349 | qi = &ah->txq[q]; | 348 | qi = &ah->txq[q]; |
350 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 349 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
351 | ath_dbg(common, ATH_DBG_QUEUE, | 350 | ath_dbg(common, QUEUE, "Release TXQ, inactive queue: %u\n", q); |
352 | "Release TXQ, inactive queue: %u\n", q); | ||
353 | return false; | 351 | return false; |
354 | } | 352 | } |
355 | 353 | ||
356 | ath_dbg(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q); | 354 | ath_dbg(common, QUEUE, "Release TX queue: %u\n", q); |
357 | 355 | ||
358 | qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; | 356 | qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; |
359 | ah->txok_interrupt_mask &= ~(1 << q); | 357 | ah->txok_interrupt_mask &= ~(1 << q); |
@@ -376,12 +374,11 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
376 | 374 | ||
377 | qi = &ah->txq[q]; | 375 | qi = &ah->txq[q]; |
378 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | 376 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { |
379 | ath_dbg(common, ATH_DBG_QUEUE, | 377 | ath_dbg(common, QUEUE, "Reset TXQ, inactive queue: %u\n", q); |
380 | "Reset TXQ, inactive queue: %u\n", q); | ||
381 | return true; | 378 | return true; |
382 | } | 379 | } |
383 | 380 | ||
384 | ath_dbg(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q); | 381 | ath_dbg(common, QUEUE, "Reset TX queue: %u\n", q); |
385 | 382 | ||
386 | if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { | 383 | if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { |
387 | if (chan && IS_CHAN_B(chan)) | 384 | if (chan && IS_CHAN_B(chan)) |
@@ -784,7 +781,7 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah) | |||
784 | else | 781 | else |
785 | atomic_dec(&ah->intr_ref_cnt); | 782 | atomic_dec(&ah->intr_ref_cnt); |
786 | 783 | ||
787 | ath_dbg(common, ATH_DBG_INTERRUPT, "disable IER\n"); | 784 | ath_dbg(common, INTERRUPT, "disable IER\n"); |
788 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); | 785 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); |
789 | (void) REG_READ(ah, AR_IER); | 786 | (void) REG_READ(ah, AR_IER); |
790 | if (!AR_SREV_9100(ah)) { | 787 | if (!AR_SREV_9100(ah)) { |
@@ -807,8 +804,7 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) | |||
807 | return; | 804 | return; |
808 | 805 | ||
809 | if (!atomic_inc_and_test(&ah->intr_ref_cnt)) { | 806 | if (!atomic_inc_and_test(&ah->intr_ref_cnt)) { |
810 | ath_dbg(common, ATH_DBG_INTERRUPT, | 807 | ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n", |
811 | "Do not enable IER ref count %d\n", | ||
812 | atomic_read(&ah->intr_ref_cnt)); | 808 | atomic_read(&ah->intr_ref_cnt)); |
813 | return; | 809 | return; |
814 | } | 810 | } |
@@ -821,7 +817,7 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) | |||
821 | if (ah->imask & ATH9K_INT_MCI) | 817 | if (ah->imask & ATH9K_INT_MCI) |
822 | async_mask |= AR_INTR_ASYNC_MASK_MCI; | 818 | async_mask |= AR_INTR_ASYNC_MASK_MCI; |
823 | 819 | ||
824 | ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n"); | 820 | ath_dbg(common, INTERRUPT, "enable IER\n"); |
825 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | 821 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); |
826 | if (!AR_SREV_9100(ah)) { | 822 | if (!AR_SREV_9100(ah)) { |
827 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, async_mask); | 823 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, async_mask); |
@@ -830,7 +826,7 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) | |||
830 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); | 826 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); |
831 | REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default); | 827 | REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default); |
832 | } | 828 | } |
833 | ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", | 829 | ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", |
834 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); | 830 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); |
835 | } | 831 | } |
836 | EXPORT_SYMBOL(ath9k_hw_enable_interrupts); | 832 | EXPORT_SYMBOL(ath9k_hw_enable_interrupts); |
@@ -845,7 +841,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah) | |||
845 | if (!(ints & ATH9K_INT_GLOBAL)) | 841 | if (!(ints & ATH9K_INT_GLOBAL)) |
846 | ath9k_hw_disable_interrupts(ah); | 842 | ath9k_hw_disable_interrupts(ah); |
847 | 843 | ||
848 | ath_dbg(common, ATH_DBG_INTERRUPT, "New interrupt mask 0x%x\n", ints); | 844 | ath_dbg(common, INTERRUPT, "New interrupt mask 0x%x\n", ints); |
849 | 845 | ||
850 | mask = ints & ATH9K_INT_COMMON; | 846 | mask = ints & ATH9K_INT_COMMON; |
851 | mask2 = 0; | 847 | mask2 = 0; |
@@ -908,7 +904,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah) | |||
908 | mask2 |= AR_IMR_S2_CST; | 904 | mask2 |= AR_IMR_S2_CST; |
909 | } | 905 | } |
910 | 906 | ||
911 | ath_dbg(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); | 907 | ath_dbg(common, INTERRUPT, "new IMR 0x%x\n", mask); |
912 | REG_WRITE(ah, AR_IMR, mask); | 908 | REG_WRITE(ah, AR_IMR, mask); |
913 | ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | | 909 | ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | |
914 | AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | | 910 | AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 7fbc4bdd4efe..6e3d8384e081 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -339,8 +339,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
339 | if (!ath_prepare_reset(sc, retry_tx, flush)) | 339 | if (!ath_prepare_reset(sc, retry_tx, flush)) |
340 | fastcc = false; | 340 | fastcc = false; |
341 | 341 | ||
342 | ath_dbg(common, ATH_DBG_CONFIG, | 342 | ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", |
343 | "Reset to %u MHz, HT40: %d fastcc: %d\n", | ||
344 | hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS | | 343 | hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS | |
345 | CHANNEL_HT40PLUS)), | 344 | CHANNEL_HT40PLUS)), |
346 | fastcc); | 345 | fastcc); |
@@ -429,7 +428,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
429 | txctl.paprd = BIT(chain); | 428 | txctl.paprd = BIT(chain); |
430 | 429 | ||
431 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 430 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
432 | ath_dbg(common, ATH_DBG_CALIBRATE, "PAPRD TX failed\n"); | 431 | ath_dbg(common, CALIBRATE, "PAPRD TX failed\n"); |
433 | dev_kfree_skb_any(skb); | 432 | dev_kfree_skb_any(skb); |
434 | return false; | 433 | return false; |
435 | } | 434 | } |
@@ -438,7 +437,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
438 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | 437 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); |
439 | 438 | ||
440 | if (!time_left) | 439 | if (!time_left) |
441 | ath_dbg(common, ATH_DBG_CALIBRATE, | 440 | ath_dbg(common, CALIBRATE, |
442 | "Timeout waiting for paprd training on TX chain %d\n", | 441 | "Timeout waiting for paprd training on TX chain %d\n", |
443 | chain); | 442 | chain); |
444 | 443 | ||
@@ -487,27 +486,27 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
487 | 486 | ||
488 | chain_ok = 0; | 487 | chain_ok = 0; |
489 | 488 | ||
490 | ath_dbg(common, ATH_DBG_CALIBRATE, | 489 | ath_dbg(common, CALIBRATE, |
491 | "Sending PAPRD frame for thermal measurement " | 490 | "Sending PAPRD frame for thermal measurement on chain %d\n", |
492 | "on chain %d\n", chain); | 491 | chain); |
493 | if (!ath_paprd_send_frame(sc, skb, chain)) | 492 | if (!ath_paprd_send_frame(sc, skb, chain)) |
494 | goto fail_paprd; | 493 | goto fail_paprd; |
495 | 494 | ||
496 | ar9003_paprd_setup_gain_table(ah, chain); | 495 | ar9003_paprd_setup_gain_table(ah, chain); |
497 | 496 | ||
498 | ath_dbg(common, ATH_DBG_CALIBRATE, | 497 | ath_dbg(common, CALIBRATE, |
499 | "Sending PAPRD training frame on chain %d\n", chain); | 498 | "Sending PAPRD training frame on chain %d\n", chain); |
500 | if (!ath_paprd_send_frame(sc, skb, chain)) | 499 | if (!ath_paprd_send_frame(sc, skb, chain)) |
501 | goto fail_paprd; | 500 | goto fail_paprd; |
502 | 501 | ||
503 | if (!ar9003_paprd_is_done(ah)) { | 502 | if (!ar9003_paprd_is_done(ah)) { |
504 | ath_dbg(common, ATH_DBG_CALIBRATE, | 503 | ath_dbg(common, CALIBRATE, |
505 | "PAPRD not yet done on chain %d\n", chain); | 504 | "PAPRD not yet done on chain %d\n", chain); |
506 | break; | 505 | break; |
507 | } | 506 | } |
508 | 507 | ||
509 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | 508 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { |
510 | ath_dbg(common, ATH_DBG_CALIBRATE, | 509 | ath_dbg(common, CALIBRATE, |
511 | "PAPRD create curve failed on chain %d\n", | 510 | "PAPRD create curve failed on chain %d\n", |
512 | chain); | 511 | chain); |
513 | break; | 512 | break; |
@@ -604,8 +603,9 @@ void ath_ani_calibrate(unsigned long data) | |||
604 | ah->rxchainmask, longcal); | 603 | ah->rxchainmask, longcal); |
605 | } | 604 | } |
606 | 605 | ||
607 | ath_dbg(common, ATH_DBG_ANI, | 606 | ath_dbg(common, ANI, |
608 | "Calibration @%lu finished: %s %s %s, caldone: %s\n", jiffies, | 607 | "Calibration @%lu finished: %s %s %s, caldone: %s\n", |
608 | jiffies, | ||
609 | longcal ? "long" : "", shortcal ? "short" : "", | 609 | longcal ? "long" : "", shortcal ? "short" : "", |
610 | aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); | 610 | aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); |
611 | 611 | ||
@@ -715,8 +715,7 @@ void ath9k_tasklet(unsigned long data) | |||
715 | * TSF sync does not look correct; remain awake to sync with | 715 | * TSF sync does not look correct; remain awake to sync with |
716 | * the next Beacon. | 716 | * the next Beacon. |
717 | */ | 717 | */ |
718 | ath_dbg(common, ATH_DBG_PS, | 718 | ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n"); |
719 | "TSFOOR - Sync with next Beacon\n"); | ||
720 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; | 719 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; |
721 | } | 720 | } |
722 | 721 | ||
@@ -742,11 +741,11 @@ void ath9k_tasklet(unsigned long data) | |||
742 | ath_tx_tasklet(sc); | 741 | ath_tx_tasklet(sc); |
743 | } | 742 | } |
744 | 743 | ||
745 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 744 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) |
746 | if (status & ATH9K_INT_GENTIMER) | 745 | if (status & ATH9K_INT_GENTIMER) |
747 | ath_gen_timer_isr(sc->sc_ah); | 746 | ath_gen_timer_isr(sc->sc_ah); |
748 | 747 | ||
749 | if (status & ATH9K_INT_MCI) | 748 | if ((status & ATH9K_INT_MCI) && ATH9K_HW_CAP_MCI) |
750 | ath_mci_intr(sc); | 749 | ath_mci_intr(sc); |
751 | 750 | ||
752 | out: | 751 | out: |
@@ -936,8 +935,8 @@ void ath_hw_check(struct work_struct *work) | |||
936 | busy = ath_update_survey_stats(sc); | 935 | busy = ath_update_survey_stats(sc); |
937 | spin_unlock_irqrestore(&common->cc_lock, flags); | 936 | spin_unlock_irqrestore(&common->cc_lock, flags); |
938 | 937 | ||
939 | ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " | 938 | ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n", |
940 | "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); | 939 | busy, sc->hw_busy_count + 1); |
941 | if (busy >= 99) { | 940 | if (busy >= 99) { |
942 | if (++sc->hw_busy_count >= 3) { | 941 | if (++sc->hw_busy_count >= 3) { |
943 | RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); | 942 | RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); |
@@ -960,8 +959,7 @@ static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | |||
960 | count++; | 959 | count++; |
961 | if (count == 3) { | 960 | if (count == 3) { |
962 | /* Rx is hung for more than 500ms. Reset it */ | 961 | /* Rx is hung for more than 500ms. Reset it */ |
963 | ath_dbg(common, ATH_DBG_RESET, | 962 | ath_dbg(common, RESET, "Possible RX hang, resetting\n"); |
964 | "Possible RX hang, resetting"); | ||
965 | RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); | 963 | RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); |
966 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 964 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
967 | count = 0; | 965 | count = 0; |
@@ -1001,7 +999,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1001 | struct ath9k_channel *init_channel; | 999 | struct ath9k_channel *init_channel; |
1002 | int r; | 1000 | int r; |
1003 | 1001 | ||
1004 | ath_dbg(common, ATH_DBG_CONFIG, | 1002 | ath_dbg(common, CONFIG, |
1005 | "Starting driver with initial channel: %d MHz\n", | 1003 | "Starting driver with initial channel: %d MHz\n", |
1006 | curchan->center_freq); | 1004 | curchan->center_freq); |
1007 | 1005 | ||
@@ -1083,14 +1081,14 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1083 | 1081 | ||
1084 | spin_unlock_bh(&sc->sc_pcu_lock); | 1082 | spin_unlock_bh(&sc->sc_pcu_lock); |
1085 | 1083 | ||
1086 | if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && | 1084 | if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && |
1087 | !ah->btcoex_hw.enabled) { | 1085 | !ah->btcoex_hw.enabled) { |
1088 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) | 1086 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
1089 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | 1087 | ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, |
1090 | AR_STOMP_LOW_WLAN_WGHT); | 1088 | AR_STOMP_LOW_WLAN_WGHT); |
1091 | ath9k_hw_btcoex_enable(ah); | 1089 | ath9k_hw_btcoex_enable(ah); |
1092 | 1090 | ||
1093 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 1091 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) |
1094 | ath9k_btcoex_timer_resume(sc); | 1092 | ath9k_btcoex_timer_resume(sc); |
1095 | } | 1093 | } |
1096 | 1094 | ||
@@ -1120,7 +1118,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1120 | if (ieee80211_is_data(hdr->frame_control) && | 1118 | if (ieee80211_is_data(hdr->frame_control) && |
1121 | !ieee80211_is_nullfunc(hdr->frame_control) && | 1119 | !ieee80211_is_nullfunc(hdr->frame_control) && |
1122 | !ieee80211_has_pm(hdr->frame_control)) { | 1120 | !ieee80211_has_pm(hdr->frame_control)) { |
1123 | ath_dbg(common, ATH_DBG_PS, | 1121 | ath_dbg(common, PS, |
1124 | "Add PM=1 for a TX frame while in PS mode\n"); | 1122 | "Add PM=1 for a TX frame while in PS mode\n"); |
1125 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | 1123 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); |
1126 | } | 1124 | } |
@@ -1143,12 +1141,11 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1143 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | 1141 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) |
1144 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 1142 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
1145 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 1143 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
1146 | ath_dbg(common, ATH_DBG_PS, | 1144 | ath_dbg(common, PS, |
1147 | "Sending PS-Poll to pick a buffered frame\n"); | 1145 | "Sending PS-Poll to pick a buffered frame\n"); |
1148 | sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA; | 1146 | sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA; |
1149 | } else { | 1147 | } else { |
1150 | ath_dbg(common, ATH_DBG_PS, | 1148 | ath_dbg(common, PS, "Wake up to complete TX\n"); |
1151 | "Wake up to complete TX\n"); | ||
1152 | sc->ps_flags |= PS_WAIT_FOR_TX_ACK; | 1149 | sc->ps_flags |= PS_WAIT_FOR_TX_ACK; |
1153 | } | 1150 | } |
1154 | /* | 1151 | /* |
@@ -1162,10 +1159,10 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1162 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | 1159 | memset(&txctl, 0, sizeof(struct ath_tx_control)); |
1163 | txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; | 1160 | txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; |
1164 | 1161 | ||
1165 | ath_dbg(common, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb); | 1162 | ath_dbg(common, XMIT, "transmitting packet, skb: %p\n", skb); |
1166 | 1163 | ||
1167 | if (ath_tx_start(hw, skb, &txctl) != 0) { | 1164 | if (ath_tx_start(hw, skb, &txctl) != 0) { |
1168 | ath_dbg(common, ATH_DBG_XMIT, "TX failed\n"); | 1165 | ath_dbg(common, XMIT, "TX failed\n"); |
1169 | goto exit; | 1166 | goto exit; |
1170 | } | 1167 | } |
1171 | 1168 | ||
@@ -1186,7 +1183,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1186 | ath_cancel_work(sc); | 1183 | ath_cancel_work(sc); |
1187 | 1184 | ||
1188 | if (sc->sc_flags & SC_OP_INVALID) { | 1185 | if (sc->sc_flags & SC_OP_INVALID) { |
1189 | ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); | 1186 | ath_dbg(common, ANY, "Device not present\n"); |
1190 | mutex_unlock(&sc->mutex); | 1187 | mutex_unlock(&sc->mutex); |
1191 | return; | 1188 | return; |
1192 | } | 1189 | } |
@@ -1194,9 +1191,10 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1194 | /* Ensure HW is awake when we try to shut it down. */ | 1191 | /* Ensure HW is awake when we try to shut it down. */ |
1195 | ath9k_ps_wakeup(sc); | 1192 | ath9k_ps_wakeup(sc); |
1196 | 1193 | ||
1197 | if (ah->btcoex_hw.enabled) { | 1194 | if (ah->btcoex_hw.enabled && |
1195 | ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { | ||
1198 | ath9k_hw_btcoex_disable(ah); | 1196 | ath9k_hw_btcoex_disable(ah); |
1199 | if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) | 1197 | if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) |
1200 | ath9k_btcoex_timer_pause(sc); | 1198 | ath9k_btcoex_timer_pause(sc); |
1201 | ath_mci_flush_profile(&sc->btcoex.mci); | 1199 | ath_mci_flush_profile(&sc->btcoex.mci); |
1202 | } | 1200 | } |
@@ -1252,7 +1250,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1252 | 1250 | ||
1253 | mutex_unlock(&sc->mutex); | 1251 | mutex_unlock(&sc->mutex); |
1254 | 1252 | ||
1255 | ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); | 1253 | ath_dbg(common, CONFIG, "Driver halt\n"); |
1256 | } | 1254 | } |
1257 | 1255 | ||
1258 | bool ath9k_uses_beacons(int type) | 1256 | bool ath9k_uses_beacons(int type) |
@@ -1467,8 +1465,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1467 | goto out; | 1465 | goto out; |
1468 | } | 1466 | } |
1469 | 1467 | ||
1470 | ath_dbg(common, ATH_DBG_CONFIG, | 1468 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); |
1471 | "Attach a VIF of type: %d\n", vif->type); | ||
1472 | 1469 | ||
1473 | sc->nvifs++; | 1470 | sc->nvifs++; |
1474 | 1471 | ||
@@ -1488,7 +1485,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, | |||
1488 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1485 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1489 | int ret = 0; | 1486 | int ret = 0; |
1490 | 1487 | ||
1491 | ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n"); | 1488 | ath_dbg(common, CONFIG, "Change Interface\n"); |
1492 | mutex_lock(&sc->mutex); | 1489 | mutex_lock(&sc->mutex); |
1493 | ath9k_ps_wakeup(sc); | 1490 | ath9k_ps_wakeup(sc); |
1494 | 1491 | ||
@@ -1531,7 +1528,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1531 | struct ath_softc *sc = hw->priv; | 1528 | struct ath_softc *sc = hw->priv; |
1532 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1529 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1533 | 1530 | ||
1534 | ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1531 | ath_dbg(common, CONFIG, "Detach Interface\n"); |
1535 | 1532 | ||
1536 | ath9k_ps_wakeup(sc); | 1533 | ath9k_ps_wakeup(sc); |
1537 | mutex_lock(&sc->mutex); | 1534 | mutex_lock(&sc->mutex); |
@@ -1622,12 +1619,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1622 | 1619 | ||
1623 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | 1620 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { |
1624 | if (conf->flags & IEEE80211_CONF_MONITOR) { | 1621 | if (conf->flags & IEEE80211_CONF_MONITOR) { |
1625 | ath_dbg(common, ATH_DBG_CONFIG, | 1622 | ath_dbg(common, CONFIG, "Monitor mode is enabled\n"); |
1626 | "Monitor mode is enabled\n"); | ||
1627 | sc->sc_ah->is_monitoring = true; | 1623 | sc->sc_ah->is_monitoring = true; |
1628 | } else { | 1624 | } else { |
1629 | ath_dbg(common, ATH_DBG_CONFIG, | 1625 | ath_dbg(common, CONFIG, "Monitor mode is disabled\n"); |
1630 | "Monitor mode is disabled\n"); | ||
1631 | sc->sc_ah->is_monitoring = false; | 1626 | sc->sc_ah->is_monitoring = false; |
1632 | } | 1627 | } |
1633 | } | 1628 | } |
@@ -1647,8 +1642,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1647 | else | 1642 | else |
1648 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; | 1643 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; |
1649 | 1644 | ||
1650 | ath_dbg(common, ATH_DBG_CONFIG, | 1645 | ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", |
1651 | "Set channel: %d MHz type: %d\n", | ||
1652 | curchan->center_freq, conf->channel_type); | 1646 | curchan->center_freq, conf->channel_type); |
1653 | 1647 | ||
1654 | /* update survey stats for the old channel before switching */ | 1648 | /* update survey stats for the old channel before switching */ |
@@ -1705,8 +1699,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1705 | } | 1699 | } |
1706 | 1700 | ||
1707 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 1701 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
1708 | ath_dbg(common, ATH_DBG_CONFIG, | 1702 | ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level); |
1709 | "Set power: %d\n", conf->power_level); | ||
1710 | sc->config.txpowlimit = 2 * conf->power_level; | 1703 | sc->config.txpowlimit = 2 * conf->power_level; |
1711 | ath9k_cmn_update_txpow(ah, sc->curtxpow, | 1704 | ath9k_cmn_update_txpow(ah, sc->curtxpow, |
1712 | sc->config.txpowlimit, &sc->curtxpow); | 1705 | sc->config.txpowlimit, &sc->curtxpow); |
@@ -1746,8 +1739,8 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
1746 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); | 1739 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); |
1747 | ath9k_ps_restore(sc); | 1740 | ath9k_ps_restore(sc); |
1748 | 1741 | ||
1749 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, | 1742 | ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG, "Set HW RX filter: 0x%x\n", |
1750 | "Set HW RX filter: 0x%x\n", rfilt); | 1743 | rfilt); |
1751 | } | 1744 | } |
1752 | 1745 | ||
1753 | static int ath9k_sta_add(struct ieee80211_hw *hw, | 1746 | static int ath9k_sta_add(struct ieee80211_hw *hw, |
@@ -1841,7 +1834,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
1841 | qi.tqi_cwmax = params->cw_max; | 1834 | qi.tqi_cwmax = params->cw_max; |
1842 | qi.tqi_burstTime = params->txop; | 1835 | qi.tqi_burstTime = params->txop; |
1843 | 1836 | ||
1844 | ath_dbg(common, ATH_DBG_CONFIG, | 1837 | ath_dbg(common, CONFIG, |
1845 | "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | 1838 | "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", |
1846 | queue, txq->axq_qnum, params->aifs, params->cw_min, | 1839 | queue, txq->axq_qnum, params->aifs, params->cw_min, |
1847 | params->cw_max, params->txop); | 1840 | params->cw_max, params->txop); |
@@ -1890,7 +1883,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1890 | 1883 | ||
1891 | mutex_lock(&sc->mutex); | 1884 | mutex_lock(&sc->mutex); |
1892 | ath9k_ps_wakeup(sc); | 1885 | ath9k_ps_wakeup(sc); |
1893 | ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n"); | 1886 | ath_dbg(common, CONFIG, "Set HW Key\n"); |
1894 | 1887 | ||
1895 | switch (cmd) { | 1888 | switch (cmd) { |
1896 | case SET_KEY: | 1889 | case SET_KEY: |
@@ -1942,9 +1935,8 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1942 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1935 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1943 | common->curaid = bss_conf->aid; | 1936 | common->curaid = bss_conf->aid; |
1944 | ath9k_hw_write_associd(sc->sc_ah); | 1937 | ath9k_hw_write_associd(sc->sc_ah); |
1945 | ath_dbg(common, ATH_DBG_CONFIG, | 1938 | ath_dbg(common, CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", |
1946 | "Bss Info ASSOC %d, bssid: %pM\n", | 1939 | bss_conf->aid, common->curbssid); |
1947 | bss_conf->aid, common->curbssid); | ||
1948 | ath_beacon_config(sc, vif); | 1940 | ath_beacon_config(sc, vif); |
1949 | /* | 1941 | /* |
1950 | * Request a re-configuration of Beacon related timers | 1942 | * Request a re-configuration of Beacon related timers |
@@ -1975,8 +1967,7 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
1975 | 1967 | ||
1976 | /* Reconfigure bss info */ | 1968 | /* Reconfigure bss info */ |
1977 | if (avp->primary_sta_vif && !bss_conf->assoc) { | 1969 | if (avp->primary_sta_vif && !bss_conf->assoc) { |
1978 | ath_dbg(common, ATH_DBG_CONFIG, | 1970 | ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n", |
1979 | "Bss Info DISASSOC %d, bssid %pM\n", | ||
1980 | common->curaid, common->curbssid); | 1971 | common->curaid, common->curbssid); |
1981 | sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS); | 1972 | sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS); |
1982 | avp->primary_sta_vif = false; | 1973 | avp->primary_sta_vif = false; |
@@ -2018,7 +2009,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2018 | if (changed & BSS_CHANGED_BSSID) { | 2009 | if (changed & BSS_CHANGED_BSSID) { |
2019 | ath9k_config_bss(sc, vif); | 2010 | ath9k_config_bss(sc, vif); |
2020 | 2011 | ||
2021 | ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", | 2012 | ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", |
2022 | common->curbssid, common->curaid); | 2013 | common->curbssid, common->curaid); |
2023 | } | 2014 | } |
2024 | 2015 | ||
@@ -2096,7 +2087,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2096 | } | 2087 | } |
2097 | 2088 | ||
2098 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | 2089 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { |
2099 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | 2090 | ath_dbg(common, CONFIG, "BSS Changed PREAMBLE %d\n", |
2100 | bss_conf->use_short_preamble); | 2091 | bss_conf->use_short_preamble); |
2101 | if (bss_conf->use_short_preamble) | 2092 | if (bss_conf->use_short_preamble) |
2102 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; | 2093 | sc->sc_flags |= SC_OP_PREAMBLE_SHORT; |
@@ -2105,7 +2096,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2105 | } | 2096 | } |
2106 | 2097 | ||
2107 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | 2098 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { |
2108 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", | 2099 | ath_dbg(common, CONFIG, "BSS Changed CTS PROT %d\n", |
2109 | bss_conf->use_cts_prot); | 2100 | bss_conf->use_cts_prot); |
2110 | if (bss_conf->use_cts_prot && | 2101 | if (bss_conf->use_cts_prot && |
2111 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) | 2102 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) |
@@ -2271,13 +2262,13 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2271 | cancel_delayed_work_sync(&sc->tx_complete_work); | 2262 | cancel_delayed_work_sync(&sc->tx_complete_work); |
2272 | 2263 | ||
2273 | if (ah->ah_flags & AH_UNPLUGGED) { | 2264 | if (ah->ah_flags & AH_UNPLUGGED) { |
2274 | ath_dbg(common, ATH_DBG_ANY, "Device has been unplugged!\n"); | 2265 | ath_dbg(common, ANY, "Device has been unplugged!\n"); |
2275 | mutex_unlock(&sc->mutex); | 2266 | mutex_unlock(&sc->mutex); |
2276 | return; | 2267 | return; |
2277 | } | 2268 | } |
2278 | 2269 | ||
2279 | if (sc->sc_flags & SC_OP_INVALID) { | 2270 | if (sc->sc_flags & SC_OP_INVALID) { |
2280 | ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); | 2271 | ath_dbg(common, ANY, "Device not present\n"); |
2281 | mutex_unlock(&sc->mutex); | 2272 | mutex_unlock(&sc->mutex); |
2282 | return; | 2273 | return; |
2283 | } | 2274 | } |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 691bf47906e2..fee8c6f0b251 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -43,14 +43,14 @@ static bool ath_mci_add_profile(struct ath_common *common, | |||
43 | 43 | ||
44 | if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && | 44 | if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && |
45 | (info->type == MCI_GPM_COEX_PROFILE_VOICE)) { | 45 | (info->type == MCI_GPM_COEX_PROFILE_VOICE)) { |
46 | ath_dbg(common, ATH_DBG_MCI, | 46 | ath_dbg(common, MCI, |
47 | "Too many SCO profile, failed to add new profile\n"); | 47 | "Too many SCO profile, failed to add new profile\n"); |
48 | return false; | 48 | return false; |
49 | } | 49 | } |
50 | 50 | ||
51 | if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) && | 51 | if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) && |
52 | (info->type != MCI_GPM_COEX_PROFILE_VOICE)) { | 52 | (info->type != MCI_GPM_COEX_PROFILE_VOICE)) { |
53 | ath_dbg(common, ATH_DBG_MCI, | 53 | ath_dbg(common, MCI, |
54 | "Too many ACL profile, failed to add new profile\n"); | 54 | "Too many ACL profile, failed to add new profile\n"); |
55 | return false; | 55 | return false; |
56 | } | 56 | } |
@@ -80,8 +80,7 @@ static void ath_mci_del_profile(struct ath_common *common, | |||
80 | entry = ath_mci_find_profile(mci, info); | 80 | entry = ath_mci_find_profile(mci, info); |
81 | 81 | ||
82 | if (!entry) { | 82 | if (!entry) { |
83 | ath_dbg(common, ATH_DBG_MCI, | 83 | ath_dbg(common, MCI, "Profile to be deleted not found\n"); |
84 | "Profile to be deleted not found\n"); | ||
85 | return; | 84 | return; |
86 | } | 85 | } |
87 | DEC_PROF(mci, entry); | 86 | DEC_PROF(mci, entry); |
@@ -132,30 +131,30 @@ static void ath_mci_update_scheme(struct ath_softc *sc) | |||
132 | list); | 131 | list); |
133 | if (mci->num_sco && info->T == 12) { | 132 | if (mci->num_sco && info->T == 12) { |
134 | mci->aggr_limit = 8; | 133 | mci->aggr_limit = 8; |
135 | ath_dbg(common, ATH_DBG_MCI, | 134 | ath_dbg(common, MCI, |
136 | "Single SCO, aggregation limit 2 ms\n"); | 135 | "Single SCO, aggregation limit 2 ms\n"); |
137 | } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) && | 136 | } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) && |
138 | !info->master) { | 137 | !info->master) { |
139 | btcoex->btcoex_period = 60; | 138 | btcoex->btcoex_period = 60; |
140 | ath_dbg(common, ATH_DBG_MCI, | 139 | ath_dbg(common, MCI, |
141 | "Single slave PAN/FTP, bt period 60 ms\n"); | 140 | "Single slave PAN/FTP, bt period 60 ms\n"); |
142 | } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) && | 141 | } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) && |
143 | (info->T > 0 && info->T < 50) && | 142 | (info->T > 0 && info->T < 50) && |
144 | (info->A > 1 || info->W > 1)) { | 143 | (info->A > 1 || info->W > 1)) { |
145 | btcoex->duty_cycle = 30; | 144 | btcoex->duty_cycle = 30; |
146 | mci->aggr_limit = 8; | 145 | mci->aggr_limit = 8; |
147 | ath_dbg(common, ATH_DBG_MCI, | 146 | ath_dbg(common, MCI, |
148 | "Multiple attempt/timeout single HID " | 147 | "Multiple attempt/timeout single HID " |
149 | "aggregation limit 2 ms dutycycle 30%%\n"); | 148 | "aggregation limit 2 ms dutycycle 30%%\n"); |
150 | } | 149 | } |
151 | } else if ((num_profile == 2) && (mci->num_hid == 2)) { | 150 | } else if ((num_profile == 2) && (mci->num_hid == 2)) { |
152 | btcoex->duty_cycle = 30; | 151 | btcoex->duty_cycle = 30; |
153 | mci->aggr_limit = 8; | 152 | mci->aggr_limit = 8; |
154 | ath_dbg(common, ATH_DBG_MCI, | 153 | ath_dbg(common, MCI, |
155 | "Two HIDs aggregation limit 2 ms dutycycle 30%%\n"); | 154 | "Two HIDs aggregation limit 2 ms dutycycle 30%%\n"); |
156 | } else if (num_profile > 3) { | 155 | } else if (num_profile > 3) { |
157 | mci->aggr_limit = 6; | 156 | mci->aggr_limit = 6; |
158 | ath_dbg(common, ATH_DBG_MCI, | 157 | ath_dbg(common, MCI, |
159 | "Three or more profiles aggregation limit 1.5 ms\n"); | 158 | "Three or more profiles aggregation limit 1.5 ms\n"); |
160 | } | 159 | } |
161 | 160 | ||
@@ -194,42 +193,41 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
194 | switch (opcode) { | 193 | switch (opcode) { |
195 | case MCI_GPM_BT_CAL_REQ: | 194 | case MCI_GPM_BT_CAL_REQ: |
196 | 195 | ||
197 | ath_dbg(common, ATH_DBG_MCI, "MCI received BT_CAL_REQ\n"); | 196 | ath_dbg(common, MCI, "MCI received BT_CAL_REQ\n"); |
198 | 197 | ||
199 | if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { | 198 | if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { |
200 | ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL); | 199 | ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL); |
201 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 200 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
202 | } else | 201 | } else |
203 | ath_dbg(common, ATH_DBG_MCI, | 202 | ath_dbg(common, MCI, "MCI State mismatches: %d\n", |
204 | "MCI State mismatches: %d\n", | ||
205 | ar9003_mci_state(ah, MCI_STATE_BT, NULL)); | 203 | ar9003_mci_state(ah, MCI_STATE_BT, NULL)); |
206 | 204 | ||
207 | break; | 205 | break; |
208 | 206 | ||
209 | case MCI_GPM_BT_CAL_DONE: | 207 | case MCI_GPM_BT_CAL_DONE: |
210 | 208 | ||
211 | ath_dbg(common, ATH_DBG_MCI, "MCI received BT_CAL_DONE\n"); | 209 | ath_dbg(common, MCI, "MCI received BT_CAL_DONE\n"); |
212 | 210 | ||
213 | if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_CAL) | 211 | if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_CAL) |
214 | ath_dbg(common, ATH_DBG_MCI, "MCI error illegal!\n"); | 212 | ath_dbg(common, MCI, "MCI error illegal!\n"); |
215 | else | 213 | else |
216 | ath_dbg(common, ATH_DBG_MCI, "MCI BT not in CAL state\n"); | 214 | ath_dbg(common, MCI, "MCI BT not in CAL state\n"); |
217 | 215 | ||
218 | break; | 216 | break; |
219 | 217 | ||
220 | case MCI_GPM_BT_CAL_GRANT: | 218 | case MCI_GPM_BT_CAL_GRANT: |
221 | 219 | ||
222 | ath_dbg(common, ATH_DBG_MCI, "MCI received BT_CAL_GRANT\n"); | 220 | ath_dbg(common, MCI, "MCI received BT_CAL_GRANT\n"); |
223 | 221 | ||
224 | /* Send WLAN_CAL_DONE for now */ | 222 | /* Send WLAN_CAL_DONE for now */ |
225 | ath_dbg(common, ATH_DBG_MCI, "MCI send WLAN_CAL_DONE\n"); | 223 | ath_dbg(common, MCI, "MCI send WLAN_CAL_DONE\n"); |
226 | MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); | 224 | MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); |
227 | ar9003_mci_send_message(sc->sc_ah, MCI_GPM, 0, payload, | 225 | ar9003_mci_send_message(sc->sc_ah, MCI_GPM, 0, payload, |
228 | 16, false, true); | 226 | 16, false, true); |
229 | break; | 227 | break; |
230 | 228 | ||
231 | default: | 229 | default: |
232 | ath_dbg(common, ATH_DBG_MCI, "MCI Unknown GPM CAL message\n"); | 230 | ath_dbg(common, MCI, "MCI Unknown GPM CAL message\n"); |
233 | break; | 231 | break; |
234 | } | 232 | } |
235 | } | 233 | } |
@@ -272,8 +270,7 @@ static void ath_mci_process_status(struct ath_softc *sc, | |||
272 | 270 | ||
273 | /* Link status type are not handled */ | 271 | /* Link status type are not handled */ |
274 | if (status->is_link) { | 272 | if (status->is_link) { |
275 | ath_dbg(common, ATH_DBG_MCI, | 273 | ath_dbg(common, MCI, "Skip link type status update\n"); |
276 | "Skip link type status update\n"); | ||
277 | return; | 274 | return; |
278 | } | 275 | } |
279 | 276 | ||
@@ -281,14 +278,13 @@ static void ath_mci_process_status(struct ath_softc *sc, | |||
281 | 278 | ||
282 | info.conn_handle = status->conn_handle; | 279 | info.conn_handle = status->conn_handle; |
283 | if (ath_mci_find_profile(mci, &info)) { | 280 | if (ath_mci_find_profile(mci, &info)) { |
284 | ath_dbg(common, ATH_DBG_MCI, | 281 | ath_dbg(common, MCI, |
285 | "Skip non link state update for existing profile %d\n", | 282 | "Skip non link state update for existing profile %d\n", |
286 | status->conn_handle); | 283 | status->conn_handle); |
287 | return; | 284 | return; |
288 | } | 285 | } |
289 | if (status->conn_handle >= ATH_MCI_MAX_PROFILE) { | 286 | if (status->conn_handle >= ATH_MCI_MAX_PROFILE) { |
290 | ath_dbg(common, ATH_DBG_MCI, | 287 | ath_dbg(common, MCI, "Ignore too many non-link update\n"); |
291 | "Ignore too many non-link update\n"); | ||
292 | return; | 288 | return; |
293 | } | 289 | } |
294 | if (status->is_critical) | 290 | if (status->is_critical) |
@@ -320,35 +316,32 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
320 | switch (opcode) { | 316 | switch (opcode) { |
321 | 317 | ||
322 | case MCI_GPM_COEX_VERSION_QUERY: | 318 | case MCI_GPM_COEX_VERSION_QUERY: |
323 | ath_dbg(common, ATH_DBG_MCI, | 319 | ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n"); |
324 | "MCI Recv GPM COEX Version Query.\n"); | ||
325 | version = ar9003_mci_state(ah, | 320 | version = ar9003_mci_state(ah, |
326 | MCI_STATE_SEND_WLAN_COEX_VERSION, NULL); | 321 | MCI_STATE_SEND_WLAN_COEX_VERSION, NULL); |
327 | break; | 322 | break; |
328 | 323 | ||
329 | case MCI_GPM_COEX_VERSION_RESPONSE: | 324 | case MCI_GPM_COEX_VERSION_RESPONSE: |
330 | ath_dbg(common, ATH_DBG_MCI, | 325 | ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n"); |
331 | "MCI Recv GPM COEX Version Response.\n"); | ||
332 | major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); | 326 | major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); |
333 | minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); | 327 | minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); |
334 | ath_dbg(common, ATH_DBG_MCI, | 328 | ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n", |
335 | "MCI BT Coex version: %d.%d\n", major, minor); | 329 | major, minor); |
336 | version = (major << 8) + minor; | 330 | version = (major << 8) + minor; |
337 | version = ar9003_mci_state(ah, | 331 | version = ar9003_mci_state(ah, |
338 | MCI_STATE_SET_BT_COEX_VERSION, &version); | 332 | MCI_STATE_SET_BT_COEX_VERSION, &version); |
339 | break; | 333 | break; |
340 | 334 | ||
341 | case MCI_GPM_COEX_STATUS_QUERY: | 335 | case MCI_GPM_COEX_STATUS_QUERY: |
342 | ath_dbg(common, ATH_DBG_MCI, | 336 | ath_dbg(common, MCI, |
343 | "MCI Recv GPM COEX Status Query = 0x%02x.\n", | 337 | "MCI Recv GPM COEX Status Query = 0x%02x\n", |
344 | *(rx_payload + MCI_GPM_COEX_B_WLAN_BITMAP)); | 338 | *(rx_payload + MCI_GPM_COEX_B_WLAN_BITMAP)); |
345 | ar9003_mci_state(ah, | 339 | ar9003_mci_state(ah, |
346 | MCI_STATE_SEND_WLAN_CHANNELS, NULL); | 340 | MCI_STATE_SEND_WLAN_CHANNELS, NULL); |
347 | break; | 341 | break; |
348 | 342 | ||
349 | case MCI_GPM_COEX_BT_PROFILE_INFO: | 343 | case MCI_GPM_COEX_BT_PROFILE_INFO: |
350 | ath_dbg(common, ATH_DBG_MCI, | 344 | ath_dbg(common, MCI, "MCI Recv GPM Coex BT profile info\n"); |
351 | "MCI Recv GPM Coex BT profile info\n"); | ||
352 | memcpy(&profile_info, | 345 | memcpy(&profile_info, |
353 | (rx_payload + MCI_GPM_COEX_B_PROFILE_TYPE), 10); | 346 | (rx_payload + MCI_GPM_COEX_B_PROFILE_TYPE), 10); |
354 | 347 | ||
@@ -356,9 +349,9 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
356 | || (profile_info.type >= | 349 | || (profile_info.type >= |
357 | MCI_GPM_COEX_PROFILE_MAX)) { | 350 | MCI_GPM_COEX_PROFILE_MAX)) { |
358 | 351 | ||
359 | ath_dbg(common, ATH_DBG_MCI, | 352 | ath_dbg(common, MCI, |
360 | "illegal profile type = %d," | 353 | "illegal profile type = %d, state = %d\n", |
361 | "state = %d\n", profile_info.type, | 354 | profile_info.type, |
362 | profile_info.start); | 355 | profile_info.start); |
363 | break; | 356 | break; |
364 | } | 357 | } |
@@ -375,9 +368,8 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
375 | MCI_GPM_COEX_B_STATUS_STATE); | 368 | MCI_GPM_COEX_B_STATUS_STATE); |
376 | 369 | ||
377 | seq_num = *((u32 *)(rx_payload + 12)); | 370 | seq_num = *((u32 *)(rx_payload + 12)); |
378 | ath_dbg(common, ATH_DBG_MCI, | 371 | ath_dbg(common, MCI, |
379 | "MCI Recv GPM COEX BT_Status_Update: " | 372 | "MCI Recv GPM COEX BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n", |
380 | "is_link=%d, linkId=%d, state=%d, SEQ=%d\n", | ||
381 | profile_status.is_link, profile_status.conn_handle, | 373 | profile_status.is_link, profile_status.conn_handle, |
382 | profile_status.is_critical, seq_num); | 374 | profile_status.is_critical, seq_num); |
383 | 375 | ||
@@ -385,8 +377,8 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
385 | break; | 377 | break; |
386 | 378 | ||
387 | default: | 379 | default: |
388 | ath_dbg(common, ATH_DBG_MCI, | 380 | ath_dbg(common, MCI, "MCI Unknown GPM COEX message = 0x%02x\n", |
389 | "MCI Unknown GPM COEX message = 0x%02x\n", opcode); | 381 | opcode); |
390 | break; | 382 | break; |
391 | } | 383 | } |
392 | } | 384 | } |
@@ -425,10 +417,13 @@ int ath_mci_setup(struct ath_softc *sc) | |||
425 | struct ath_mci_coex *mci = &sc->mci_coex; | 417 | struct ath_mci_coex *mci = &sc->mci_coex; |
426 | int error = 0; | 418 | int error = 0; |
427 | 419 | ||
420 | if (!ATH9K_HW_CAP_MCI) | ||
421 | return 0; | ||
422 | |||
428 | mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE; | 423 | mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE; |
429 | 424 | ||
430 | if (ath_mci_buf_alloc(sc, &mci->sched_buf)) { | 425 | if (ath_mci_buf_alloc(sc, &mci->sched_buf)) { |
431 | ath_dbg(common, ATH_DBG_FATAL, "MCI buffer alloc failed\n"); | 426 | ath_dbg(common, FATAL, "MCI buffer alloc failed\n"); |
432 | error = -ENOMEM; | 427 | error = -ENOMEM; |
433 | goto fail; | 428 | goto fail; |
434 | } | 429 | } |
@@ -458,6 +453,9 @@ void ath_mci_cleanup(struct ath_softc *sc) | |||
458 | struct ath_hw *ah = sc->sc_ah; | 453 | struct ath_hw *ah = sc->sc_ah; |
459 | struct ath_mci_coex *mci = &sc->mci_coex; | 454 | struct ath_mci_coex *mci = &sc->mci_coex; |
460 | 455 | ||
456 | if (!ATH9K_HW_CAP_MCI) | ||
457 | return; | ||
458 | |||
461 | /* | 459 | /* |
462 | * both schedule and gpm buffers will be released | 460 | * both schedule and gpm buffers will be released |
463 | */ | 461 | */ |
@@ -476,15 +474,17 @@ void ath_mci_intr(struct ath_softc *sc) | |||
476 | u32 more_data = MCI_GPM_MORE; | 474 | u32 more_data = MCI_GPM_MORE; |
477 | bool skip_gpm = false; | 475 | bool skip_gpm = false; |
478 | 476 | ||
477 | if (!ATH9K_HW_CAP_MCI) | ||
478 | return; | ||
479 | |||
479 | ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); | 480 | ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); |
480 | 481 | ||
481 | if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { | 482 | if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { |
482 | 483 | ||
483 | ar9003_mci_state(sc->sc_ah, MCI_STATE_INIT_GPM_OFFSET, NULL); | 484 | ar9003_mci_state(sc->sc_ah, MCI_STATE_INIT_GPM_OFFSET, NULL); |
484 | ath_dbg(common, ATH_DBG_MCI, | 485 | ath_dbg(common, MCI, "MCI interrupt but MCI disabled\n"); |
485 | "MCI interrupt but MCI disabled\n"); | ||
486 | 486 | ||
487 | ath_dbg(common, ATH_DBG_MCI, | 487 | ath_dbg(common, MCI, |
488 | "MCI interrupt: intr = 0x%x, intr_rxmsg = 0x%x\n", | 488 | "MCI interrupt: intr = 0x%x, intr_rxmsg = 0x%x\n", |
489 | mci_int, mci_int_rxmsg); | 489 | mci_int, mci_int_rxmsg); |
490 | return; | 490 | return; |
@@ -499,11 +499,11 @@ void ath_mci_intr(struct ath_softc *sc) | |||
499 | * only when BT wake up. Now they are always sent, as a | 499 | * only when BT wake up. Now they are always sent, as a |
500 | * recovery method to reset BT MCI's RX alignment. | 500 | * recovery method to reset BT MCI's RX alignment. |
501 | */ | 501 | */ |
502 | ath_dbg(common, ATH_DBG_MCI, "MCI interrupt send REMOTE_RESET\n"); | 502 | ath_dbg(common, MCI, "MCI interrupt send REMOTE_RESET\n"); |
503 | 503 | ||
504 | ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, | 504 | ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, |
505 | payload, 16, true, false); | 505 | payload, 16, true, false); |
506 | ath_dbg(common, ATH_DBG_MCI, "MCI interrupt send SYS_WAKING\n"); | 506 | ath_dbg(common, MCI, "MCI interrupt send SYS_WAKING\n"); |
507 | ar9003_mci_send_message(ah, MCI_SYS_WAKING, 0, | 507 | ar9003_mci_send_message(ah, MCI_SYS_WAKING, 0, |
508 | NULL, 0, true, false); | 508 | NULL, 0, true, false); |
509 | 509 | ||
@@ -513,7 +513,7 @@ void ath_mci_intr(struct ath_softc *sc) | |||
513 | /* | 513 | /* |
514 | * always do this for recovery and 2G/5G toggling and LNA_TRANS | 514 | * always do this for recovery and 2G/5G toggling and LNA_TRANS |
515 | */ | 515 | */ |
516 | ath_dbg(common, ATH_DBG_MCI, "MCI Set BT state to AWAKE.\n"); | 516 | ath_dbg(common, MCI, "MCI Set BT state to AWAKE\n"); |
517 | ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL); | 517 | ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL); |
518 | } | 518 | } |
519 | 519 | ||
@@ -525,17 +525,16 @@ void ath_mci_intr(struct ath_softc *sc) | |||
525 | 525 | ||
526 | if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) | 526 | if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) |
527 | == MCI_BT_SLEEP) | 527 | == MCI_BT_SLEEP) |
528 | ath_dbg(common, ATH_DBG_MCI, | 528 | ath_dbg(common, MCI, |
529 | "MCI BT stays in sleep mode\n"); | 529 | "MCI BT stays in sleep mode\n"); |
530 | else { | 530 | else { |
531 | ath_dbg(common, ATH_DBG_MCI, | 531 | ath_dbg(common, MCI, |
532 | "MCI Set BT state to AWAKE.\n"); | 532 | "MCI Set BT state to AWAKE\n"); |
533 | ar9003_mci_state(ah, | 533 | ar9003_mci_state(ah, |
534 | MCI_STATE_SET_BT_AWAKE, NULL); | 534 | MCI_STATE_SET_BT_AWAKE, NULL); |
535 | } | 535 | } |
536 | } else | 536 | } else |
537 | ath_dbg(common, ATH_DBG_MCI, | 537 | ath_dbg(common, MCI, "MCI BT stays in AWAKE mode\n"); |
538 | "MCI BT stays in AWAKE mode.\n"); | ||
539 | } | 538 | } |
540 | 539 | ||
541 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { | 540 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { |
@@ -546,23 +545,22 @@ void ath_mci_intr(struct ath_softc *sc) | |||
546 | 545 | ||
547 | if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) | 546 | if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) |
548 | == MCI_BT_AWAKE) | 547 | == MCI_BT_AWAKE) |
549 | ath_dbg(common, ATH_DBG_MCI, | 548 | ath_dbg(common, MCI, |
550 | "MCI BT stays in AWAKE mode.\n"); | 549 | "MCI BT stays in AWAKE mode\n"); |
551 | else { | 550 | else { |
552 | ath_dbg(common, ATH_DBG_MCI, | 551 | ath_dbg(common, MCI, |
553 | "MCI SetBT state to SLEEP\n"); | 552 | "MCI SetBT state to SLEEP\n"); |
554 | ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP, | 553 | ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP, |
555 | NULL); | 554 | NULL); |
556 | } | 555 | } |
557 | } else | 556 | } else |
558 | ath_dbg(common, ATH_DBG_MCI, | 557 | ath_dbg(common, MCI, "MCI BT stays in SLEEP mode\n"); |
559 | "MCI BT stays in SLEEP mode\n"); | ||
560 | } | 558 | } |
561 | 559 | ||
562 | if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || | 560 | if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || |
563 | (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { | 561 | (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { |
564 | 562 | ||
565 | ath_dbg(common, ATH_DBG_MCI, "MCI RX broken, skip GPM msgs\n"); | 563 | ath_dbg(common, MCI, "MCI RX broken, skip GPM msgs\n"); |
566 | ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL); | 564 | ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL); |
567 | skip_gpm = true; | 565 | skip_gpm = true; |
568 | } | 566 | } |
@@ -624,7 +622,7 @@ void ath_mci_intr(struct ath_softc *sc) | |||
624 | 622 | ||
625 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_INFO) { | 623 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_INFO) { |
626 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; | 624 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; |
627 | ath_dbg(common, ATH_DBG_MCI, "MCI LNA_INFO\n"); | 625 | ath_dbg(common, MCI, "MCI LNA_INFO\n"); |
628 | } | 626 | } |
629 | 627 | ||
630 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { | 628 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { |
@@ -635,16 +633,14 @@ void ath_mci_intr(struct ath_softc *sc) | |||
635 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; | 633 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; |
636 | 634 | ||
637 | if (ar9003_mci_state(ah, MCI_STATE_CONT_TXRX, NULL)) | 635 | if (ar9003_mci_state(ah, MCI_STATE_CONT_TXRX, NULL)) |
638 | ath_dbg(common, ATH_DBG_MCI, | 636 | ath_dbg(common, MCI, |
639 | "MCI CONT_INFO: " | 637 | "MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n", |
640 | "(tx) pri = %d, pwr = %d dBm\n", | ||
641 | ar9003_mci_state(ah, | 638 | ar9003_mci_state(ah, |
642 | MCI_STATE_CONT_PRIORITY, NULL), | 639 | MCI_STATE_CONT_PRIORITY, NULL), |
643 | value_dbm); | 640 | value_dbm); |
644 | else | 641 | else |
645 | ath_dbg(common, ATH_DBG_MCI, | 642 | ath_dbg(common, MCI, |
646 | "MCI CONT_INFO:" | 643 | "MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n", |
647 | "(rx) pri = %d,pwr = %d dBm\n", | ||
648 | ar9003_mci_state(ah, | 644 | ar9003_mci_state(ah, |
649 | MCI_STATE_CONT_PRIORITY, NULL), | 645 | MCI_STATE_CONT_PRIORITY, NULL), |
650 | value_dbm); | 646 | value_dbm); |
@@ -652,12 +648,12 @@ void ath_mci_intr(struct ath_softc *sc) | |||
652 | 648 | ||
653 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) { | 649 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) { |
654 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_NACK; | 650 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_NACK; |
655 | ath_dbg(common, ATH_DBG_MCI, "MCI CONT_NACK\n"); | 651 | ath_dbg(common, MCI, "MCI CONT_NACK\n"); |
656 | } | 652 | } |
657 | 653 | ||
658 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_RST) { | 654 | if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_RST) { |
659 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_RST; | 655 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_RST; |
660 | ath_dbg(common, ATH_DBG_MCI, "MCI CONT_RST\n"); | 656 | ath_dbg(common, MCI, "MCI CONT_RST\n"); |
661 | } | 657 | } |
662 | } | 658 | } |
663 | 659 | ||
@@ -667,7 +663,6 @@ void ath_mci_intr(struct ath_softc *sc) | |||
667 | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); | 663 | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); |
668 | 664 | ||
669 | if (mci_int_rxmsg & 0xfffffffe) | 665 | if (mci_int_rxmsg & 0xfffffffe) |
670 | ath_dbg(common, ATH_DBG_MCI, | 666 | ath_dbg(common, MCI, "MCI not processed mci_int_rxmsg = 0x%x\n", |
671 | "MCI not processed mci_int_rxmsg = 0x%x\n", | ||
672 | mci_int_rxmsg); | 667 | mci_int_rxmsg); |
673 | } | 668 | } |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index a439edc5dc06..77dc327def8d 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -121,7 +121,7 @@ static void ath_pci_aspm_init(struct ath_common *common) | |||
121 | if (!parent) | 121 | if (!parent) |
122 | return; | 122 | return; |
123 | 123 | ||
124 | if (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) { | 124 | if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { |
125 | /* Bluetooth coexistance requires disabling ASPM. */ | 125 | /* Bluetooth coexistance requires disabling ASPM. */ |
126 | pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm); | 126 | pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm); |
127 | aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); | 127 | aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 528d5f3e868c..b3c3798fe513 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1199,7 +1199,7 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, | |||
1199 | return &ar5416_11na_ratetable; | 1199 | return &ar5416_11na_ratetable; |
1200 | return &ar5416_11a_ratetable; | 1200 | return &ar5416_11a_ratetable; |
1201 | default: | 1201 | default: |
1202 | ath_dbg(common, ATH_DBG_CONFIG, "Invalid band\n"); | 1202 | ath_dbg(common, CONFIG, "Invalid band\n"); |
1203 | return NULL; | 1203 | return NULL; |
1204 | } | 1204 | } |
1205 | } | 1205 | } |
@@ -1276,8 +1276,7 @@ static void ath_rc_init(struct ath_softc *sc, | |||
1276 | ath_rc_priv->valid_rate_index[k-1]; | 1276 | ath_rc_priv->valid_rate_index[k-1]; |
1277 | ath_rc_priv->rate_table = rate_table; | 1277 | ath_rc_priv->rate_table = rate_table; |
1278 | 1278 | ||
1279 | ath_dbg(common, ATH_DBG_CONFIG, | 1279 | ath_dbg(common, CONFIG, "RC Initialized with capabilities: 0x%x\n", |
1280 | "RC Initialized with capabilities: 0x%x\n", | ||
1281 | ath_rc_priv->ht_cap); | 1280 | ath_rc_priv->ht_cap); |
1282 | } | 1281 | } |
1283 | 1282 | ||
@@ -1474,7 +1473,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | |||
1474 | oper_cw40, oper_sgi); | 1473 | oper_cw40, oper_sgi); |
1475 | ath_rc_init(sc, priv_sta, sband, sta, rate_table); | 1474 | ath_rc_init(sc, priv_sta, sband, sta, rate_table); |
1476 | 1475 | ||
1477 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, | 1476 | ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG, |
1478 | "Operating HT Bandwidth changed to: %d\n", | 1477 | "Operating HT Bandwidth changed to: %d\n", |
1479 | sc->hw->conf.channel_type); | 1478 | sc->hw->conf.channel_type); |
1480 | } | 1479 | } |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index ad5176de07dc..0e666fbe0842 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -172,7 +172,7 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc, | |||
172 | u32 nbuf = 0; | 172 | u32 nbuf = 0; |
173 | 173 | ||
174 | if (list_empty(&sc->rx.rxbuf)) { | 174 | if (list_empty(&sc->rx.rxbuf)) { |
175 | ath_dbg(common, ATH_DBG_QUEUE, "No free rx buf available\n"); | 175 | ath_dbg(common, QUEUE, "No free rx buf available\n"); |
176 | return; | 176 | return; |
177 | } | 177 | } |
178 | 178 | ||
@@ -337,7 +337,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
337 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 337 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
338 | return ath_rx_edma_init(sc, nbufs); | 338 | return ath_rx_edma_init(sc, nbufs); |
339 | } else { | 339 | } else { |
340 | ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", | 340 | ath_dbg(common, CONFIG, "cachelsz %u rxbufsize %u\n", |
341 | common->cachelsz, common->rx_bufsize); | 341 | common->cachelsz, common->rx_bufsize); |
342 | 342 | ||
343 | /* Initialize rx descriptors */ | 343 | /* Initialize rx descriptors */ |
@@ -591,7 +591,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
591 | 591 | ||
592 | if (sc->ps_flags & PS_BEACON_SYNC) { | 592 | if (sc->ps_flags & PS_BEACON_SYNC) { |
593 | sc->ps_flags &= ~PS_BEACON_SYNC; | 593 | sc->ps_flags &= ~PS_BEACON_SYNC; |
594 | ath_dbg(common, ATH_DBG_PS, | 594 | ath_dbg(common, PS, |
595 | "Reconfigure Beacon timers based on timestamp from the AP\n"); | 595 | "Reconfigure Beacon timers based on timestamp from the AP\n"); |
596 | ath_set_beacon(sc); | 596 | ath_set_beacon(sc); |
597 | } | 597 | } |
@@ -604,7 +604,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
604 | * a backup trigger for returning into NETWORK SLEEP state, | 604 | * a backup trigger for returning into NETWORK SLEEP state, |
605 | * so we are waiting for it as well. | 605 | * so we are waiting for it as well. |
606 | */ | 606 | */ |
607 | ath_dbg(common, ATH_DBG_PS, | 607 | ath_dbg(common, PS, |
608 | "Received DTIM beacon indicating buffered broadcast/multicast frame(s)\n"); | 608 | "Received DTIM beacon indicating buffered broadcast/multicast frame(s)\n"); |
609 | sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON; | 609 | sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON; |
610 | return; | 610 | return; |
@@ -617,8 +617,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
617 | * been delivered. | 617 | * been delivered. |
618 | */ | 618 | */ |
619 | sc->ps_flags &= ~PS_WAIT_FOR_CAB; | 619 | sc->ps_flags &= ~PS_WAIT_FOR_CAB; |
620 | ath_dbg(common, ATH_DBG_PS, | 620 | ath_dbg(common, PS, "PS wait for CAB frames timed out\n"); |
621 | "PS wait for CAB frames timed out\n"); | ||
622 | } | 621 | } |
623 | } | 622 | } |
624 | 623 | ||
@@ -643,13 +642,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) | |||
643 | * point. | 642 | * point. |
644 | */ | 643 | */ |
645 | sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON); | 644 | sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON); |
646 | ath_dbg(common, ATH_DBG_PS, | 645 | ath_dbg(common, PS, |
647 | "All PS CAB frames received, back to sleep\n"); | 646 | "All PS CAB frames received, back to sleep\n"); |
648 | } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) && | 647 | } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) && |
649 | !is_multicast_ether_addr(hdr->addr1) && | 648 | !is_multicast_ether_addr(hdr->addr1) && |
650 | !ieee80211_has_morefrags(hdr->frame_control)) { | 649 | !ieee80211_has_morefrags(hdr->frame_control)) { |
651 | sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA; | 650 | sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA; |
652 | ath_dbg(common, ATH_DBG_PS, | 651 | ath_dbg(common, PS, |
653 | "Going back to sleep after having received PS-Poll data (0x%lx)\n", | 652 | "Going back to sleep after having received PS-Poll data (0x%lx)\n", |
654 | sc->ps_flags & (PS_WAIT_FOR_BEACON | | 653 | sc->ps_flags & (PS_WAIT_FOR_BEACON | |
655 | PS_WAIT_FOR_CAB | | 654 | PS_WAIT_FOR_CAB | |
@@ -932,7 +931,7 @@ static int ath9k_process_rate(struct ath_common *common, | |||
932 | * No valid hardware bitrate found -- we should not get here | 931 | * No valid hardware bitrate found -- we should not get here |
933 | * because hardware has already validated this frame as OK. | 932 | * because hardware has already validated this frame as OK. |
934 | */ | 933 | */ |
935 | ath_dbg(common, ATH_DBG_ANY, | 934 | ath_dbg(common, ANY, |
936 | "unsupported hw bitrate detected 0x%02x using 1 Mbit\n", | 935 | "unsupported hw bitrate detected 0x%02x using 1 Mbit\n", |
937 | rx_stats->rs_rate); | 936 | rx_stats->rs_rate); |
938 | 937 | ||
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 35422fc1f2ce..65c8894c5f81 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -187,7 +187,7 @@ void ath9k_fatal_work(struct work_struct *work) | |||
187 | fatal_work); | 187 | fatal_work); |
188 | struct ath_common *common = ath9k_hw_common(priv->ah); | 188 | struct ath_common *common = ath9k_hw_common(priv->ah); |
189 | 189 | ||
190 | ath_dbg(common, ATH_DBG_FATAL, "FATAL Event received, resetting device\n"); | 190 | ath_dbg(common, FATAL, "FATAL Event received, resetting device\n"); |
191 | ath9k_htc_reset(priv); | 191 | ath9k_htc_reset(priv); |
192 | } | 192 | } |
193 | 193 | ||
@@ -330,8 +330,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
330 | 330 | ||
331 | time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); | 331 | time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); |
332 | if (!time_left) { | 332 | if (!time_left) { |
333 | ath_dbg(common, ATH_DBG_WMI, | 333 | ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n", |
334 | "Timeout waiting for WMI command: %s\n", | ||
335 | wmi_cmd_to_name(cmd_id)); | 334 | wmi_cmd_to_name(cmd_id)); |
336 | mutex_unlock(&wmi->op_mutex); | 335 | mutex_unlock(&wmi->op_mutex); |
337 | return -ETIMEDOUT; | 336 | return -ETIMEDOUT; |
@@ -342,8 +341,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | |||
342 | return 0; | 341 | return 0; |
343 | 342 | ||
344 | out: | 343 | out: |
345 | ath_dbg(common, ATH_DBG_WMI, | 344 | ath_dbg(common, WMI, "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id)); |
346 | "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id)); | ||
347 | mutex_unlock(&wmi->op_mutex); | 345 | mutex_unlock(&wmi->op_mutex); |
348 | kfree_skb(skb); | 346 | kfree_skb(skb); |
349 | 347 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2622fcee8c96..9aa01997b1ea 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -104,6 +104,29 @@ static int ath_max_4ms_framelen[4][32] = { | |||
104 | /* Aggregation logic */ | 104 | /* Aggregation logic */ |
105 | /*********************/ | 105 | /*********************/ |
106 | 106 | ||
107 | static void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) | ||
108 | { | ||
109 | spin_lock_bh(&txq->axq_lock); | ||
110 | } | ||
111 | |||
112 | static void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) | ||
113 | { | ||
114 | spin_unlock_bh(&txq->axq_lock); | ||
115 | } | ||
116 | |||
117 | static void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) | ||
118 | { | ||
119 | struct sk_buff_head q; | ||
120 | struct sk_buff *skb; | ||
121 | |||
122 | __skb_queue_head_init(&q); | ||
123 | skb_queue_splice_init(&txq->complete_q, &q); | ||
124 | spin_unlock_bh(&txq->axq_lock); | ||
125 | |||
126 | while ((skb = __skb_dequeue(&q))) | ||
127 | ieee80211_tx_status(sc->hw, skb); | ||
128 | } | ||
129 | |||
107 | static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) | 130 | static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) |
108 | { | 131 | { |
109 | struct ath_atx_ac *ac = tid->ac; | 132 | struct ath_atx_ac *ac = tid->ac; |
@@ -130,7 +153,7 @@ static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
130 | 153 | ||
131 | WARN_ON(!tid->paused); | 154 | WARN_ON(!tid->paused); |
132 | 155 | ||
133 | spin_lock_bh(&txq->axq_lock); | 156 | ath_txq_lock(sc, txq); |
134 | tid->paused = false; | 157 | tid->paused = false; |
135 | 158 | ||
136 | if (skb_queue_empty(&tid->buf_q)) | 159 | if (skb_queue_empty(&tid->buf_q)) |
@@ -139,7 +162,7 @@ static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
139 | ath_tx_queue_tid(txq, tid); | 162 | ath_tx_queue_tid(txq, tid); |
140 | ath_txq_schedule(sc, txq); | 163 | ath_txq_schedule(sc, txq); |
141 | unlock: | 164 | unlock: |
142 | spin_unlock_bh(&txq->axq_lock); | 165 | ath_txq_unlock_complete(sc, txq); |
143 | } | 166 | } |
144 | 167 | ||
145 | static struct ath_frame_info *get_frame_info(struct sk_buff *skb) | 168 | static struct ath_frame_info *get_frame_info(struct sk_buff *skb) |
@@ -189,8 +212,11 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
189 | tid->state &= ~AGGR_CLEANUP; | 212 | tid->state &= ~AGGR_CLEANUP; |
190 | } | 213 | } |
191 | 214 | ||
192 | if (sendbar) | 215 | if (sendbar) { |
216 | ath_txq_unlock(sc, txq); | ||
193 | ath_send_bar(tid, tid->seq_start); | 217 | ath_send_bar(tid, tid->seq_start); |
218 | ath_txq_lock(sc, txq); | ||
219 | } | ||
194 | } | 220 | } |
195 | 221 | ||
196 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | 222 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
@@ -554,13 +580,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
554 | bf = bf_next; | 580 | bf = bf_next; |
555 | } | 581 | } |
556 | 582 | ||
557 | if (bar_index >= 0) { | ||
558 | u16 bar_seq = ATH_BA_INDEX2SEQ(seq_first, bar_index); | ||
559 | ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1)); | ||
560 | if (BAW_WITHIN(tid->seq_start, tid->baw_size, bar_seq)) | ||
561 | tid->bar_index = ATH_BA_INDEX(tid->seq_start, bar_seq); | ||
562 | } | ||
563 | |||
564 | /* prepend un-acked frames to the beginning of the pending frame queue */ | 583 | /* prepend un-acked frames to the beginning of the pending frame queue */ |
565 | if (!skb_queue_empty(&bf_pending)) { | 584 | if (!skb_queue_empty(&bf_pending)) { |
566 | if (an->sleeping) | 585 | if (an->sleeping) |
@@ -575,6 +594,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
575 | } | 594 | } |
576 | } | 595 | } |
577 | 596 | ||
597 | if (bar_index >= 0) { | ||
598 | u16 bar_seq = ATH_BA_INDEX2SEQ(seq_first, bar_index); | ||
599 | |||
600 | if (BAW_WITHIN(tid->seq_start, tid->baw_size, bar_seq)) | ||
601 | tid->bar_index = ATH_BA_INDEX(tid->seq_start, bar_seq); | ||
602 | |||
603 | ath_txq_unlock(sc, txq); | ||
604 | ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1)); | ||
605 | ath_txq_lock(sc, txq); | ||
606 | } | ||
607 | |||
578 | if (tid->state & AGGR_CLEANUP) | 608 | if (tid->state & AGGR_CLEANUP) |
579 | ath_tx_flush_tid(sc, tid); | 609 | ath_tx_flush_tid(sc, tid); |
580 | 610 | ||
@@ -1172,7 +1202,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
1172 | return; | 1202 | return; |
1173 | } | 1203 | } |
1174 | 1204 | ||
1175 | spin_lock_bh(&txq->axq_lock); | 1205 | ath_txq_lock(sc, txq); |
1176 | txtid->paused = true; | 1206 | txtid->paused = true; |
1177 | 1207 | ||
1178 | /* | 1208 | /* |
@@ -1187,7 +1217,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
1187 | txtid->state &= ~AGGR_ADDBA_COMPLETE; | 1217 | txtid->state &= ~AGGR_ADDBA_COMPLETE; |
1188 | 1218 | ||
1189 | ath_tx_flush_tid(sc, txtid); | 1219 | ath_tx_flush_tid(sc, txtid); |
1190 | spin_unlock_bh(&txq->axq_lock); | 1220 | ath_txq_unlock_complete(sc, txq); |
1191 | } | 1221 | } |
1192 | 1222 | ||
1193 | void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | 1223 | void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, |
@@ -1208,7 +1238,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
1208 | ac = tid->ac; | 1238 | ac = tid->ac; |
1209 | txq = ac->txq; | 1239 | txq = ac->txq; |
1210 | 1240 | ||
1211 | spin_lock_bh(&txq->axq_lock); | 1241 | ath_txq_lock(sc, txq); |
1212 | 1242 | ||
1213 | buffered = !skb_queue_empty(&tid->buf_q); | 1243 | buffered = !skb_queue_empty(&tid->buf_q); |
1214 | 1244 | ||
@@ -1220,7 +1250,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
1220 | list_del(&ac->list); | 1250 | list_del(&ac->list); |
1221 | } | 1251 | } |
1222 | 1252 | ||
1223 | spin_unlock_bh(&txq->axq_lock); | 1253 | ath_txq_unlock(sc, txq); |
1224 | 1254 | ||
1225 | ieee80211_sta_set_buffered(sta, tidno, buffered); | 1255 | ieee80211_sta_set_buffered(sta, tidno, buffered); |
1226 | } | 1256 | } |
@@ -1239,7 +1269,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) | |||
1239 | ac = tid->ac; | 1269 | ac = tid->ac; |
1240 | txq = ac->txq; | 1270 | txq = ac->txq; |
1241 | 1271 | ||
1242 | spin_lock_bh(&txq->axq_lock); | 1272 | ath_txq_lock(sc, txq); |
1243 | ac->clear_ps_filter = true; | 1273 | ac->clear_ps_filter = true; |
1244 | 1274 | ||
1245 | if (!skb_queue_empty(&tid->buf_q) && !tid->paused) { | 1275 | if (!skb_queue_empty(&tid->buf_q) && !tid->paused) { |
@@ -1247,7 +1277,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) | |||
1247 | ath_txq_schedule(sc, txq); | 1277 | ath_txq_schedule(sc, txq); |
1248 | } | 1278 | } |
1249 | 1279 | ||
1250 | spin_unlock_bh(&txq->axq_lock); | 1280 | ath_txq_unlock_complete(sc, txq); |
1251 | } | 1281 | } |
1252 | } | 1282 | } |
1253 | 1283 | ||
@@ -1347,6 +1377,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
1347 | txq->axq_qnum = axq_qnum; | 1377 | txq->axq_qnum = axq_qnum; |
1348 | txq->mac80211_qnum = -1; | 1378 | txq->mac80211_qnum = -1; |
1349 | txq->axq_link = NULL; | 1379 | txq->axq_link = NULL; |
1380 | __skb_queue_head_init(&txq->complete_q); | ||
1350 | INIT_LIST_HEAD(&txq->axq_q); | 1381 | INIT_LIST_HEAD(&txq->axq_q); |
1351 | INIT_LIST_HEAD(&txq->axq_acq); | 1382 | INIT_LIST_HEAD(&txq->axq_acq); |
1352 | spin_lock_init(&txq->axq_lock); | 1383 | spin_lock_init(&txq->axq_lock); |
@@ -1471,7 +1502,8 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, | |||
1471 | */ | 1502 | */ |
1472 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | 1503 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) |
1473 | { | 1504 | { |
1474 | spin_lock_bh(&txq->axq_lock); | 1505 | ath_txq_lock(sc, txq); |
1506 | |||
1475 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 1507 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
1476 | int idx = txq->txq_tailidx; | 1508 | int idx = txq->txq_tailidx; |
1477 | 1509 | ||
@@ -1492,7 +1524,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1492 | if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) | 1524 | if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) |
1493 | ath_txq_drain_pending_buffers(sc, txq); | 1525 | ath_txq_drain_pending_buffers(sc, txq); |
1494 | 1526 | ||
1495 | spin_unlock_bh(&txq->axq_lock); | 1527 | ath_txq_unlock_complete(sc, txq); |
1496 | } | 1528 | } |
1497 | 1529 | ||
1498 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1530 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
@@ -1626,8 +1658,8 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1626 | bf = list_first_entry(head, struct ath_buf, list); | 1658 | bf = list_first_entry(head, struct ath_buf, list); |
1627 | bf_last = list_entry(head->prev, struct ath_buf, list); | 1659 | bf_last = list_entry(head->prev, struct ath_buf, list); |
1628 | 1660 | ||
1629 | ath_dbg(common, ATH_DBG_QUEUE, | 1661 | ath_dbg(common, QUEUE, "qnum: %d, txq depth: %d\n", |
1630 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | 1662 | txq->axq_qnum, txq->axq_depth); |
1631 | 1663 | ||
1632 | if (edma && list_empty(&txq->txq_fifo[txq->txq_headidx])) { | 1664 | if (edma && list_empty(&txq->txq_fifo[txq->txq_headidx])) { |
1633 | list_splice_tail_init(head, &txq->txq_fifo[txq->txq_headidx]); | 1665 | list_splice_tail_init(head, &txq->txq_fifo[txq->txq_headidx]); |
@@ -1638,8 +1670,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1638 | 1670 | ||
1639 | if (txq->axq_link) { | 1671 | if (txq->axq_link) { |
1640 | ath9k_hw_set_desc_link(ah, txq->axq_link, bf->bf_daddr); | 1672 | ath9k_hw_set_desc_link(ah, txq->axq_link, bf->bf_daddr); |
1641 | ath_dbg(common, ATH_DBG_XMIT, | 1673 | ath_dbg(common, XMIT, "link[%u] (%p)=%llx (%p)\n", |
1642 | "link[%u] (%p)=%llx (%p)\n", | ||
1643 | txq->axq_qnum, txq->axq_link, | 1674 | txq->axq_qnum, txq->axq_link, |
1644 | ito64(bf->bf_daddr), bf->bf_desc); | 1675 | ito64(bf->bf_daddr), bf->bf_desc); |
1645 | } else if (!edma) | 1676 | } else if (!edma) |
@@ -1651,7 +1682,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1651 | if (puttxbuf) { | 1682 | if (puttxbuf) { |
1652 | TX_STAT_INC(txq->axq_qnum, puttxbuf); | 1683 | TX_STAT_INC(txq->axq_qnum, puttxbuf); |
1653 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | 1684 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); |
1654 | ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", | 1685 | ath_dbg(common, XMIT, "TXDP[%u] = %llx (%p)\n", |
1655 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); | 1686 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); |
1656 | } | 1687 | } |
1657 | 1688 | ||
@@ -1793,7 +1824,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
1793 | 1824 | ||
1794 | bf = ath_tx_get_buffer(sc); | 1825 | bf = ath_tx_get_buffer(sc); |
1795 | if (!bf) { | 1826 | if (!bf) { |
1796 | ath_dbg(common, ATH_DBG_XMIT, "TX buffers are full\n"); | 1827 | ath_dbg(common, XMIT, "TX buffers are full\n"); |
1797 | goto error; | 1828 | goto error; |
1798 | } | 1829 | } |
1799 | 1830 | ||
@@ -1925,7 +1956,8 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1925 | */ | 1956 | */ |
1926 | 1957 | ||
1927 | q = skb_get_queue_mapping(skb); | 1958 | q = skb_get_queue_mapping(skb); |
1928 | spin_lock_bh(&txq->axq_lock); | 1959 | |
1960 | ath_txq_lock(sc, txq); | ||
1929 | if (txq == sc->tx.txq_map[q] && | 1961 | if (txq == sc->tx.txq_map[q] && |
1930 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { | 1962 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { |
1931 | ieee80211_stop_queue(sc->hw, q); | 1963 | ieee80211_stop_queue(sc->hw, q); |
@@ -1934,7 +1966,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1934 | 1966 | ||
1935 | ath_tx_start_dma(sc, skb, txctl); | 1967 | ath_tx_start_dma(sc, skb, txctl); |
1936 | 1968 | ||
1937 | spin_unlock_bh(&txq->axq_lock); | 1969 | ath_txq_unlock(sc, txq); |
1938 | 1970 | ||
1939 | return 0; | 1971 | return 0; |
1940 | } | 1972 | } |
@@ -1946,13 +1978,12 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1946 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1978 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1947 | int tx_flags, struct ath_txq *txq) | 1979 | int tx_flags, struct ath_txq *txq) |
1948 | { | 1980 | { |
1949 | struct ieee80211_hw *hw = sc->hw; | ||
1950 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1981 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1951 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1982 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1952 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; | 1983 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
1953 | int q, padpos, padsize; | 1984 | int q, padpos, padsize; |
1954 | 1985 | ||
1955 | ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1986 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
1956 | 1987 | ||
1957 | if (!(tx_flags & ATH_TX_ERROR)) | 1988 | if (!(tx_flags & ATH_TX_ERROR)) |
1958 | /* Frame was ACKed */ | 1989 | /* Frame was ACKed */ |
@@ -1971,7 +2002,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1971 | 2002 | ||
1972 | if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { | 2003 | if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { |
1973 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; | 2004 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; |
1974 | ath_dbg(common, ATH_DBG_PS, | 2005 | ath_dbg(common, PS, |
1975 | "Going back to sleep after having received TX status (0x%lx)\n", | 2006 | "Going back to sleep after having received TX status (0x%lx)\n", |
1976 | sc->ps_flags & (PS_WAIT_FOR_BEACON | | 2007 | sc->ps_flags & (PS_WAIT_FOR_BEACON | |
1977 | PS_WAIT_FOR_CAB | | 2008 | PS_WAIT_FOR_CAB | |
@@ -1990,7 +2021,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1990 | } | 2021 | } |
1991 | } | 2022 | } |
1992 | 2023 | ||
1993 | ieee80211_tx_status(hw, skb); | 2024 | __skb_queue_tail(&txq->complete_q, skb); |
1994 | } | 2025 | } |
1995 | 2026 | ||
1996 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 2027 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
@@ -2122,11 +2153,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2122 | struct ath_tx_status ts; | 2153 | struct ath_tx_status ts; |
2123 | int status; | 2154 | int status; |
2124 | 2155 | ||
2125 | ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", | 2156 | ath_dbg(common, QUEUE, "tx queue %d (%x), link %p\n", |
2126 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | 2157 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), |
2127 | txq->axq_link); | 2158 | txq->axq_link); |
2128 | 2159 | ||
2129 | spin_lock_bh(&txq->axq_lock); | 2160 | ath_txq_lock(sc, txq); |
2130 | for (;;) { | 2161 | for (;;) { |
2131 | if (work_pending(&sc->hw_reset_work)) | 2162 | if (work_pending(&sc->hw_reset_work)) |
2132 | break; | 2163 | break; |
@@ -2185,7 +2216,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2185 | 2216 | ||
2186 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); | 2217 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); |
2187 | } | 2218 | } |
2188 | spin_unlock_bh(&txq->axq_lock); | 2219 | ath_txq_unlock_complete(sc, txq); |
2189 | } | 2220 | } |
2190 | 2221 | ||
2191 | static void ath_tx_complete_poll_work(struct work_struct *work) | 2222 | static void ath_tx_complete_poll_work(struct work_struct *work) |
@@ -2202,21 +2233,21 @@ static void ath_tx_complete_poll_work(struct work_struct *work) | |||
2202 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 2233 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
2203 | if (ATH_TXQ_SETUP(sc, i)) { | 2234 | if (ATH_TXQ_SETUP(sc, i)) { |
2204 | txq = &sc->tx.txq[i]; | 2235 | txq = &sc->tx.txq[i]; |
2205 | spin_lock_bh(&txq->axq_lock); | 2236 | ath_txq_lock(sc, txq); |
2206 | if (txq->axq_depth) { | 2237 | if (txq->axq_depth) { |
2207 | if (txq->axq_tx_inprogress) { | 2238 | if (txq->axq_tx_inprogress) { |
2208 | needreset = true; | 2239 | needreset = true; |
2209 | spin_unlock_bh(&txq->axq_lock); | 2240 | ath_txq_unlock(sc, txq); |
2210 | break; | 2241 | break; |
2211 | } else { | 2242 | } else { |
2212 | txq->axq_tx_inprogress = true; | 2243 | txq->axq_tx_inprogress = true; |
2213 | } | 2244 | } |
2214 | } | 2245 | } |
2215 | spin_unlock_bh(&txq->axq_lock); | 2246 | ath_txq_unlock_complete(sc, txq); |
2216 | } | 2247 | } |
2217 | 2248 | ||
2218 | if (needreset) { | 2249 | if (needreset) { |
2219 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, | 2250 | ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, |
2220 | "tx hung, resetting the chip\n"); | 2251 | "tx hung, resetting the chip\n"); |
2221 | RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); | 2252 | RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); |
2222 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 2253 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
@@ -2259,8 +2290,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2259 | if (status == -EINPROGRESS) | 2290 | if (status == -EINPROGRESS) |
2260 | break; | 2291 | break; |
2261 | if (status == -EIO) { | 2292 | if (status == -EIO) { |
2262 | ath_dbg(common, ATH_DBG_XMIT, | 2293 | ath_dbg(common, XMIT, "Error processing tx status\n"); |
2263 | "Error processing tx status\n"); | ||
2264 | break; | 2294 | break; |
2265 | } | 2295 | } |
2266 | 2296 | ||
@@ -2270,10 +2300,10 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2270 | 2300 | ||
2271 | txq = &sc->tx.txq[ts.qid]; | 2301 | txq = &sc->tx.txq[ts.qid]; |
2272 | 2302 | ||
2273 | spin_lock_bh(&txq->axq_lock); | 2303 | ath_txq_lock(sc, txq); |
2274 | 2304 | ||
2275 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { | 2305 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { |
2276 | spin_unlock_bh(&txq->axq_lock); | 2306 | ath_txq_unlock(sc, txq); |
2277 | return; | 2307 | return; |
2278 | } | 2308 | } |
2279 | 2309 | ||
@@ -2299,7 +2329,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2299 | } | 2329 | } |
2300 | 2330 | ||
2301 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); | 2331 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); |
2302 | spin_unlock_bh(&txq->axq_lock); | 2332 | ath_txq_unlock_complete(sc, txq); |
2303 | } | 2333 | } |
2304 | } | 2334 | } |
2305 | 2335 | ||
@@ -2437,7 +2467,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2437 | ac = tid->ac; | 2467 | ac = tid->ac; |
2438 | txq = ac->txq; | 2468 | txq = ac->txq; |
2439 | 2469 | ||
2440 | spin_lock_bh(&txq->axq_lock); | 2470 | ath_txq_lock(sc, txq); |
2441 | 2471 | ||
2442 | if (tid->sched) { | 2472 | if (tid->sched) { |
2443 | list_del(&tid->list); | 2473 | list_del(&tid->list); |
@@ -2453,6 +2483,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2453 | tid->state &= ~AGGR_ADDBA_COMPLETE; | 2483 | tid->state &= ~AGGR_ADDBA_COMPLETE; |
2454 | tid->state &= ~AGGR_CLEANUP; | 2484 | tid->state &= ~AGGR_CLEANUP; |
2455 | 2485 | ||
2456 | spin_unlock_bh(&txq->axq_lock); | 2486 | ath_txq_unlock(sc, txq); |
2457 | } | 2487 | } |
2458 | } | 2488 | } |
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 4cf7c5eb4813..0e81904956cf 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c | |||
@@ -143,7 +143,7 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, | |||
143 | break; | 143 | break; |
144 | case ATH_CIPHER_AES_CCM: | 144 | case ATH_CIPHER_AES_CCM: |
145 | if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) { | 145 | if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) { |
146 | ath_dbg(common, ATH_DBG_ANY, | 146 | ath_dbg(common, ANY, |
147 | "AES-CCM not supported by this mac rev\n"); | 147 | "AES-CCM not supported by this mac rev\n"); |
148 | return false; | 148 | return false; |
149 | } | 149 | } |
@@ -152,15 +152,15 @@ static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, | |||
152 | case ATH_CIPHER_TKIP: | 152 | case ATH_CIPHER_TKIP: |
153 | keyType = AR_KEYTABLE_TYPE_TKIP; | 153 | keyType = AR_KEYTABLE_TYPE_TKIP; |
154 | if (entry + 64 >= common->keymax) { | 154 | if (entry + 64 >= common->keymax) { |
155 | ath_dbg(common, ATH_DBG_ANY, | 155 | ath_dbg(common, ANY, |
156 | "entry %u inappropriate for TKIP\n", entry); | 156 | "entry %u inappropriate for TKIP\n", entry); |
157 | return false; | 157 | return false; |
158 | } | 158 | } |
159 | break; | 159 | break; |
160 | case ATH_CIPHER_WEP: | 160 | case ATH_CIPHER_WEP: |
161 | if (k->kv_len < WLAN_KEY_LEN_WEP40) { | 161 | if (k->kv_len < WLAN_KEY_LEN_WEP40) { |
162 | ath_dbg(common, ATH_DBG_ANY, | 162 | ath_dbg(common, ANY, "WEP key length %u too small\n", |
163 | "WEP key length %u too small\n", k->kv_len); | 163 | k->kv_len); |
164 | return false; | 164 | return false; |
165 | } | 165 | } |
166 | if (k->kv_len <= WLAN_KEY_LEN_WEP40) | 166 | if (k->kv_len <= WLAN_KEY_LEN_WEP40) |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 37110dfd2c96..f19605e8eb4c 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -667,6 +667,7 @@ struct b43_key { | |||
667 | }; | 667 | }; |
668 | 668 | ||
669 | /* SHM offsets to the QOS data structures for the 4 different queues. */ | 669 | /* SHM offsets to the QOS data structures for the 4 different queues. */ |
670 | #define B43_QOS_QUEUE_NUM 4 | ||
670 | #define B43_QOS_PARAMS(queue) (B43_SHM_SH_EDCFQ + \ | 671 | #define B43_QOS_PARAMS(queue) (B43_SHM_SH_EDCFQ + \ |
671 | (B43_NR_QOSPARAMS * sizeof(u16) * (queue))) | 672 | (B43_NR_QOSPARAMS * sizeof(u16) * (queue))) |
672 | #define B43_QOS_BACKGROUND B43_QOS_PARAMS(0) | 673 | #define B43_QOS_BACKGROUND B43_QOS_PARAMS(0) |
@@ -904,7 +905,7 @@ struct b43_wl { | |||
904 | struct work_struct beacon_update_trigger; | 905 | struct work_struct beacon_update_trigger; |
905 | 906 | ||
906 | /* The current QOS parameters for the 4 queues. */ | 907 | /* The current QOS parameters for the 4 queues. */ |
907 | struct b43_qos_params qos_params[4]; | 908 | struct b43_qos_params qos_params[B43_QOS_QUEUE_NUM]; |
908 | 909 | ||
909 | /* Work for adjustment of the transmission power. | 910 | /* Work for adjustment of the transmission power. |
910 | * This is scheduled when we determine that the actual TX output | 911 | * This is scheduled when we determine that the actual TX output |
@@ -913,8 +914,12 @@ struct b43_wl { | |||
913 | 914 | ||
914 | /* Packet transmit work */ | 915 | /* Packet transmit work */ |
915 | struct work_struct tx_work; | 916 | struct work_struct tx_work; |
917 | |||
916 | /* Queue of packets to be transmitted. */ | 918 | /* Queue of packets to be transmitted. */ |
917 | struct sk_buff_head tx_queue; | 919 | struct sk_buff_head tx_queue[B43_QOS_QUEUE_NUM]; |
920 | |||
921 | /* Flag that implement the queues stopping. */ | ||
922 | bool tx_queue_stopped[B43_QOS_QUEUE_NUM]; | ||
918 | 923 | ||
919 | /* The device LEDs. */ | 924 | /* The device LEDs. */ |
920 | struct b43_leds leds; | 925 | struct b43_leds leds; |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index af23968520b6..b5f1b91002bb 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -1465,7 +1465,9 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb) | |||
1465 | if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || | 1465 | if ((free_slots(ring) < TX_SLOTS_PER_FRAME) || |
1466 | should_inject_overflow(ring)) { | 1466 | should_inject_overflow(ring)) { |
1467 | /* This TX ring is full. */ | 1467 | /* This TX ring is full. */ |
1468 | ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); | 1468 | unsigned int skb_mapping = skb_get_queue_mapping(skb); |
1469 | ieee80211_stop_queue(dev->wl->hw, skb_mapping); | ||
1470 | dev->wl->tx_queue_stopped[skb_mapping] = 1; | ||
1469 | ring->stopped = true; | 1471 | ring->stopped = true; |
1470 | if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { | 1472 | if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { |
1471 | b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); | 1473 | b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); |
@@ -1584,12 +1586,21 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1584 | } | 1586 | } |
1585 | if (ring->stopped) { | 1587 | if (ring->stopped) { |
1586 | B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME); | 1588 | B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME); |
1587 | ieee80211_wake_queue(dev->wl->hw, ring->queue_prio); | ||
1588 | ring->stopped = false; | 1589 | ring->stopped = false; |
1590 | } | ||
1591 | |||
1592 | if (dev->wl->tx_queue_stopped[ring->queue_prio]) { | ||
1593 | dev->wl->tx_queue_stopped[ring->queue_prio] = 0; | ||
1594 | } else { | ||
1595 | /* If the driver queue is running wake the corresponding | ||
1596 | * mac80211 queue. */ | ||
1597 | ieee80211_wake_queue(dev->wl->hw, ring->queue_prio); | ||
1589 | if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { | 1598 | if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { |
1590 | b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); | 1599 | b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); |
1591 | } | 1600 | } |
1592 | } | 1601 | } |
1602 | /* Add work to the queue. */ | ||
1603 | ieee80211_queue_work(dev->wl->hw, &dev->wl->tx_work); | ||
1593 | } | 1604 | } |
1594 | 1605 | ||
1595 | static void dma_rx(struct b43_dmaring *ring, int *slot) | 1606 | static void dma_rx(struct b43_dmaring *ring, int *slot) |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c74f36f6e348..1c6f19393efa 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3378,6 +3378,7 @@ static void b43_tx_work(struct work_struct *work) | |||
3378 | struct b43_wl *wl = container_of(work, struct b43_wl, tx_work); | 3378 | struct b43_wl *wl = container_of(work, struct b43_wl, tx_work); |
3379 | struct b43_wldev *dev; | 3379 | struct b43_wldev *dev; |
3380 | struct sk_buff *skb; | 3380 | struct sk_buff *skb; |
3381 | int queue_num; | ||
3381 | int err = 0; | 3382 | int err = 0; |
3382 | 3383 | ||
3383 | mutex_lock(&wl->mutex); | 3384 | mutex_lock(&wl->mutex); |
@@ -3387,15 +3388,26 @@ static void b43_tx_work(struct work_struct *work) | |||
3387 | return; | 3388 | return; |
3388 | } | 3389 | } |
3389 | 3390 | ||
3390 | while (skb_queue_len(&wl->tx_queue)) { | 3391 | for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) { |
3391 | skb = skb_dequeue(&wl->tx_queue); | 3392 | while (skb_queue_len(&wl->tx_queue[queue_num])) { |
3393 | skb = skb_dequeue(&wl->tx_queue[queue_num]); | ||
3394 | if (b43_using_pio_transfers(dev)) | ||
3395 | err = b43_pio_tx(dev, skb); | ||
3396 | else | ||
3397 | err = b43_dma_tx(dev, skb); | ||
3398 | if (err == -ENOSPC) { | ||
3399 | wl->tx_queue_stopped[queue_num] = 1; | ||
3400 | ieee80211_stop_queue(wl->hw, queue_num); | ||
3401 | skb_queue_head(&wl->tx_queue[queue_num], skb); | ||
3402 | break; | ||
3403 | } | ||
3404 | if (unlikely(err)) | ||
3405 | dev_kfree_skb(skb); /* Drop it */ | ||
3406 | err = 0; | ||
3407 | } | ||
3392 | 3408 | ||
3393 | if (b43_using_pio_transfers(dev)) | 3409 | if (!err) |
3394 | err = b43_pio_tx(dev, skb); | 3410 | wl->tx_queue_stopped[queue_num] = 0; |
3395 | else | ||
3396 | err = b43_dma_tx(dev, skb); | ||
3397 | if (unlikely(err)) | ||
3398 | dev_kfree_skb(skb); /* Drop it */ | ||
3399 | } | 3411 | } |
3400 | 3412 | ||
3401 | #if B43_DEBUG | 3413 | #if B43_DEBUG |
@@ -3416,8 +3428,12 @@ static void b43_op_tx(struct ieee80211_hw *hw, | |||
3416 | } | 3428 | } |
3417 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); | 3429 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); |
3418 | 3430 | ||
3419 | skb_queue_tail(&wl->tx_queue, skb); | 3431 | skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb); |
3420 | ieee80211_queue_work(wl->hw, &wl->tx_work); | 3432 | if (!wl->tx_queue_stopped[skb->queue_mapping]) { |
3433 | ieee80211_queue_work(wl->hw, &wl->tx_work); | ||
3434 | } else { | ||
3435 | ieee80211_stop_queue(wl->hw, skb->queue_mapping); | ||
3436 | } | ||
3421 | } | 3437 | } |
3422 | 3438 | ||
3423 | static void b43_qos_params_upload(struct b43_wldev *dev, | 3439 | static void b43_qos_params_upload(struct b43_wldev *dev, |
@@ -4147,6 +4163,7 @@ static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev) | |||
4147 | struct b43_wl *wl; | 4163 | struct b43_wl *wl; |
4148 | struct b43_wldev *orig_dev; | 4164 | struct b43_wldev *orig_dev; |
4149 | u32 mask; | 4165 | u32 mask; |
4166 | int queue_num; | ||
4150 | 4167 | ||
4151 | if (!dev) | 4168 | if (!dev) |
4152 | return NULL; | 4169 | return NULL; |
@@ -4199,9 +4216,11 @@ redo: | |||
4199 | mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); | 4216 | mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); |
4200 | B43_WARN_ON(mask != 0xFFFFFFFF && mask); | 4217 | B43_WARN_ON(mask != 0xFFFFFFFF && mask); |
4201 | 4218 | ||
4202 | /* Drain the TX queue */ | 4219 | /* Drain all TX queues. */ |
4203 | while (skb_queue_len(&wl->tx_queue)) | 4220 | for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) { |
4204 | dev_kfree_skb(skb_dequeue(&wl->tx_queue)); | 4221 | while (skb_queue_len(&wl->tx_queue[queue_num])) |
4222 | dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num])); | ||
4223 | } | ||
4205 | 4224 | ||
4206 | b43_mac_suspend(dev); | 4225 | b43_mac_suspend(dev); |
4207 | b43_leds_exit(dev); | 4226 | b43_leds_exit(dev); |
@@ -5245,6 +5264,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) | |||
5245 | struct ieee80211_hw *hw; | 5264 | struct ieee80211_hw *hw; |
5246 | struct b43_wl *wl; | 5265 | struct b43_wl *wl; |
5247 | char chip_name[6]; | 5266 | char chip_name[6]; |
5267 | int queue_num; | ||
5248 | 5268 | ||
5249 | hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); | 5269 | hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); |
5250 | if (!hw) { | 5270 | if (!hw) { |
@@ -5264,7 +5284,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) | |||
5264 | BIT(NL80211_IFTYPE_WDS) | | 5284 | BIT(NL80211_IFTYPE_WDS) | |
5265 | BIT(NL80211_IFTYPE_ADHOC); | 5285 | BIT(NL80211_IFTYPE_ADHOC); |
5266 | 5286 | ||
5267 | hw->queues = modparam_qos ? 4 : 1; | 5287 | hw->queues = modparam_qos ? B43_QOS_QUEUE_NUM : 1; |
5268 | wl->mac80211_initially_registered_queues = hw->queues; | 5288 | wl->mac80211_initially_registered_queues = hw->queues; |
5269 | hw->max_rates = 2; | 5289 | hw->max_rates = 2; |
5270 | SET_IEEE80211_DEV(hw, dev->dev); | 5290 | SET_IEEE80211_DEV(hw, dev->dev); |
@@ -5281,7 +5301,12 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) | |||
5281 | INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); | 5301 | INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); |
5282 | INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); | 5302 | INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); |
5283 | INIT_WORK(&wl->tx_work, b43_tx_work); | 5303 | INIT_WORK(&wl->tx_work, b43_tx_work); |
5284 | skb_queue_head_init(&wl->tx_queue); | 5304 | |
5305 | /* Initialize queues and flags. */ | ||
5306 | for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) { | ||
5307 | skb_queue_head_init(&wl->tx_queue[queue_num]); | ||
5308 | wl->tx_queue_stopped[queue_num] = 0; | ||
5309 | } | ||
5285 | 5310 | ||
5286 | snprintf(chip_name, ARRAY_SIZE(chip_name), | 5311 | snprintf(chip_name, ARRAY_SIZE(chip_name), |
5287 | (dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id); | 5312 | (dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id); |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f1a7e5890adc..0d25fe4069bf 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -78,19 +78,6 @@ enum b43_nphy_rssi_type { | |||
78 | B43_NPHY_RSSI_TBD, | 78 | B43_NPHY_RSSI_TBD, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /* TODO: reorder functions */ | ||
82 | static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, | ||
83 | bool enable); | ||
84 | static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, | ||
85 | u8 *events, u8 *delays, u8 length); | ||
86 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | ||
87 | enum b43_nphy_rf_sequence seq); | ||
88 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | ||
89 | u16 value, u8 core, bool off); | ||
90 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | ||
91 | u16 value, u8 core); | ||
92 | static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev); | ||
93 | |||
94 | static inline bool b43_nphy_ipa(struct b43_wldev *dev) | 81 | static inline bool b43_nphy_ipa(struct b43_wldev *dev) |
95 | { | 82 | { |
96 | enum ieee80211_band band = b43_current_band(dev->wl); | 83 | enum ieee80211_band band = b43_current_band(dev->wl); |
@@ -98,57 +85,394 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev) | |||
98 | (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); | 85 | (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); |
99 | } | 86 | } |
100 | 87 | ||
101 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | 88 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ |
102 | {//TODO | 89 | static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) |
90 | { | ||
91 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
92 | if (dev->phy.rev >= 6) { | ||
93 | if (dev->dev->chip_id == 47162) | ||
94 | return txpwrctrl_tx_gain_ipa_rev5; | ||
95 | return txpwrctrl_tx_gain_ipa_rev6; | ||
96 | } else if (dev->phy.rev >= 5) { | ||
97 | return txpwrctrl_tx_gain_ipa_rev5; | ||
98 | } else { | ||
99 | return txpwrctrl_tx_gain_ipa; | ||
100 | } | ||
101 | } else { | ||
102 | return txpwrctrl_tx_gain_ipa_5g; | ||
103 | } | ||
103 | } | 104 | } |
104 | 105 | ||
105 | static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev) | 106 | /************************************************** |
106 | {//TODO | 107 | * RF (just without b43_nphy_rf_control_intc_override) |
108 | **************************************************/ | ||
109 | |||
110 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ | ||
111 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | ||
112 | enum b43_nphy_rf_sequence seq) | ||
113 | { | ||
114 | static const u16 trigger[] = { | ||
115 | [B43_RFSEQ_RX2TX] = B43_NPHY_RFSEQTR_RX2TX, | ||
116 | [B43_RFSEQ_TX2RX] = B43_NPHY_RFSEQTR_TX2RX, | ||
117 | [B43_RFSEQ_RESET2RX] = B43_NPHY_RFSEQTR_RST2RX, | ||
118 | [B43_RFSEQ_UPDATE_GAINH] = B43_NPHY_RFSEQTR_UPGH, | ||
119 | [B43_RFSEQ_UPDATE_GAINL] = B43_NPHY_RFSEQTR_UPGL, | ||
120 | [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, | ||
121 | }; | ||
122 | int i; | ||
123 | u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); | ||
124 | |||
125 | B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); | ||
126 | |||
127 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, | ||
128 | B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER); | ||
129 | b43_phy_set(dev, B43_NPHY_RFSEQTR, trigger[seq]); | ||
130 | for (i = 0; i < 200; i++) { | ||
131 | if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & trigger[seq])) | ||
132 | goto ok; | ||
133 | msleep(1); | ||
134 | } | ||
135 | b43err(dev->wl, "RF sequence status timeout\n"); | ||
136 | ok: | ||
137 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); | ||
107 | } | 138 | } |
108 | 139 | ||
109 | static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev, | 140 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ |
110 | bool ignore_tssi) | 141 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, |
111 | {//TODO | 142 | u16 value, u8 core, bool off) |
112 | return B43_TXPWR_RES_DONE; | 143 | { |
144 | int i; | ||
145 | u8 index = fls(field); | ||
146 | u8 addr, en_addr, val_addr; | ||
147 | /* we expect only one bit set */ | ||
148 | B43_WARN_ON(field & (~(1 << (index - 1)))); | ||
149 | |||
150 | if (dev->phy.rev >= 3) { | ||
151 | const struct nphy_rf_control_override_rev3 *rf_ctrl; | ||
152 | for (i = 0; i < 2; i++) { | ||
153 | if (index == 0 || index == 16) { | ||
154 | b43err(dev->wl, | ||
155 | "Unsupported RF Ctrl Override call\n"); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | rf_ctrl = &tbl_rf_control_override_rev3[index - 1]; | ||
160 | en_addr = B43_PHY_N((i == 0) ? | ||
161 | rf_ctrl->en_addr0 : rf_ctrl->en_addr1); | ||
162 | val_addr = B43_PHY_N((i == 0) ? | ||
163 | rf_ctrl->val_addr0 : rf_ctrl->val_addr1); | ||
164 | |||
165 | if (off) { | ||
166 | b43_phy_mask(dev, en_addr, ~(field)); | ||
167 | b43_phy_mask(dev, val_addr, | ||
168 | ~(rf_ctrl->val_mask)); | ||
169 | } else { | ||
170 | if (core == 0 || ((1 << core) & i) != 0) { | ||
171 | b43_phy_set(dev, en_addr, field); | ||
172 | b43_phy_maskset(dev, val_addr, | ||
173 | ~(rf_ctrl->val_mask), | ||
174 | (value << rf_ctrl->val_shift)); | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | } else { | ||
179 | const struct nphy_rf_control_override_rev2 *rf_ctrl; | ||
180 | if (off) { | ||
181 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field)); | ||
182 | value = 0; | ||
183 | } else { | ||
184 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field); | ||
185 | } | ||
186 | |||
187 | for (i = 0; i < 2; i++) { | ||
188 | if (index <= 1 || index == 16) { | ||
189 | b43err(dev->wl, | ||
190 | "Unsupported RF Ctrl Override call\n"); | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | if (index == 2 || index == 10 || | ||
195 | (index >= 13 && index <= 15)) { | ||
196 | core = 1; | ||
197 | } | ||
198 | |||
199 | rf_ctrl = &tbl_rf_control_override_rev2[index - 2]; | ||
200 | addr = B43_PHY_N((i == 0) ? | ||
201 | rf_ctrl->addr0 : rf_ctrl->addr1); | ||
202 | |||
203 | if ((core & (1 << i)) != 0) | ||
204 | b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask), | ||
205 | (value << rf_ctrl->shift)); | ||
206 | |||
207 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); | ||
208 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
209 | B43_NPHY_RFCTL_CMD_START); | ||
210 | udelay(1); | ||
211 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE); | ||
212 | } | ||
213 | } | ||
113 | } | 214 | } |
114 | 215 | ||
115 | static void b43_chantab_radio_upload(struct b43_wldev *dev, | 216 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */ |
116 | const struct b43_nphy_channeltab_entry_rev2 *e) | 217 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, |
218 | u16 value, u8 core) | ||
117 | { | 219 | { |
118 | b43_radio_write(dev, B2055_PLL_REF, e->radio_pll_ref); | 220 | u8 i, j; |
119 | b43_radio_write(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0); | 221 | u16 reg, tmp, val; |
120 | b43_radio_write(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1); | ||
121 | b43_radio_write(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail); | ||
122 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
123 | 222 | ||
124 | b43_radio_write(dev, B2055_VCO_CAL1, e->radio_vco_cal1); | 223 | B43_WARN_ON(dev->phy.rev < 3); |
125 | b43_radio_write(dev, B2055_VCO_CAL2, e->radio_vco_cal2); | 224 | B43_WARN_ON(field > 4); |
126 | b43_radio_write(dev, B2055_PLL_LFC1, e->radio_pll_lfc1); | ||
127 | b43_radio_write(dev, B2055_PLL_LFR1, e->radio_pll_lfr1); | ||
128 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
129 | 225 | ||
130 | b43_radio_write(dev, B2055_PLL_LFC2, e->radio_pll_lfc2); | 226 | for (i = 0; i < 2; i++) { |
131 | b43_radio_write(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf); | 227 | if ((core == 1 && i == 1) || (core == 2 && !i)) |
132 | b43_radio_write(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1); | 228 | continue; |
133 | b43_radio_write(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2); | ||
134 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
135 | 229 | ||
136 | b43_radio_write(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune); | 230 | reg = (i == 0) ? |
137 | b43_radio_write(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune); | 231 | B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; |
138 | b43_radio_write(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1); | 232 | b43_phy_mask(dev, reg, 0xFBFF); |
139 | b43_radio_write(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn); | ||
140 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
141 | 233 | ||
142 | b43_radio_write(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim); | 234 | switch (field) { |
143 | b43_radio_write(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune); | 235 | case 0: |
144 | b43_radio_write(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune); | 236 | b43_phy_write(dev, reg, 0); |
145 | b43_radio_write(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1); | 237 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
146 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | 238 | break; |
239 | case 1: | ||
240 | if (!i) { | ||
241 | b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1, | ||
242 | 0xFC3F, (value << 6)); | ||
243 | b43_phy_maskset(dev, B43_NPHY_TXF_40CO_B1S1, | ||
244 | 0xFFFE, 1); | ||
245 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
246 | B43_NPHY_RFCTL_CMD_START); | ||
247 | for (j = 0; j < 100; j++) { | ||
248 | if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) { | ||
249 | j = 0; | ||
250 | break; | ||
251 | } | ||
252 | udelay(10); | ||
253 | } | ||
254 | if (j) | ||
255 | b43err(dev->wl, | ||
256 | "intc override timeout\n"); | ||
257 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, | ||
258 | 0xFFFE); | ||
259 | } else { | ||
260 | b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC2, | ||
261 | 0xFC3F, (value << 6)); | ||
262 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, | ||
263 | 0xFFFE, 1); | ||
264 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
265 | B43_NPHY_RFCTL_CMD_RXTX); | ||
266 | for (j = 0; j < 100; j++) { | ||
267 | if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) { | ||
268 | j = 0; | ||
269 | break; | ||
270 | } | ||
271 | udelay(10); | ||
272 | } | ||
273 | if (j) | ||
274 | b43err(dev->wl, | ||
275 | "intc override timeout\n"); | ||
276 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, | ||
277 | 0xFFFE); | ||
278 | } | ||
279 | break; | ||
280 | case 2: | ||
281 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
282 | tmp = 0x0020; | ||
283 | val = value << 5; | ||
284 | } else { | ||
285 | tmp = 0x0010; | ||
286 | val = value << 4; | ||
287 | } | ||
288 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
289 | break; | ||
290 | case 3: | ||
291 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
292 | tmp = 0x0001; | ||
293 | val = value; | ||
294 | } else { | ||
295 | tmp = 0x0004; | ||
296 | val = value << 2; | ||
297 | } | ||
298 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
299 | break; | ||
300 | case 4: | ||
301 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
302 | tmp = 0x0002; | ||
303 | val = value << 1; | ||
304 | } else { | ||
305 | tmp = 0x0008; | ||
306 | val = value << 3; | ||
307 | } | ||
308 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
309 | break; | ||
310 | } | ||
311 | } | ||
312 | } | ||
147 | 313 | ||
148 | b43_radio_write(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn); | 314 | /************************************************** |
149 | b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); | 315 | * Various PHY ops |
316 | **************************************************/ | ||
317 | |||
318 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */ | ||
319 | static void b43_nphy_write_clip_detection(struct b43_wldev *dev, | ||
320 | const u16 *clip_st) | ||
321 | { | ||
322 | b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]); | ||
323 | b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]); | ||
324 | } | ||
325 | |||
326 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */ | ||
327 | static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st) | ||
328 | { | ||
329 | clip_st[0] = b43_phy_read(dev, B43_NPHY_C1_CLIP1THRES); | ||
330 | clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES); | ||
331 | } | ||
332 | |||
333 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ | ||
334 | static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) | ||
335 | { | ||
336 | u16 tmp; | ||
337 | |||
338 | if (dev->dev->core_rev == 16) | ||
339 | b43_mac_suspend(dev); | ||
340 | |||
341 | tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); | ||
342 | tmp &= (B43_NPHY_CLASSCTL_CCKEN | B43_NPHY_CLASSCTL_OFDMEN | | ||
343 | B43_NPHY_CLASSCTL_WAITEDEN); | ||
344 | tmp &= ~mask; | ||
345 | tmp |= (val & mask); | ||
346 | b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); | ||
347 | |||
348 | if (dev->dev->core_rev == 16) | ||
349 | b43_mac_enable(dev); | ||
350 | |||
351 | return tmp; | ||
150 | } | 352 | } |
151 | 353 | ||
354 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ | ||
355 | static void b43_nphy_reset_cca(struct b43_wldev *dev) | ||
356 | { | ||
357 | u16 bbcfg; | ||
358 | |||
359 | b43_phy_force_clock(dev, 1); | ||
360 | bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); | ||
361 | b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA); | ||
362 | udelay(1); | ||
363 | b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); | ||
364 | b43_phy_force_clock(dev, 0); | ||
365 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | ||
366 | } | ||
367 | |||
368 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */ | ||
369 | static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable) | ||
370 | { | ||
371 | struct b43_phy *phy = &dev->phy; | ||
372 | struct b43_phy_n *nphy = phy->n; | ||
373 | |||
374 | if (enable) { | ||
375 | static const u16 clip[] = { 0xFFFF, 0xFFFF }; | ||
376 | if (nphy->deaf_count++ == 0) { | ||
377 | nphy->classifier_state = b43_nphy_classifier(dev, 0, 0); | ||
378 | b43_nphy_classifier(dev, 0x7, 0); | ||
379 | b43_nphy_read_clip_detection(dev, nphy->clip_state); | ||
380 | b43_nphy_write_clip_detection(dev, clip); | ||
381 | } | ||
382 | b43_nphy_reset_cca(dev); | ||
383 | } else { | ||
384 | if (--nphy->deaf_count == 0) { | ||
385 | b43_nphy_classifier(dev, 0x7, nphy->classifier_state); | ||
386 | b43_nphy_write_clip_detection(dev, nphy->clip_state); | ||
387 | } | ||
388 | } | ||
389 | } | ||
390 | |||
391 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */ | ||
392 | static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) | ||
393 | { | ||
394 | struct b43_phy_n *nphy = dev->phy.n; | ||
395 | |||
396 | u8 i; | ||
397 | s16 tmp; | ||
398 | u16 data[4]; | ||
399 | s16 gain[2]; | ||
400 | u16 minmax[2]; | ||
401 | static const u16 lna_gain[4] = { -2, 10, 19, 25 }; | ||
402 | |||
403 | if (nphy->hang_avoid) | ||
404 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
405 | |||
406 | if (nphy->gain_boost) { | ||
407 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
408 | gain[0] = 6; | ||
409 | gain[1] = 6; | ||
410 | } else { | ||
411 | tmp = 40370 - 315 * dev->phy.channel; | ||
412 | gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1)); | ||
413 | tmp = 23242 - 224 * dev->phy.channel; | ||
414 | gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1)); | ||
415 | } | ||
416 | } else { | ||
417 | gain[0] = 0; | ||
418 | gain[1] = 0; | ||
419 | } | ||
420 | |||
421 | for (i = 0; i < 2; i++) { | ||
422 | if (nphy->elna_gain_config) { | ||
423 | data[0] = 19 + gain[i]; | ||
424 | data[1] = 25 + gain[i]; | ||
425 | data[2] = 25 + gain[i]; | ||
426 | data[3] = 25 + gain[i]; | ||
427 | } else { | ||
428 | data[0] = lna_gain[0] + gain[i]; | ||
429 | data[1] = lna_gain[1] + gain[i]; | ||
430 | data[2] = lna_gain[2] + gain[i]; | ||
431 | data[3] = lna_gain[3] + gain[i]; | ||
432 | } | ||
433 | b43_ntab_write_bulk(dev, B43_NTAB16(i, 8), 4, data); | ||
434 | |||
435 | minmax[i] = 23 + gain[i]; | ||
436 | } | ||
437 | |||
438 | b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, ~B43_NPHY_C1_MINGAIN, | ||
439 | minmax[0] << B43_NPHY_C1_MINGAIN_SHIFT); | ||
440 | b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, ~B43_NPHY_C2_MINGAIN, | ||
441 | minmax[1] << B43_NPHY_C2_MINGAIN_SHIFT); | ||
442 | |||
443 | if (nphy->hang_avoid) | ||
444 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
445 | } | ||
446 | |||
447 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */ | ||
448 | static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, | ||
449 | u8 *events, u8 *delays, u8 length) | ||
450 | { | ||
451 | struct b43_phy_n *nphy = dev->phy.n; | ||
452 | u8 i; | ||
453 | u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F; | ||
454 | u16 offset1 = cmd << 4; | ||
455 | u16 offset2 = offset1 + 0x80; | ||
456 | |||
457 | if (nphy->hang_avoid) | ||
458 | b43_nphy_stay_in_carrier_search(dev, true); | ||
459 | |||
460 | b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events); | ||
461 | b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays); | ||
462 | |||
463 | for (i = length; i < 16; i++) { | ||
464 | b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end); | ||
465 | b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1); | ||
466 | } | ||
467 | |||
468 | if (nphy->hang_avoid) | ||
469 | b43_nphy_stay_in_carrier_search(dev, false); | ||
470 | } | ||
471 | |||
472 | /************************************************** | ||
473 | * Radio 0x2056 | ||
474 | **************************************************/ | ||
475 | |||
152 | static void b43_chantab_radio_2056_upload(struct b43_wldev *dev, | 476 | static void b43_chantab_radio_2056_upload(struct b43_wldev *dev, |
153 | const struct b43_nphy_channeltab_entry_rev3 *e) | 477 | const struct b43_nphy_channeltab_entry_rev3 *e) |
154 | { | 478 | { |
@@ -330,15 +654,1296 @@ static void b43_radio_2056_setup(struct b43_wldev *dev, | |||
330 | udelay(300); | 654 | udelay(300); |
331 | } | 655 | } |
332 | 656 | ||
333 | static void b43_chantab_phy_upload(struct b43_wldev *dev, | 657 | static void b43_radio_init2056_pre(struct b43_wldev *dev) |
334 | const struct b43_phy_n_sfo_cfg *e) | ||
335 | { | 658 | { |
336 | b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a); | 659 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, |
337 | b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2); | 660 | ~B43_NPHY_RFCTL_CMD_CHIP0PU); |
338 | b43_phy_write(dev, B43_NPHY_BW3, e->phy_bw3); | 661 | /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */ |
339 | b43_phy_write(dev, B43_NPHY_BW4, e->phy_bw4); | 662 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, |
340 | b43_phy_write(dev, B43_NPHY_BW5, e->phy_bw5); | 663 | B43_NPHY_RFCTL_CMD_OEPORFORCE); |
341 | b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6); | 664 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, |
665 | ~B43_NPHY_RFCTL_CMD_OEPORFORCE); | ||
666 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
667 | B43_NPHY_RFCTL_CMD_CHIP0PU); | ||
668 | } | ||
669 | |||
670 | static void b43_radio_init2056_post(struct b43_wldev *dev) | ||
671 | { | ||
672 | b43_radio_set(dev, B2056_SYN_COM_CTRL, 0xB); | ||
673 | b43_radio_set(dev, B2056_SYN_COM_PU, 0x2); | ||
674 | b43_radio_set(dev, B2056_SYN_COM_RESET, 0x2); | ||
675 | msleep(1); | ||
676 | b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2); | ||
677 | b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC); | ||
678 | b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1); | ||
679 | /* | ||
680 | if (nphy->init_por) | ||
681 | Call Radio 2056 Recalibrate | ||
682 | */ | ||
683 | } | ||
684 | |||
685 | /* | ||
686 | * Initialize a Broadcom 2056 N-radio | ||
687 | * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init | ||
688 | */ | ||
689 | static void b43_radio_init2056(struct b43_wldev *dev) | ||
690 | { | ||
691 | b43_radio_init2056_pre(dev); | ||
692 | b2056_upload_inittabs(dev, 0, 0); | ||
693 | b43_radio_init2056_post(dev); | ||
694 | } | ||
695 | |||
696 | /************************************************** | ||
697 | * Radio 0x2055 | ||
698 | **************************************************/ | ||
699 | |||
700 | static void b43_chantab_radio_upload(struct b43_wldev *dev, | ||
701 | const struct b43_nphy_channeltab_entry_rev2 *e) | ||
702 | { | ||
703 | b43_radio_write(dev, B2055_PLL_REF, e->radio_pll_ref); | ||
704 | b43_radio_write(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0); | ||
705 | b43_radio_write(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1); | ||
706 | b43_radio_write(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail); | ||
707 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
708 | |||
709 | b43_radio_write(dev, B2055_VCO_CAL1, e->radio_vco_cal1); | ||
710 | b43_radio_write(dev, B2055_VCO_CAL2, e->radio_vco_cal2); | ||
711 | b43_radio_write(dev, B2055_PLL_LFC1, e->radio_pll_lfc1); | ||
712 | b43_radio_write(dev, B2055_PLL_LFR1, e->radio_pll_lfr1); | ||
713 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
714 | |||
715 | b43_radio_write(dev, B2055_PLL_LFC2, e->radio_pll_lfc2); | ||
716 | b43_radio_write(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf); | ||
717 | b43_radio_write(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1); | ||
718 | b43_radio_write(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2); | ||
719 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
720 | |||
721 | b43_radio_write(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune); | ||
722 | b43_radio_write(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune); | ||
723 | b43_radio_write(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1); | ||
724 | b43_radio_write(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn); | ||
725 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
726 | |||
727 | b43_radio_write(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim); | ||
728 | b43_radio_write(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune); | ||
729 | b43_radio_write(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune); | ||
730 | b43_radio_write(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1); | ||
731 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
732 | |||
733 | b43_radio_write(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn); | ||
734 | b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); | ||
735 | } | ||
736 | |||
737 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */ | ||
738 | static void b43_radio_2055_setup(struct b43_wldev *dev, | ||
739 | const struct b43_nphy_channeltab_entry_rev2 *e) | ||
740 | { | ||
741 | B43_WARN_ON(dev->phy.rev >= 3); | ||
742 | |||
743 | b43_chantab_radio_upload(dev, e); | ||
744 | udelay(50); | ||
745 | b43_radio_write(dev, B2055_VCO_CAL10, 0x05); | ||
746 | b43_radio_write(dev, B2055_VCO_CAL10, 0x45); | ||
747 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
748 | b43_radio_write(dev, B2055_VCO_CAL10, 0x65); | ||
749 | udelay(300); | ||
750 | } | ||
751 | |||
752 | static void b43_radio_init2055_pre(struct b43_wldev *dev) | ||
753 | { | ||
754 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
755 | ~B43_NPHY_RFCTL_CMD_PORFORCE); | ||
756 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
757 | B43_NPHY_RFCTL_CMD_CHIP0PU | | ||
758 | B43_NPHY_RFCTL_CMD_OEPORFORCE); | ||
759 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
760 | B43_NPHY_RFCTL_CMD_PORFORCE); | ||
761 | } | ||
762 | |||
763 | static void b43_radio_init2055_post(struct b43_wldev *dev) | ||
764 | { | ||
765 | struct b43_phy_n *nphy = dev->phy.n; | ||
766 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
767 | int i; | ||
768 | u16 val; | ||
769 | bool workaround = false; | ||
770 | |||
771 | if (sprom->revision < 4) | ||
772 | workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM | ||
773 | && dev->dev->board_type == 0x46D | ||
774 | && dev->dev->board_rev >= 0x41); | ||
775 | else | ||
776 | workaround = | ||
777 | !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); | ||
778 | |||
779 | b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); | ||
780 | if (workaround) { | ||
781 | b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F); | ||
782 | b43_radio_mask(dev, B2055_C2_RX_BB_REG, 0x7F); | ||
783 | } | ||
784 | b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C); | ||
785 | b43_radio_write(dev, B2055_CAL_MISC, 0x3C); | ||
786 | b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE); | ||
787 | b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80); | ||
788 | b43_radio_set(dev, B2055_CAL_MISC, 0x1); | ||
789 | msleep(1); | ||
790 | b43_radio_set(dev, B2055_CAL_MISC, 0x40); | ||
791 | for (i = 0; i < 200; i++) { | ||
792 | val = b43_radio_read(dev, B2055_CAL_COUT2); | ||
793 | if (val & 0x80) { | ||
794 | i = 0; | ||
795 | break; | ||
796 | } | ||
797 | udelay(10); | ||
798 | } | ||
799 | if (i) | ||
800 | b43err(dev->wl, "radio post init timeout\n"); | ||
801 | b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); | ||
802 | b43_switch_channel(dev, dev->phy.channel); | ||
803 | b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9); | ||
804 | b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9); | ||
805 | b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83); | ||
806 | b43_radio_write(dev, B2055_C2_RX_BB_MIDACHP, 0x83); | ||
807 | b43_radio_maskset(dev, B2055_C1_LNA_GAINBST, 0xFFF8, 0x6); | ||
808 | b43_radio_maskset(dev, B2055_C2_LNA_GAINBST, 0xFFF8, 0x6); | ||
809 | if (!nphy->gain_boost) { | ||
810 | b43_radio_set(dev, B2055_C1_RX_RFSPC1, 0x2); | ||
811 | b43_radio_set(dev, B2055_C2_RX_RFSPC1, 0x2); | ||
812 | } else { | ||
813 | b43_radio_mask(dev, B2055_C1_RX_RFSPC1, 0xFFFD); | ||
814 | b43_radio_mask(dev, B2055_C2_RX_RFSPC1, 0xFFFD); | ||
815 | } | ||
816 | udelay(2); | ||
817 | } | ||
818 | |||
819 | /* | ||
820 | * Initialize a Broadcom 2055 N-radio | ||
821 | * http://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init | ||
822 | */ | ||
823 | static void b43_radio_init2055(struct b43_wldev *dev) | ||
824 | { | ||
825 | b43_radio_init2055_pre(dev); | ||
826 | if (b43_status(dev) < B43_STAT_INITIALIZED) { | ||
827 | /* Follow wl, not specs. Do not force uploading all regs */ | ||
828 | b2055_upload_inittab(dev, 0, 0); | ||
829 | } else { | ||
830 | bool ghz5 = b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ; | ||
831 | b2055_upload_inittab(dev, ghz5, 0); | ||
832 | } | ||
833 | b43_radio_init2055_post(dev); | ||
834 | } | ||
835 | |||
836 | /************************************************** | ||
837 | * Samples | ||
838 | **************************************************/ | ||
839 | |||
840 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */ | ||
841 | static int b43_nphy_load_samples(struct b43_wldev *dev, | ||
842 | struct b43_c32 *samples, u16 len) { | ||
843 | struct b43_phy_n *nphy = dev->phy.n; | ||
844 | u16 i; | ||
845 | u32 *data; | ||
846 | |||
847 | data = kzalloc(len * sizeof(u32), GFP_KERNEL); | ||
848 | if (!data) { | ||
849 | b43err(dev->wl, "allocation for samples loading failed\n"); | ||
850 | return -ENOMEM; | ||
851 | } | ||
852 | if (nphy->hang_avoid) | ||
853 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
854 | |||
855 | for (i = 0; i < len; i++) { | ||
856 | data[i] = (samples[i].i & 0x3FF << 10); | ||
857 | data[i] |= samples[i].q & 0x3FF; | ||
858 | } | ||
859 | b43_ntab_write_bulk(dev, B43_NTAB32(17, 0), len, data); | ||
860 | |||
861 | kfree(data); | ||
862 | if (nphy->hang_avoid) | ||
863 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */ | ||
868 | static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, | ||
869 | bool test) | ||
870 | { | ||
871 | int i; | ||
872 | u16 bw, len, rot, angle; | ||
873 | struct b43_c32 *samples; | ||
874 | |||
875 | |||
876 | bw = (dev->phy.is_40mhz) ? 40 : 20; | ||
877 | len = bw << 3; | ||
878 | |||
879 | if (test) { | ||
880 | if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX) | ||
881 | bw = 82; | ||
882 | else | ||
883 | bw = 80; | ||
884 | |||
885 | if (dev->phy.is_40mhz) | ||
886 | bw <<= 1; | ||
887 | |||
888 | len = bw << 1; | ||
889 | } | ||
890 | |||
891 | samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL); | ||
892 | if (!samples) { | ||
893 | b43err(dev->wl, "allocation for samples generation failed\n"); | ||
894 | return 0; | ||
895 | } | ||
896 | rot = (((freq * 36) / bw) << 16) / 100; | ||
897 | angle = 0; | ||
898 | |||
899 | for (i = 0; i < len; i++) { | ||
900 | samples[i] = b43_cordic(angle); | ||
901 | angle += rot; | ||
902 | samples[i].q = CORDIC_CONVERT(samples[i].q * max); | ||
903 | samples[i].i = CORDIC_CONVERT(samples[i].i * max); | ||
904 | } | ||
905 | |||
906 | i = b43_nphy_load_samples(dev, samples, len); | ||
907 | kfree(samples); | ||
908 | return (i < 0) ? 0 : len; | ||
909 | } | ||
910 | |||
911 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ | ||
912 | static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, | ||
913 | u16 wait, bool iqmode, bool dac_test) | ||
914 | { | ||
915 | struct b43_phy_n *nphy = dev->phy.n; | ||
916 | int i; | ||
917 | u16 seq_mode; | ||
918 | u32 tmp; | ||
919 | |||
920 | if (nphy->hang_avoid) | ||
921 | b43_nphy_stay_in_carrier_search(dev, true); | ||
922 | |||
923 | if ((nphy->bb_mult_save & 0x80000000) == 0) { | ||
924 | tmp = b43_ntab_read(dev, B43_NTAB16(15, 87)); | ||
925 | nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000; | ||
926 | } | ||
927 | |||
928 | if (!dev->phy.is_40mhz) | ||
929 | tmp = 0x6464; | ||
930 | else | ||
931 | tmp = 0x4747; | ||
932 | b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); | ||
933 | |||
934 | if (nphy->hang_avoid) | ||
935 | b43_nphy_stay_in_carrier_search(dev, false); | ||
936 | |||
937 | b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1)); | ||
938 | |||
939 | if (loops != 0xFFFF) | ||
940 | b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1)); | ||
941 | else | ||
942 | b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops); | ||
943 | |||
944 | b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait); | ||
945 | |||
946 | seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); | ||
947 | |||
948 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER); | ||
949 | if (iqmode) { | ||
950 | b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); | ||
951 | b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000); | ||
952 | } else { | ||
953 | if (dac_test) | ||
954 | b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5); | ||
955 | else | ||
956 | b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1); | ||
957 | } | ||
958 | for (i = 0; i < 100; i++) { | ||
959 | if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) { | ||
960 | i = 0; | ||
961 | break; | ||
962 | } | ||
963 | udelay(10); | ||
964 | } | ||
965 | if (i) | ||
966 | b43err(dev->wl, "run samples timeout\n"); | ||
967 | |||
968 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); | ||
969 | } | ||
970 | |||
971 | /************************************************** | ||
972 | * RSSI | ||
973 | **************************************************/ | ||
974 | |||
975 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */ | ||
976 | static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, | ||
977 | s8 offset, u8 core, u8 rail, | ||
978 | enum b43_nphy_rssi_type type) | ||
979 | { | ||
980 | u16 tmp; | ||
981 | bool core1or5 = (core == 1) || (core == 5); | ||
982 | bool core2or5 = (core == 2) || (core == 5); | ||
983 | |||
984 | offset = clamp_val(offset, -32, 31); | ||
985 | tmp = ((scale & 0x3F) << 8) | (offset & 0x3F); | ||
986 | |||
987 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) | ||
988 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); | ||
989 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) | ||
990 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); | ||
991 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) | ||
992 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); | ||
993 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) | ||
994 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); | ||
995 | |||
996 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) | ||
997 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); | ||
998 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) | ||
999 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); | ||
1000 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) | ||
1001 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); | ||
1002 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) | ||
1003 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); | ||
1004 | |||
1005 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) | ||
1006 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); | ||
1007 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) | ||
1008 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); | ||
1009 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) | ||
1010 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); | ||
1011 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) | ||
1012 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); | ||
1013 | |||
1014 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) | ||
1015 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); | ||
1016 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) | ||
1017 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); | ||
1018 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) | ||
1019 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); | ||
1020 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) | ||
1021 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); | ||
1022 | |||
1023 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) | ||
1024 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); | ||
1025 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) | ||
1026 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); | ||
1027 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) | ||
1028 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); | ||
1029 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) | ||
1030 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); | ||
1031 | |||
1032 | if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I)) | ||
1033 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); | ||
1034 | if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I)) | ||
1035 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); | ||
1036 | |||
1037 | if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q)) | ||
1038 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); | ||
1039 | if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q)) | ||
1040 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); | ||
1041 | } | ||
1042 | |||
1043 | static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
1044 | { | ||
1045 | u8 i; | ||
1046 | u16 reg, val; | ||
1047 | |||
1048 | if (code == 0) { | ||
1049 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF); | ||
1050 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF); | ||
1051 | b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF); | ||
1052 | b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF); | ||
1053 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF); | ||
1054 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF); | ||
1055 | b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3); | ||
1056 | b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3); | ||
1057 | } else { | ||
1058 | for (i = 0; i < 2; i++) { | ||
1059 | if ((code == 1 && i == 1) || (code == 2 && !i)) | ||
1060 | continue; | ||
1061 | |||
1062 | reg = (i == 0) ? | ||
1063 | B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER; | ||
1064 | b43_phy_maskset(dev, reg, 0xFDFF, 0x0200); | ||
1065 | |||
1066 | if (type < 3) { | ||
1067 | reg = (i == 0) ? | ||
1068 | B43_NPHY_AFECTL_C1 : | ||
1069 | B43_NPHY_AFECTL_C2; | ||
1070 | b43_phy_maskset(dev, reg, 0xFCFF, 0); | ||
1071 | |||
1072 | reg = (i == 0) ? | ||
1073 | B43_NPHY_RFCTL_LUT_TRSW_UP1 : | ||
1074 | B43_NPHY_RFCTL_LUT_TRSW_UP2; | ||
1075 | b43_phy_maskset(dev, reg, 0xFFC3, 0); | ||
1076 | |||
1077 | if (type == 0) | ||
1078 | val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8; | ||
1079 | else if (type == 1) | ||
1080 | val = 16; | ||
1081 | else | ||
1082 | val = 32; | ||
1083 | b43_phy_set(dev, reg, val); | ||
1084 | |||
1085 | reg = (i == 0) ? | ||
1086 | B43_NPHY_TXF_40CO_B1S0 : | ||
1087 | B43_NPHY_TXF_40CO_B32S1; | ||
1088 | b43_phy_set(dev, reg, 0x0020); | ||
1089 | } else { | ||
1090 | if (type == 6) | ||
1091 | val = 0x0100; | ||
1092 | else if (type == 3) | ||
1093 | val = 0x0200; | ||
1094 | else | ||
1095 | val = 0x0300; | ||
1096 | |||
1097 | reg = (i == 0) ? | ||
1098 | B43_NPHY_AFECTL_C1 : | ||
1099 | B43_NPHY_AFECTL_C2; | ||
1100 | |||
1101 | b43_phy_maskset(dev, reg, 0xFCFF, val); | ||
1102 | b43_phy_maskset(dev, reg, 0xF3FF, val << 2); | ||
1103 | |||
1104 | if (type != 3 && type != 6) { | ||
1105 | enum ieee80211_band band = | ||
1106 | b43_current_band(dev->wl); | ||
1107 | |||
1108 | if (b43_nphy_ipa(dev)) | ||
1109 | val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; | ||
1110 | else | ||
1111 | val = 0x11; | ||
1112 | reg = (i == 0) ? 0x2000 : 0x3000; | ||
1113 | reg |= B2055_PADDRV; | ||
1114 | b43_radio_write16(dev, reg, val); | ||
1115 | |||
1116 | reg = (i == 0) ? | ||
1117 | B43_NPHY_AFECTL_OVER1 : | ||
1118 | B43_NPHY_AFECTL_OVER; | ||
1119 | b43_phy_set(dev, reg, 0x0200); | ||
1120 | } | ||
1121 | } | ||
1122 | } | ||
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
1127 | { | ||
1128 | u16 val; | ||
1129 | |||
1130 | if (type < 3) | ||
1131 | val = 0; | ||
1132 | else if (type == 6) | ||
1133 | val = 1; | ||
1134 | else if (type == 3) | ||
1135 | val = 2; | ||
1136 | else | ||
1137 | val = 3; | ||
1138 | |||
1139 | val = (val << 12) | (val << 14); | ||
1140 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); | ||
1141 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); | ||
1142 | |||
1143 | if (type < 3) { | ||
1144 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, | ||
1145 | (type + 1) << 4); | ||
1146 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, | ||
1147 | (type + 1) << 4); | ||
1148 | } | ||
1149 | |||
1150 | if (code == 0) { | ||
1151 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000); | ||
1152 | if (type < 3) { | ||
1153 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
1154 | ~(B43_NPHY_RFCTL_CMD_RXEN | | ||
1155 | B43_NPHY_RFCTL_CMD_CORESEL)); | ||
1156 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, | ||
1157 | ~(0x1 << 12 | | ||
1158 | 0x1 << 5 | | ||
1159 | 0x1 << 1 | | ||
1160 | 0x1)); | ||
1161 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
1162 | ~B43_NPHY_RFCTL_CMD_START); | ||
1163 | udelay(20); | ||
1164 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1); | ||
1165 | } | ||
1166 | } else { | ||
1167 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000); | ||
1168 | if (type < 3) { | ||
1169 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, | ||
1170 | ~(B43_NPHY_RFCTL_CMD_RXEN | | ||
1171 | B43_NPHY_RFCTL_CMD_CORESEL), | ||
1172 | (B43_NPHY_RFCTL_CMD_RXEN | | ||
1173 | code << B43_NPHY_RFCTL_CMD_CORESEL_SHIFT)); | ||
1174 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, | ||
1175 | (0x1 << 12 | | ||
1176 | 0x1 << 5 | | ||
1177 | 0x1 << 1 | | ||
1178 | 0x1)); | ||
1179 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
1180 | B43_NPHY_RFCTL_CMD_START); | ||
1181 | udelay(20); | ||
1182 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1); | ||
1183 | } | ||
1184 | } | ||
1185 | } | ||
1186 | |||
1187 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ | ||
1188 | static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
1189 | { | ||
1190 | if (dev->phy.rev >= 3) | ||
1191 | b43_nphy_rev3_rssi_select(dev, code, type); | ||
1192 | else | ||
1193 | b43_nphy_rev2_rssi_select(dev, code, type); | ||
1194 | } | ||
1195 | |||
1196 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ | ||
1197 | static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) | ||
1198 | { | ||
1199 | int i; | ||
1200 | for (i = 0; i < 2; i++) { | ||
1201 | if (type == 2) { | ||
1202 | if (i == 0) { | ||
1203 | b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM, | ||
1204 | 0xFC, buf[0]); | ||
1205 | b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5, | ||
1206 | 0xFC, buf[1]); | ||
1207 | } else { | ||
1208 | b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM, | ||
1209 | 0xFC, buf[2 * i]); | ||
1210 | b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5, | ||
1211 | 0xFC, buf[2 * i + 1]); | ||
1212 | } | ||
1213 | } else { | ||
1214 | if (i == 0) | ||
1215 | b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5, | ||
1216 | 0xF3, buf[0] << 2); | ||
1217 | else | ||
1218 | b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5, | ||
1219 | 0xF3, buf[2 * i + 1] << 2); | ||
1220 | } | ||
1221 | } | ||
1222 | } | ||
1223 | |||
1224 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */ | ||
1225 | static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | ||
1226 | u8 nsamp) | ||
1227 | { | ||
1228 | int i; | ||
1229 | int out; | ||
1230 | u16 save_regs_phy[9]; | ||
1231 | u16 s[2]; | ||
1232 | |||
1233 | if (dev->phy.rev >= 3) { | ||
1234 | save_regs_phy[0] = b43_phy_read(dev, | ||
1235 | B43_NPHY_RFCTL_LUT_TRSW_UP1); | ||
1236 | save_regs_phy[1] = b43_phy_read(dev, | ||
1237 | B43_NPHY_RFCTL_LUT_TRSW_UP2); | ||
1238 | save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
1239 | save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
1240 | save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); | ||
1241 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
1242 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); | ||
1243 | save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); | ||
1244 | save_regs_phy[8] = 0; | ||
1245 | } else { | ||
1246 | save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
1247 | save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
1248 | save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
1249 | save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD); | ||
1250 | save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); | ||
1251 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); | ||
1252 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); | ||
1253 | save_regs_phy[7] = 0; | ||
1254 | save_regs_phy[8] = 0; | ||
1255 | } | ||
1256 | |||
1257 | b43_nphy_rssi_select(dev, 5, type); | ||
1258 | |||
1259 | if (dev->phy.rev < 2) { | ||
1260 | save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL); | ||
1261 | b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5); | ||
1262 | } | ||
1263 | |||
1264 | for (i = 0; i < 4; i++) | ||
1265 | buf[i] = 0; | ||
1266 | |||
1267 | for (i = 0; i < nsamp; i++) { | ||
1268 | if (dev->phy.rev < 2) { | ||
1269 | s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT); | ||
1270 | s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT); | ||
1271 | } else { | ||
1272 | s[0] = b43_phy_read(dev, B43_NPHY_RSSI1); | ||
1273 | s[1] = b43_phy_read(dev, B43_NPHY_RSSI2); | ||
1274 | } | ||
1275 | |||
1276 | buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2; | ||
1277 | buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2; | ||
1278 | buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2; | ||
1279 | buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2; | ||
1280 | } | ||
1281 | out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 | | ||
1282 | (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF); | ||
1283 | |||
1284 | if (dev->phy.rev < 2) | ||
1285 | b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]); | ||
1286 | |||
1287 | if (dev->phy.rev >= 3) { | ||
1288 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, | ||
1289 | save_regs_phy[0]); | ||
1290 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, | ||
1291 | save_regs_phy[1]); | ||
1292 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]); | ||
1293 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]); | ||
1294 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]); | ||
1295 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); | ||
1296 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); | ||
1297 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]); | ||
1298 | } else { | ||
1299 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]); | ||
1300 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]); | ||
1301 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]); | ||
1302 | b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]); | ||
1303 | b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]); | ||
1304 | b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]); | ||
1305 | b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]); | ||
1306 | } | ||
1307 | |||
1308 | return out; | ||
1309 | } | ||
1310 | |||
1311 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ | ||
1312 | static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) | ||
1313 | { | ||
1314 | int i, j; | ||
1315 | u8 state[4]; | ||
1316 | u8 code, val; | ||
1317 | u16 class, override; | ||
1318 | u8 regs_save_radio[2]; | ||
1319 | u16 regs_save_phy[2]; | ||
1320 | |||
1321 | s8 offset[4]; | ||
1322 | u8 core; | ||
1323 | u8 rail; | ||
1324 | |||
1325 | u16 clip_state[2]; | ||
1326 | u16 clip_off[2] = { 0xFFFF, 0xFFFF }; | ||
1327 | s32 results_min[4] = { }; | ||
1328 | u8 vcm_final[4] = { }; | ||
1329 | s32 results[4][4] = { }; | ||
1330 | s32 miniq[4][2] = { }; | ||
1331 | |||
1332 | if (type == 2) { | ||
1333 | code = 0; | ||
1334 | val = 6; | ||
1335 | } else if (type < 2) { | ||
1336 | code = 25; | ||
1337 | val = 4; | ||
1338 | } else { | ||
1339 | B43_WARN_ON(1); | ||
1340 | return; | ||
1341 | } | ||
1342 | |||
1343 | class = b43_nphy_classifier(dev, 0, 0); | ||
1344 | b43_nphy_classifier(dev, 7, 4); | ||
1345 | b43_nphy_read_clip_detection(dev, clip_state); | ||
1346 | b43_nphy_write_clip_detection(dev, clip_off); | ||
1347 | |||
1348 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
1349 | override = 0x140; | ||
1350 | else | ||
1351 | override = 0x110; | ||
1352 | |||
1353 | regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
1354 | regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX); | ||
1355 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override); | ||
1356 | b43_radio_write16(dev, B2055_C1_PD_RXTX, val); | ||
1357 | |||
1358 | regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
1359 | regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX); | ||
1360 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override); | ||
1361 | b43_radio_write16(dev, B2055_C2_PD_RXTX, val); | ||
1362 | |||
1363 | state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07; | ||
1364 | state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07; | ||
1365 | b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8); | ||
1366 | b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8); | ||
1367 | state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07; | ||
1368 | state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07; | ||
1369 | |||
1370 | b43_nphy_rssi_select(dev, 5, type); | ||
1371 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type); | ||
1372 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type); | ||
1373 | |||
1374 | for (i = 0; i < 4; i++) { | ||
1375 | u8 tmp[4]; | ||
1376 | for (j = 0; j < 4; j++) | ||
1377 | tmp[j] = i; | ||
1378 | if (type != 1) | ||
1379 | b43_nphy_set_rssi_2055_vcm(dev, type, tmp); | ||
1380 | b43_nphy_poll_rssi(dev, type, results[i], 8); | ||
1381 | if (type < 2) | ||
1382 | for (j = 0; j < 2; j++) | ||
1383 | miniq[i][j] = min(results[i][2 * j], | ||
1384 | results[i][2 * j + 1]); | ||
1385 | } | ||
1386 | |||
1387 | for (i = 0; i < 4; i++) { | ||
1388 | s32 mind = 40; | ||
1389 | u8 minvcm = 0; | ||
1390 | s32 minpoll = 249; | ||
1391 | s32 curr; | ||
1392 | for (j = 0; j < 4; j++) { | ||
1393 | if (type == 2) | ||
1394 | curr = abs(results[j][i]); | ||
1395 | else | ||
1396 | curr = abs(miniq[j][i / 2] - code * 8); | ||
1397 | |||
1398 | if (curr < mind) { | ||
1399 | mind = curr; | ||
1400 | minvcm = j; | ||
1401 | } | ||
1402 | |||
1403 | if (results[j][i] < minpoll) | ||
1404 | minpoll = results[j][i]; | ||
1405 | } | ||
1406 | results_min[i] = minpoll; | ||
1407 | vcm_final[i] = minvcm; | ||
1408 | } | ||
1409 | |||
1410 | if (type != 1) | ||
1411 | b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final); | ||
1412 | |||
1413 | for (i = 0; i < 4; i++) { | ||
1414 | offset[i] = (code * 8) - results[vcm_final[i]][i]; | ||
1415 | |||
1416 | if (offset[i] < 0) | ||
1417 | offset[i] = -((abs(offset[i]) + 4) / 8); | ||
1418 | else | ||
1419 | offset[i] = (offset[i] + 4) / 8; | ||
1420 | |||
1421 | if (results_min[i] == 248) | ||
1422 | offset[i] = code - 32; | ||
1423 | |||
1424 | core = (i / 2) ? 2 : 1; | ||
1425 | rail = (i % 2) ? 1 : 0; | ||
1426 | |||
1427 | b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail, | ||
1428 | type); | ||
1429 | } | ||
1430 | |||
1431 | b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]); | ||
1432 | b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]); | ||
1433 | |||
1434 | switch (state[2]) { | ||
1435 | case 1: | ||
1436 | b43_nphy_rssi_select(dev, 1, 2); | ||
1437 | break; | ||
1438 | case 4: | ||
1439 | b43_nphy_rssi_select(dev, 1, 0); | ||
1440 | break; | ||
1441 | case 2: | ||
1442 | b43_nphy_rssi_select(dev, 1, 1); | ||
1443 | break; | ||
1444 | default: | ||
1445 | b43_nphy_rssi_select(dev, 1, 1); | ||
1446 | break; | ||
1447 | } | ||
1448 | |||
1449 | switch (state[3]) { | ||
1450 | case 1: | ||
1451 | b43_nphy_rssi_select(dev, 2, 2); | ||
1452 | break; | ||
1453 | case 4: | ||
1454 | b43_nphy_rssi_select(dev, 2, 0); | ||
1455 | break; | ||
1456 | default: | ||
1457 | b43_nphy_rssi_select(dev, 2, 1); | ||
1458 | break; | ||
1459 | } | ||
1460 | |||
1461 | b43_nphy_rssi_select(dev, 0, type); | ||
1462 | |||
1463 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]); | ||
1464 | b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]); | ||
1465 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]); | ||
1466 | b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]); | ||
1467 | |||
1468 | b43_nphy_classifier(dev, 7, class); | ||
1469 | b43_nphy_write_clip_detection(dev, clip_state); | ||
1470 | /* Specs don't say about reset here, but it makes wl and b43 dumps | ||
1471 | identical, it really seems wl performs this */ | ||
1472 | b43_nphy_reset_cca(dev); | ||
1473 | } | ||
1474 | |||
1475 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ | ||
1476 | static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | ||
1477 | { | ||
1478 | /* TODO */ | ||
1479 | } | ||
1480 | |||
1481 | /* | ||
1482 | * RSSI Calibration | ||
1483 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal | ||
1484 | */ | ||
1485 | static void b43_nphy_rssi_cal(struct b43_wldev *dev) | ||
1486 | { | ||
1487 | if (dev->phy.rev >= 3) { | ||
1488 | b43_nphy_rev3_rssi_cal(dev); | ||
1489 | } else { | ||
1490 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z); | ||
1491 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X); | ||
1492 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y); | ||
1493 | } | ||
1494 | } | ||
1495 | |||
1496 | /************************************************** | ||
1497 | * Workarounds | ||
1498 | **************************************************/ | ||
1499 | |||
1500 | static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev) | ||
1501 | { | ||
1502 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
1503 | |||
1504 | bool ghz5; | ||
1505 | bool ext_lna; | ||
1506 | u16 rssi_gain; | ||
1507 | struct nphy_gain_ctl_workaround_entry *e; | ||
1508 | u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; | ||
1509 | u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; | ||
1510 | |||
1511 | /* Prepare values */ | ||
1512 | ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL) | ||
1513 | & B43_NPHY_BANDCTL_5GHZ; | ||
1514 | ext_lna = sprom->boardflags_lo & B43_BFL_EXTLNA; | ||
1515 | e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna); | ||
1516 | if (ghz5 && dev->phy.rev >= 5) | ||
1517 | rssi_gain = 0x90; | ||
1518 | else | ||
1519 | rssi_gain = 0x50; | ||
1520 | |||
1521 | b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040); | ||
1522 | |||
1523 | /* Set Clip 2 detect */ | ||
1524 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | ||
1525 | B43_NPHY_C1_CGAINI_CL2DETECT); | ||
1526 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
1527 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
1528 | |||
1529 | b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC, | ||
1530 | 0x17); | ||
1531 | b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAG1_IDAC, | ||
1532 | 0x17); | ||
1533 | b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG2_IDAC, 0xF0); | ||
1534 | b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG2_IDAC, 0xF0); | ||
1535 | b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_POLE, 0x00); | ||
1536 | b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_POLE, 0x00); | ||
1537 | b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_GAIN, | ||
1538 | rssi_gain); | ||
1539 | b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_GAIN, | ||
1540 | rssi_gain); | ||
1541 | b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAA1_IDAC, | ||
1542 | 0x17); | ||
1543 | b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAA1_IDAC, | ||
1544 | 0x17); | ||
1545 | b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA2_IDAC, 0xFF); | ||
1546 | b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA2_IDAC, 0xFF); | ||
1547 | |||
1548 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 8), 4, e->lna1_gain); | ||
1549 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 8), 4, e->lna1_gain); | ||
1550 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 16), 4, e->lna2_gain); | ||
1551 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 16), 4, e->lna2_gain); | ||
1552 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 32), 10, e->gain_db); | ||
1553 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 32), 10, e->gain_db); | ||
1554 | b43_ntab_write_bulk(dev, B43_NTAB8(2, 32), 10, e->gain_bits); | ||
1555 | b43_ntab_write_bulk(dev, B43_NTAB8(3, 32), 10, e->gain_bits); | ||
1556 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 0x40), 6, lpf_gain); | ||
1557 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 0x40), 6, lpf_gain); | ||
1558 | b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits); | ||
1559 | b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits); | ||
1560 | |||
1561 | b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); | ||
1562 | b43_phy_write(dev, 0x2A7, e->init_gain); | ||
1563 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, | ||
1564 | e->rfseq_init); | ||
1565 | b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); | ||
1566 | |||
1567 | /* TODO: check defines. Do not match variables names */ | ||
1568 | b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain); | ||
1569 | b43_phy_write(dev, 0x2A9, e->cliphi_gain); | ||
1570 | b43_phy_write(dev, B43_NPHY_C1_CLIP2_GAIN, e->clipmd_gain); | ||
1571 | b43_phy_write(dev, 0x2AB, e->clipmd_gain); | ||
1572 | b43_phy_write(dev, B43_NPHY_C2_CLIP1_HIGAIN, e->cliplo_gain); | ||
1573 | b43_phy_write(dev, 0x2AD, e->cliplo_gain); | ||
1574 | |||
1575 | b43_phy_maskset(dev, 0x27D, 0xFF00, e->crsmin); | ||
1576 | b43_phy_maskset(dev, 0x280, 0xFF00, e->crsminl); | ||
1577 | b43_phy_maskset(dev, 0x283, 0xFF00, e->crsminu); | ||
1578 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip); | ||
1579 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip); | ||
1580 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
1581 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, e->wlclip); | ||
1582 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
1583 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, e->wlclip); | ||
1584 | b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); | ||
1585 | } | ||
1586 | |||
1587 | static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev) | ||
1588 | { | ||
1589 | struct b43_phy_n *nphy = dev->phy.n; | ||
1590 | |||
1591 | u8 i, j; | ||
1592 | u8 code; | ||
1593 | u16 tmp; | ||
1594 | u8 rfseq_events[3] = { 6, 8, 7 }; | ||
1595 | u8 rfseq_delays[3] = { 10, 30, 1 }; | ||
1596 | |||
1597 | /* Set Clip 2 detect */ | ||
1598 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, B43_NPHY_C1_CGAINI_CL2DETECT); | ||
1599 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, B43_NPHY_C2_CGAINI_CL2DETECT); | ||
1600 | |||
1601 | /* Set narrowband clip threshold */ | ||
1602 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); | ||
1603 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); | ||
1604 | |||
1605 | if (!dev->phy.is_40mhz) { | ||
1606 | /* Set dwell lengths */ | ||
1607 | b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); | ||
1608 | b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); | ||
1609 | b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009); | ||
1610 | b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009); | ||
1611 | } | ||
1612 | |||
1613 | /* Set wideband clip 2 threshold */ | ||
1614 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
1615 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, 21); | ||
1616 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
1617 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21); | ||
1618 | |||
1619 | if (!dev->phy.is_40mhz) { | ||
1620 | b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, | ||
1621 | ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1); | ||
1622 | b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, | ||
1623 | ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1); | ||
1624 | b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI, | ||
1625 | ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1); | ||
1626 | b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI, | ||
1627 | ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1); | ||
1628 | } | ||
1629 | |||
1630 | b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); | ||
1631 | |||
1632 | if (nphy->gain_boost) { | ||
1633 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ && | ||
1634 | dev->phy.is_40mhz) | ||
1635 | code = 4; | ||
1636 | else | ||
1637 | code = 5; | ||
1638 | } else { | ||
1639 | code = dev->phy.is_40mhz ? 6 : 7; | ||
1640 | } | ||
1641 | |||
1642 | /* Set HPVGA2 index */ | ||
1643 | b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, ~B43_NPHY_C1_INITGAIN_HPVGA2, | ||
1644 | code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); | ||
1645 | b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, ~B43_NPHY_C2_INITGAIN_HPVGA2, | ||
1646 | code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); | ||
1647 | |||
1648 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); | ||
1649 | /* specs say about 2 loops, but wl does 4 */ | ||
1650 | for (i = 0; i < 4; i++) | ||
1651 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, (code << 8 | 0x7C)); | ||
1652 | |||
1653 | b43_nphy_adjust_lna_gain_table(dev); | ||
1654 | |||
1655 | if (nphy->elna_gain_config) { | ||
1656 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); | ||
1657 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); | ||
1658 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1659 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1660 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1661 | |||
1662 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08); | ||
1663 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); | ||
1664 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1665 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1666 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1667 | |||
1668 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); | ||
1669 | /* specs say about 2 loops, but wl does 4 */ | ||
1670 | for (i = 0; i < 4; i++) | ||
1671 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
1672 | (code << 8 | 0x74)); | ||
1673 | } | ||
1674 | |||
1675 | if (dev->phy.rev == 2) { | ||
1676 | for (i = 0; i < 4; i++) { | ||
1677 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, | ||
1678 | (0x0400 * i) + 0x0020); | ||
1679 | for (j = 0; j < 21; j++) { | ||
1680 | tmp = j * (i < 2 ? 3 : 1); | ||
1681 | b43_phy_write(dev, | ||
1682 | B43_NPHY_TABLE_DATALO, tmp); | ||
1683 | } | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | b43_nphy_set_rf_sequence(dev, 5, rfseq_events, rfseq_delays, 3); | ||
1688 | b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, | ||
1689 | ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF, | ||
1690 | 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); | ||
1691 | |||
1692 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
1693 | b43_phy_maskset(dev, B43_PHY_N(0xC5D), 0xFF80, 4); | ||
1694 | } | ||
1695 | |||
1696 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ | ||
1697 | static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev) | ||
1698 | { | ||
1699 | if (dev->phy.rev >= 3) | ||
1700 | b43_nphy_gain_ctl_workarounds_rev3plus(dev); | ||
1701 | else | ||
1702 | b43_nphy_gain_ctl_workarounds_rev1_2(dev); | ||
1703 | } | ||
1704 | |||
1705 | static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) | ||
1706 | { | ||
1707 | struct b43_phy_n *nphy = dev->phy.n; | ||
1708 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
1709 | |||
1710 | /* TX to RX */ | ||
1711 | u8 tx2rx_events[8] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F }; | ||
1712 | u8 tx2rx_delays[8] = { 8, 4, 2, 2, 4, 4, 6, 1 }; | ||
1713 | /* RX to TX */ | ||
1714 | u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3, | ||
1715 | 0x1F }; | ||
1716 | u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; | ||
1717 | u8 rx2tx_events[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0x3, 0x4, 0x1F }; | ||
1718 | u8 rx2tx_delays[9] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; | ||
1719 | |||
1720 | u16 tmp16; | ||
1721 | u32 tmp32; | ||
1722 | |||
1723 | b43_phy_write(dev, 0x23f, 0x1f8); | ||
1724 | b43_phy_write(dev, 0x240, 0x1f8); | ||
1725 | |||
1726 | tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); | ||
1727 | tmp32 &= 0xffffff; | ||
1728 | b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32); | ||
1729 | |||
1730 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125); | ||
1731 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3); | ||
1732 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105); | ||
1733 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E); | ||
1734 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); | ||
1735 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); | ||
1736 | |||
1737 | b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); | ||
1738 | b43_phy_write(dev, 0x2AE, 0x000C); | ||
1739 | |||
1740 | /* TX to RX */ | ||
1741 | b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays, | ||
1742 | ARRAY_SIZE(tx2rx_events)); | ||
1743 | |||
1744 | /* RX to TX */ | ||
1745 | if (b43_nphy_ipa(dev)) | ||
1746 | b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa, | ||
1747 | rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa)); | ||
1748 | if (nphy->hw_phyrxchain != 3 && | ||
1749 | nphy->hw_phyrxchain != nphy->hw_phytxchain) { | ||
1750 | if (b43_nphy_ipa(dev)) { | ||
1751 | rx2tx_delays[5] = 59; | ||
1752 | rx2tx_delays[6] = 1; | ||
1753 | rx2tx_events[7] = 0x1F; | ||
1754 | } | ||
1755 | b43_nphy_set_rf_sequence(dev, 1, rx2tx_events, rx2tx_delays, | ||
1756 | ARRAY_SIZE(rx2tx_events)); | ||
1757 | } | ||
1758 | |||
1759 | tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? | ||
1760 | 0x2 : 0x9C40; | ||
1761 | b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); | ||
1762 | |||
1763 | b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); | ||
1764 | |||
1765 | b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); | ||
1766 | b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D); | ||
1767 | |||
1768 | b43_nphy_gain_ctl_workarounds(dev); | ||
1769 | |||
1770 | b43_ntab_write(dev, B43_NTAB16(8, 0), 2); | ||
1771 | b43_ntab_write(dev, B43_NTAB16(8, 16), 2); | ||
1772 | |||
1773 | /* TODO */ | ||
1774 | |||
1775 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00); | ||
1776 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00); | ||
1777 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06); | ||
1778 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06); | ||
1779 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07); | ||
1780 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07); | ||
1781 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88); | ||
1782 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88); | ||
1783 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_CMFB_IDAC, 0x00); | ||
1784 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_CMFB_IDAC, 0x00); | ||
1785 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | ||
1786 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | ||
1787 | |||
1788 | /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ | ||
1789 | |||
1790 | if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR && | ||
1791 | b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || | ||
1792 | (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR && | ||
1793 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) | ||
1794 | tmp32 = 0x00088888; | ||
1795 | else | ||
1796 | tmp32 = 0x88888888; | ||
1797 | b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32); | ||
1798 | b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32); | ||
1799 | b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32); | ||
1800 | |||
1801 | if (dev->phy.rev == 4 && | ||
1802 | b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
1803 | b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC, | ||
1804 | 0x70); | ||
1805 | b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC, | ||
1806 | 0x70); | ||
1807 | } | ||
1808 | |||
1809 | b43_phy_write(dev, 0x224, 0x03eb); | ||
1810 | b43_phy_write(dev, 0x225, 0x03eb); | ||
1811 | b43_phy_write(dev, 0x226, 0x0341); | ||
1812 | b43_phy_write(dev, 0x227, 0x0341); | ||
1813 | b43_phy_write(dev, 0x228, 0x042b); | ||
1814 | b43_phy_write(dev, 0x229, 0x042b); | ||
1815 | b43_phy_write(dev, 0x22a, 0x0381); | ||
1816 | b43_phy_write(dev, 0x22b, 0x0381); | ||
1817 | b43_phy_write(dev, 0x22c, 0x042b); | ||
1818 | b43_phy_write(dev, 0x22d, 0x042b); | ||
1819 | b43_phy_write(dev, 0x22e, 0x0381); | ||
1820 | b43_phy_write(dev, 0x22f, 0x0381); | ||
1821 | } | ||
1822 | |||
1823 | static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev) | ||
1824 | { | ||
1825 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
1826 | struct b43_phy *phy = &dev->phy; | ||
1827 | struct b43_phy_n *nphy = phy->n; | ||
1828 | |||
1829 | u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; | ||
1830 | u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; | ||
1831 | |||
1832 | u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; | ||
1833 | u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; | ||
1834 | |||
1835 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && | ||
1836 | nphy->band5g_pwrgain) { | ||
1837 | b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8); | ||
1838 | b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8); | ||
1839 | } else { | ||
1840 | b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); | ||
1841 | b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); | ||
1842 | } | ||
1843 | |||
1844 | b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A); | ||
1845 | b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A); | ||
1846 | b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); | ||
1847 | b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); | ||
1848 | |||
1849 | if (dev->phy.rev < 2) { | ||
1850 | b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000); | ||
1851 | b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000); | ||
1852 | b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); | ||
1853 | b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); | ||
1854 | b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800); | ||
1855 | b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800); | ||
1856 | } | ||
1857 | |||
1858 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
1859 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
1860 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
1861 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
1862 | |||
1863 | if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD && | ||
1864 | dev->dev->board_type == 0x8B) { | ||
1865 | delays1[0] = 0x1; | ||
1866 | delays1[5] = 0x14; | ||
1867 | } | ||
1868 | b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); | ||
1869 | b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); | ||
1870 | |||
1871 | b43_nphy_gain_ctl_workarounds(dev); | ||
1872 | |||
1873 | if (dev->phy.rev < 2) { | ||
1874 | if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) | ||
1875 | b43_hf_write(dev, b43_hf_read(dev) | | ||
1876 | B43_HF_MLADVW); | ||
1877 | } else if (dev->phy.rev == 2) { | ||
1878 | b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); | ||
1879 | b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); | ||
1880 | } | ||
1881 | |||
1882 | if (dev->phy.rev < 2) | ||
1883 | b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, | ||
1884 | ~B43_NPHY_SCRAM_SIGCTL_SCM); | ||
1885 | |||
1886 | /* Set phase track alpha and beta */ | ||
1887 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); | ||
1888 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); | ||
1889 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); | ||
1890 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); | ||
1891 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); | ||
1892 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); | ||
1893 | |||
1894 | b43_phy_mask(dev, B43_NPHY_PIL_DW1, | ||
1895 | ~B43_NPHY_PIL_DW_64QAM & 0xFFFF); | ||
1896 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); | ||
1897 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); | ||
1898 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); | ||
1899 | |||
1900 | if (dev->phy.rev == 2) | ||
1901 | b43_phy_set(dev, B43_NPHY_FINERX2_CGC, | ||
1902 | B43_NPHY_FINERX2_CGC_DECGC); | ||
1903 | } | ||
1904 | |||
1905 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ | ||
1906 | static void b43_nphy_workarounds(struct b43_wldev *dev) | ||
1907 | { | ||
1908 | struct b43_phy *phy = &dev->phy; | ||
1909 | struct b43_phy_n *nphy = phy->n; | ||
1910 | |||
1911 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
1912 | b43_nphy_classifier(dev, 1, 0); | ||
1913 | else | ||
1914 | b43_nphy_classifier(dev, 1, 1); | ||
1915 | |||
1916 | if (nphy->hang_avoid) | ||
1917 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
1918 | |||
1919 | b43_phy_set(dev, B43_NPHY_IQFLIP, | ||
1920 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | ||
1921 | |||
1922 | if (dev->phy.rev >= 3) | ||
1923 | b43_nphy_workarounds_rev3plus(dev); | ||
1924 | else | ||
1925 | b43_nphy_workarounds_rev1_2(dev); | ||
1926 | |||
1927 | if (nphy->hang_avoid) | ||
1928 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
1929 | } | ||
1930 | |||
1931 | /************************************************** | ||
1932 | * Tx and Rx | ||
1933 | **************************************************/ | ||
1934 | |||
1935 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | ||
1936 | {//TODO | ||
1937 | } | ||
1938 | |||
1939 | static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev) | ||
1940 | {//TODO | ||
1941 | } | ||
1942 | |||
1943 | static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev, | ||
1944 | bool ignore_tssi) | ||
1945 | {//TODO | ||
1946 | return B43_TXPWR_RES_DONE; | ||
342 | } | 1947 | } |
343 | 1948 | ||
344 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */ | 1949 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */ |
@@ -633,156 +2238,6 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) | |||
633 | } | 2238 | } |
634 | } | 2239 | } |
635 | 2240 | ||
636 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */ | ||
637 | static void b43_radio_2055_setup(struct b43_wldev *dev, | ||
638 | const struct b43_nphy_channeltab_entry_rev2 *e) | ||
639 | { | ||
640 | B43_WARN_ON(dev->phy.rev >= 3); | ||
641 | |||
642 | b43_chantab_radio_upload(dev, e); | ||
643 | udelay(50); | ||
644 | b43_radio_write(dev, B2055_VCO_CAL10, 0x05); | ||
645 | b43_radio_write(dev, B2055_VCO_CAL10, 0x45); | ||
646 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
647 | b43_radio_write(dev, B2055_VCO_CAL10, 0x65); | ||
648 | udelay(300); | ||
649 | } | ||
650 | |||
651 | static void b43_radio_init2055_pre(struct b43_wldev *dev) | ||
652 | { | ||
653 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
654 | ~B43_NPHY_RFCTL_CMD_PORFORCE); | ||
655 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
656 | B43_NPHY_RFCTL_CMD_CHIP0PU | | ||
657 | B43_NPHY_RFCTL_CMD_OEPORFORCE); | ||
658 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
659 | B43_NPHY_RFCTL_CMD_PORFORCE); | ||
660 | } | ||
661 | |||
662 | static void b43_radio_init2055_post(struct b43_wldev *dev) | ||
663 | { | ||
664 | struct b43_phy_n *nphy = dev->phy.n; | ||
665 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
666 | int i; | ||
667 | u16 val; | ||
668 | bool workaround = false; | ||
669 | |||
670 | if (sprom->revision < 4) | ||
671 | workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM | ||
672 | && dev->dev->board_type == 0x46D | ||
673 | && dev->dev->board_rev >= 0x41); | ||
674 | else | ||
675 | workaround = | ||
676 | !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); | ||
677 | |||
678 | b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); | ||
679 | if (workaround) { | ||
680 | b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F); | ||
681 | b43_radio_mask(dev, B2055_C2_RX_BB_REG, 0x7F); | ||
682 | } | ||
683 | b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C); | ||
684 | b43_radio_write(dev, B2055_CAL_MISC, 0x3C); | ||
685 | b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE); | ||
686 | b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80); | ||
687 | b43_radio_set(dev, B2055_CAL_MISC, 0x1); | ||
688 | msleep(1); | ||
689 | b43_radio_set(dev, B2055_CAL_MISC, 0x40); | ||
690 | for (i = 0; i < 200; i++) { | ||
691 | val = b43_radio_read(dev, B2055_CAL_COUT2); | ||
692 | if (val & 0x80) { | ||
693 | i = 0; | ||
694 | break; | ||
695 | } | ||
696 | udelay(10); | ||
697 | } | ||
698 | if (i) | ||
699 | b43err(dev->wl, "radio post init timeout\n"); | ||
700 | b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); | ||
701 | b43_switch_channel(dev, dev->phy.channel); | ||
702 | b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9); | ||
703 | b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9); | ||
704 | b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83); | ||
705 | b43_radio_write(dev, B2055_C2_RX_BB_MIDACHP, 0x83); | ||
706 | b43_radio_maskset(dev, B2055_C1_LNA_GAINBST, 0xFFF8, 0x6); | ||
707 | b43_radio_maskset(dev, B2055_C2_LNA_GAINBST, 0xFFF8, 0x6); | ||
708 | if (!nphy->gain_boost) { | ||
709 | b43_radio_set(dev, B2055_C1_RX_RFSPC1, 0x2); | ||
710 | b43_radio_set(dev, B2055_C2_RX_RFSPC1, 0x2); | ||
711 | } else { | ||
712 | b43_radio_mask(dev, B2055_C1_RX_RFSPC1, 0xFFFD); | ||
713 | b43_radio_mask(dev, B2055_C2_RX_RFSPC1, 0xFFFD); | ||
714 | } | ||
715 | udelay(2); | ||
716 | } | ||
717 | |||
718 | /* | ||
719 | * Initialize a Broadcom 2055 N-radio | ||
720 | * http://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init | ||
721 | */ | ||
722 | static void b43_radio_init2055(struct b43_wldev *dev) | ||
723 | { | ||
724 | b43_radio_init2055_pre(dev); | ||
725 | if (b43_status(dev) < B43_STAT_INITIALIZED) { | ||
726 | /* Follow wl, not specs. Do not force uploading all regs */ | ||
727 | b2055_upload_inittab(dev, 0, 0); | ||
728 | } else { | ||
729 | bool ghz5 = b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ; | ||
730 | b2055_upload_inittab(dev, ghz5, 0); | ||
731 | } | ||
732 | b43_radio_init2055_post(dev); | ||
733 | } | ||
734 | |||
735 | static void b43_radio_init2056_pre(struct b43_wldev *dev) | ||
736 | { | ||
737 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
738 | ~B43_NPHY_RFCTL_CMD_CHIP0PU); | ||
739 | /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */ | ||
740 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
741 | B43_NPHY_RFCTL_CMD_OEPORFORCE); | ||
742 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
743 | ~B43_NPHY_RFCTL_CMD_OEPORFORCE); | ||
744 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
745 | B43_NPHY_RFCTL_CMD_CHIP0PU); | ||
746 | } | ||
747 | |||
748 | static void b43_radio_init2056_post(struct b43_wldev *dev) | ||
749 | { | ||
750 | b43_radio_set(dev, B2056_SYN_COM_CTRL, 0xB); | ||
751 | b43_radio_set(dev, B2056_SYN_COM_PU, 0x2); | ||
752 | b43_radio_set(dev, B2056_SYN_COM_RESET, 0x2); | ||
753 | msleep(1); | ||
754 | b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2); | ||
755 | b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC); | ||
756 | b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1); | ||
757 | /* | ||
758 | if (nphy->init_por) | ||
759 | Call Radio 2056 Recalibrate | ||
760 | */ | ||
761 | } | ||
762 | |||
763 | /* | ||
764 | * Initialize a Broadcom 2056 N-radio | ||
765 | * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init | ||
766 | */ | ||
767 | static void b43_radio_init2056(struct b43_wldev *dev) | ||
768 | { | ||
769 | b43_radio_init2056_pre(dev); | ||
770 | b2056_upload_inittabs(dev, 0, 0); | ||
771 | b43_radio_init2056_post(dev); | ||
772 | } | ||
773 | |||
774 | /* | ||
775 | * Upload the N-PHY tables. | ||
776 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables | ||
777 | */ | ||
778 | static void b43_nphy_tables_init(struct b43_wldev *dev) | ||
779 | { | ||
780 | if (dev->phy.rev < 3) | ||
781 | b43_nphy_rev0_1_2_tables_init(dev); | ||
782 | else | ||
783 | b43_nphy_rev3plus_tables_init(dev); | ||
784 | } | ||
785 | |||
786 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */ | 2241 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */ |
787 | static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) | 2242 | static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) |
788 | { | 2243 | { |
@@ -835,34 +2290,6 @@ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev) | |||
835 | } | 2290 | } |
836 | } | 2291 | } |
837 | 2292 | ||
838 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ | ||
839 | static void b43_nphy_reset_cca(struct b43_wldev *dev) | ||
840 | { | ||
841 | u16 bbcfg; | ||
842 | |||
843 | b43_phy_force_clock(dev, 1); | ||
844 | bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); | ||
845 | b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA); | ||
846 | udelay(1); | ||
847 | b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); | ||
848 | b43_phy_force_clock(dev, 0); | ||
849 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | ||
850 | } | ||
851 | |||
852 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ | ||
853 | static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) | ||
854 | { | ||
855 | u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG); | ||
856 | |||
857 | mimocfg |= B43_NPHY_MIMOCFG_AUTO; | ||
858 | if (preamble == 1) | ||
859 | mimocfg |= B43_NPHY_MIMOCFG_GFMIX; | ||
860 | else | ||
861 | mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX; | ||
862 | |||
863 | b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg); | ||
864 | } | ||
865 | |||
866 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */ | 2293 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */ |
867 | static void b43_nphy_update_txrx_chain(struct b43_wldev *dev) | 2294 | static void b43_nphy_update_txrx_chain(struct b43_wldev *dev) |
868 | { | 2295 | { |
@@ -1142,113 +2569,6 @@ static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev) | |||
1142 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]); | 2569 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]); |
1143 | } | 2570 | } |
1144 | 2571 | ||
1145 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */ | ||
1146 | static void b43_nphy_write_clip_detection(struct b43_wldev *dev, | ||
1147 | const u16 *clip_st) | ||
1148 | { | ||
1149 | b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]); | ||
1150 | b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]); | ||
1151 | } | ||
1152 | |||
1153 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */ | ||
1154 | static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st) | ||
1155 | { | ||
1156 | clip_st[0] = b43_phy_read(dev, B43_NPHY_C1_CLIP1THRES); | ||
1157 | clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES); | ||
1158 | } | ||
1159 | |||
1160 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */ | ||
1161 | static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) | ||
1162 | { | ||
1163 | if (dev->phy.rev >= 3) { | ||
1164 | if (!init) | ||
1165 | return; | ||
1166 | if (0 /* FIXME */) { | ||
1167 | b43_ntab_write(dev, B43_NTAB16(9, 2), 0x211); | ||
1168 | b43_ntab_write(dev, B43_NTAB16(9, 3), 0x222); | ||
1169 | b43_ntab_write(dev, B43_NTAB16(9, 8), 0x144); | ||
1170 | b43_ntab_write(dev, B43_NTAB16(9, 12), 0x188); | ||
1171 | } | ||
1172 | } else { | ||
1173 | b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); | ||
1174 | b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); | ||
1175 | |||
1176 | switch (dev->dev->bus_type) { | ||
1177 | #ifdef CONFIG_B43_BCMA | ||
1178 | case B43_BUS_BCMA: | ||
1179 | bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, | ||
1180 | 0xFC00, 0xFC00); | ||
1181 | break; | ||
1182 | #endif | ||
1183 | #ifdef CONFIG_B43_SSB | ||
1184 | case B43_BUS_SSB: | ||
1185 | ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco, | ||
1186 | 0xFC00, 0xFC00); | ||
1187 | break; | ||
1188 | #endif | ||
1189 | } | ||
1190 | |||
1191 | b43_write32(dev, B43_MMIO_MACCTL, | ||
1192 | b43_read32(dev, B43_MMIO_MACCTL) & | ||
1193 | ~B43_MACCTL_GPOUTSMSK); | ||
1194 | b43_write16(dev, B43_MMIO_GPIO_MASK, | ||
1195 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00); | ||
1196 | b43_write16(dev, B43_MMIO_GPIO_CONTROL, | ||
1197 | b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00); | ||
1198 | |||
1199 | if (init) { | ||
1200 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
1201 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
1202 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
1203 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
1204 | } | ||
1205 | } | ||
1206 | } | ||
1207 | |||
1208 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ | ||
1209 | static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) | ||
1210 | { | ||
1211 | u16 tmp; | ||
1212 | |||
1213 | if (dev->dev->core_rev == 16) | ||
1214 | b43_mac_suspend(dev); | ||
1215 | |||
1216 | tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); | ||
1217 | tmp &= (B43_NPHY_CLASSCTL_CCKEN | B43_NPHY_CLASSCTL_OFDMEN | | ||
1218 | B43_NPHY_CLASSCTL_WAITEDEN); | ||
1219 | tmp &= ~mask; | ||
1220 | tmp |= (val & mask); | ||
1221 | b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); | ||
1222 | |||
1223 | if (dev->dev->core_rev == 16) | ||
1224 | b43_mac_enable(dev); | ||
1225 | |||
1226 | return tmp; | ||
1227 | } | ||
1228 | |||
1229 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */ | ||
1230 | static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable) | ||
1231 | { | ||
1232 | struct b43_phy *phy = &dev->phy; | ||
1233 | struct b43_phy_n *nphy = phy->n; | ||
1234 | |||
1235 | if (enable) { | ||
1236 | static const u16 clip[] = { 0xFFFF, 0xFFFF }; | ||
1237 | if (nphy->deaf_count++ == 0) { | ||
1238 | nphy->classifier_state = b43_nphy_classifier(dev, 0, 0); | ||
1239 | b43_nphy_classifier(dev, 0x7, 0); | ||
1240 | b43_nphy_read_clip_detection(dev, nphy->clip_state); | ||
1241 | b43_nphy_write_clip_detection(dev, clip); | ||
1242 | } | ||
1243 | b43_nphy_reset_cca(dev); | ||
1244 | } else { | ||
1245 | if (--nphy->deaf_count == 0) { | ||
1246 | b43_nphy_classifier(dev, 0x7, nphy->classifier_state); | ||
1247 | b43_nphy_write_clip_detection(dev, nphy->clip_state); | ||
1248 | } | ||
1249 | } | ||
1250 | } | ||
1251 | |||
1252 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */ | 2572 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */ |
1253 | static void b43_nphy_stop_playback(struct b43_wldev *dev) | 2573 | static void b43_nphy_stop_playback(struct b43_wldev *dev) |
1254 | { | 2574 | { |
@@ -1335,625 +2655,6 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev) | |||
1335 | b43_nphy_stay_in_carrier_search(dev, 0); | 2655 | b43_nphy_stay_in_carrier_search(dev, 0); |
1336 | } | 2656 | } |
1337 | 2657 | ||
1338 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */ | ||
1339 | static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) | ||
1340 | { | ||
1341 | struct b43_phy_n *nphy = dev->phy.n; | ||
1342 | |||
1343 | u8 i; | ||
1344 | s16 tmp; | ||
1345 | u16 data[4]; | ||
1346 | s16 gain[2]; | ||
1347 | u16 minmax[2]; | ||
1348 | static const u16 lna_gain[4] = { -2, 10, 19, 25 }; | ||
1349 | |||
1350 | if (nphy->hang_avoid) | ||
1351 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
1352 | |||
1353 | if (nphy->gain_boost) { | ||
1354 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
1355 | gain[0] = 6; | ||
1356 | gain[1] = 6; | ||
1357 | } else { | ||
1358 | tmp = 40370 - 315 * dev->phy.channel; | ||
1359 | gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1)); | ||
1360 | tmp = 23242 - 224 * dev->phy.channel; | ||
1361 | gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1)); | ||
1362 | } | ||
1363 | } else { | ||
1364 | gain[0] = 0; | ||
1365 | gain[1] = 0; | ||
1366 | } | ||
1367 | |||
1368 | for (i = 0; i < 2; i++) { | ||
1369 | if (nphy->elna_gain_config) { | ||
1370 | data[0] = 19 + gain[i]; | ||
1371 | data[1] = 25 + gain[i]; | ||
1372 | data[2] = 25 + gain[i]; | ||
1373 | data[3] = 25 + gain[i]; | ||
1374 | } else { | ||
1375 | data[0] = lna_gain[0] + gain[i]; | ||
1376 | data[1] = lna_gain[1] + gain[i]; | ||
1377 | data[2] = lna_gain[2] + gain[i]; | ||
1378 | data[3] = lna_gain[3] + gain[i]; | ||
1379 | } | ||
1380 | b43_ntab_write_bulk(dev, B43_NTAB16(i, 8), 4, data); | ||
1381 | |||
1382 | minmax[i] = 23 + gain[i]; | ||
1383 | } | ||
1384 | |||
1385 | b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, ~B43_NPHY_C1_MINGAIN, | ||
1386 | minmax[0] << B43_NPHY_C1_MINGAIN_SHIFT); | ||
1387 | b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, ~B43_NPHY_C2_MINGAIN, | ||
1388 | minmax[1] << B43_NPHY_C2_MINGAIN_SHIFT); | ||
1389 | |||
1390 | if (nphy->hang_avoid) | ||
1391 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
1392 | } | ||
1393 | |||
1394 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ | ||
1395 | static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) | ||
1396 | { | ||
1397 | struct b43_phy_n *nphy = dev->phy.n; | ||
1398 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
1399 | |||
1400 | /* PHY rev 0, 1, 2 */ | ||
1401 | u8 i, j; | ||
1402 | u8 code; | ||
1403 | u16 tmp; | ||
1404 | u8 rfseq_events[3] = { 6, 8, 7 }; | ||
1405 | u8 rfseq_delays[3] = { 10, 30, 1 }; | ||
1406 | |||
1407 | /* PHY rev >= 3 */ | ||
1408 | bool ghz5; | ||
1409 | bool ext_lna; | ||
1410 | u16 rssi_gain; | ||
1411 | struct nphy_gain_ctl_workaround_entry *e; | ||
1412 | u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; | ||
1413 | u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; | ||
1414 | |||
1415 | if (dev->phy.rev >= 3) { | ||
1416 | /* Prepare values */ | ||
1417 | ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL) | ||
1418 | & B43_NPHY_BANDCTL_5GHZ; | ||
1419 | ext_lna = sprom->boardflags_lo & B43_BFL_EXTLNA; | ||
1420 | e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna); | ||
1421 | if (ghz5 && dev->phy.rev >= 5) | ||
1422 | rssi_gain = 0x90; | ||
1423 | else | ||
1424 | rssi_gain = 0x50; | ||
1425 | |||
1426 | b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040); | ||
1427 | |||
1428 | /* Set Clip 2 detect */ | ||
1429 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | ||
1430 | B43_NPHY_C1_CGAINI_CL2DETECT); | ||
1431 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
1432 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
1433 | |||
1434 | b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC, | ||
1435 | 0x17); | ||
1436 | b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAG1_IDAC, | ||
1437 | 0x17); | ||
1438 | b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG2_IDAC, 0xF0); | ||
1439 | b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG2_IDAC, 0xF0); | ||
1440 | b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_POLE, 0x00); | ||
1441 | b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_POLE, 0x00); | ||
1442 | b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_GAIN, | ||
1443 | rssi_gain); | ||
1444 | b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_GAIN, | ||
1445 | rssi_gain); | ||
1446 | b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAA1_IDAC, | ||
1447 | 0x17); | ||
1448 | b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAA1_IDAC, | ||
1449 | 0x17); | ||
1450 | b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA2_IDAC, 0xFF); | ||
1451 | b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA2_IDAC, 0xFF); | ||
1452 | |||
1453 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 8), 4, e->lna1_gain); | ||
1454 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 8), 4, e->lna1_gain); | ||
1455 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 16), 4, e->lna2_gain); | ||
1456 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 16), 4, e->lna2_gain); | ||
1457 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 32), 10, e->gain_db); | ||
1458 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 32), 10, e->gain_db); | ||
1459 | b43_ntab_write_bulk(dev, B43_NTAB8(2, 32), 10, e->gain_bits); | ||
1460 | b43_ntab_write_bulk(dev, B43_NTAB8(3, 32), 10, e->gain_bits); | ||
1461 | b43_ntab_write_bulk(dev, B43_NTAB8(0, 0x40), 6, lpf_gain); | ||
1462 | b43_ntab_write_bulk(dev, B43_NTAB8(1, 0x40), 6, lpf_gain); | ||
1463 | b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits); | ||
1464 | b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits); | ||
1465 | |||
1466 | b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); | ||
1467 | b43_phy_write(dev, 0x2A7, e->init_gain); | ||
1468 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, | ||
1469 | e->rfseq_init); | ||
1470 | b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); | ||
1471 | |||
1472 | /* TODO: check defines. Do not match variables names */ | ||
1473 | b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain); | ||
1474 | b43_phy_write(dev, 0x2A9, e->cliphi_gain); | ||
1475 | b43_phy_write(dev, B43_NPHY_C1_CLIP2_GAIN, e->clipmd_gain); | ||
1476 | b43_phy_write(dev, 0x2AB, e->clipmd_gain); | ||
1477 | b43_phy_write(dev, B43_NPHY_C2_CLIP1_HIGAIN, e->cliplo_gain); | ||
1478 | b43_phy_write(dev, 0x2AD, e->cliplo_gain); | ||
1479 | |||
1480 | b43_phy_maskset(dev, 0x27D, 0xFF00, e->crsmin); | ||
1481 | b43_phy_maskset(dev, 0x280, 0xFF00, e->crsminl); | ||
1482 | b43_phy_maskset(dev, 0x283, 0xFF00, e->crsminu); | ||
1483 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip); | ||
1484 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip); | ||
1485 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
1486 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, e->wlclip); | ||
1487 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
1488 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, e->wlclip); | ||
1489 | b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); | ||
1490 | } else { | ||
1491 | /* Set Clip 2 detect */ | ||
1492 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | ||
1493 | B43_NPHY_C1_CGAINI_CL2DETECT); | ||
1494 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
1495 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
1496 | |||
1497 | /* Set narrowband clip threshold */ | ||
1498 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); | ||
1499 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); | ||
1500 | |||
1501 | if (!dev->phy.is_40mhz) { | ||
1502 | /* Set dwell lengths */ | ||
1503 | b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); | ||
1504 | b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); | ||
1505 | b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009); | ||
1506 | b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009); | ||
1507 | } | ||
1508 | |||
1509 | /* Set wideband clip 2 threshold */ | ||
1510 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
1511 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, | ||
1512 | 21); | ||
1513 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
1514 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, | ||
1515 | 21); | ||
1516 | |||
1517 | if (!dev->phy.is_40mhz) { | ||
1518 | b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, | ||
1519 | ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1); | ||
1520 | b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, | ||
1521 | ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1); | ||
1522 | b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI, | ||
1523 | ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1); | ||
1524 | b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI, | ||
1525 | ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1); | ||
1526 | } | ||
1527 | |||
1528 | b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); | ||
1529 | |||
1530 | if (nphy->gain_boost) { | ||
1531 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ && | ||
1532 | dev->phy.is_40mhz) | ||
1533 | code = 4; | ||
1534 | else | ||
1535 | code = 5; | ||
1536 | } else { | ||
1537 | code = dev->phy.is_40mhz ? 6 : 7; | ||
1538 | } | ||
1539 | |||
1540 | /* Set HPVGA2 index */ | ||
1541 | b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, | ||
1542 | ~B43_NPHY_C1_INITGAIN_HPVGA2, | ||
1543 | code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); | ||
1544 | b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, | ||
1545 | ~B43_NPHY_C2_INITGAIN_HPVGA2, | ||
1546 | code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); | ||
1547 | |||
1548 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); | ||
1549 | /* specs say about 2 loops, but wl does 4 */ | ||
1550 | for (i = 0; i < 4; i++) | ||
1551 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
1552 | (code << 8 | 0x7C)); | ||
1553 | |||
1554 | b43_nphy_adjust_lna_gain_table(dev); | ||
1555 | |||
1556 | if (nphy->elna_gain_config) { | ||
1557 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); | ||
1558 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); | ||
1559 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1560 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1561 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1562 | |||
1563 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08); | ||
1564 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); | ||
1565 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1566 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1567 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
1568 | |||
1569 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); | ||
1570 | /* specs say about 2 loops, but wl does 4 */ | ||
1571 | for (i = 0; i < 4; i++) | ||
1572 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
1573 | (code << 8 | 0x74)); | ||
1574 | } | ||
1575 | |||
1576 | if (dev->phy.rev == 2) { | ||
1577 | for (i = 0; i < 4; i++) { | ||
1578 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, | ||
1579 | (0x0400 * i) + 0x0020); | ||
1580 | for (j = 0; j < 21; j++) { | ||
1581 | tmp = j * (i < 2 ? 3 : 1); | ||
1582 | b43_phy_write(dev, | ||
1583 | B43_NPHY_TABLE_DATALO, tmp); | ||
1584 | } | ||
1585 | } | ||
1586 | } | ||
1587 | |||
1588 | b43_nphy_set_rf_sequence(dev, 5, | ||
1589 | rfseq_events, rfseq_delays, 3); | ||
1590 | b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, | ||
1591 | ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF, | ||
1592 | 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); | ||
1593 | |||
1594 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
1595 | b43_phy_maskset(dev, B43_PHY_N(0xC5D), | ||
1596 | 0xFF80, 4); | ||
1597 | } | ||
1598 | } | ||
1599 | |||
1600 | static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) | ||
1601 | { | ||
1602 | struct b43_phy_n *nphy = dev->phy.n; | ||
1603 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
1604 | |||
1605 | /* TX to RX */ | ||
1606 | u8 tx2rx_events[8] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F }; | ||
1607 | u8 tx2rx_delays[8] = { 8, 4, 2, 2, 4, 4, 6, 1 }; | ||
1608 | /* RX to TX */ | ||
1609 | u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3, | ||
1610 | 0x1F }; | ||
1611 | u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; | ||
1612 | u8 rx2tx_events[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0x3, 0x4, 0x1F }; | ||
1613 | u8 rx2tx_delays[9] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; | ||
1614 | |||
1615 | u16 tmp16; | ||
1616 | u32 tmp32; | ||
1617 | |||
1618 | b43_phy_write(dev, 0x23f, 0x1f8); | ||
1619 | b43_phy_write(dev, 0x240, 0x1f8); | ||
1620 | |||
1621 | tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); | ||
1622 | tmp32 &= 0xffffff; | ||
1623 | b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32); | ||
1624 | |||
1625 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125); | ||
1626 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3); | ||
1627 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105); | ||
1628 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E); | ||
1629 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); | ||
1630 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); | ||
1631 | |||
1632 | b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); | ||
1633 | b43_phy_write(dev, 0x2AE, 0x000C); | ||
1634 | |||
1635 | /* TX to RX */ | ||
1636 | b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays, | ||
1637 | ARRAY_SIZE(tx2rx_events)); | ||
1638 | |||
1639 | /* RX to TX */ | ||
1640 | if (b43_nphy_ipa(dev)) | ||
1641 | b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa, | ||
1642 | rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa)); | ||
1643 | if (nphy->hw_phyrxchain != 3 && | ||
1644 | nphy->hw_phyrxchain != nphy->hw_phytxchain) { | ||
1645 | if (b43_nphy_ipa(dev)) { | ||
1646 | rx2tx_delays[5] = 59; | ||
1647 | rx2tx_delays[6] = 1; | ||
1648 | rx2tx_events[7] = 0x1F; | ||
1649 | } | ||
1650 | b43_nphy_set_rf_sequence(dev, 1, rx2tx_events, rx2tx_delays, | ||
1651 | ARRAY_SIZE(rx2tx_events)); | ||
1652 | } | ||
1653 | |||
1654 | tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? | ||
1655 | 0x2 : 0x9C40; | ||
1656 | b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); | ||
1657 | |||
1658 | b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); | ||
1659 | |||
1660 | b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); | ||
1661 | b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D); | ||
1662 | |||
1663 | b43_nphy_gain_ctrl_workarounds(dev); | ||
1664 | |||
1665 | b43_ntab_write(dev, B43_NTAB16(8, 0), 2); | ||
1666 | b43_ntab_write(dev, B43_NTAB16(8, 16), 2); | ||
1667 | |||
1668 | /* TODO */ | ||
1669 | |||
1670 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00); | ||
1671 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00); | ||
1672 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06); | ||
1673 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06); | ||
1674 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07); | ||
1675 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07); | ||
1676 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88); | ||
1677 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88); | ||
1678 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_CMFB_IDAC, 0x00); | ||
1679 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_CMFB_IDAC, 0x00); | ||
1680 | b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | ||
1681 | b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | ||
1682 | |||
1683 | /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ | ||
1684 | |||
1685 | if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR && | ||
1686 | b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || | ||
1687 | (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR && | ||
1688 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) | ||
1689 | tmp32 = 0x00088888; | ||
1690 | else | ||
1691 | tmp32 = 0x88888888; | ||
1692 | b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32); | ||
1693 | b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32); | ||
1694 | b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32); | ||
1695 | |||
1696 | if (dev->phy.rev == 4 && | ||
1697 | b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
1698 | b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC, | ||
1699 | 0x70); | ||
1700 | b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC, | ||
1701 | 0x70); | ||
1702 | } | ||
1703 | |||
1704 | b43_phy_write(dev, 0x224, 0x03eb); | ||
1705 | b43_phy_write(dev, 0x225, 0x03eb); | ||
1706 | b43_phy_write(dev, 0x226, 0x0341); | ||
1707 | b43_phy_write(dev, 0x227, 0x0341); | ||
1708 | b43_phy_write(dev, 0x228, 0x042b); | ||
1709 | b43_phy_write(dev, 0x229, 0x042b); | ||
1710 | b43_phy_write(dev, 0x22a, 0x0381); | ||
1711 | b43_phy_write(dev, 0x22b, 0x0381); | ||
1712 | b43_phy_write(dev, 0x22c, 0x042b); | ||
1713 | b43_phy_write(dev, 0x22d, 0x042b); | ||
1714 | b43_phy_write(dev, 0x22e, 0x0381); | ||
1715 | b43_phy_write(dev, 0x22f, 0x0381); | ||
1716 | } | ||
1717 | |||
1718 | static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev) | ||
1719 | { | ||
1720 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
1721 | struct b43_phy *phy = &dev->phy; | ||
1722 | struct b43_phy_n *nphy = phy->n; | ||
1723 | |||
1724 | u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; | ||
1725 | u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; | ||
1726 | |||
1727 | u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; | ||
1728 | u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; | ||
1729 | |||
1730 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && | ||
1731 | nphy->band5g_pwrgain) { | ||
1732 | b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8); | ||
1733 | b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8); | ||
1734 | } else { | ||
1735 | b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); | ||
1736 | b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); | ||
1737 | } | ||
1738 | |||
1739 | b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A); | ||
1740 | b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A); | ||
1741 | b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); | ||
1742 | b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); | ||
1743 | |||
1744 | if (dev->phy.rev < 2) { | ||
1745 | b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000); | ||
1746 | b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000); | ||
1747 | b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); | ||
1748 | b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); | ||
1749 | b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800); | ||
1750 | b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800); | ||
1751 | } | ||
1752 | |||
1753 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
1754 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
1755 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
1756 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
1757 | |||
1758 | if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD && | ||
1759 | dev->dev->board_type == 0x8B) { | ||
1760 | delays1[0] = 0x1; | ||
1761 | delays1[5] = 0x14; | ||
1762 | } | ||
1763 | b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); | ||
1764 | b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); | ||
1765 | |||
1766 | b43_nphy_gain_ctrl_workarounds(dev); | ||
1767 | |||
1768 | if (dev->phy.rev < 2) { | ||
1769 | if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) | ||
1770 | b43_hf_write(dev, b43_hf_read(dev) | | ||
1771 | B43_HF_MLADVW); | ||
1772 | } else if (dev->phy.rev == 2) { | ||
1773 | b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); | ||
1774 | b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); | ||
1775 | } | ||
1776 | |||
1777 | if (dev->phy.rev < 2) | ||
1778 | b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, | ||
1779 | ~B43_NPHY_SCRAM_SIGCTL_SCM); | ||
1780 | |||
1781 | /* Set phase track alpha and beta */ | ||
1782 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); | ||
1783 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); | ||
1784 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); | ||
1785 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); | ||
1786 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); | ||
1787 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); | ||
1788 | |||
1789 | b43_phy_mask(dev, B43_NPHY_PIL_DW1, | ||
1790 | ~B43_NPHY_PIL_DW_64QAM & 0xFFFF); | ||
1791 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); | ||
1792 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); | ||
1793 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); | ||
1794 | |||
1795 | if (dev->phy.rev == 2) | ||
1796 | b43_phy_set(dev, B43_NPHY_FINERX2_CGC, | ||
1797 | B43_NPHY_FINERX2_CGC_DECGC); | ||
1798 | } | ||
1799 | |||
1800 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ | ||
1801 | static void b43_nphy_workarounds(struct b43_wldev *dev) | ||
1802 | { | ||
1803 | struct b43_phy *phy = &dev->phy; | ||
1804 | struct b43_phy_n *nphy = phy->n; | ||
1805 | |||
1806 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
1807 | b43_nphy_classifier(dev, 1, 0); | ||
1808 | else | ||
1809 | b43_nphy_classifier(dev, 1, 1); | ||
1810 | |||
1811 | if (nphy->hang_avoid) | ||
1812 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
1813 | |||
1814 | b43_phy_set(dev, B43_NPHY_IQFLIP, | ||
1815 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | ||
1816 | |||
1817 | if (dev->phy.rev >= 3) | ||
1818 | b43_nphy_workarounds_rev3plus(dev); | ||
1819 | else | ||
1820 | b43_nphy_workarounds_rev1_2(dev); | ||
1821 | |||
1822 | if (nphy->hang_avoid) | ||
1823 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
1824 | } | ||
1825 | |||
1826 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */ | ||
1827 | static int b43_nphy_load_samples(struct b43_wldev *dev, | ||
1828 | struct b43_c32 *samples, u16 len) { | ||
1829 | struct b43_phy_n *nphy = dev->phy.n; | ||
1830 | u16 i; | ||
1831 | u32 *data; | ||
1832 | |||
1833 | data = kzalloc(len * sizeof(u32), GFP_KERNEL); | ||
1834 | if (!data) { | ||
1835 | b43err(dev->wl, "allocation for samples loading failed\n"); | ||
1836 | return -ENOMEM; | ||
1837 | } | ||
1838 | if (nphy->hang_avoid) | ||
1839 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
1840 | |||
1841 | for (i = 0; i < len; i++) { | ||
1842 | data[i] = (samples[i].i & 0x3FF << 10); | ||
1843 | data[i] |= samples[i].q & 0x3FF; | ||
1844 | } | ||
1845 | b43_ntab_write_bulk(dev, B43_NTAB32(17, 0), len, data); | ||
1846 | |||
1847 | kfree(data); | ||
1848 | if (nphy->hang_avoid) | ||
1849 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
1850 | return 0; | ||
1851 | } | ||
1852 | |||
1853 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */ | ||
1854 | static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, | ||
1855 | bool test) | ||
1856 | { | ||
1857 | int i; | ||
1858 | u16 bw, len, rot, angle; | ||
1859 | struct b43_c32 *samples; | ||
1860 | |||
1861 | |||
1862 | bw = (dev->phy.is_40mhz) ? 40 : 20; | ||
1863 | len = bw << 3; | ||
1864 | |||
1865 | if (test) { | ||
1866 | if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX) | ||
1867 | bw = 82; | ||
1868 | else | ||
1869 | bw = 80; | ||
1870 | |||
1871 | if (dev->phy.is_40mhz) | ||
1872 | bw <<= 1; | ||
1873 | |||
1874 | len = bw << 1; | ||
1875 | } | ||
1876 | |||
1877 | samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL); | ||
1878 | if (!samples) { | ||
1879 | b43err(dev->wl, "allocation for samples generation failed\n"); | ||
1880 | return 0; | ||
1881 | } | ||
1882 | rot = (((freq * 36) / bw) << 16) / 100; | ||
1883 | angle = 0; | ||
1884 | |||
1885 | for (i = 0; i < len; i++) { | ||
1886 | samples[i] = b43_cordic(angle); | ||
1887 | angle += rot; | ||
1888 | samples[i].q = CORDIC_CONVERT(samples[i].q * max); | ||
1889 | samples[i].i = CORDIC_CONVERT(samples[i].i * max); | ||
1890 | } | ||
1891 | |||
1892 | i = b43_nphy_load_samples(dev, samples, len); | ||
1893 | kfree(samples); | ||
1894 | return (i < 0) ? 0 : len; | ||
1895 | } | ||
1896 | |||
1897 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ | ||
1898 | static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, | ||
1899 | u16 wait, bool iqmode, bool dac_test) | ||
1900 | { | ||
1901 | struct b43_phy_n *nphy = dev->phy.n; | ||
1902 | int i; | ||
1903 | u16 seq_mode; | ||
1904 | u32 tmp; | ||
1905 | |||
1906 | if (nphy->hang_avoid) | ||
1907 | b43_nphy_stay_in_carrier_search(dev, true); | ||
1908 | |||
1909 | if ((nphy->bb_mult_save & 0x80000000) == 0) { | ||
1910 | tmp = b43_ntab_read(dev, B43_NTAB16(15, 87)); | ||
1911 | nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000; | ||
1912 | } | ||
1913 | |||
1914 | if (!dev->phy.is_40mhz) | ||
1915 | tmp = 0x6464; | ||
1916 | else | ||
1917 | tmp = 0x4747; | ||
1918 | b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); | ||
1919 | |||
1920 | if (nphy->hang_avoid) | ||
1921 | b43_nphy_stay_in_carrier_search(dev, false); | ||
1922 | |||
1923 | b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1)); | ||
1924 | |||
1925 | if (loops != 0xFFFF) | ||
1926 | b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1)); | ||
1927 | else | ||
1928 | b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops); | ||
1929 | |||
1930 | b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait); | ||
1931 | |||
1932 | seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); | ||
1933 | |||
1934 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER); | ||
1935 | if (iqmode) { | ||
1936 | b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); | ||
1937 | b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000); | ||
1938 | } else { | ||
1939 | if (dac_test) | ||
1940 | b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5); | ||
1941 | else | ||
1942 | b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1); | ||
1943 | } | ||
1944 | for (i = 0; i < 100; i++) { | ||
1945 | if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) { | ||
1946 | i = 0; | ||
1947 | break; | ||
1948 | } | ||
1949 | udelay(10); | ||
1950 | } | ||
1951 | if (i) | ||
1952 | b43err(dev->wl, "run samples timeout\n"); | ||
1953 | |||
1954 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); | ||
1955 | } | ||
1956 | |||
1957 | /* | 2658 | /* |
1958 | * Transmits a known value for LO calibration | 2659 | * Transmits a known value for LO calibration |
1959 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone | 2660 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone |
@@ -2034,775 +2735,6 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) | |||
2034 | b43_nphy_stay_in_carrier_search(dev, false); | 2735 | b43_nphy_stay_in_carrier_search(dev, false); |
2035 | } | 2736 | } |
2036 | 2737 | ||
2037 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */ | ||
2038 | static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, | ||
2039 | u8 *events, u8 *delays, u8 length) | ||
2040 | { | ||
2041 | struct b43_phy_n *nphy = dev->phy.n; | ||
2042 | u8 i; | ||
2043 | u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F; | ||
2044 | u16 offset1 = cmd << 4; | ||
2045 | u16 offset2 = offset1 + 0x80; | ||
2046 | |||
2047 | if (nphy->hang_avoid) | ||
2048 | b43_nphy_stay_in_carrier_search(dev, true); | ||
2049 | |||
2050 | b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events); | ||
2051 | b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays); | ||
2052 | |||
2053 | for (i = length; i < 16; i++) { | ||
2054 | b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end); | ||
2055 | b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1); | ||
2056 | } | ||
2057 | |||
2058 | if (nphy->hang_avoid) | ||
2059 | b43_nphy_stay_in_carrier_search(dev, false); | ||
2060 | } | ||
2061 | |||
2062 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ | ||
2063 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | ||
2064 | enum b43_nphy_rf_sequence seq) | ||
2065 | { | ||
2066 | static const u16 trigger[] = { | ||
2067 | [B43_RFSEQ_RX2TX] = B43_NPHY_RFSEQTR_RX2TX, | ||
2068 | [B43_RFSEQ_TX2RX] = B43_NPHY_RFSEQTR_TX2RX, | ||
2069 | [B43_RFSEQ_RESET2RX] = B43_NPHY_RFSEQTR_RST2RX, | ||
2070 | [B43_RFSEQ_UPDATE_GAINH] = B43_NPHY_RFSEQTR_UPGH, | ||
2071 | [B43_RFSEQ_UPDATE_GAINL] = B43_NPHY_RFSEQTR_UPGL, | ||
2072 | [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, | ||
2073 | }; | ||
2074 | int i; | ||
2075 | u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); | ||
2076 | |||
2077 | B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); | ||
2078 | |||
2079 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, | ||
2080 | B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER); | ||
2081 | b43_phy_set(dev, B43_NPHY_RFSEQTR, trigger[seq]); | ||
2082 | for (i = 0; i < 200; i++) { | ||
2083 | if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & trigger[seq])) | ||
2084 | goto ok; | ||
2085 | msleep(1); | ||
2086 | } | ||
2087 | b43err(dev->wl, "RF sequence status timeout\n"); | ||
2088 | ok: | ||
2089 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); | ||
2090 | } | ||
2091 | |||
2092 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ | ||
2093 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | ||
2094 | u16 value, u8 core, bool off) | ||
2095 | { | ||
2096 | int i; | ||
2097 | u8 index = fls(field); | ||
2098 | u8 addr, en_addr, val_addr; | ||
2099 | /* we expect only one bit set */ | ||
2100 | B43_WARN_ON(field & (~(1 << (index - 1)))); | ||
2101 | |||
2102 | if (dev->phy.rev >= 3) { | ||
2103 | const struct nphy_rf_control_override_rev3 *rf_ctrl; | ||
2104 | for (i = 0; i < 2; i++) { | ||
2105 | if (index == 0 || index == 16) { | ||
2106 | b43err(dev->wl, | ||
2107 | "Unsupported RF Ctrl Override call\n"); | ||
2108 | return; | ||
2109 | } | ||
2110 | |||
2111 | rf_ctrl = &tbl_rf_control_override_rev3[index - 1]; | ||
2112 | en_addr = B43_PHY_N((i == 0) ? | ||
2113 | rf_ctrl->en_addr0 : rf_ctrl->en_addr1); | ||
2114 | val_addr = B43_PHY_N((i == 0) ? | ||
2115 | rf_ctrl->val_addr0 : rf_ctrl->val_addr1); | ||
2116 | |||
2117 | if (off) { | ||
2118 | b43_phy_mask(dev, en_addr, ~(field)); | ||
2119 | b43_phy_mask(dev, val_addr, | ||
2120 | ~(rf_ctrl->val_mask)); | ||
2121 | } else { | ||
2122 | if (core == 0 || ((1 << core) & i) != 0) { | ||
2123 | b43_phy_set(dev, en_addr, field); | ||
2124 | b43_phy_maskset(dev, val_addr, | ||
2125 | ~(rf_ctrl->val_mask), | ||
2126 | (value << rf_ctrl->val_shift)); | ||
2127 | } | ||
2128 | } | ||
2129 | } | ||
2130 | } else { | ||
2131 | const struct nphy_rf_control_override_rev2 *rf_ctrl; | ||
2132 | if (off) { | ||
2133 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field)); | ||
2134 | value = 0; | ||
2135 | } else { | ||
2136 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field); | ||
2137 | } | ||
2138 | |||
2139 | for (i = 0; i < 2; i++) { | ||
2140 | if (index <= 1 || index == 16) { | ||
2141 | b43err(dev->wl, | ||
2142 | "Unsupported RF Ctrl Override call\n"); | ||
2143 | return; | ||
2144 | } | ||
2145 | |||
2146 | if (index == 2 || index == 10 || | ||
2147 | (index >= 13 && index <= 15)) { | ||
2148 | core = 1; | ||
2149 | } | ||
2150 | |||
2151 | rf_ctrl = &tbl_rf_control_override_rev2[index - 2]; | ||
2152 | addr = B43_PHY_N((i == 0) ? | ||
2153 | rf_ctrl->addr0 : rf_ctrl->addr1); | ||
2154 | |||
2155 | if ((core & (1 << i)) != 0) | ||
2156 | b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask), | ||
2157 | (value << rf_ctrl->shift)); | ||
2158 | |||
2159 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); | ||
2160 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
2161 | B43_NPHY_RFCTL_CMD_START); | ||
2162 | udelay(1); | ||
2163 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE); | ||
2164 | } | ||
2165 | } | ||
2166 | } | ||
2167 | |||
2168 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */ | ||
2169 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | ||
2170 | u16 value, u8 core) | ||
2171 | { | ||
2172 | u8 i, j; | ||
2173 | u16 reg, tmp, val; | ||
2174 | |||
2175 | B43_WARN_ON(dev->phy.rev < 3); | ||
2176 | B43_WARN_ON(field > 4); | ||
2177 | |||
2178 | for (i = 0; i < 2; i++) { | ||
2179 | if ((core == 1 && i == 1) || (core == 2 && !i)) | ||
2180 | continue; | ||
2181 | |||
2182 | reg = (i == 0) ? | ||
2183 | B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; | ||
2184 | b43_phy_mask(dev, reg, 0xFBFF); | ||
2185 | |||
2186 | switch (field) { | ||
2187 | case 0: | ||
2188 | b43_phy_write(dev, reg, 0); | ||
2189 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | ||
2190 | break; | ||
2191 | case 1: | ||
2192 | if (!i) { | ||
2193 | b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1, | ||
2194 | 0xFC3F, (value << 6)); | ||
2195 | b43_phy_maskset(dev, B43_NPHY_TXF_40CO_B1S1, | ||
2196 | 0xFFFE, 1); | ||
2197 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
2198 | B43_NPHY_RFCTL_CMD_START); | ||
2199 | for (j = 0; j < 100; j++) { | ||
2200 | if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) { | ||
2201 | j = 0; | ||
2202 | break; | ||
2203 | } | ||
2204 | udelay(10); | ||
2205 | } | ||
2206 | if (j) | ||
2207 | b43err(dev->wl, | ||
2208 | "intc override timeout\n"); | ||
2209 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, | ||
2210 | 0xFFFE); | ||
2211 | } else { | ||
2212 | b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC2, | ||
2213 | 0xFC3F, (value << 6)); | ||
2214 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, | ||
2215 | 0xFFFE, 1); | ||
2216 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
2217 | B43_NPHY_RFCTL_CMD_RXTX); | ||
2218 | for (j = 0; j < 100; j++) { | ||
2219 | if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) { | ||
2220 | j = 0; | ||
2221 | break; | ||
2222 | } | ||
2223 | udelay(10); | ||
2224 | } | ||
2225 | if (j) | ||
2226 | b43err(dev->wl, | ||
2227 | "intc override timeout\n"); | ||
2228 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, | ||
2229 | 0xFFFE); | ||
2230 | } | ||
2231 | break; | ||
2232 | case 2: | ||
2233 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
2234 | tmp = 0x0020; | ||
2235 | val = value << 5; | ||
2236 | } else { | ||
2237 | tmp = 0x0010; | ||
2238 | val = value << 4; | ||
2239 | } | ||
2240 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
2241 | break; | ||
2242 | case 3: | ||
2243 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
2244 | tmp = 0x0001; | ||
2245 | val = value; | ||
2246 | } else { | ||
2247 | tmp = 0x0004; | ||
2248 | val = value << 2; | ||
2249 | } | ||
2250 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
2251 | break; | ||
2252 | case 4: | ||
2253 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
2254 | tmp = 0x0002; | ||
2255 | val = value << 1; | ||
2256 | } else { | ||
2257 | tmp = 0x0008; | ||
2258 | val = value << 3; | ||
2259 | } | ||
2260 | b43_phy_maskset(dev, reg, ~tmp, val); | ||
2261 | break; | ||
2262 | } | ||
2263 | } | ||
2264 | } | ||
2265 | |||
2266 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */ | ||
2267 | static void b43_nphy_bphy_init(struct b43_wldev *dev) | ||
2268 | { | ||
2269 | unsigned int i; | ||
2270 | u16 val; | ||
2271 | |||
2272 | val = 0x1E1F; | ||
2273 | for (i = 0; i < 16; i++) { | ||
2274 | b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val); | ||
2275 | val -= 0x202; | ||
2276 | } | ||
2277 | val = 0x3E3F; | ||
2278 | for (i = 0; i < 16; i++) { | ||
2279 | b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val); | ||
2280 | val -= 0x202; | ||
2281 | } | ||
2282 | b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); | ||
2283 | } | ||
2284 | |||
2285 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */ | ||
2286 | static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, | ||
2287 | s8 offset, u8 core, u8 rail, | ||
2288 | enum b43_nphy_rssi_type type) | ||
2289 | { | ||
2290 | u16 tmp; | ||
2291 | bool core1or5 = (core == 1) || (core == 5); | ||
2292 | bool core2or5 = (core == 2) || (core == 5); | ||
2293 | |||
2294 | offset = clamp_val(offset, -32, 31); | ||
2295 | tmp = ((scale & 0x3F) << 8) | (offset & 0x3F); | ||
2296 | |||
2297 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) | ||
2298 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); | ||
2299 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) | ||
2300 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); | ||
2301 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z)) | ||
2302 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); | ||
2303 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z)) | ||
2304 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); | ||
2305 | |||
2306 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) | ||
2307 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); | ||
2308 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) | ||
2309 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); | ||
2310 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X)) | ||
2311 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); | ||
2312 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X)) | ||
2313 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); | ||
2314 | |||
2315 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) | ||
2316 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); | ||
2317 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) | ||
2318 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); | ||
2319 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y)) | ||
2320 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); | ||
2321 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y)) | ||
2322 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); | ||
2323 | |||
2324 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) | ||
2325 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); | ||
2326 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) | ||
2327 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); | ||
2328 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD)) | ||
2329 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); | ||
2330 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD)) | ||
2331 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); | ||
2332 | |||
2333 | if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) | ||
2334 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); | ||
2335 | if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) | ||
2336 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); | ||
2337 | if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET)) | ||
2338 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); | ||
2339 | if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET)) | ||
2340 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); | ||
2341 | |||
2342 | if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I)) | ||
2343 | b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); | ||
2344 | if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I)) | ||
2345 | b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); | ||
2346 | |||
2347 | if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q)) | ||
2348 | b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); | ||
2349 | if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q)) | ||
2350 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); | ||
2351 | } | ||
2352 | |||
2353 | static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
2354 | { | ||
2355 | u16 val; | ||
2356 | |||
2357 | if (type < 3) | ||
2358 | val = 0; | ||
2359 | else if (type == 6) | ||
2360 | val = 1; | ||
2361 | else if (type == 3) | ||
2362 | val = 2; | ||
2363 | else | ||
2364 | val = 3; | ||
2365 | |||
2366 | val = (val << 12) | (val << 14); | ||
2367 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); | ||
2368 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); | ||
2369 | |||
2370 | if (type < 3) { | ||
2371 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, | ||
2372 | (type + 1) << 4); | ||
2373 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, | ||
2374 | (type + 1) << 4); | ||
2375 | } | ||
2376 | |||
2377 | if (code == 0) { | ||
2378 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000); | ||
2379 | if (type < 3) { | ||
2380 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
2381 | ~(B43_NPHY_RFCTL_CMD_RXEN | | ||
2382 | B43_NPHY_RFCTL_CMD_CORESEL)); | ||
2383 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, | ||
2384 | ~(0x1 << 12 | | ||
2385 | 0x1 << 5 | | ||
2386 | 0x1 << 1 | | ||
2387 | 0x1)); | ||
2388 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
2389 | ~B43_NPHY_RFCTL_CMD_START); | ||
2390 | udelay(20); | ||
2391 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1); | ||
2392 | } | ||
2393 | } else { | ||
2394 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000); | ||
2395 | if (type < 3) { | ||
2396 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, | ||
2397 | ~(B43_NPHY_RFCTL_CMD_RXEN | | ||
2398 | B43_NPHY_RFCTL_CMD_CORESEL), | ||
2399 | (B43_NPHY_RFCTL_CMD_RXEN | | ||
2400 | code << B43_NPHY_RFCTL_CMD_CORESEL_SHIFT)); | ||
2401 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, | ||
2402 | (0x1 << 12 | | ||
2403 | 0x1 << 5 | | ||
2404 | 0x1 << 1 | | ||
2405 | 0x1)); | ||
2406 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
2407 | B43_NPHY_RFCTL_CMD_START); | ||
2408 | udelay(20); | ||
2409 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1); | ||
2410 | } | ||
2411 | } | ||
2412 | } | ||
2413 | |||
2414 | static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
2415 | { | ||
2416 | u8 i; | ||
2417 | u16 reg, val; | ||
2418 | |||
2419 | if (code == 0) { | ||
2420 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF); | ||
2421 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF); | ||
2422 | b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF); | ||
2423 | b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF); | ||
2424 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF); | ||
2425 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF); | ||
2426 | b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3); | ||
2427 | b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3); | ||
2428 | } else { | ||
2429 | for (i = 0; i < 2; i++) { | ||
2430 | if ((code == 1 && i == 1) || (code == 2 && !i)) | ||
2431 | continue; | ||
2432 | |||
2433 | reg = (i == 0) ? | ||
2434 | B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER; | ||
2435 | b43_phy_maskset(dev, reg, 0xFDFF, 0x0200); | ||
2436 | |||
2437 | if (type < 3) { | ||
2438 | reg = (i == 0) ? | ||
2439 | B43_NPHY_AFECTL_C1 : | ||
2440 | B43_NPHY_AFECTL_C2; | ||
2441 | b43_phy_maskset(dev, reg, 0xFCFF, 0); | ||
2442 | |||
2443 | reg = (i == 0) ? | ||
2444 | B43_NPHY_RFCTL_LUT_TRSW_UP1 : | ||
2445 | B43_NPHY_RFCTL_LUT_TRSW_UP2; | ||
2446 | b43_phy_maskset(dev, reg, 0xFFC3, 0); | ||
2447 | |||
2448 | if (type == 0) | ||
2449 | val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8; | ||
2450 | else if (type == 1) | ||
2451 | val = 16; | ||
2452 | else | ||
2453 | val = 32; | ||
2454 | b43_phy_set(dev, reg, val); | ||
2455 | |||
2456 | reg = (i == 0) ? | ||
2457 | B43_NPHY_TXF_40CO_B1S0 : | ||
2458 | B43_NPHY_TXF_40CO_B32S1; | ||
2459 | b43_phy_set(dev, reg, 0x0020); | ||
2460 | } else { | ||
2461 | if (type == 6) | ||
2462 | val = 0x0100; | ||
2463 | else if (type == 3) | ||
2464 | val = 0x0200; | ||
2465 | else | ||
2466 | val = 0x0300; | ||
2467 | |||
2468 | reg = (i == 0) ? | ||
2469 | B43_NPHY_AFECTL_C1 : | ||
2470 | B43_NPHY_AFECTL_C2; | ||
2471 | |||
2472 | b43_phy_maskset(dev, reg, 0xFCFF, val); | ||
2473 | b43_phy_maskset(dev, reg, 0xF3FF, val << 2); | ||
2474 | |||
2475 | if (type != 3 && type != 6) { | ||
2476 | enum ieee80211_band band = | ||
2477 | b43_current_band(dev->wl); | ||
2478 | |||
2479 | if (b43_nphy_ipa(dev)) | ||
2480 | val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; | ||
2481 | else | ||
2482 | val = 0x11; | ||
2483 | reg = (i == 0) ? 0x2000 : 0x3000; | ||
2484 | reg |= B2055_PADDRV; | ||
2485 | b43_radio_write16(dev, reg, val); | ||
2486 | |||
2487 | reg = (i == 0) ? | ||
2488 | B43_NPHY_AFECTL_OVER1 : | ||
2489 | B43_NPHY_AFECTL_OVER; | ||
2490 | b43_phy_set(dev, reg, 0x0200); | ||
2491 | } | ||
2492 | } | ||
2493 | } | ||
2494 | } | ||
2495 | } | ||
2496 | |||
2497 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ | ||
2498 | static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
2499 | { | ||
2500 | if (dev->phy.rev >= 3) | ||
2501 | b43_nphy_rev3_rssi_select(dev, code, type); | ||
2502 | else | ||
2503 | b43_nphy_rev2_rssi_select(dev, code, type); | ||
2504 | } | ||
2505 | |||
2506 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ | ||
2507 | static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) | ||
2508 | { | ||
2509 | int i; | ||
2510 | for (i = 0; i < 2; i++) { | ||
2511 | if (type == 2) { | ||
2512 | if (i == 0) { | ||
2513 | b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM, | ||
2514 | 0xFC, buf[0]); | ||
2515 | b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5, | ||
2516 | 0xFC, buf[1]); | ||
2517 | } else { | ||
2518 | b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM, | ||
2519 | 0xFC, buf[2 * i]); | ||
2520 | b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5, | ||
2521 | 0xFC, buf[2 * i + 1]); | ||
2522 | } | ||
2523 | } else { | ||
2524 | if (i == 0) | ||
2525 | b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5, | ||
2526 | 0xF3, buf[0] << 2); | ||
2527 | else | ||
2528 | b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5, | ||
2529 | 0xF3, buf[2 * i + 1] << 2); | ||
2530 | } | ||
2531 | } | ||
2532 | } | ||
2533 | |||
2534 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */ | ||
2535 | static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | ||
2536 | u8 nsamp) | ||
2537 | { | ||
2538 | int i; | ||
2539 | int out; | ||
2540 | u16 save_regs_phy[9]; | ||
2541 | u16 s[2]; | ||
2542 | |||
2543 | if (dev->phy.rev >= 3) { | ||
2544 | save_regs_phy[0] = b43_phy_read(dev, | ||
2545 | B43_NPHY_RFCTL_LUT_TRSW_UP1); | ||
2546 | save_regs_phy[1] = b43_phy_read(dev, | ||
2547 | B43_NPHY_RFCTL_LUT_TRSW_UP2); | ||
2548 | save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
2549 | save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
2550 | save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); | ||
2551 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
2552 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); | ||
2553 | save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); | ||
2554 | save_regs_phy[8] = 0; | ||
2555 | } else { | ||
2556 | save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
2557 | save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
2558 | save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
2559 | save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD); | ||
2560 | save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); | ||
2561 | save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); | ||
2562 | save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); | ||
2563 | save_regs_phy[7] = 0; | ||
2564 | save_regs_phy[8] = 0; | ||
2565 | } | ||
2566 | |||
2567 | b43_nphy_rssi_select(dev, 5, type); | ||
2568 | |||
2569 | if (dev->phy.rev < 2) { | ||
2570 | save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL); | ||
2571 | b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5); | ||
2572 | } | ||
2573 | |||
2574 | for (i = 0; i < 4; i++) | ||
2575 | buf[i] = 0; | ||
2576 | |||
2577 | for (i = 0; i < nsamp; i++) { | ||
2578 | if (dev->phy.rev < 2) { | ||
2579 | s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT); | ||
2580 | s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT); | ||
2581 | } else { | ||
2582 | s[0] = b43_phy_read(dev, B43_NPHY_RSSI1); | ||
2583 | s[1] = b43_phy_read(dev, B43_NPHY_RSSI2); | ||
2584 | } | ||
2585 | |||
2586 | buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2; | ||
2587 | buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2; | ||
2588 | buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2; | ||
2589 | buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2; | ||
2590 | } | ||
2591 | out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 | | ||
2592 | (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF); | ||
2593 | |||
2594 | if (dev->phy.rev < 2) | ||
2595 | b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]); | ||
2596 | |||
2597 | if (dev->phy.rev >= 3) { | ||
2598 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, | ||
2599 | save_regs_phy[0]); | ||
2600 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, | ||
2601 | save_regs_phy[1]); | ||
2602 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]); | ||
2603 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]); | ||
2604 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]); | ||
2605 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); | ||
2606 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); | ||
2607 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]); | ||
2608 | } else { | ||
2609 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]); | ||
2610 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]); | ||
2611 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]); | ||
2612 | b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]); | ||
2613 | b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]); | ||
2614 | b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]); | ||
2615 | b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]); | ||
2616 | } | ||
2617 | |||
2618 | return out; | ||
2619 | } | ||
2620 | |||
2621 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ | ||
2622 | static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) | ||
2623 | { | ||
2624 | int i, j; | ||
2625 | u8 state[4]; | ||
2626 | u8 code, val; | ||
2627 | u16 class, override; | ||
2628 | u8 regs_save_radio[2]; | ||
2629 | u16 regs_save_phy[2]; | ||
2630 | |||
2631 | s8 offset[4]; | ||
2632 | u8 core; | ||
2633 | u8 rail; | ||
2634 | |||
2635 | u16 clip_state[2]; | ||
2636 | u16 clip_off[2] = { 0xFFFF, 0xFFFF }; | ||
2637 | s32 results_min[4] = { }; | ||
2638 | u8 vcm_final[4] = { }; | ||
2639 | s32 results[4][4] = { }; | ||
2640 | s32 miniq[4][2] = { }; | ||
2641 | |||
2642 | if (type == 2) { | ||
2643 | code = 0; | ||
2644 | val = 6; | ||
2645 | } else if (type < 2) { | ||
2646 | code = 25; | ||
2647 | val = 4; | ||
2648 | } else { | ||
2649 | B43_WARN_ON(1); | ||
2650 | return; | ||
2651 | } | ||
2652 | |||
2653 | class = b43_nphy_classifier(dev, 0, 0); | ||
2654 | b43_nphy_classifier(dev, 7, 4); | ||
2655 | b43_nphy_read_clip_detection(dev, clip_state); | ||
2656 | b43_nphy_write_clip_detection(dev, clip_off); | ||
2657 | |||
2658 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
2659 | override = 0x140; | ||
2660 | else | ||
2661 | override = 0x110; | ||
2662 | |||
2663 | regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
2664 | regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX); | ||
2665 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override); | ||
2666 | b43_radio_write16(dev, B2055_C1_PD_RXTX, val); | ||
2667 | |||
2668 | regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
2669 | regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX); | ||
2670 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override); | ||
2671 | b43_radio_write16(dev, B2055_C2_PD_RXTX, val); | ||
2672 | |||
2673 | state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07; | ||
2674 | state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07; | ||
2675 | b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8); | ||
2676 | b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8); | ||
2677 | state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07; | ||
2678 | state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07; | ||
2679 | |||
2680 | b43_nphy_rssi_select(dev, 5, type); | ||
2681 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type); | ||
2682 | b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type); | ||
2683 | |||
2684 | for (i = 0; i < 4; i++) { | ||
2685 | u8 tmp[4]; | ||
2686 | for (j = 0; j < 4; j++) | ||
2687 | tmp[j] = i; | ||
2688 | if (type != 1) | ||
2689 | b43_nphy_set_rssi_2055_vcm(dev, type, tmp); | ||
2690 | b43_nphy_poll_rssi(dev, type, results[i], 8); | ||
2691 | if (type < 2) | ||
2692 | for (j = 0; j < 2; j++) | ||
2693 | miniq[i][j] = min(results[i][2 * j], | ||
2694 | results[i][2 * j + 1]); | ||
2695 | } | ||
2696 | |||
2697 | for (i = 0; i < 4; i++) { | ||
2698 | s32 mind = 40; | ||
2699 | u8 minvcm = 0; | ||
2700 | s32 minpoll = 249; | ||
2701 | s32 curr; | ||
2702 | for (j = 0; j < 4; j++) { | ||
2703 | if (type == 2) | ||
2704 | curr = abs(results[j][i]); | ||
2705 | else | ||
2706 | curr = abs(miniq[j][i / 2] - code * 8); | ||
2707 | |||
2708 | if (curr < mind) { | ||
2709 | mind = curr; | ||
2710 | minvcm = j; | ||
2711 | } | ||
2712 | |||
2713 | if (results[j][i] < minpoll) | ||
2714 | minpoll = results[j][i]; | ||
2715 | } | ||
2716 | results_min[i] = minpoll; | ||
2717 | vcm_final[i] = minvcm; | ||
2718 | } | ||
2719 | |||
2720 | if (type != 1) | ||
2721 | b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final); | ||
2722 | |||
2723 | for (i = 0; i < 4; i++) { | ||
2724 | offset[i] = (code * 8) - results[vcm_final[i]][i]; | ||
2725 | |||
2726 | if (offset[i] < 0) | ||
2727 | offset[i] = -((abs(offset[i]) + 4) / 8); | ||
2728 | else | ||
2729 | offset[i] = (offset[i] + 4) / 8; | ||
2730 | |||
2731 | if (results_min[i] == 248) | ||
2732 | offset[i] = code - 32; | ||
2733 | |||
2734 | core = (i / 2) ? 2 : 1; | ||
2735 | rail = (i % 2) ? 1 : 0; | ||
2736 | |||
2737 | b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail, | ||
2738 | type); | ||
2739 | } | ||
2740 | |||
2741 | b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]); | ||
2742 | b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]); | ||
2743 | |||
2744 | switch (state[2]) { | ||
2745 | case 1: | ||
2746 | b43_nphy_rssi_select(dev, 1, 2); | ||
2747 | break; | ||
2748 | case 4: | ||
2749 | b43_nphy_rssi_select(dev, 1, 0); | ||
2750 | break; | ||
2751 | case 2: | ||
2752 | b43_nphy_rssi_select(dev, 1, 1); | ||
2753 | break; | ||
2754 | default: | ||
2755 | b43_nphy_rssi_select(dev, 1, 1); | ||
2756 | break; | ||
2757 | } | ||
2758 | |||
2759 | switch (state[3]) { | ||
2760 | case 1: | ||
2761 | b43_nphy_rssi_select(dev, 2, 2); | ||
2762 | break; | ||
2763 | case 4: | ||
2764 | b43_nphy_rssi_select(dev, 2, 0); | ||
2765 | break; | ||
2766 | default: | ||
2767 | b43_nphy_rssi_select(dev, 2, 1); | ||
2768 | break; | ||
2769 | } | ||
2770 | |||
2771 | b43_nphy_rssi_select(dev, 0, type); | ||
2772 | |||
2773 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]); | ||
2774 | b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]); | ||
2775 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]); | ||
2776 | b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]); | ||
2777 | |||
2778 | b43_nphy_classifier(dev, 7, class); | ||
2779 | b43_nphy_write_clip_detection(dev, clip_state); | ||
2780 | /* Specs don't say about reset here, but it makes wl and b43 dumps | ||
2781 | identical, it really seems wl performs this */ | ||
2782 | b43_nphy_reset_cca(dev); | ||
2783 | } | ||
2784 | |||
2785 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ | ||
2786 | static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) | ||
2787 | { | ||
2788 | /* TODO */ | ||
2789 | } | ||
2790 | |||
2791 | /* | ||
2792 | * RSSI Calibration | ||
2793 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal | ||
2794 | */ | ||
2795 | static void b43_nphy_rssi_cal(struct b43_wldev *dev) | ||
2796 | { | ||
2797 | if (dev->phy.rev >= 3) { | ||
2798 | b43_nphy_rev3_rssi_cal(dev); | ||
2799 | } else { | ||
2800 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z); | ||
2801 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X); | ||
2802 | b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y); | ||
2803 | } | ||
2804 | } | ||
2805 | |||
2806 | /* | 2738 | /* |
2807 | * Restore RSSI Calibration | 2739 | * Restore RSSI Calibration |
2808 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal | 2740 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal |
@@ -2846,24 +2778,6 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev) | |||
2846 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]); | 2778 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]); |
2847 | } | 2779 | } |
2848 | 2780 | ||
2849 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ | ||
2850 | static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) | ||
2851 | { | ||
2852 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
2853 | if (dev->phy.rev >= 6) { | ||
2854 | if (dev->dev->chip_id == 47162) | ||
2855 | return txpwrctrl_tx_gain_ipa_rev5; | ||
2856 | return txpwrctrl_tx_gain_ipa_rev6; | ||
2857 | } else if (dev->phy.rev >= 5) { | ||
2858 | return txpwrctrl_tx_gain_ipa_rev5; | ||
2859 | } else { | ||
2860 | return txpwrctrl_tx_gain_ipa; | ||
2861 | } | ||
2862 | } else { | ||
2863 | return txpwrctrl_tx_gain_ipa_5g; | ||
2864 | } | ||
2865 | } | ||
2866 | |||
2867 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */ | 2781 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */ |
2868 | static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev) | 2782 | static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev) |
2869 | { | 2783 | { |
@@ -3847,10 +3761,104 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) | |||
3847 | b43_mac_enable(dev); | 3761 | b43_mac_enable(dev); |
3848 | } | 3762 | } |
3849 | 3763 | ||
3764 | /************************************************** | ||
3765 | * N-PHY init | ||
3766 | **************************************************/ | ||
3767 | |||
3850 | /* | 3768 | /* |
3851 | * Init N-PHY | 3769 | * Upload the N-PHY tables. |
3852 | * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N | 3770 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables |
3853 | */ | 3771 | */ |
3772 | static void b43_nphy_tables_init(struct b43_wldev *dev) | ||
3773 | { | ||
3774 | if (dev->phy.rev < 3) | ||
3775 | b43_nphy_rev0_1_2_tables_init(dev); | ||
3776 | else | ||
3777 | b43_nphy_rev3plus_tables_init(dev); | ||
3778 | } | ||
3779 | |||
3780 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ | ||
3781 | static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) | ||
3782 | { | ||
3783 | u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG); | ||
3784 | |||
3785 | mimocfg |= B43_NPHY_MIMOCFG_AUTO; | ||
3786 | if (preamble == 1) | ||
3787 | mimocfg |= B43_NPHY_MIMOCFG_GFMIX; | ||
3788 | else | ||
3789 | mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX; | ||
3790 | |||
3791 | b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg); | ||
3792 | } | ||
3793 | |||
3794 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */ | ||
3795 | static void b43_nphy_bphy_init(struct b43_wldev *dev) | ||
3796 | { | ||
3797 | unsigned int i; | ||
3798 | u16 val; | ||
3799 | |||
3800 | val = 0x1E1F; | ||
3801 | for (i = 0; i < 16; i++) { | ||
3802 | b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val); | ||
3803 | val -= 0x202; | ||
3804 | } | ||
3805 | val = 0x3E3F; | ||
3806 | for (i = 0; i < 16; i++) { | ||
3807 | b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val); | ||
3808 | val -= 0x202; | ||
3809 | } | ||
3810 | b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); | ||
3811 | } | ||
3812 | |||
3813 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */ | ||
3814 | static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) | ||
3815 | { | ||
3816 | if (dev->phy.rev >= 3) { | ||
3817 | if (!init) | ||
3818 | return; | ||
3819 | if (0 /* FIXME */) { | ||
3820 | b43_ntab_write(dev, B43_NTAB16(9, 2), 0x211); | ||
3821 | b43_ntab_write(dev, B43_NTAB16(9, 3), 0x222); | ||
3822 | b43_ntab_write(dev, B43_NTAB16(9, 8), 0x144); | ||
3823 | b43_ntab_write(dev, B43_NTAB16(9, 12), 0x188); | ||
3824 | } | ||
3825 | } else { | ||
3826 | b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); | ||
3827 | b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); | ||
3828 | |||
3829 | switch (dev->dev->bus_type) { | ||
3830 | #ifdef CONFIG_B43_BCMA | ||
3831 | case B43_BUS_BCMA: | ||
3832 | bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, | ||
3833 | 0xFC00, 0xFC00); | ||
3834 | break; | ||
3835 | #endif | ||
3836 | #ifdef CONFIG_B43_SSB | ||
3837 | case B43_BUS_SSB: | ||
3838 | ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco, | ||
3839 | 0xFC00, 0xFC00); | ||
3840 | break; | ||
3841 | #endif | ||
3842 | } | ||
3843 | |||
3844 | b43_write32(dev, B43_MMIO_MACCTL, | ||
3845 | b43_read32(dev, B43_MMIO_MACCTL) & | ||
3846 | ~B43_MACCTL_GPOUTSMSK); | ||
3847 | b43_write16(dev, B43_MMIO_GPIO_MASK, | ||
3848 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00); | ||
3849 | b43_write16(dev, B43_MMIO_GPIO_CONTROL, | ||
3850 | b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00); | ||
3851 | |||
3852 | if (init) { | ||
3853 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
3854 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
3855 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
3856 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
3857 | } | ||
3858 | } | ||
3859 | } | ||
3860 | |||
3861 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N */ | ||
3854 | int b43_phy_initn(struct b43_wldev *dev) | 3862 | int b43_phy_initn(struct b43_wldev *dev) |
3855 | { | 3863 | { |
3856 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | 3864 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
@@ -4045,11 +4053,26 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
4045 | return 0; | 4053 | return 0; |
4046 | } | 4054 | } |
4047 | 4055 | ||
4056 | /************************************************** | ||
4057 | * Channel switching ops. | ||
4058 | **************************************************/ | ||
4059 | |||
4060 | static void b43_chantab_phy_upload(struct b43_wldev *dev, | ||
4061 | const struct b43_phy_n_sfo_cfg *e) | ||
4062 | { | ||
4063 | b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a); | ||
4064 | b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2); | ||
4065 | b43_phy_write(dev, B43_NPHY_BW3, e->phy_bw3); | ||
4066 | b43_phy_write(dev, B43_NPHY_BW4, e->phy_bw4); | ||
4067 | b43_phy_write(dev, B43_NPHY_BW5, e->phy_bw5); | ||
4068 | b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6); | ||
4069 | } | ||
4070 | |||
4048 | /* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */ | 4071 | /* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */ |
4049 | static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) | 4072 | static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) |
4050 | { | 4073 | { |
4051 | struct bcma_drv_cc *cc; | 4074 | struct bcma_drv_cc __maybe_unused *cc; |
4052 | u32 pmu_ctl; | 4075 | u32 __maybe_unused pmu_ctl; |
4053 | 4076 | ||
4054 | switch (dev->dev->bus_type) { | 4077 | switch (dev->dev->bus_type) { |
4055 | #ifdef CONFIG_B43_BCMA | 4078 | #ifdef CONFIG_B43_BCMA |
@@ -4260,6 +4283,10 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, | |||
4260 | return 0; | 4283 | return 0; |
4261 | } | 4284 | } |
4262 | 4285 | ||
4286 | /************************************************** | ||
4287 | * Basic PHY ops. | ||
4288 | **************************************************/ | ||
4289 | |||
4263 | static int b43_nphy_op_allocate(struct b43_wldev *dev) | 4290 | static int b43_nphy_op_allocate(struct b43_wldev *dev) |
4264 | { | 4291 | { |
4265 | struct b43_phy_n *nphy; | 4292 | struct b43_phy_n *nphy; |
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index 8f54c2eb6824..cd6375de2a60 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig | |||
@@ -17,16 +17,26 @@ config BRCMSMAC | |||
17 | 17 | ||
18 | config BRCMFMAC | 18 | config BRCMFMAC |
19 | tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver" | 19 | tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver" |
20 | depends on MMC | ||
21 | depends on CFG80211 | 20 | depends on CFG80211 |
22 | select BRCMUTIL | 21 | select BRCMUTIL |
23 | select FW_LOADER | ||
24 | ---help--- | 22 | ---help--- |
25 | This module adds support for embedded wireless adapters based on | 23 | This module adds support for embedded wireless adapters based on |
26 | Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's | 24 | Broadcom IEEE802.11n FullMAC chipsets. It has to work with at least |
27 | wireless extensions subsystem. If you choose to build a module, | 25 | one of the bus interface support. If you choose to build a module, |
28 | it'll be called brcmfmac.ko. | 26 | it'll be called brcmfmac.ko. |
29 | 27 | ||
28 | config BRCMFMAC_SDIO | ||
29 | bool "SDIO bus interface support for FullMAC" | ||
30 | depends on MMC | ||
31 | depends on BRCMFMAC | ||
32 | select FW_LOADER | ||
33 | default y | ||
34 | ---help--- | ||
35 | This option enables the SDIO bus interface support for Broadcom | ||
36 | FullMAC WLAN driver. | ||
37 | Say Y if you want to use brcmfmac for a compatible SDIO interface | ||
38 | wireless card. | ||
39 | |||
30 | config BRCMDBG | 40 | config BRCMDBG |
31 | bool "Broadcom driver debug functions" | 41 | bool "Broadcom driver debug functions" |
32 | depends on BRCMSMAC || BRCMFMAC | 42 | depends on BRCMSMAC || BRCMFMAC |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index d58aa1b0a932..9ca9ea1135ea 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile | |||
@@ -19,16 +19,16 @@ ccflags-y += \ | |||
19 | -Idrivers/net/wireless/brcm80211/brcmfmac \ | 19 | -Idrivers/net/wireless/brcm80211/brcmfmac \ |
20 | -Idrivers/net/wireless/brcm80211/include | 20 | -Idrivers/net/wireless/brcm80211/include |
21 | 21 | ||
22 | DHDOFILES = \ | ||
23 | wl_cfg80211.o \ | ||
24 | dhd_cdc.o \ | ||
25 | dhd_common.o \ | ||
26 | dhd_sdio.o \ | ||
27 | dhd_linux.o \ | ||
28 | bcmsdh.o \ | ||
29 | bcmsdh_sdmmc.o \ | ||
30 | sdio_chip.o | ||
31 | |||
32 | obj-$(CONFIG_BRCMFMAC) += brcmfmac.o | 22 | obj-$(CONFIG_BRCMFMAC) += brcmfmac.o |
33 | brcmfmac-objs += $(DHDOFILES) | 23 | brcmfmac-objs += \ |
24 | wl_cfg80211.o \ | ||
25 | dhd_cdc.o \ | ||
26 | dhd_common.o \ | ||
27 | dhd_linux.o | ||
28 | brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ | ||
29 | dhd_sdio.o \ | ||
30 | bcmsdh.o \ | ||
31 | bcmsdh_sdmmc.o \ | ||
32 | sdio_chip.o | ||
33 | |||
34 | ccflags-y += -D__CHECK_ENDIAN__ | 34 | ccflags-y += -D__CHECK_ENDIAN__ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 6c85d668c9d7..4bc8d251acf8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <brcmu_utils.h> | 31 | #include <brcmu_utils.h> |
32 | #include <brcmu_wifi.h> | 32 | #include <brcmu_wifi.h> |
33 | #include <soc.h> | 33 | #include <soc.h> |
34 | #include "dhd.h" | ||
35 | #include "dhd_bus.h" | 34 | #include "dhd_bus.h" |
36 | #include "dhd_dbg.h" | 35 | #include "dhd_dbg.h" |
37 | #include "sdio_host.h" | 36 | #include "sdio_host.h" |
@@ -51,12 +50,18 @@ static void brcmf_sdioh_irqhandler(struct sdio_func *func) | |||
51 | sdio_claim_host(func); | 50 | sdio_claim_host(func); |
52 | } | 51 | } |
53 | 52 | ||
53 | /* dummy handler for SDIO function 2 interrupt */ | ||
54 | static void brcmf_sdioh_dummy_irq_handler(struct sdio_func *func) | ||
55 | { | ||
56 | } | ||
57 | |||
54 | int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev) | 58 | int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev) |
55 | { | 59 | { |
56 | brcmf_dbg(TRACE, "Entering\n"); | 60 | brcmf_dbg(TRACE, "Entering\n"); |
57 | 61 | ||
58 | sdio_claim_host(sdiodev->func[1]); | 62 | sdio_claim_host(sdiodev->func[1]); |
59 | sdio_claim_irq(sdiodev->func[1], brcmf_sdioh_irqhandler); | 63 | sdio_claim_irq(sdiodev->func[1], brcmf_sdioh_irqhandler); |
64 | sdio_claim_irq(sdiodev->func[2], brcmf_sdioh_dummy_irq_handler); | ||
60 | sdio_release_host(sdiodev->func[1]); | 65 | sdio_release_host(sdiodev->func[1]); |
61 | 66 | ||
62 | return 0; | 67 | return 0; |
@@ -67,6 +72,7 @@ int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev) | |||
67 | brcmf_dbg(TRACE, "Entering\n"); | 72 | brcmf_dbg(TRACE, "Entering\n"); |
68 | 73 | ||
69 | sdio_claim_host(sdiodev->func[1]); | 74 | sdio_claim_host(sdiodev->func[1]); |
75 | sdio_release_irq(sdiodev->func[2]); | ||
70 | sdio_release_irq(sdiodev->func[1]); | 76 | sdio_release_irq(sdiodev->func[1]); |
71 | sdio_release_host(sdiodev->func[1]); | 77 | sdio_release_host(sdiodev->func[1]); |
72 | 78 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index b895f198a950..9b8c0ed833d4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -31,9 +31,8 @@ | |||
31 | #include <brcmu_utils.h> | 31 | #include <brcmu_utils.h> |
32 | #include <brcmu_wifi.h> | 32 | #include <brcmu_wifi.h> |
33 | #include "sdio_host.h" | 33 | #include "sdio_host.h" |
34 | #include "dhd.h" | ||
35 | #include "dhd_dbg.h" | 34 | #include "dhd_dbg.h" |
36 | #include "wl_cfg80211.h" | 35 | #include "dhd_bus.h" |
37 | 36 | ||
38 | #define SDIO_VENDOR_ID_BROADCOM 0x02d0 | 37 | #define SDIO_VENDOR_ID_BROADCOM 0x02d0 |
39 | 38 | ||
@@ -488,6 +487,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
488 | sdiodev->bus_if = bus_if; | 487 | sdiodev->bus_if = bus_if; |
489 | bus_if->bus_priv = sdiodev; | 488 | bus_if->bus_priv = sdiodev; |
490 | bus_if->type = SDIO_BUS; | 489 | bus_if->type = SDIO_BUS; |
490 | bus_if->align = BRCMF_SDALIGN; | ||
491 | dev_set_drvdata(&func->card->dev, sdiodev); | 491 | dev_set_drvdata(&func->card->dev, sdiodev); |
492 | 492 | ||
493 | atomic_set(&sdiodev->suspend, false); | 493 | atomic_set(&sdiodev->suspend, false); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index ed60f4d69627..e58ea40a75b0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -156,18 +156,6 @@ struct brcmf_event { | |||
156 | struct brcmf_event_msg msg; | 156 | struct brcmf_event_msg msg; |
157 | } __packed; | 157 | } __packed; |
158 | 158 | ||
159 | struct dngl_stats { | ||
160 | unsigned long rx_packets; /* total packets received */ | ||
161 | unsigned long tx_packets; /* total packets transmitted */ | ||
162 | unsigned long rx_bytes; /* total bytes received */ | ||
163 | unsigned long tx_bytes; /* total bytes transmitted */ | ||
164 | unsigned long rx_errors; /* bad packets received */ | ||
165 | unsigned long tx_errors; /* packet transmit problems */ | ||
166 | unsigned long rx_dropped; /* packets dropped by dongle */ | ||
167 | unsigned long tx_dropped; /* packets dropped by dongle */ | ||
168 | unsigned long multicast; /* multicast packets received */ | ||
169 | }; | ||
170 | |||
171 | /* event codes sent by the dongle to this driver */ | 159 | /* event codes sent by the dongle to this driver */ |
172 | #define BRCMF_E_SET_SSID 0 | 160 | #define BRCMF_E_SET_SSID 0 |
173 | #define BRCMF_E_JOIN 1 | 161 | #define BRCMF_E_JOIN 1 |
@@ -317,13 +305,6 @@ struct dngl_stats { | |||
317 | #define BRCMF_E_LINK_ASSOC_REC 3 | 305 | #define BRCMF_E_LINK_ASSOC_REC 3 |
318 | #define BRCMF_E_LINK_BSSCFG_DIS 4 | 306 | #define BRCMF_E_LINK_BSSCFG_DIS 4 |
319 | 307 | ||
320 | /* The level of bus communication with the dongle */ | ||
321 | enum brcmf_bus_state { | ||
322 | BRCMF_BUS_DOWN, /* Not ready for frame transfers */ | ||
323 | BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ | ||
324 | BRCMF_BUS_DATA /* Ready for frame transfers */ | ||
325 | }; | ||
326 | |||
327 | /* Pattern matching filter. Specifies an offset within received packets to | 308 | /* Pattern matching filter. Specifies an offset within received packets to |
328 | * start matching, the pattern to match, the size of the pattern, and a bitmask | 309 | * start matching, the pattern to match, the size of the pattern, and a bitmask |
329 | * that indicates which bits within the pattern should be matched. | 310 | * that indicates which bits within the pattern should be matched. |
@@ -571,33 +552,20 @@ struct brcmf_dcmd { | |||
571 | uint needed; /* bytes needed (optional) */ | 552 | uint needed; /* bytes needed (optional) */ |
572 | }; | 553 | }; |
573 | 554 | ||
574 | struct brcmf_bus { | ||
575 | u8 type; /* bus type */ | ||
576 | void *bus_priv; /* pointer to bus private structure */ | ||
577 | enum brcmf_bus_state state; | ||
578 | }; | ||
579 | |||
580 | /* Forward decls for struct brcmf_pub (see below) */ | 555 | /* Forward decls for struct brcmf_pub (see below) */ |
581 | struct brcmf_sdio; /* device bus info */ | ||
582 | struct brcmf_proto; /* device communication protocol info */ | 556 | struct brcmf_proto; /* device communication protocol info */ |
583 | struct brcmf_info; /* device driver info */ | ||
584 | struct brcmf_cfg80211_dev; /* cfg80211 device info */ | 557 | struct brcmf_cfg80211_dev; /* cfg80211 device info */ |
585 | 558 | ||
586 | /* Common structure for module and instance linkage */ | 559 | /* Common structure for module and instance linkage */ |
587 | struct brcmf_pub { | 560 | struct brcmf_pub { |
588 | /* Linkage ponters */ | 561 | /* Linkage ponters */ |
589 | struct brcmf_sdio *bus; | ||
590 | struct brcmf_bus *bus_if; | 562 | struct brcmf_bus *bus_if; |
591 | struct brcmf_proto *prot; | 563 | struct brcmf_proto *prot; |
592 | struct brcmf_info *info; | ||
593 | struct brcmf_cfg80211_dev *config; | 564 | struct brcmf_cfg80211_dev *config; |
594 | struct device *dev; /* fullmac dongle device pointer */ | 565 | struct device *dev; /* fullmac dongle device pointer */ |
595 | 566 | ||
596 | /* Internal brcmf items */ | 567 | /* Internal brcmf items */ |
597 | bool up; /* Driver up/down (to OS) */ | ||
598 | bool txoff; /* Transmit flow-controlled */ | ||
599 | uint hdrlen; /* Total BRCMF header length (proto + bus) */ | 568 | uint hdrlen; /* Total BRCMF header length (proto + bus) */ |
600 | uint maxctl; /* Max size rxctl request from proto to bus */ | ||
601 | uint rxsz; /* Rx buffer size bus module should use */ | 569 | uint rxsz; /* Rx buffer size bus module should use */ |
602 | u8 wme_dp; /* wme discard priority */ | 570 | u8 wme_dp; /* wme discard priority */ |
603 | 571 | ||
@@ -605,48 +573,21 @@ struct brcmf_pub { | |||
605 | bool iswl; /* Dongle-resident driver is wl */ | 573 | bool iswl; /* Dongle-resident driver is wl */ |
606 | unsigned long drv_version; /* Version of dongle-resident driver */ | 574 | unsigned long drv_version; /* Version of dongle-resident driver */ |
607 | u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ | 575 | u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ |
608 | struct dngl_stats dstats; /* Stats for dongle-based data */ | ||
609 | 576 | ||
610 | /* Additional stats for the bus level */ | 577 | /* Additional stats for the bus level */ |
611 | 578 | ||
612 | /* Data packets sent to dongle */ | ||
613 | unsigned long tx_packets; | ||
614 | /* Multicast data packets sent to dongle */ | 579 | /* Multicast data packets sent to dongle */ |
615 | unsigned long tx_multicast; | 580 | unsigned long tx_multicast; |
616 | /* Errors in sending data to dongle */ | ||
617 | unsigned long tx_errors; | ||
618 | /* Control packets sent to dongle */ | ||
619 | unsigned long tx_ctlpkts; | ||
620 | /* Errors sending control frames to dongle */ | ||
621 | unsigned long tx_ctlerrs; | ||
622 | /* Packets sent up the network interface */ | ||
623 | unsigned long rx_packets; | ||
624 | /* Multicast packets sent up the network interface */ | ||
625 | unsigned long rx_multicast; | ||
626 | /* Errors processing rx data packets */ | ||
627 | unsigned long rx_errors; | ||
628 | /* Control frames processed from dongle */ | ||
629 | unsigned long rx_ctlpkts; | ||
630 | |||
631 | /* Errors in processing rx control frames */ | ||
632 | unsigned long rx_ctlerrs; | ||
633 | /* Packets dropped locally (no memory) */ | ||
634 | unsigned long rx_dropped; | ||
635 | /* Packets flushed due to unscheduled sendup thread */ | 581 | /* Packets flushed due to unscheduled sendup thread */ |
636 | unsigned long rx_flushed; | 582 | unsigned long rx_flushed; |
637 | /* Number of times dpc scheduled by watchdog timer */ | 583 | /* Number of times dpc scheduled by watchdog timer */ |
638 | unsigned long wd_dpc_sched; | 584 | unsigned long wd_dpc_sched; |
639 | 585 | ||
640 | /* Number of packets where header read-ahead was used. */ | ||
641 | unsigned long rx_readahead_cnt; | ||
642 | /* Number of tx packets we had to realloc for headroom */ | ||
643 | unsigned long tx_realloc; | ||
644 | /* Number of flow control pkts recvd */ | 586 | /* Number of flow control pkts recvd */ |
645 | unsigned long fc_packets; | 587 | unsigned long fc_packets; |
646 | 588 | ||
647 | /* Last error return */ | 589 | /* Last error return */ |
648 | int bcmerror; | 590 | int bcmerror; |
649 | uint tickcnt; | ||
650 | 591 | ||
651 | /* Last error from dongle */ | 592 | /* Last error from dongle */ |
652 | int dongle_error; | 593 | int dongle_error; |
@@ -663,6 +604,15 @@ struct brcmf_pub { | |||
663 | 604 | ||
664 | u8 country_code[BRCM_CNTRY_BUF_SZ]; | 605 | u8 country_code[BRCM_CNTRY_BUF_SZ]; |
665 | char eventmask[BRCMF_EVENTING_MASK_LEN]; | 606 | char eventmask[BRCMF_EVENTING_MASK_LEN]; |
607 | |||
608 | struct brcmf_if *iflist[BRCMF_MAX_IFS]; | ||
609 | |||
610 | struct mutex proto_block; | ||
611 | |||
612 | struct work_struct setmacaddr_work; | ||
613 | struct work_struct multicast_work; | ||
614 | u8 macvalue[ETH_ALEN]; | ||
615 | atomic_t pend_8021x_cnt; | ||
666 | }; | 616 | }; |
667 | 617 | ||
668 | struct brcmf_if_event { | 618 | struct brcmf_if_event { |
@@ -682,73 +632,33 @@ extern const struct bcmevent_name bcmevent_names[]; | |||
682 | extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, | 632 | extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, |
683 | char *buf, uint len); | 633 | char *buf, uint len); |
684 | 634 | ||
685 | /* Indication from bus module regarding presence/insertion of dongle. | ||
686 | * Return struct brcmf_pub pointer, used as handle to OS module in later calls. | ||
687 | * Returned structure should have bus and prot pointers filled in. | ||
688 | * bus_hdrlen specifies required headroom for bus module header. | ||
689 | */ | ||
690 | extern struct brcmf_pub *brcmf_attach(struct brcmf_sdio *bus, | ||
691 | uint bus_hdrlen, struct device *dev); | ||
692 | extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx); | 635 | extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx); |
693 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); | 636 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); |
694 | 637 | ||
695 | extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len); | 638 | extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len); |
696 | 639 | ||
697 | /* Indication from bus module regarding removal/absence of dongle */ | ||
698 | extern void brcmf_detach(struct brcmf_pub *drvr); | ||
699 | |||
700 | /* Indication from bus module to change flow-control state */ | ||
701 | extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on); | ||
702 | |||
703 | extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q, | ||
704 | struct sk_buff *pkt, int prec); | ||
705 | |||
706 | /* Receive frame for delivery to OS. Callee disposes of rxp. */ | ||
707 | extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, | ||
708 | struct sk_buff_head *rxlist); | ||
709 | static inline void brcmf_rx_packet(struct brcmf_pub *drvr, int ifidx, | ||
710 | struct sk_buff *pkt) | ||
711 | { | ||
712 | struct sk_buff_head q; | ||
713 | |||
714 | skb_queue_head_init(&q); | ||
715 | skb_queue_tail(&q, pkt); | ||
716 | brcmf_rx_frame(drvr, ifidx, &q); | ||
717 | } | ||
718 | |||
719 | /* Return pointer to interface name */ | 640 | /* Return pointer to interface name */ |
720 | extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); | 641 | extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); |
721 | 642 | ||
722 | /* Notify tx completion */ | ||
723 | extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, | ||
724 | bool success); | ||
725 | |||
726 | /* Query dongle */ | 643 | /* Query dongle */ |
727 | extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, | 644 | extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, |
728 | uint cmd, void *buf, uint len); | 645 | uint cmd, void *buf, uint len); |
729 | 646 | ||
730 | /* OS independent layer functions */ | ||
731 | extern int brcmf_os_proto_block(struct brcmf_pub *drvr); | ||
732 | extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr); | ||
733 | #ifdef BCMDBG | 647 | #ifdef BCMDBG |
734 | extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size); | 648 | extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size); |
735 | #endif /* BCMDBG */ | 649 | #endif /* BCMDBG */ |
736 | 650 | ||
737 | extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name); | 651 | extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); |
738 | extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx, | 652 | extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, |
739 | void *pktdata, struct brcmf_event_msg *, | 653 | void *pktdata, struct brcmf_event_msg *, |
740 | void **data_ptr); | 654 | void **data_ptr); |
741 | 655 | ||
742 | extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, | 656 | extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); |
743 | char *name, u8 *mac_addr); | ||
744 | extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); | ||
745 | 657 | ||
746 | /* Send packet to dongle via data channel */ | 658 | /* Send packet to dongle via data channel */ |
747 | extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\ | 659 | extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\ |
748 | struct sk_buff *pkt); | 660 | struct sk_buff *pkt); |
749 | 661 | ||
750 | extern int brcmf_bus_start(struct brcmf_pub *drvr); | ||
751 | |||
752 | extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg); | 662 | extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg); |
753 | extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, | 663 | extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, |
754 | int enable, int master_mode); | 664 | int enable, int master_mode); |
@@ -757,25 +667,4 @@ extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, | |||
757 | #define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */ | 667 | #define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */ |
758 | #define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */ | 668 | #define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */ |
759 | 669 | ||
760 | /* message levels */ | ||
761 | #define BRCMF_ERROR_VAL 0x0001 | ||
762 | #define BRCMF_TRACE_VAL 0x0002 | ||
763 | #define BRCMF_INFO_VAL 0x0004 | ||
764 | #define BRCMF_DATA_VAL 0x0008 | ||
765 | #define BRCMF_CTL_VAL 0x0010 | ||
766 | #define BRCMF_TIMER_VAL 0x0020 | ||
767 | #define BRCMF_HDRS_VAL 0x0040 | ||
768 | #define BRCMF_BYTES_VAL 0x0080 | ||
769 | #define BRCMF_INTR_VAL 0x0100 | ||
770 | #define BRCMF_GLOM_VAL 0x0400 | ||
771 | #define BRCMF_EVENT_VAL 0x0800 | ||
772 | #define BRCMF_BTA_VAL 0x1000 | ||
773 | #define BRCMF_ISCAN_VAL 0x2000 | ||
774 | |||
775 | /* Enter idle immediately (no timeout) */ | ||
776 | #define BRCMF_IDLE_IMMEDIATE (-1) | ||
777 | #define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change | ||
778 | when idle */ | ||
779 | #define BRCMF_IDLE_INTERVAL 1 | ||
780 | |||
781 | #endif /* _BRCMF_H_ */ | 670 | #endif /* _BRCMF_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 1841f996110b..ad9be2410b59 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
@@ -17,34 +17,89 @@ | |||
17 | #ifndef _BRCMF_BUS_H_ | 17 | #ifndef _BRCMF_BUS_H_ |
18 | #define _BRCMF_BUS_H_ | 18 | #define _BRCMF_BUS_H_ |
19 | 19 | ||
20 | /* Packet alignment for most efficient SDIO (can change based on platform) */ | 20 | /* The level of bus communication with the dongle */ |
21 | #define BRCMF_SDALIGN (1 << 6) | 21 | enum brcmf_bus_state { |
22 | BRCMF_BUS_DOWN, /* Not ready for frame transfers */ | ||
23 | BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ | ||
24 | BRCMF_BUS_DATA /* Ready for frame transfers */ | ||
25 | }; | ||
22 | 26 | ||
23 | /* watchdog polling interval in ms */ | 27 | struct dngl_stats { |
24 | #define BRCMF_WD_POLL_MS 10 | 28 | unsigned long rx_packets; /* total packets received */ |
29 | unsigned long tx_packets; /* total packets transmitted */ | ||
30 | unsigned long rx_bytes; /* total bytes received */ | ||
31 | unsigned long tx_bytes; /* total bytes transmitted */ | ||
32 | unsigned long rx_errors; /* bad packets received */ | ||
33 | unsigned long tx_errors; /* packet transmit problems */ | ||
34 | unsigned long rx_dropped; /* packets dropped by dongle */ | ||
35 | unsigned long tx_dropped; /* packets dropped by dongle */ | ||
36 | unsigned long multicast; /* multicast packets received */ | ||
37 | }; | ||
38 | |||
39 | /* interface structure between common and bus layer */ | ||
40 | struct brcmf_bus { | ||
41 | u8 type; /* bus type */ | ||
42 | void *bus_priv; /* pointer to bus private structure */ | ||
43 | void *drvr; /* pointer to driver pub structure brcmf_pub */ | ||
44 | enum brcmf_bus_state state; | ||
45 | uint maxctl; /* Max size rxctl request from proto to bus */ | ||
46 | bool drvr_up; /* Status flag of driver up/down */ | ||
47 | unsigned long tx_realloc; /* Tx packets realloced for headroom */ | ||
48 | struct dngl_stats dstats; /* Stats for dongle-based data */ | ||
49 | u8 align; /* bus alignment requirement */ | ||
50 | |||
51 | /* interface functions pointers */ | ||
52 | /* Stop bus module: clear pending frames, disable data flow */ | ||
53 | void (*brcmf_bus_stop)(struct device *); | ||
54 | /* Initialize bus module: prepare for communication w/dongle */ | ||
55 | int (*brcmf_bus_init)(struct device *); | ||
56 | /* Send a data frame to the dongle. Callee disposes of txp. */ | ||
57 | int (*brcmf_bus_txdata)(struct device *, struct sk_buff *); | ||
58 | /* Send/receive a control message to/from the dongle. | ||
59 | * Expects caller to enforce a single outstanding transaction. | ||
60 | */ | ||
61 | int (*brcmf_bus_txctl)(struct device *, unsigned char *, uint); | ||
62 | int (*brcmf_bus_rxctl)(struct device *, unsigned char *, uint); | ||
63 | }; | ||
25 | 64 | ||
26 | /* | 65 | /* |
27 | * Exported from brcmf bus module (brcmf_usb, brcmf_sdio) | 66 | * interface functions from common layer |
28 | */ | 67 | */ |
29 | 68 | ||
30 | /* Stop bus module: clear pending frames, disable data flow */ | 69 | /* Remove any protocol-specific data header. */ |
31 | extern void brcmf_sdbrcm_bus_stop(struct device *dev); | 70 | extern int brcmf_proto_hdrpull(struct device *dev, int *ifidx, |
71 | struct sk_buff *rxp); | ||
32 | 72 | ||
33 | /* Initialize bus module: prepare for communication w/dongle */ | 73 | extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, |
34 | extern int brcmf_sdbrcm_bus_init(struct device *dev); | 74 | struct sk_buff *pkt, int prec); |
35 | 75 | ||
36 | /* Send a data frame to the dongle. Callee disposes of txp. */ | 76 | /* Receive frame for delivery to OS. Callee disposes of rxp. */ |
37 | extern int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *txp); | 77 | extern void brcmf_rx_frame(struct device *dev, int ifidx, |
78 | struct sk_buff_head *rxlist); | ||
79 | static inline void brcmf_rx_packet(struct device *dev, int ifidx, | ||
80 | struct sk_buff *pkt) | ||
81 | { | ||
82 | struct sk_buff_head q; | ||
38 | 83 | ||
39 | /* Send/receive a control message to/from the dongle. | 84 | skb_queue_head_init(&q); |
40 | * Expects caller to enforce a single outstanding transaction. | 85 | skb_queue_tail(&q, pkt); |
41 | */ | 86 | brcmf_rx_frame(dev, ifidx, &q); |
42 | extern int | 87 | } |
43 | brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen); | 88 | |
89 | /* Indication from bus module regarding presence/insertion of dongle. */ | ||
90 | extern int brcmf_attach(uint bus_hdrlen, struct device *dev); | ||
91 | /* Indication from bus module regarding removal/absence of dongle */ | ||
92 | extern void brcmf_detach(struct device *dev); | ||
93 | |||
94 | /* Indication from bus module to change flow-control state */ | ||
95 | extern void brcmf_txflowcontrol(struct device *dev, int ifidx, bool on); | ||
44 | 96 | ||
45 | extern int | 97 | /* Notify tx completion */ |
46 | brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen); | 98 | extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, |
99 | bool success); | ||
47 | 100 | ||
48 | extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); | 101 | extern int brcmf_bus_start(struct device *dev); |
49 | 102 | ||
103 | extern int brcmf_add_if(struct device *dev, int ifidx, | ||
104 | char *name, u8 *mac_addr); | ||
50 | #endif /* _BRCMF_BUS_H_ */ | 105 | #endif /* _BRCMF_BUS_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index ebd53aa7202b..ac8d1f437888 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | |||
@@ -82,13 +82,14 @@ struct brcmf_proto_bdc_header { | |||
82 | 82 | ||
83 | 83 | ||
84 | #define RETRIES 2 /* # of retries to retrieve matching dcmd response */ | 84 | #define RETRIES 2 /* # of retries to retrieve matching dcmd response */ |
85 | #define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE | 85 | #define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE |
86 | * (amount of header tha might be added) | 86 | * (amount of header tha might be added) |
87 | * plus any space that might be needed | 87 | * plus any space that might be needed |
88 | * for alignment padding. | 88 | * for bus alignment padding. |
89 | */ | 89 | */ |
90 | #define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for | 90 | #define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for |
91 | * round off at the end of buffer | 91 | * round off at the end of buffer |
92 | * Currently is SDIO | ||
92 | */ | 93 | */ |
93 | 94 | ||
94 | struct brcmf_proto { | 95 | struct brcmf_proto { |
@@ -116,8 +117,9 @@ static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) | |||
116 | len = CDC_MAX_MSG_SIZE; | 117 | len = CDC_MAX_MSG_SIZE; |
117 | 118 | ||
118 | /* Send request */ | 119 | /* Send request */ |
119 | return brcmf_sdbrcm_bus_txctl(drvr->dev, (unsigned char *)&prot->msg, | 120 | return drvr->bus_if->brcmf_bus_txctl(drvr->dev, |
120 | len); | 121 | (unsigned char *)&prot->msg, |
122 | len); | ||
121 | } | 123 | } |
122 | 124 | ||
123 | static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) | 125 | static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) |
@@ -128,7 +130,7 @@ static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) | |||
128 | brcmf_dbg(TRACE, "Enter\n"); | 130 | brcmf_dbg(TRACE, "Enter\n"); |
129 | 131 | ||
130 | do { | 132 | do { |
131 | ret = brcmf_sdbrcm_bus_rxctl(drvr->dev, | 133 | ret = drvr->bus_if->brcmf_bus_rxctl(drvr->dev, |
132 | (unsigned char *)&prot->msg, | 134 | (unsigned char *)&prot->msg, |
133 | len + sizeof(struct brcmf_proto_cdc_dcmd)); | 135 | len + sizeof(struct brcmf_proto_cdc_dcmd)); |
134 | if (ret < 0) | 136 | if (ret < 0) |
@@ -284,7 +286,7 @@ brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd, | |||
284 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); | 286 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); |
285 | return ret; | 287 | return ret; |
286 | } | 288 | } |
287 | brcmf_os_proto_block(drvr); | 289 | mutex_lock(&drvr->proto_block); |
288 | 290 | ||
289 | brcmf_dbg(TRACE, "Enter\n"); | 291 | brcmf_dbg(TRACE, "Enter\n"); |
290 | 292 | ||
@@ -338,7 +340,7 @@ brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd, | |||
338 | prot->pending = false; | 340 | prot->pending = false; |
339 | 341 | ||
340 | done: | 342 | done: |
341 | brcmf_os_proto_unblock(drvr); | 343 | mutex_unlock(&drvr->proto_block); |
342 | 344 | ||
343 | return ret; | 345 | return ret; |
344 | } | 346 | } |
@@ -376,10 +378,12 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, | |||
376 | BDC_SET_IF_IDX(h, ifidx); | 378 | BDC_SET_IF_IDX(h, ifidx); |
377 | } | 379 | } |
378 | 380 | ||
379 | int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx, | 381 | int brcmf_proto_hdrpull(struct device *dev, int *ifidx, |
380 | struct sk_buff *pktbuf) | 382 | struct sk_buff *pktbuf) |
381 | { | 383 | { |
382 | struct brcmf_proto_bdc_header *h; | 384 | struct brcmf_proto_bdc_header *h; |
385 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
386 | struct brcmf_pub *drvr = bus_if->drvr; | ||
383 | 387 | ||
384 | brcmf_dbg(TRACE, "Enter\n"); | 388 | brcmf_dbg(TRACE, "Enter\n"); |
385 | 389 | ||
@@ -435,7 +439,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr) | |||
435 | 439 | ||
436 | drvr->prot = cdc; | 440 | drvr->prot = cdc; |
437 | drvr->hdrlen += BDC_HEADER_LEN; | 441 | drvr->hdrlen += BDC_HEADER_LEN; |
438 | drvr->maxctl = BRCMF_DCMD_MAXLEN + | 442 | drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + |
439 | sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; | 443 | sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; |
440 | return 0; | 444 | return 0; |
441 | 445 | ||
@@ -451,18 +455,6 @@ void brcmf_proto_detach(struct brcmf_pub *drvr) | |||
451 | drvr->prot = NULL; | 455 | drvr->prot = NULL; |
452 | } | 456 | } |
453 | 457 | ||
454 | void brcmf_proto_dstats(struct brcmf_pub *drvr) | ||
455 | { | ||
456 | /* No stats from dongle added yet, copy bus stats */ | ||
457 | drvr->dstats.tx_packets = drvr->tx_packets; | ||
458 | drvr->dstats.tx_errors = drvr->tx_errors; | ||
459 | drvr->dstats.rx_packets = drvr->rx_packets; | ||
460 | drvr->dstats.rx_errors = drvr->rx_errors; | ||
461 | drvr->dstats.rx_dropped = drvr->rx_dropped; | ||
462 | drvr->dstats.multicast = drvr->rx_multicast; | ||
463 | return; | ||
464 | } | ||
465 | |||
466 | int brcmf_proto_init(struct brcmf_pub *drvr) | 458 | int brcmf_proto_init(struct brcmf_pub *drvr) |
467 | { | 459 | { |
468 | int ret = 0; | 460 | int ret = 0; |
@@ -470,19 +462,19 @@ int brcmf_proto_init(struct brcmf_pub *drvr) | |||
470 | 462 | ||
471 | brcmf_dbg(TRACE, "Enter\n"); | 463 | brcmf_dbg(TRACE, "Enter\n"); |
472 | 464 | ||
473 | brcmf_os_proto_block(drvr); | 465 | mutex_lock(&drvr->proto_block); |
474 | 466 | ||
475 | /* Get the device MAC address */ | 467 | /* Get the device MAC address */ |
476 | strcpy(buf, "cur_etheraddr"); | 468 | strcpy(buf, "cur_etheraddr"); |
477 | ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, | 469 | ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, |
478 | buf, sizeof(buf)); | 470 | buf, sizeof(buf)); |
479 | if (ret < 0) { | 471 | if (ret < 0) { |
480 | brcmf_os_proto_unblock(drvr); | 472 | mutex_unlock(&drvr->proto_block); |
481 | return ret; | 473 | return ret; |
482 | } | 474 | } |
483 | memcpy(drvr->mac, buf, ETH_ALEN); | 475 | memcpy(drvr->mac, buf, ETH_ALEN); |
484 | 476 | ||
485 | brcmf_os_proto_unblock(drvr); | 477 | mutex_unlock(&drvr->proto_block); |
486 | 478 | ||
487 | ret = brcmf_c_preinit_dcmds(drvr); | 479 | ret = brcmf_c_preinit_dcmds(drvr); |
488 | 480 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 69f335aeb255..a51d8f5d36fc 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -83,12 +83,14 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) | |||
83 | return len; | 83 | return len; |
84 | } | 84 | } |
85 | 85 | ||
86 | bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q, | 86 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, |
87 | struct sk_buff *pkt, int prec) | 87 | struct sk_buff *pkt, int prec) |
88 | { | 88 | { |
89 | struct sk_buff *p; | 89 | struct sk_buff *p; |
90 | int eprec = -1; /* precedence to evict from */ | 90 | int eprec = -1; /* precedence to evict from */ |
91 | bool discard_oldest; | 91 | bool discard_oldest; |
92 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
93 | struct brcmf_pub *drvr = bus_if->drvr; | ||
92 | 94 | ||
93 | /* Fast case, precedence queue is not full and we are also not | 95 | /* Fast case, precedence queue is not full and we are also not |
94 | * exceeding total queue length | 96 | * exceeding total queue length |
@@ -431,7 +433,7 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) | |||
431 | #endif /* BCMDBG */ | 433 | #endif /* BCMDBG */ |
432 | 434 | ||
433 | int | 435 | int |
434 | brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, | 436 | brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, |
435 | struct brcmf_event_msg *event, void **data_ptr) | 437 | struct brcmf_event_msg *event, void **data_ptr) |
436 | { | 438 | { |
437 | /* check whether packet is a BRCM event pkt */ | 439 | /* check whether packet is a BRCM event pkt */ |
@@ -473,18 +475,18 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, | |||
473 | 475 | ||
474 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { | 476 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { |
475 | if (ifevent->action == BRCMF_E_IF_ADD) | 477 | if (ifevent->action == BRCMF_E_IF_ADD) |
476 | brcmf_add_if(drvr_priv, ifevent->ifidx, | 478 | brcmf_add_if(drvr->dev, ifevent->ifidx, |
477 | event->ifname, | 479 | event->ifname, |
478 | pvt_data->eth.h_dest); | 480 | pvt_data->eth.h_dest); |
479 | else | 481 | else |
480 | brcmf_del_if(drvr_priv, ifevent->ifidx); | 482 | brcmf_del_if(drvr, ifevent->ifidx); |
481 | } else { | 483 | } else { |
482 | brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", | 484 | brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", |
483 | ifevent->ifidx, event->ifname); | 485 | ifevent->ifidx, event->ifname); |
484 | } | 486 | } |
485 | 487 | ||
486 | /* send up the if event: btamp user needs it */ | 488 | /* send up the if event: btamp user needs it */ |
487 | *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); | 489 | *ifidx = brcmf_ifname2idx(drvr, event->ifname); |
488 | break; | 490 | break; |
489 | 491 | ||
490 | /* These are what external supplicant/authenticator wants */ | 492 | /* These are what external supplicant/authenticator wants */ |
@@ -496,7 +498,7 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, | |||
496 | default: | 498 | default: |
497 | /* Fall through: this should get _everything_ */ | 499 | /* Fall through: this should get _everything_ */ |
498 | 500 | ||
499 | *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); | 501 | *ifidx = brcmf_ifname2idx(drvr, event->ifname); |
500 | brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n", | 502 | brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n", |
501 | type, flags, status); | 503 | type, flags, status); |
502 | 504 | ||
@@ -796,7 +798,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) | |||
796 | "event_msgs" + '\0' + bitvec */ | 798 | "event_msgs" + '\0' + bitvec */ |
797 | uint up = 0; | 799 | uint up = 0; |
798 | char buf[128], *ptr; | 800 | char buf[128], *ptr; |
799 | u32 dongle_align = BRCMF_SDALIGN; | 801 | u32 dongle_align = drvr->bus_if->align; |
800 | u32 glom = 0; | 802 | u32 glom = 0; |
801 | u32 roaming = 1; | 803 | u32 roaming = 1; |
802 | uint bcn_timeout = 3; | 804 | uint bcn_timeout = 3; |
@@ -804,7 +806,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) | |||
804 | int scan_unassoc_time = 40; | 806 | int scan_unassoc_time = 40; |
805 | int i; | 807 | int i; |
806 | 808 | ||
807 | brcmf_os_proto_block(drvr); | 809 | mutex_lock(&drvr->proto_block); |
808 | 810 | ||
809 | /* Set Country code */ | 811 | /* Set Country code */ |
810 | if (drvr->country_code[0] != 0) { | 812 | if (drvr->country_code[0] != 0) { |
@@ -873,7 +875,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) | |||
873 | 0, true); | 875 | 0, true); |
874 | } | 876 | } |
875 | 877 | ||
876 | brcmf_os_proto_unblock(drvr); | 878 | mutex_unlock(&drvr->proto_block); |
877 | 879 | ||
878 | return 0; | 880 | return 0; |
879 | } | 881 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index 7467922f0536..bb26ee36bc68 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | |||
@@ -17,6 +17,21 @@ | |||
17 | #ifndef _BRCMF_DBG_H_ | 17 | #ifndef _BRCMF_DBG_H_ |
18 | #define _BRCMF_DBG_H_ | 18 | #define _BRCMF_DBG_H_ |
19 | 19 | ||
20 | /* message levels */ | ||
21 | #define BRCMF_ERROR_VAL 0x0001 | ||
22 | #define BRCMF_TRACE_VAL 0x0002 | ||
23 | #define BRCMF_INFO_VAL 0x0004 | ||
24 | #define BRCMF_DATA_VAL 0x0008 | ||
25 | #define BRCMF_CTL_VAL 0x0010 | ||
26 | #define BRCMF_TIMER_VAL 0x0020 | ||
27 | #define BRCMF_HDRS_VAL 0x0040 | ||
28 | #define BRCMF_BYTES_VAL 0x0080 | ||
29 | #define BRCMF_INTR_VAL 0x0100 | ||
30 | #define BRCMF_GLOM_VAL 0x0400 | ||
31 | #define BRCMF_EVENT_VAL 0x0800 | ||
32 | #define BRCMF_BTA_VAL 0x1000 | ||
33 | #define BRCMF_ISCAN_VAL 0x2000 | ||
34 | |||
20 | #if defined(BCMDBG) | 35 | #if defined(BCMDBG) |
21 | 36 | ||
22 | #define brcmf_dbg(level, fmt, ...) \ | 37 | #define brcmf_dbg(level, fmt, ...) \ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 2c3a99d6c9a6..eb9eb766ac27 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -52,7 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
52 | 52 | ||
53 | /* Interface control information */ | 53 | /* Interface control information */ |
54 | struct brcmf_if { | 54 | struct brcmf_if { |
55 | struct brcmf_info *info; /* back pointer to brcmf_info */ | 55 | struct brcmf_pub *drvr; /* back pointer to brcmf_pub */ |
56 | /* OS/stack specifics */ | 56 | /* OS/stack specifics */ |
57 | struct net_device *ndev; | 57 | struct net_device *ndev; |
58 | struct net_device_stats stats; | 58 | struct net_device_stats stats; |
@@ -60,26 +60,11 @@ struct brcmf_if { | |||
60 | u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ | 60 | u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* Local private structure (extension of pub) */ | ||
64 | struct brcmf_info { | ||
65 | struct brcmf_pub pub; | ||
66 | |||
67 | /* OS/stack specifics */ | ||
68 | struct brcmf_if *iflist[BRCMF_MAX_IFS]; | ||
69 | |||
70 | struct mutex proto_block; | ||
71 | |||
72 | struct work_struct setmacaddr_work; | ||
73 | struct work_struct multicast_work; | ||
74 | u8 macvalue[ETH_ALEN]; | ||
75 | atomic_t pend_8021x_cnt; | ||
76 | }; | ||
77 | |||
78 | /* Error bits */ | 63 | /* Error bits */ |
79 | int brcmf_msg_level = BRCMF_ERROR_VAL; | 64 | int brcmf_msg_level = BRCMF_ERROR_VAL; |
80 | module_param(brcmf_msg_level, int, 0); | 65 | module_param(brcmf_msg_level, int, 0); |
81 | 66 | ||
82 | int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) | 67 | int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name) |
83 | { | 68 | { |
84 | int i = BRCMF_MAX_IFS; | 69 | int i = BRCMF_MAX_IFS; |
85 | struct brcmf_if *ifp; | 70 | struct brcmf_if *ifp; |
@@ -88,7 +73,7 @@ int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) | |||
88 | return 0; | 73 | return 0; |
89 | 74 | ||
90 | while (--i > 0) { | 75 | while (--i > 0) { |
91 | ifp = drvr_priv->iflist[i]; | 76 | ifp = drvr->iflist[i]; |
92 | if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ)) | 77 | if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ)) |
93 | break; | 78 | break; |
94 | } | 79 | } |
@@ -100,20 +85,18 @@ int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) | |||
100 | 85 | ||
101 | char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) | 86 | char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) |
102 | { | 87 | { |
103 | struct brcmf_info *drvr_priv = drvr->info; | ||
104 | |||
105 | if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { | 88 | if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { |
106 | brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx); | 89 | brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx); |
107 | return "<if_bad>"; | 90 | return "<if_bad>"; |
108 | } | 91 | } |
109 | 92 | ||
110 | if (drvr_priv->iflist[ifidx] == NULL) { | 93 | if (drvr->iflist[ifidx] == NULL) { |
111 | brcmf_dbg(ERROR, "null i/f %d\n", ifidx); | 94 | brcmf_dbg(ERROR, "null i/f %d\n", ifidx); |
112 | return "<if_null>"; | 95 | return "<if_null>"; |
113 | } | 96 | } |
114 | 97 | ||
115 | if (drvr_priv->iflist[ifidx]->ndev) | 98 | if (drvr->iflist[ifidx]->ndev) |
116 | return drvr_priv->iflist[ifidx]->ndev->name; | 99 | return drvr->iflist[ifidx]->ndev->name; |
117 | 100 | ||
118 | return "<if_none>"; | 101 | return "<if_none>"; |
119 | } | 102 | } |
@@ -131,10 +114,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work) | |||
131 | uint buflen; | 114 | uint buflen; |
132 | int ret; | 115 | int ret; |
133 | 116 | ||
134 | struct brcmf_info *drvr_priv = container_of(work, struct brcmf_info, | 117 | struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, |
135 | multicast_work); | 118 | multicast_work); |
136 | 119 | ||
137 | ndev = drvr_priv->iflist[0]->ndev; | 120 | ndev = drvr->iflist[0]->ndev; |
138 | cnt = netdev_mc_count(ndev); | 121 | cnt = netdev_mc_count(ndev); |
139 | 122 | ||
140 | /* Determine initial value of allmulti flag */ | 123 | /* Determine initial value of allmulti flag */ |
@@ -168,10 +151,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work) | |||
168 | dcmd.len = buflen; | 151 | dcmd.len = buflen; |
169 | dcmd.set = true; | 152 | dcmd.set = true; |
170 | 153 | ||
171 | ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len); | 154 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); |
172 | if (ret < 0) { | 155 | if (ret < 0) { |
173 | brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", | 156 | brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", |
174 | brcmf_ifname(&drvr_priv->pub, 0), cnt); | 157 | brcmf_ifname(drvr, 0), cnt); |
175 | dcmd_value = cnt ? true : dcmd_value; | 158 | dcmd_value = cnt ? true : dcmd_value; |
176 | } | 159 | } |
177 | 160 | ||
@@ -193,7 +176,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work) | |||
193 | ("allmulti", (void *)&dcmd_le_value, | 176 | ("allmulti", (void *)&dcmd_le_value, |
194 | sizeof(dcmd_le_value), buf, buflen)) { | 177 | sizeof(dcmd_le_value), buf, buflen)) { |
195 | brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", | 178 | brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", |
196 | brcmf_ifname(&drvr_priv->pub, 0), | 179 | brcmf_ifname(drvr, 0), |
197 | (int)sizeof(dcmd_value), buflen); | 180 | (int)sizeof(dcmd_value), buflen); |
198 | kfree(buf); | 181 | kfree(buf); |
199 | return; | 182 | return; |
@@ -205,10 +188,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work) | |||
205 | dcmd.len = buflen; | 188 | dcmd.len = buflen; |
206 | dcmd.set = true; | 189 | dcmd.set = true; |
207 | 190 | ||
208 | ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len); | 191 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); |
209 | if (ret < 0) { | 192 | if (ret < 0) { |
210 | brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", | 193 | brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", |
211 | brcmf_ifname(&drvr_priv->pub, 0), | 194 | brcmf_ifname(drvr, 0), |
212 | le32_to_cpu(dcmd_le_value)); | 195 | le32_to_cpu(dcmd_le_value)); |
213 | } | 196 | } |
214 | 197 | ||
@@ -226,10 +209,10 @@ static void _brcmf_set_multicast_list(struct work_struct *work) | |||
226 | dcmd.len = sizeof(dcmd_le_value); | 209 | dcmd.len = sizeof(dcmd_le_value); |
227 | dcmd.set = true; | 210 | dcmd.set = true; |
228 | 211 | ||
229 | ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len); | 212 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); |
230 | if (ret < 0) { | 213 | if (ret < 0) { |
231 | brcmf_dbg(ERROR, "%s: set promisc %d failed\n", | 214 | brcmf_dbg(ERROR, "%s: set promisc %d failed\n", |
232 | brcmf_ifname(&drvr_priv->pub, 0), | 215 | brcmf_ifname(drvr, 0), |
233 | le32_to_cpu(dcmd_le_value)); | 216 | le32_to_cpu(dcmd_le_value)); |
234 | } | 217 | } |
235 | } | 218 | } |
@@ -241,14 +224,14 @@ _brcmf_set_mac_address(struct work_struct *work) | |||
241 | struct brcmf_dcmd dcmd; | 224 | struct brcmf_dcmd dcmd; |
242 | int ret; | 225 | int ret; |
243 | 226 | ||
244 | struct brcmf_info *drvr_priv = container_of(work, struct brcmf_info, | 227 | struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, |
245 | setmacaddr_work); | 228 | setmacaddr_work); |
246 | 229 | ||
247 | brcmf_dbg(TRACE, "enter\n"); | 230 | brcmf_dbg(TRACE, "enter\n"); |
248 | if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr_priv->macvalue, | 231 | if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue, |
249 | ETH_ALEN, buf, 32)) { | 232 | ETH_ALEN, buf, 32)) { |
250 | brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", | 233 | brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", |
251 | brcmf_ifname(&drvr_priv->pub, 0)); | 234 | brcmf_ifname(drvr, 0)); |
252 | return; | 235 | return; |
253 | } | 236 | } |
254 | memset(&dcmd, 0, sizeof(dcmd)); | 237 | memset(&dcmd, 0, sizeof(dcmd)); |
@@ -257,13 +240,13 @@ _brcmf_set_mac_address(struct work_struct *work) | |||
257 | dcmd.len = 32; | 240 | dcmd.len = 32; |
258 | dcmd.set = true; | 241 | dcmd.set = true; |
259 | 242 | ||
260 | ret = brcmf_proto_dcmd(&drvr_priv->pub, 0, &dcmd, dcmd.len); | 243 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); |
261 | if (ret < 0) | 244 | if (ret < 0) |
262 | brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", | 245 | brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", |
263 | brcmf_ifname(&drvr_priv->pub, 0)); | 246 | brcmf_ifname(drvr, 0)); |
264 | else | 247 | else |
265 | memcpy(drvr_priv->iflist[0]->ndev->dev_addr, | 248 | memcpy(drvr->iflist[0]->ndev->dev_addr, |
266 | drvr_priv->macvalue, ETH_ALEN); | 249 | drvr->macvalue, ETH_ALEN); |
267 | 250 | ||
268 | return; | 251 | return; |
269 | } | 252 | } |
@@ -271,28 +254,26 @@ _brcmf_set_mac_address(struct work_struct *work) | |||
271 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) | 254 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) |
272 | { | 255 | { |
273 | struct brcmf_if *ifp = netdev_priv(ndev); | 256 | struct brcmf_if *ifp = netdev_priv(ndev); |
274 | struct brcmf_info *drvr_priv = ifp->info; | 257 | struct brcmf_pub *drvr = ifp->drvr; |
275 | struct sockaddr *sa = (struct sockaddr *)addr; | 258 | struct sockaddr *sa = (struct sockaddr *)addr; |
276 | 259 | ||
277 | memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); | 260 | memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN); |
278 | schedule_work(&drvr_priv->setmacaddr_work); | 261 | schedule_work(&drvr->setmacaddr_work); |
279 | return 0; | 262 | return 0; |
280 | } | 263 | } |
281 | 264 | ||
282 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) | 265 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) |
283 | { | 266 | { |
284 | struct brcmf_if *ifp = netdev_priv(ndev); | 267 | struct brcmf_if *ifp = netdev_priv(ndev); |
285 | struct brcmf_info *drvr_priv = ifp->info; | 268 | struct brcmf_pub *drvr = ifp->drvr; |
286 | 269 | ||
287 | schedule_work(&drvr_priv->multicast_work); | 270 | schedule_work(&drvr->multicast_work); |
288 | } | 271 | } |
289 | 272 | ||
290 | int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) | 273 | int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) |
291 | { | 274 | { |
292 | struct brcmf_info *drvr_priv = drvr->info; | ||
293 | |||
294 | /* Reject if down */ | 275 | /* Reject if down */ |
295 | if (!drvr->up || (drvr->bus_if->state == BRCMF_BUS_DOWN)) | 276 | if (!drvr->bus_if->drvr_up || (drvr->bus_if->state == BRCMF_BUS_DOWN)) |
296 | return -ENODEV; | 277 | return -ENODEV; |
297 | 278 | ||
298 | /* Update multicast statistic */ | 279 | /* Update multicast statistic */ |
@@ -303,112 +284,113 @@ int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) | |||
303 | if (is_multicast_ether_addr(eh->h_dest)) | 284 | if (is_multicast_ether_addr(eh->h_dest)) |
304 | drvr->tx_multicast++; | 285 | drvr->tx_multicast++; |
305 | if (ntohs(eh->h_proto) == ETH_P_PAE) | 286 | if (ntohs(eh->h_proto) == ETH_P_PAE) |
306 | atomic_inc(&drvr_priv->pend_8021x_cnt); | 287 | atomic_inc(&drvr->pend_8021x_cnt); |
307 | } | 288 | } |
308 | 289 | ||
309 | /* If the protocol uses a data header, apply it */ | 290 | /* If the protocol uses a data header, apply it */ |
310 | brcmf_proto_hdrpush(drvr, ifidx, pktbuf); | 291 | brcmf_proto_hdrpush(drvr, ifidx, pktbuf); |
311 | 292 | ||
312 | /* Use bus module to send data frame */ | 293 | /* Use bus module to send data frame */ |
313 | return brcmf_sdbrcm_bus_txdata(drvr->dev, pktbuf); | 294 | return drvr->bus_if->brcmf_bus_txdata(drvr->dev, pktbuf); |
314 | } | 295 | } |
315 | 296 | ||
316 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 297 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
317 | { | 298 | { |
318 | int ret; | 299 | int ret; |
319 | struct brcmf_if *ifp = netdev_priv(ndev); | 300 | struct brcmf_if *ifp = netdev_priv(ndev); |
320 | struct brcmf_info *drvr_priv = ifp->info; | 301 | struct brcmf_pub *drvr = ifp->drvr; |
321 | 302 | ||
322 | brcmf_dbg(TRACE, "Enter\n"); | 303 | brcmf_dbg(TRACE, "Enter\n"); |
323 | 304 | ||
324 | /* Reject if down */ | 305 | /* Reject if down */ |
325 | if (!drvr_priv->pub.up || | 306 | if (!drvr->bus_if->drvr_up || |
326 | (drvr_priv->pub.bus_if->state == BRCMF_BUS_DOWN)) { | 307 | (drvr->bus_if->state == BRCMF_BUS_DOWN)) { |
327 | brcmf_dbg(ERROR, "xmit rejected pub.up=%d state=%d\n", | 308 | brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", |
328 | drvr_priv->pub.up, | 309 | drvr->bus_if->drvr_up, |
329 | drvr_priv->pub.bus_if->state); | 310 | drvr->bus_if->state); |
330 | netif_stop_queue(ndev); | 311 | netif_stop_queue(ndev); |
331 | return -ENODEV; | 312 | return -ENODEV; |
332 | } | 313 | } |
333 | 314 | ||
334 | if (!drvr_priv->iflist[ifp->idx]) { | 315 | if (!drvr->iflist[ifp->idx]) { |
335 | brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx); | 316 | brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx); |
336 | netif_stop_queue(ndev); | 317 | netif_stop_queue(ndev); |
337 | return -ENODEV; | 318 | return -ENODEV; |
338 | } | 319 | } |
339 | 320 | ||
340 | /* Make sure there's enough room for any header */ | 321 | /* Make sure there's enough room for any header */ |
341 | if (skb_headroom(skb) < drvr_priv->pub.hdrlen) { | 322 | if (skb_headroom(skb) < drvr->hdrlen) { |
342 | struct sk_buff *skb2; | 323 | struct sk_buff *skb2; |
343 | 324 | ||
344 | brcmf_dbg(INFO, "%s: insufficient headroom\n", | 325 | brcmf_dbg(INFO, "%s: insufficient headroom\n", |
345 | brcmf_ifname(&drvr_priv->pub, ifp->idx)); | 326 | brcmf_ifname(drvr, ifp->idx)); |
346 | drvr_priv->pub.tx_realloc++; | 327 | drvr->bus_if->tx_realloc++; |
347 | skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); | 328 | skb2 = skb_realloc_headroom(skb, drvr->hdrlen); |
348 | dev_kfree_skb(skb); | 329 | dev_kfree_skb(skb); |
349 | skb = skb2; | 330 | skb = skb2; |
350 | if (skb == NULL) { | 331 | if (skb == NULL) { |
351 | brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", | 332 | brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", |
352 | brcmf_ifname(&drvr_priv->pub, ifp->idx)); | 333 | brcmf_ifname(drvr, ifp->idx)); |
353 | ret = -ENOMEM; | 334 | ret = -ENOMEM; |
354 | goto done; | 335 | goto done; |
355 | } | 336 | } |
356 | } | 337 | } |
357 | 338 | ||
358 | ret = brcmf_sendpkt(&drvr_priv->pub, ifp->idx, skb); | 339 | ret = brcmf_sendpkt(drvr, ifp->idx, skb); |
359 | 340 | ||
360 | done: | 341 | done: |
361 | if (ret) | 342 | if (ret) |
362 | drvr_priv->pub.dstats.tx_dropped++; | 343 | drvr->bus_if->dstats.tx_dropped++; |
363 | else | 344 | else |
364 | drvr_priv->pub.tx_packets++; | 345 | drvr->bus_if->dstats.tx_packets++; |
365 | 346 | ||
366 | /* Return ok: we always eat the packet */ | 347 | /* Return ok: we always eat the packet */ |
367 | return 0; | 348 | return 0; |
368 | } | 349 | } |
369 | 350 | ||
370 | void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state) | 351 | void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state) |
371 | { | 352 | { |
372 | struct net_device *ndev; | 353 | struct net_device *ndev; |
373 | struct brcmf_info *drvr_priv = drvr->info; | 354 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
355 | struct brcmf_pub *drvr = bus_if->drvr; | ||
374 | 356 | ||
375 | brcmf_dbg(TRACE, "Enter\n"); | 357 | brcmf_dbg(TRACE, "Enter\n"); |
376 | 358 | ||
377 | drvr->txoff = state; | 359 | ndev = drvr->iflist[ifidx]->ndev; |
378 | ndev = drvr_priv->iflist[ifidx]->ndev; | ||
379 | if (state == ON) | 360 | if (state == ON) |
380 | netif_stop_queue(ndev); | 361 | netif_stop_queue(ndev); |
381 | else | 362 | else |
382 | netif_wake_queue(ndev); | 363 | netif_wake_queue(ndev); |
383 | } | 364 | } |
384 | 365 | ||
385 | static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, | 366 | static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, |
386 | void *pktdata, struct brcmf_event_msg *event, | 367 | void *pktdata, struct brcmf_event_msg *event, |
387 | void **data) | 368 | void **data) |
388 | { | 369 | { |
389 | int bcmerror = 0; | 370 | int bcmerror = 0; |
390 | 371 | ||
391 | bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data); | 372 | bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data); |
392 | if (bcmerror != 0) | 373 | if (bcmerror != 0) |
393 | return bcmerror; | 374 | return bcmerror; |
394 | 375 | ||
395 | if (drvr_priv->iflist[*ifidx]->ndev) | 376 | if (drvr->iflist[*ifidx]->ndev) |
396 | brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->ndev, | 377 | brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev, |
397 | event, *data); | 378 | event, *data); |
398 | 379 | ||
399 | return bcmerror; | 380 | return bcmerror; |
400 | } | 381 | } |
401 | 382 | ||
402 | void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, | 383 | void brcmf_rx_frame(struct device *dev, int ifidx, |
403 | struct sk_buff_head *skb_list) | 384 | struct sk_buff_head *skb_list) |
404 | { | 385 | { |
405 | struct brcmf_info *drvr_priv = drvr->info; | ||
406 | unsigned char *eth; | 386 | unsigned char *eth; |
407 | uint len; | 387 | uint len; |
408 | void *data; | 388 | void *data; |
409 | struct sk_buff *skb, *pnext; | 389 | struct sk_buff *skb, *pnext; |
410 | struct brcmf_if *ifp; | 390 | struct brcmf_if *ifp; |
411 | struct brcmf_event_msg event; | 391 | struct brcmf_event_msg event; |
392 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
393 | struct brcmf_pub *drvr = bus_if->drvr; | ||
412 | 394 | ||
413 | brcmf_dbg(TRACE, "Enter\n"); | 395 | brcmf_dbg(TRACE, "Enter\n"); |
414 | 396 | ||
@@ -430,9 +412,9 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, | |||
430 | eth = skb->data; | 412 | eth = skb->data; |
431 | len = skb->len; | 413 | len = skb->len; |
432 | 414 | ||
433 | ifp = drvr_priv->iflist[ifidx]; | 415 | ifp = drvr->iflist[ifidx]; |
434 | if (ifp == NULL) | 416 | if (ifp == NULL) |
435 | ifp = drvr_priv->iflist[0]; | 417 | ifp = drvr->iflist[0]; |
436 | 418 | ||
437 | if (!ifp || !ifp->ndev || | 419 | if (!ifp || !ifp->ndev || |
438 | ifp->ndev->reg_state != NETREG_REGISTERED) { | 420 | ifp->ndev->reg_state != NETREG_REGISTERED) { |
@@ -444,7 +426,7 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, | |||
444 | skb->protocol = eth_type_trans(skb, skb->dev); | 426 | skb->protocol = eth_type_trans(skb, skb->dev); |
445 | 427 | ||
446 | if (skb->pkt_type == PACKET_MULTICAST) | 428 | if (skb->pkt_type == PACKET_MULTICAST) |
447 | drvr_priv->pub.rx_multicast++; | 429 | bus_if->dstats.multicast++; |
448 | 430 | ||
449 | skb->data = eth; | 431 | skb->data = eth; |
450 | skb->len = len; | 432 | skb->len = len; |
@@ -454,17 +436,17 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, | |||
454 | 436 | ||
455 | /* Process special event packets and then discard them */ | 437 | /* Process special event packets and then discard them */ |
456 | if (ntohs(skb->protocol) == ETH_P_LINK_CTL) | 438 | if (ntohs(skb->protocol) == ETH_P_LINK_CTL) |
457 | brcmf_host_event(drvr_priv, &ifidx, | 439 | brcmf_host_event(drvr, &ifidx, |
458 | skb_mac_header(skb), | 440 | skb_mac_header(skb), |
459 | &event, &data); | 441 | &event, &data); |
460 | 442 | ||
461 | if (drvr_priv->iflist[ifidx]) { | 443 | if (drvr->iflist[ifidx]) { |
462 | ifp = drvr_priv->iflist[ifidx]; | 444 | ifp = drvr->iflist[ifidx]; |
463 | ifp->ndev->last_rx = jiffies; | 445 | ifp->ndev->last_rx = jiffies; |
464 | } | 446 | } |
465 | 447 | ||
466 | drvr->dstats.rx_bytes += skb->len; | 448 | bus_if->dstats.rx_bytes += skb->len; |
467 | drvr->rx_packets++; /* Local count */ | 449 | bus_if->dstats.rx_packets++; /* Local count */ |
468 | 450 | ||
469 | if (in_interrupt()) | 451 | if (in_interrupt()) |
470 | netif_rx(skb); | 452 | netif_rx(skb); |
@@ -479,51 +461,48 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, | |||
479 | } | 461 | } |
480 | } | 462 | } |
481 | 463 | ||
482 | void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success) | 464 | void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) |
483 | { | 465 | { |
484 | uint ifidx; | 466 | uint ifidx; |
485 | struct brcmf_info *drvr_priv = drvr->info; | ||
486 | struct ethhdr *eh; | 467 | struct ethhdr *eh; |
487 | u16 type; | 468 | u16 type; |
469 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
470 | struct brcmf_pub *drvr = bus_if->drvr; | ||
488 | 471 | ||
489 | brcmf_proto_hdrpull(drvr, &ifidx, txp); | 472 | brcmf_proto_hdrpull(dev, &ifidx, txp); |
490 | 473 | ||
491 | eh = (struct ethhdr *)(txp->data); | 474 | eh = (struct ethhdr *)(txp->data); |
492 | type = ntohs(eh->h_proto); | 475 | type = ntohs(eh->h_proto); |
493 | 476 | ||
494 | if (type == ETH_P_PAE) | 477 | if (type == ETH_P_PAE) |
495 | atomic_dec(&drvr_priv->pend_8021x_cnt); | 478 | atomic_dec(&drvr->pend_8021x_cnt); |
496 | 479 | ||
497 | } | 480 | } |
498 | 481 | ||
499 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) | 482 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) |
500 | { | 483 | { |
501 | struct brcmf_if *ifp = netdev_priv(ndev); | 484 | struct brcmf_if *ifp = netdev_priv(ndev); |
502 | struct brcmf_info *drvr_priv = ifp->info; | 485 | struct brcmf_bus *bus_if = ifp->drvr->bus_if; |
503 | 486 | ||
504 | brcmf_dbg(TRACE, "Enter\n"); | 487 | brcmf_dbg(TRACE, "Enter\n"); |
505 | 488 | ||
506 | if (drvr_priv->pub.up) | ||
507 | /* Use the protocol to get dongle stats */ | ||
508 | brcmf_proto_dstats(&drvr_priv->pub); | ||
509 | |||
510 | /* Copy dongle stats to net device stats */ | 489 | /* Copy dongle stats to net device stats */ |
511 | ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets; | 490 | ifp->stats.rx_packets = bus_if->dstats.rx_packets; |
512 | ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets; | 491 | ifp->stats.tx_packets = bus_if->dstats.tx_packets; |
513 | ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes; | 492 | ifp->stats.rx_bytes = bus_if->dstats.rx_bytes; |
514 | ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes; | 493 | ifp->stats.tx_bytes = bus_if->dstats.tx_bytes; |
515 | ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors; | 494 | ifp->stats.rx_errors = bus_if->dstats.rx_errors; |
516 | ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors; | 495 | ifp->stats.tx_errors = bus_if->dstats.tx_errors; |
517 | ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped; | 496 | ifp->stats.rx_dropped = bus_if->dstats.rx_dropped; |
518 | ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped; | 497 | ifp->stats.tx_dropped = bus_if->dstats.tx_dropped; |
519 | ifp->stats.multicast = drvr_priv->pub.dstats.multicast; | 498 | ifp->stats.multicast = bus_if->dstats.multicast; |
520 | 499 | ||
521 | return &ifp->stats; | 500 | return &ifp->stats; |
522 | } | 501 | } |
523 | 502 | ||
524 | /* Retrieve current toe component enables, which are kept | 503 | /* Retrieve current toe component enables, which are kept |
525 | as a bitmap in toe_ol iovar */ | 504 | as a bitmap in toe_ol iovar */ |
526 | static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol) | 505 | static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol) |
527 | { | 506 | { |
528 | struct brcmf_dcmd dcmd; | 507 | struct brcmf_dcmd dcmd; |
529 | __le32 toe_le; | 508 | __le32 toe_le; |
@@ -538,17 +517,17 @@ static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol) | |||
538 | dcmd.set = false; | 517 | dcmd.set = false; |
539 | 518 | ||
540 | strcpy(buf, "toe_ol"); | 519 | strcpy(buf, "toe_ol"); |
541 | ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len); | 520 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); |
542 | if (ret < 0) { | 521 | if (ret < 0) { |
543 | /* Check for older dongle image that doesn't support toe_ol */ | 522 | /* Check for older dongle image that doesn't support toe_ol */ |
544 | if (ret == -EIO) { | 523 | if (ret == -EIO) { |
545 | brcmf_dbg(ERROR, "%s: toe not supported by device\n", | 524 | brcmf_dbg(ERROR, "%s: toe not supported by device\n", |
546 | brcmf_ifname(&drvr_priv->pub, ifidx)); | 525 | brcmf_ifname(drvr, ifidx)); |
547 | return -EOPNOTSUPP; | 526 | return -EOPNOTSUPP; |
548 | } | 527 | } |
549 | 528 | ||
550 | brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", | 529 | brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", |
551 | brcmf_ifname(&drvr_priv->pub, ifidx), ret); | 530 | brcmf_ifname(drvr, ifidx), ret); |
552 | return ret; | 531 | return ret; |
553 | } | 532 | } |
554 | 533 | ||
@@ -559,7 +538,7 @@ static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol) | |||
559 | 538 | ||
560 | /* Set current toe component enables in toe_ol iovar, | 539 | /* Set current toe component enables in toe_ol iovar, |
561 | and set toe global enable iovar */ | 540 | and set toe global enable iovar */ |
562 | static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) | 541 | static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol) |
563 | { | 542 | { |
564 | struct brcmf_dcmd dcmd; | 543 | struct brcmf_dcmd dcmd; |
565 | char buf[32]; | 544 | char buf[32]; |
@@ -577,10 +556,10 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) | |||
577 | strcpy(buf, "toe_ol"); | 556 | strcpy(buf, "toe_ol"); |
578 | memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32)); | 557 | memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32)); |
579 | 558 | ||
580 | ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len); | 559 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); |
581 | if (ret < 0) { | 560 | if (ret < 0) { |
582 | brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", | 561 | brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", |
583 | brcmf_ifname(&drvr_priv->pub, ifidx), ret); | 562 | brcmf_ifname(drvr, ifidx), ret); |
584 | return ret; | 563 | return ret; |
585 | } | 564 | } |
586 | 565 | ||
@@ -590,10 +569,10 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) | |||
590 | strcpy(buf, "toe"); | 569 | strcpy(buf, "toe"); |
591 | memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32)); | 570 | memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32)); |
592 | 571 | ||
593 | ret = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, dcmd.len); | 572 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); |
594 | if (ret < 0) { | 573 | if (ret < 0) { |
595 | brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", | 574 | brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", |
596 | brcmf_ifname(&drvr_priv->pub, ifidx), ret); | 575 | brcmf_ifname(drvr, ifidx), ret); |
597 | return ret; | 576 | return ret; |
598 | } | 577 | } |
599 | 578 | ||
@@ -604,18 +583,18 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, | |||
604 | struct ethtool_drvinfo *info) | 583 | struct ethtool_drvinfo *info) |
605 | { | 584 | { |
606 | struct brcmf_if *ifp = netdev_priv(ndev); | 585 | struct brcmf_if *ifp = netdev_priv(ndev); |
607 | struct brcmf_info *drvr_priv = ifp->info; | 586 | struct brcmf_pub *drvr = ifp->drvr; |
608 | 587 | ||
609 | sprintf(info->driver, KBUILD_MODNAME); | 588 | sprintf(info->driver, KBUILD_MODNAME); |
610 | sprintf(info->version, "%lu", drvr_priv->pub.drv_version); | 589 | sprintf(info->version, "%lu", drvr->drv_version); |
611 | sprintf(info->bus_info, "%s", dev_name(drvr_priv->pub.dev)); | 590 | sprintf(info->bus_info, "%s", dev_name(drvr->dev)); |
612 | } | 591 | } |
613 | 592 | ||
614 | static struct ethtool_ops brcmf_ethtool_ops = { | 593 | static struct ethtool_ops brcmf_ethtool_ops = { |
615 | .get_drvinfo = brcmf_ethtool_get_drvinfo | 594 | .get_drvinfo = brcmf_ethtool_get_drvinfo |
616 | }; | 595 | }; |
617 | 596 | ||
618 | static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) | 597 | static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) |
619 | { | 598 | { |
620 | struct ethtool_drvinfo info; | 599 | struct ethtool_drvinfo info; |
621 | char drvname[sizeof(info.driver)]; | 600 | char drvname[sizeof(info.driver)]; |
@@ -649,18 +628,18 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) | |||
649 | } | 628 | } |
650 | 629 | ||
651 | /* otherwise, require dongle to be up */ | 630 | /* otherwise, require dongle to be up */ |
652 | else if (!drvr_priv->pub.up) { | 631 | else if (!drvr->bus_if->drvr_up) { |
653 | brcmf_dbg(ERROR, "dongle is not up\n"); | 632 | brcmf_dbg(ERROR, "dongle is not up\n"); |
654 | return -ENODEV; | 633 | return -ENODEV; |
655 | } | 634 | } |
656 | 635 | ||
657 | /* finally, report dongle driver type */ | 636 | /* finally, report dongle driver type */ |
658 | else if (drvr_priv->pub.iswl) | 637 | else if (drvr->iswl) |
659 | sprintf(info.driver, "wl"); | 638 | sprintf(info.driver, "wl"); |
660 | else | 639 | else |
661 | sprintf(info.driver, "xx"); | 640 | sprintf(info.driver, "xx"); |
662 | 641 | ||
663 | sprintf(info.version, "%lu", drvr_priv->pub.drv_version); | 642 | sprintf(info.version, "%lu", drvr->drv_version); |
664 | if (copy_to_user(uaddr, &info, sizeof(info))) | 643 | if (copy_to_user(uaddr, &info, sizeof(info))) |
665 | return -EFAULT; | 644 | return -EFAULT; |
666 | brcmf_dbg(CTL, "given %*s, returning %s\n", | 645 | brcmf_dbg(CTL, "given %*s, returning %s\n", |
@@ -670,7 +649,7 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) | |||
670 | /* Get toe offload components from dongle */ | 649 | /* Get toe offload components from dongle */ |
671 | case ETHTOOL_GRXCSUM: | 650 | case ETHTOOL_GRXCSUM: |
672 | case ETHTOOL_GTXCSUM: | 651 | case ETHTOOL_GTXCSUM: |
673 | ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt); | 652 | ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); |
674 | if (ret < 0) | 653 | if (ret < 0) |
675 | return ret; | 654 | return ret; |
676 | 655 | ||
@@ -691,7 +670,7 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) | |||
691 | return -EFAULT; | 670 | return -EFAULT; |
692 | 671 | ||
693 | /* Read the current settings, update and write back */ | 672 | /* Read the current settings, update and write back */ |
694 | ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt); | 673 | ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); |
695 | if (ret < 0) | 674 | if (ret < 0) |
696 | return ret; | 675 | return ret; |
697 | 676 | ||
@@ -703,17 +682,17 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) | |||
703 | else | 682 | else |
704 | toe_cmpnt &= ~csum_dir; | 683 | toe_cmpnt &= ~csum_dir; |
705 | 684 | ||
706 | ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt); | 685 | ret = brcmf_toe_set(drvr, 0, toe_cmpnt); |
707 | if (ret < 0) | 686 | if (ret < 0) |
708 | return ret; | 687 | return ret; |
709 | 688 | ||
710 | /* If setting TX checksum mode, tell Linux the new mode */ | 689 | /* If setting TX checksum mode, tell Linux the new mode */ |
711 | if (cmd == ETHTOOL_STXCSUM) { | 690 | if (cmd == ETHTOOL_STXCSUM) { |
712 | if (edata.data) | 691 | if (edata.data) |
713 | drvr_priv->iflist[0]->ndev->features |= | 692 | drvr->iflist[0]->ndev->features |= |
714 | NETIF_F_IP_CSUM; | 693 | NETIF_F_IP_CSUM; |
715 | else | 694 | else |
716 | drvr_priv->iflist[0]->ndev->features &= | 695 | drvr->iflist[0]->ndev->features &= |
717 | ~NETIF_F_IP_CSUM; | 696 | ~NETIF_F_IP_CSUM; |
718 | } | 697 | } |
719 | 698 | ||
@@ -730,15 +709,15 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, | |||
730 | int cmd) | 709 | int cmd) |
731 | { | 710 | { |
732 | struct brcmf_if *ifp = netdev_priv(ndev); | 711 | struct brcmf_if *ifp = netdev_priv(ndev); |
733 | struct brcmf_info *drvr_priv = ifp->info; | 712 | struct brcmf_pub *drvr = ifp->drvr; |
734 | 713 | ||
735 | brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); | 714 | brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); |
736 | 715 | ||
737 | if (!drvr_priv->iflist[ifp->idx]) | 716 | if (!drvr->iflist[ifp->idx]) |
738 | return -1; | 717 | return -1; |
739 | 718 | ||
740 | if (cmd == SIOCETHTOOL) | 719 | if (cmd == SIOCETHTOOL) |
741 | return brcmf_ethtool(drvr_priv, ifr->ifr_data); | 720 | return brcmf_ethtool(drvr, ifr->ifr_data); |
742 | 721 | ||
743 | return -EOPNOTSUPP; | 722 | return -EOPNOTSUPP; |
744 | } | 723 | } |
@@ -751,7 +730,7 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) | |||
751 | int buflen = 0; | 730 | int buflen = 0; |
752 | bool is_set_key_cmd; | 731 | bool is_set_key_cmd; |
753 | struct brcmf_if *ifp = netdev_priv(ndev); | 732 | struct brcmf_if *ifp = netdev_priv(ndev); |
754 | struct brcmf_info *drvr_priv = ifp->info; | 733 | struct brcmf_pub *drvr = ifp->drvr; |
755 | 734 | ||
756 | memset(&dcmd, 0, sizeof(dcmd)); | 735 | memset(&dcmd, 0, sizeof(dcmd)); |
757 | dcmd.cmd = cmd; | 736 | dcmd.cmd = cmd; |
@@ -762,13 +741,13 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) | |||
762 | buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); | 741 | buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); |
763 | 742 | ||
764 | /* send to dongle (must be up, and wl) */ | 743 | /* send to dongle (must be up, and wl) */ |
765 | if ((drvr_priv->pub.bus_if->state != BRCMF_BUS_DATA)) { | 744 | if ((drvr->bus_if->state != BRCMF_BUS_DATA)) { |
766 | brcmf_dbg(ERROR, "DONGLE_DOWN\n"); | 745 | brcmf_dbg(ERROR, "DONGLE_DOWN\n"); |
767 | err = -EIO; | 746 | err = -EIO; |
768 | goto done; | 747 | goto done; |
769 | } | 748 | } |
770 | 749 | ||
771 | if (!drvr_priv->pub.iswl) { | 750 | if (!drvr->iswl) { |
772 | err = -EIO; | 751 | err = -EIO; |
773 | goto done; | 752 | goto done; |
774 | } | 753 | } |
@@ -785,7 +764,7 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) | |||
785 | if (is_set_key_cmd) | 764 | if (is_set_key_cmd) |
786 | brcmf_netdev_wait_pend8021x(ndev); | 765 | brcmf_netdev_wait_pend8021x(ndev); |
787 | 766 | ||
788 | err = brcmf_proto_dcmd(&drvr_priv->pub, ifp->idx, &dcmd, buflen); | 767 | err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen); |
789 | 768 | ||
790 | done: | 769 | done: |
791 | if (err > 0) | 770 | if (err > 0) |
@@ -797,15 +776,15 @@ done: | |||
797 | static int brcmf_netdev_stop(struct net_device *ndev) | 776 | static int brcmf_netdev_stop(struct net_device *ndev) |
798 | { | 777 | { |
799 | struct brcmf_if *ifp = netdev_priv(ndev); | 778 | struct brcmf_if *ifp = netdev_priv(ndev); |
800 | struct brcmf_pub *drvr = &ifp->info->pub; | 779 | struct brcmf_pub *drvr = ifp->drvr; |
801 | 780 | ||
802 | brcmf_dbg(TRACE, "Enter\n"); | 781 | brcmf_dbg(TRACE, "Enter\n"); |
803 | brcmf_cfg80211_down(drvr->config); | 782 | brcmf_cfg80211_down(drvr->config); |
804 | if (drvr->up == 0) | 783 | if (drvr->bus_if->drvr_up == 0) |
805 | return 0; | 784 | return 0; |
806 | 785 | ||
807 | /* Set state and stop OS transmissions */ | 786 | /* Set state and stop OS transmissions */ |
808 | drvr->up = false; | 787 | drvr->bus_if->drvr_up = false; |
809 | netif_stop_queue(ndev); | 788 | netif_stop_queue(ndev); |
810 | 789 | ||
811 | return 0; | 790 | return 0; |
@@ -814,7 +793,7 @@ static int brcmf_netdev_stop(struct net_device *ndev) | |||
814 | static int brcmf_netdev_open(struct net_device *ndev) | 793 | static int brcmf_netdev_open(struct net_device *ndev) |
815 | { | 794 | { |
816 | struct brcmf_if *ifp = netdev_priv(ndev); | 795 | struct brcmf_if *ifp = netdev_priv(ndev); |
817 | struct brcmf_info *drvr_priv = ifp->info; | 796 | struct brcmf_pub *drvr = ifp->drvr; |
818 | u32 toe_ol; | 797 | u32 toe_ol; |
819 | s32 ret = 0; | 798 | s32 ret = 0; |
820 | 799 | ||
@@ -822,28 +801,28 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
822 | 801 | ||
823 | if (ifp->idx == 0) { /* do it only for primary eth0 */ | 802 | if (ifp->idx == 0) { /* do it only for primary eth0 */ |
824 | /* try to bring up bus */ | 803 | /* try to bring up bus */ |
825 | ret = brcmf_bus_start(&drvr_priv->pub); | 804 | ret = brcmf_bus_start(drvr->dev); |
826 | if (ret != 0) { | 805 | if (ret != 0) { |
827 | brcmf_dbg(ERROR, "failed with code %d\n", ret); | 806 | brcmf_dbg(ERROR, "failed with code %d\n", ret); |
828 | return -1; | 807 | return -1; |
829 | } | 808 | } |
830 | atomic_set(&drvr_priv->pend_8021x_cnt, 0); | 809 | atomic_set(&drvr->pend_8021x_cnt, 0); |
831 | 810 | ||
832 | memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN); | 811 | memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); |
833 | 812 | ||
834 | /* Get current TOE mode from dongle */ | 813 | /* Get current TOE mode from dongle */ |
835 | if (brcmf_toe_get(drvr_priv, ifp->idx, &toe_ol) >= 0 | 814 | if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0 |
836 | && (toe_ol & TOE_TX_CSUM_OL) != 0) | 815 | && (toe_ol & TOE_TX_CSUM_OL) != 0) |
837 | drvr_priv->iflist[ifp->idx]->ndev->features |= | 816 | drvr->iflist[ifp->idx]->ndev->features |= |
838 | NETIF_F_IP_CSUM; | 817 | NETIF_F_IP_CSUM; |
839 | else | 818 | else |
840 | drvr_priv->iflist[ifp->idx]->ndev->features &= | 819 | drvr->iflist[ifp->idx]->ndev->features &= |
841 | ~NETIF_F_IP_CSUM; | 820 | ~NETIF_F_IP_CSUM; |
842 | } | 821 | } |
843 | /* Allow transmit calls */ | 822 | /* Allow transmit calls */ |
844 | netif_start_queue(ndev); | 823 | netif_start_queue(ndev); |
845 | drvr_priv->pub.up = true; | 824 | drvr->bus_if->drvr_up = true; |
846 | if (brcmf_cfg80211_up(drvr_priv->pub.config)) { | 825 | if (brcmf_cfg80211_up(drvr->config)) { |
847 | brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); | 826 | brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); |
848 | return -1; | 827 | return -1; |
849 | } | 828 | } |
@@ -862,14 +841,16 @@ static const struct net_device_ops brcmf_netdev_ops_pri = { | |||
862 | }; | 841 | }; |
863 | 842 | ||
864 | int | 843 | int |
865 | brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr) | 844 | brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr) |
866 | { | 845 | { |
867 | struct brcmf_if *ifp; | 846 | struct brcmf_if *ifp; |
868 | struct net_device *ndev; | 847 | struct net_device *ndev; |
848 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
849 | struct brcmf_pub *drvr = bus_if->drvr; | ||
869 | 850 | ||
870 | brcmf_dbg(TRACE, "idx %d\n", ifidx); | 851 | brcmf_dbg(TRACE, "idx %d\n", ifidx); |
871 | 852 | ||
872 | ifp = drvr_priv->iflist[ifidx]; | 853 | ifp = drvr->iflist[ifidx]; |
873 | /* | 854 | /* |
874 | * Delete the existing interface before overwriting it | 855 | * Delete the existing interface before overwriting it |
875 | * in case we missed the BRCMF_E_IF_DEL event. | 856 | * in case we missed the BRCMF_E_IF_DEL event. |
@@ -880,7 +861,7 @@ brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr) | |||
880 | netif_stop_queue(ifp->ndev); | 861 | netif_stop_queue(ifp->ndev); |
881 | unregister_netdev(ifp->ndev); | 862 | unregister_netdev(ifp->ndev); |
882 | free_netdev(ifp->ndev); | 863 | free_netdev(ifp->ndev); |
883 | drvr_priv->iflist[ifidx] = NULL; | 864 | drvr->iflist[ifidx] = NULL; |
884 | } | 865 | } |
885 | 866 | ||
886 | /* Allocate netdev, including space for private structure */ | 867 | /* Allocate netdev, including space for private structure */ |
@@ -892,16 +873,16 @@ brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr) | |||
892 | 873 | ||
893 | ifp = netdev_priv(ndev); | 874 | ifp = netdev_priv(ndev); |
894 | ifp->ndev = ndev; | 875 | ifp->ndev = ndev; |
895 | ifp->info = drvr_priv; | 876 | ifp->drvr = drvr; |
896 | drvr_priv->iflist[ifidx] = ifp; | 877 | drvr->iflist[ifidx] = ifp; |
897 | ifp->idx = ifidx; | 878 | ifp->idx = ifidx; |
898 | if (mac_addr != NULL) | 879 | if (mac_addr != NULL) |
899 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); | 880 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); |
900 | 881 | ||
901 | if (brcmf_net_attach(&drvr_priv->pub, ifp->idx)) { | 882 | if (brcmf_net_attach(drvr, ifp->idx)) { |
902 | brcmf_dbg(ERROR, "brcmf_net_attach failed"); | 883 | brcmf_dbg(ERROR, "brcmf_net_attach failed"); |
903 | free_netdev(ifp->ndev); | 884 | free_netdev(ifp->ndev); |
904 | drvr_priv->iflist[ifidx] = NULL; | 885 | drvr->iflist[ifidx] = NULL; |
905 | return -EOPNOTSUPP; | 886 | return -EOPNOTSUPP; |
906 | } | 887 | } |
907 | 888 | ||
@@ -911,13 +892,13 @@ brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr) | |||
911 | return 0; | 892 | return 0; |
912 | } | 893 | } |
913 | 894 | ||
914 | void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) | 895 | void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) |
915 | { | 896 | { |
916 | struct brcmf_if *ifp; | 897 | struct brcmf_if *ifp; |
917 | 898 | ||
918 | brcmf_dbg(TRACE, "idx %d\n", ifidx); | 899 | brcmf_dbg(TRACE, "idx %d\n", ifidx); |
919 | 900 | ||
920 | ifp = drvr_priv->iflist[ifidx]; | 901 | ifp = drvr->iflist[ifidx]; |
921 | if (!ifp) { | 902 | if (!ifp) { |
922 | brcmf_dbg(ERROR, "Null interface\n"); | 903 | brcmf_dbg(ERROR, "Null interface\n"); |
923 | return; | 904 | return; |
@@ -934,72 +915,70 @@ void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) | |||
934 | } | 915 | } |
935 | 916 | ||
936 | unregister_netdev(ifp->ndev); | 917 | unregister_netdev(ifp->ndev); |
937 | drvr_priv->iflist[ifidx] = NULL; | 918 | drvr->iflist[ifidx] = NULL; |
938 | if (ifidx == 0) | 919 | if (ifidx == 0) |
939 | brcmf_cfg80211_detach(drvr_priv->pub.config); | 920 | brcmf_cfg80211_detach(drvr->config); |
940 | free_netdev(ifp->ndev); | 921 | free_netdev(ifp->ndev); |
941 | } | 922 | } |
942 | } | 923 | } |
943 | 924 | ||
944 | struct brcmf_pub *brcmf_attach(struct brcmf_sdio *bus, uint bus_hdrlen, | 925 | int brcmf_attach(uint bus_hdrlen, struct device *dev) |
945 | struct device *dev) | ||
946 | { | 926 | { |
947 | struct brcmf_info *drvr_priv = NULL; | 927 | struct brcmf_pub *drvr = NULL; |
928 | int ret = 0; | ||
948 | 929 | ||
949 | brcmf_dbg(TRACE, "Enter\n"); | 930 | brcmf_dbg(TRACE, "Enter\n"); |
950 | 931 | ||
951 | /* Allocate primary brcmf_info */ | 932 | /* Allocate primary brcmf_info */ |
952 | drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); | 933 | drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC); |
953 | if (!drvr_priv) | 934 | if (!drvr) |
954 | goto fail; | 935 | return -ENOMEM; |
955 | |||
956 | mutex_init(&drvr_priv->proto_block); | ||
957 | 936 | ||
958 | /* Link to info module */ | 937 | mutex_init(&drvr->proto_block); |
959 | drvr_priv->pub.info = drvr_priv; | ||
960 | 938 | ||
961 | /* Link to bus module */ | 939 | /* Link to bus module */ |
962 | drvr_priv->pub.bus = bus; | 940 | drvr->hdrlen = bus_hdrlen; |
963 | drvr_priv->pub.hdrlen = bus_hdrlen; | 941 | drvr->bus_if = dev_get_drvdata(dev); |
964 | drvr_priv->pub.bus_if = dev_get_drvdata(dev); | 942 | drvr->bus_if->drvr = drvr; |
965 | drvr_priv->pub.dev = dev; | 943 | drvr->dev = dev; |
966 | 944 | ||
967 | /* Attach and link in the protocol */ | 945 | /* Attach and link in the protocol */ |
968 | if (brcmf_proto_attach(&drvr_priv->pub) != 0) { | 946 | ret = brcmf_proto_attach(drvr); |
947 | if (ret != 0) { | ||
969 | brcmf_dbg(ERROR, "brcmf_prot_attach failed\n"); | 948 | brcmf_dbg(ERROR, "brcmf_prot_attach failed\n"); |
970 | goto fail; | 949 | goto fail; |
971 | } | 950 | } |
972 | 951 | ||
973 | INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address); | 952 | INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address); |
974 | INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list); | 953 | INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list); |
975 | 954 | ||
976 | return &drvr_priv->pub; | 955 | return ret; |
977 | 956 | ||
978 | fail: | 957 | fail: |
979 | if (drvr_priv) | 958 | brcmf_detach(dev); |
980 | brcmf_detach(&drvr_priv->pub); | ||
981 | 959 | ||
982 | return NULL; | 960 | return ret; |
983 | } | 961 | } |
984 | 962 | ||
985 | int brcmf_bus_start(struct brcmf_pub *drvr) | 963 | int brcmf_bus_start(struct device *dev) |
986 | { | 964 | { |
987 | int ret = -1; | 965 | int ret = -1; |
988 | struct brcmf_info *drvr_priv = drvr->info; | ||
989 | /* Room for "event_msgs" + '\0' + bitvec */ | 966 | /* Room for "event_msgs" + '\0' + bitvec */ |
990 | char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; | 967 | char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; |
968 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
969 | struct brcmf_pub *drvr = bus_if->drvr; | ||
991 | 970 | ||
992 | brcmf_dbg(TRACE, "\n"); | 971 | brcmf_dbg(TRACE, "\n"); |
993 | 972 | ||
994 | /* Bring up the bus */ | 973 | /* Bring up the bus */ |
995 | ret = brcmf_sdbrcm_bus_init(drvr_priv->pub.dev); | 974 | ret = bus_if->brcmf_bus_init(dev); |
996 | if (ret != 0) { | 975 | if (ret != 0) { |
997 | brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret); | 976 | brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret); |
998 | return ret; | 977 | return ret; |
999 | } | 978 | } |
1000 | 979 | ||
1001 | /* If bus is not ready, can't come up */ | 980 | /* If bus is not ready, can't come up */ |
1002 | if (drvr_priv->pub.bus_if->state != BRCMF_BUS_DATA) { | 981 | if (bus_if->state != BRCMF_BUS_DATA) { |
1003 | brcmf_dbg(ERROR, "failed bus is not ready\n"); | 982 | brcmf_dbg(ERROR, "failed bus is not ready\n"); |
1004 | return -ENODEV; | 983 | return -ENODEV; |
1005 | } | 984 | } |
@@ -1036,7 +1015,7 @@ int brcmf_bus_start(struct brcmf_pub *drvr) | |||
1036 | drvr->pktfilter[0] = "100 0 0 0 0x01 0x00"; | 1015 | drvr->pktfilter[0] = "100 0 0 0 0x01 0x00"; |
1037 | 1016 | ||
1038 | /* Bus is ready, do any protocol initialization */ | 1017 | /* Bus is ready, do any protocol initialization */ |
1039 | ret = brcmf_proto_init(&drvr_priv->pub); | 1018 | ret = brcmf_proto_init(drvr); |
1040 | if (ret < 0) | 1019 | if (ret < 0) |
1041 | return ret; | 1020 | return ret; |
1042 | 1021 | ||
@@ -1045,14 +1024,13 @@ int brcmf_bus_start(struct brcmf_pub *drvr) | |||
1045 | 1024 | ||
1046 | int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) | 1025 | int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) |
1047 | { | 1026 | { |
1048 | struct brcmf_info *drvr_priv = drvr->info; | ||
1049 | struct net_device *ndev; | 1027 | struct net_device *ndev; |
1050 | u8 temp_addr[ETH_ALEN] = { | 1028 | u8 temp_addr[ETH_ALEN] = { |
1051 | 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33}; | 1029 | 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33}; |
1052 | 1030 | ||
1053 | brcmf_dbg(TRACE, "ifidx %d\n", ifidx); | 1031 | brcmf_dbg(TRACE, "ifidx %d\n", ifidx); |
1054 | 1032 | ||
1055 | ndev = drvr_priv->iflist[ifidx]->ndev; | 1033 | ndev = drvr->iflist[ifidx]->ndev; |
1056 | ndev->netdev_ops = &brcmf_netdev_ops_pri; | 1034 | ndev->netdev_ops = &brcmf_netdev_ops_pri; |
1057 | 1035 | ||
1058 | /* | 1036 | /* |
@@ -1060,7 +1038,7 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) | |||
1060 | */ | 1038 | */ |
1061 | if (ifidx != 0) { | 1039 | if (ifidx != 0) { |
1062 | /* for virtual interfaces use the primary MAC */ | 1040 | /* for virtual interfaces use the primary MAC */ |
1063 | memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN); | 1041 | memcpy(temp_addr, drvr->mac, ETH_ALEN); |
1064 | 1042 | ||
1065 | } | 1043 | } |
1066 | 1044 | ||
@@ -1071,11 +1049,11 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) | |||
1071 | - Locally Administered address */ | 1049 | - Locally Administered address */ |
1072 | 1050 | ||
1073 | } | 1051 | } |
1074 | ndev->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen; | 1052 | ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; |
1075 | ndev->ethtool_ops = &brcmf_ethtool_ops; | 1053 | ndev->ethtool_ops = &brcmf_ethtool_ops; |
1076 | 1054 | ||
1077 | drvr_priv->pub.rxsz = ndev->mtu + ndev->hard_header_len + | 1055 | drvr->rxsz = ndev->mtu + ndev->hard_header_len + |
1078 | drvr_priv->pub.hdrlen; | 1056 | drvr->hdrlen; |
1079 | 1057 | ||
1080 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); | 1058 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); |
1081 | 1059 | ||
@@ -1104,77 +1082,46 @@ fail: | |||
1104 | 1082 | ||
1105 | static void brcmf_bus_detach(struct brcmf_pub *drvr) | 1083 | static void brcmf_bus_detach(struct brcmf_pub *drvr) |
1106 | { | 1084 | { |
1107 | struct brcmf_info *drvr_priv; | ||
1108 | |||
1109 | brcmf_dbg(TRACE, "Enter\n"); | 1085 | brcmf_dbg(TRACE, "Enter\n"); |
1110 | 1086 | ||
1111 | if (drvr) { | 1087 | if (drvr) { |
1112 | drvr_priv = drvr->info; | 1088 | /* Stop the protocol module */ |
1113 | if (drvr_priv) { | 1089 | brcmf_proto_stop(drvr); |
1114 | /* Stop the protocol module */ | ||
1115 | brcmf_proto_stop(&drvr_priv->pub); | ||
1116 | 1090 | ||
1117 | /* Stop the bus module */ | 1091 | /* Stop the bus module */ |
1118 | brcmf_sdbrcm_bus_stop(drvr_priv->pub.dev); | 1092 | drvr->bus_if->brcmf_bus_stop(drvr->dev); |
1119 | } | ||
1120 | } | 1093 | } |
1121 | } | 1094 | } |
1122 | 1095 | ||
1123 | void brcmf_detach(struct brcmf_pub *drvr) | 1096 | void brcmf_detach(struct device *dev) |
1124 | { | 1097 | { |
1125 | struct brcmf_info *drvr_priv; | 1098 | int i; |
1099 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
1100 | struct brcmf_pub *drvr = bus_if->drvr; | ||
1126 | 1101 | ||
1127 | brcmf_dbg(TRACE, "Enter\n"); | 1102 | brcmf_dbg(TRACE, "Enter\n"); |
1128 | 1103 | ||
1129 | if (drvr) { | ||
1130 | drvr_priv = drvr->info; | ||
1131 | if (drvr_priv) { | ||
1132 | int i; | ||
1133 | 1104 | ||
1134 | /* make sure primary interface removed last */ | 1105 | /* make sure primary interface removed last */ |
1135 | for (i = BRCMF_MAX_IFS-1; i > -1; i--) | 1106 | for (i = BRCMF_MAX_IFS-1; i > -1; i--) |
1136 | if (drvr_priv->iflist[i]) | 1107 | if (drvr->iflist[i]) |
1137 | brcmf_del_if(drvr_priv, i); | 1108 | brcmf_del_if(drvr, i); |
1138 | 1109 | ||
1139 | cancel_work_sync(&drvr_priv->setmacaddr_work); | 1110 | cancel_work_sync(&drvr->setmacaddr_work); |
1140 | cancel_work_sync(&drvr_priv->multicast_work); | 1111 | cancel_work_sync(&drvr->multicast_work); |
1141 | 1112 | ||
1142 | brcmf_bus_detach(drvr); | 1113 | brcmf_bus_detach(drvr); |
1143 | 1114 | ||
1144 | if (drvr->prot) | 1115 | if (drvr->prot) |
1145 | brcmf_proto_detach(drvr); | 1116 | brcmf_proto_detach(drvr); |
1146 | 1117 | ||
1147 | kfree(drvr_priv); | 1118 | bus_if->drvr = NULL; |
1148 | } | 1119 | kfree(drvr); |
1149 | } | ||
1150 | } | ||
1151 | |||
1152 | int brcmf_os_proto_block(struct brcmf_pub *drvr) | ||
1153 | { | ||
1154 | struct brcmf_info *drvr_priv = drvr->info; | ||
1155 | |||
1156 | if (drvr_priv) { | ||
1157 | mutex_lock(&drvr_priv->proto_block); | ||
1158 | return 1; | ||
1159 | } | ||
1160 | return 0; | ||
1161 | } | ||
1162 | |||
1163 | int brcmf_os_proto_unblock(struct brcmf_pub *drvr) | ||
1164 | { | ||
1165 | struct brcmf_info *drvr_priv = drvr->info; | ||
1166 | |||
1167 | if (drvr_priv) { | ||
1168 | mutex_unlock(&drvr_priv->proto_block); | ||
1169 | return 1; | ||
1170 | } | ||
1171 | |||
1172 | return 0; | ||
1173 | } | 1120 | } |
1174 | 1121 | ||
1175 | static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv) | 1122 | static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) |
1176 | { | 1123 | { |
1177 | return atomic_read(&drvr_priv->pend_8021x_cnt); | 1124 | return atomic_read(&drvr->pend_8021x_cnt); |
1178 | } | 1125 | } |
1179 | 1126 | ||
1180 | #define MAX_WAIT_FOR_8021X_TX 10 | 1127 | #define MAX_WAIT_FOR_8021X_TX 10 |
@@ -1182,10 +1129,10 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv) | |||
1182 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) | 1129 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) |
1183 | { | 1130 | { |
1184 | struct brcmf_if *ifp = netdev_priv(ndev); | 1131 | struct brcmf_if *ifp = netdev_priv(ndev); |
1185 | struct brcmf_info *drvr_priv = ifp->info; | 1132 | struct brcmf_pub *drvr = ifp->drvr; |
1186 | int timeout = 10 * HZ / 1000; | 1133 | int timeout = 10 * HZ / 1000; |
1187 | int ntimes = MAX_WAIT_FOR_8021X_TX; | 1134 | int ntimes = MAX_WAIT_FOR_8021X_TX; |
1188 | int pend = brcmf_get_pend_8021x_cnt(drvr_priv); | 1135 | int pend = brcmf_get_pend_8021x_cnt(drvr); |
1189 | 1136 | ||
1190 | while (ntimes && pend) { | 1137 | while (ntimes && pend) { |
1191 | if (pend) { | 1138 | if (pend) { |
@@ -1194,7 +1141,7 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev) | |||
1194 | set_current_state(TASK_RUNNING); | 1141 | set_current_state(TASK_RUNNING); |
1195 | ntimes--; | 1142 | ntimes--; |
1196 | } | 1143 | } |
1197 | pend = brcmf_get_pend_8021x_cnt(drvr_priv); | 1144 | pend = brcmf_get_pend_8021x_cnt(drvr); |
1198 | } | 1145 | } |
1199 | return pend; | 1146 | return pend; |
1200 | } | 1147 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 4ee1ea846f6d..6bc4425a8b0f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h | |||
@@ -41,17 +41,10 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr); | |||
41 | extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, | 41 | extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, |
42 | struct sk_buff *txp); | 42 | struct sk_buff *txp); |
43 | 43 | ||
44 | /* Remove any protocol-specific data header. */ | ||
45 | extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx, | ||
46 | struct sk_buff *rxp); | ||
47 | |||
48 | /* Use protocol to issue command to dongle */ | 44 | /* Use protocol to issue command to dongle */ |
49 | extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, | 45 | extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, |
50 | struct brcmf_dcmd *dcmd, int len); | 46 | struct brcmf_dcmd *dcmd, int len); |
51 | 47 | ||
52 | /* Update local copy of dongle statistics */ | ||
53 | extern void brcmf_proto_dstats(struct brcmf_pub *drvr); | ||
54 | |||
55 | extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr); | 48 | extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr); |
56 | 49 | ||
57 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, | 50 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 43ba0dd48354..5a002a21f108 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -87,9 +87,7 @@ struct rte_console { | |||
87 | #endif /* BCMDBG */ | 87 | #endif /* BCMDBG */ |
88 | #include <chipcommon.h> | 88 | #include <chipcommon.h> |
89 | 89 | ||
90 | #include "dhd.h" | ||
91 | #include "dhd_bus.h" | 90 | #include "dhd_bus.h" |
92 | #include "dhd_proto.h" | ||
93 | #include "dhd_dbg.h" | 91 | #include "dhd_dbg.h" |
94 | 92 | ||
95 | #define TXQLEN 2048 /* bulk tx queue length */ | 93 | #define TXQLEN 2048 /* bulk tx queue length */ |
@@ -314,6 +312,12 @@ struct rte_console { | |||
314 | MODULE_FIRMWARE(BRCMFMAC_FW_NAME); | 312 | MODULE_FIRMWARE(BRCMFMAC_FW_NAME); |
315 | MODULE_FIRMWARE(BRCMFMAC_NV_NAME); | 313 | MODULE_FIRMWARE(BRCMFMAC_NV_NAME); |
316 | 314 | ||
315 | #define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */ | ||
316 | #define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change | ||
317 | * when idle | ||
318 | */ | ||
319 | #define BRCMF_IDLE_INTERVAL 1 | ||
320 | |||
317 | /* | 321 | /* |
318 | * Conversion of 802.1D priority to precedence level | 322 | * Conversion of 802.1D priority to precedence level |
319 | */ | 323 | */ |
@@ -450,8 +454,6 @@ struct sdpcm_shared_le { | |||
450 | /* misc chip info needed by some of the routines */ | 454 | /* misc chip info needed by some of the routines */ |
451 | /* Private data for SDIO bus interaction */ | 455 | /* Private data for SDIO bus interaction */ |
452 | struct brcmf_sdio { | 456 | struct brcmf_sdio { |
453 | struct brcmf_pub *drvr; | ||
454 | |||
455 | struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ | 457 | struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ |
456 | struct chip_info *ci; /* Chip info struct */ | 458 | struct chip_info *ci; /* Chip info struct */ |
457 | char *vars; /* Variables (from CIS and/or other) */ | 459 | char *vars; /* Variables (from CIS and/or other) */ |
@@ -546,6 +548,13 @@ struct brcmf_sdio { | |||
546 | uint f2rxdata; /* Number of frame data reads */ | 548 | uint f2rxdata; /* Number of frame data reads */ |
547 | uint f2txdata; /* Number of f2 frame writes */ | 549 | uint f2txdata; /* Number of f2 frame writes */ |
548 | uint f1regdata; /* Number of f1 register accesses */ | 550 | uint f1regdata; /* Number of f1 register accesses */ |
551 | uint tickcnt; /* Number of watchdog been schedule */ | ||
552 | unsigned long tx_ctlerrs; /* Err of sending ctrl frames */ | ||
553 | unsigned long tx_ctlpkts; /* Ctrl frames sent to dongle */ | ||
554 | unsigned long rx_ctlerrs; /* Err of processing rx ctrl frames */ | ||
555 | unsigned long rx_ctlpkts; /* Ctrl frames processed from dongle */ | ||
556 | unsigned long rx_readahead_cnt; /* Number of packets where header | ||
557 | * read-ahead was used. */ | ||
549 | 558 | ||
550 | u8 *ctrl_frame_buf; | 559 | u8 *ctrl_frame_buf; |
551 | u32 ctrl_frame_len; | 560 | u32 ctrl_frame_len; |
@@ -568,6 +577,8 @@ struct brcmf_sdio { | |||
568 | 577 | ||
569 | const struct firmware *firmware; | 578 | const struct firmware *firmware; |
570 | u32 fw_ptr; | 579 | u32 fw_ptr; |
580 | |||
581 | bool txoff; /* Transmit flow-controlled */ | ||
571 | }; | 582 | }; |
572 | 583 | ||
573 | /* clkstate */ | 584 | /* clkstate */ |
@@ -1068,7 +1079,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) | |||
1068 | 1079 | ||
1069 | /* If we can't reach the device, signal failure */ | 1080 | /* If we can't reach the device, signal failure */ |
1070 | if (err || brcmf_sdcard_regfail(bus->sdiodev)) | 1081 | if (err || brcmf_sdcard_regfail(bus->sdiodev)) |
1071 | bus->drvr->bus_if->state = BRCMF_BUS_DOWN; | 1082 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; |
1072 | } | 1083 | } |
1073 | 1084 | ||
1074 | /* copy a buffer into a pkt buffer chain */ | 1085 | /* copy a buffer into a pkt buffer chain */ |
@@ -1256,7 +1267,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1256 | if (errcode < 0) { | 1267 | if (errcode < 0) { |
1257 | brcmf_dbg(ERROR, "glom read of %d bytes failed: %d\n", | 1268 | brcmf_dbg(ERROR, "glom read of %d bytes failed: %d\n", |
1258 | dlen, errcode); | 1269 | dlen, errcode); |
1259 | bus->drvr->rx_errors++; | 1270 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1260 | 1271 | ||
1261 | if (bus->glomerr++ < 3) { | 1272 | if (bus->glomerr++ < 3) { |
1262 | brcmf_sdbrcm_rxfail(bus, true, true); | 1273 | brcmf_sdbrcm_rxfail(bus, true, true); |
@@ -1437,10 +1448,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1437 | skb_unlink(pfirst, &bus->glom); | 1448 | skb_unlink(pfirst, &bus->glom); |
1438 | brcmu_pkt_buf_free_skb(pfirst); | 1449 | brcmu_pkt_buf_free_skb(pfirst); |
1439 | continue; | 1450 | continue; |
1440 | } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, | 1451 | } else if (brcmf_proto_hdrpull(bus->sdiodev->dev, |
1441 | pfirst) != 0) { | 1452 | &ifidx, pfirst) != 0) { |
1442 | brcmf_dbg(ERROR, "rx protocol error\n"); | 1453 | brcmf_dbg(ERROR, "rx protocol error\n"); |
1443 | bus->drvr->rx_errors++; | 1454 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1444 | skb_unlink(pfirst, &bus->glom); | 1455 | skb_unlink(pfirst, &bus->glom); |
1445 | brcmu_pkt_buf_free_skb(pfirst); | 1456 | brcmu_pkt_buf_free_skb(pfirst); |
1446 | continue; | 1457 | continue; |
@@ -1461,7 +1472,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1461 | /* sent any remaining packets up */ | 1472 | /* sent any remaining packets up */ |
1462 | if (bus->glom.qlen) { | 1473 | if (bus->glom.qlen) { |
1463 | up(&bus->sdsem); | 1474 | up(&bus->sdsem); |
1464 | brcmf_rx_frame(bus->drvr, ifidx, &bus->glom); | 1475 | brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); |
1465 | down(&bus->sdsem); | 1476 | down(&bus->sdsem); |
1466 | } | 1477 | } |
1467 | 1478 | ||
@@ -1527,7 +1538,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) | |||
1527 | if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { | 1538 | if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { |
1528 | pad = bus->blocksize - (rdlen % bus->blocksize); | 1539 | pad = bus->blocksize - (rdlen % bus->blocksize); |
1529 | if ((pad <= bus->roundup) && (pad < bus->blocksize) && | 1540 | if ((pad <= bus->roundup) && (pad < bus->blocksize) && |
1530 | ((len + pad) < bus->drvr->maxctl)) | 1541 | ((len + pad) < bus->sdiodev->bus_if->maxctl)) |
1531 | rdlen += pad; | 1542 | rdlen += pad; |
1532 | } else if (rdlen % BRCMF_SDALIGN) { | 1543 | } else if (rdlen % BRCMF_SDALIGN) { |
1533 | rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); | 1544 | rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); |
@@ -1538,18 +1549,18 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) | |||
1538 | rdlen = roundup(rdlen, ALIGNMENT); | 1549 | rdlen = roundup(rdlen, ALIGNMENT); |
1539 | 1550 | ||
1540 | /* Drop if the read is too big or it exceeds our maximum */ | 1551 | /* Drop if the read is too big or it exceeds our maximum */ |
1541 | if ((rdlen + BRCMF_FIRSTREAD) > bus->drvr->maxctl) { | 1552 | if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { |
1542 | brcmf_dbg(ERROR, "%d-byte control read exceeds %d-byte buffer\n", | 1553 | brcmf_dbg(ERROR, "%d-byte control read exceeds %d-byte buffer\n", |
1543 | rdlen, bus->drvr->maxctl); | 1554 | rdlen, bus->sdiodev->bus_if->maxctl); |
1544 | bus->drvr->rx_errors++; | 1555 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1545 | brcmf_sdbrcm_rxfail(bus, false, false); | 1556 | brcmf_sdbrcm_rxfail(bus, false, false); |
1546 | goto done; | 1557 | goto done; |
1547 | } | 1558 | } |
1548 | 1559 | ||
1549 | if ((len - doff) > bus->drvr->maxctl) { | 1560 | if ((len - doff) > bus->sdiodev->bus_if->maxctl) { |
1550 | brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", | 1561 | brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", |
1551 | len, len - doff, bus->drvr->maxctl); | 1562 | len, len - doff, bus->sdiodev->bus_if->maxctl); |
1552 | bus->drvr->rx_errors++; | 1563 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1553 | bus->rx_toolong++; | 1564 | bus->rx_toolong++; |
1554 | brcmf_sdbrcm_rxfail(bus, false, false); | 1565 | brcmf_sdbrcm_rxfail(bus, false, false); |
1555 | goto done; | 1566 | goto done; |
@@ -1623,7 +1634,7 @@ brcmf_alloc_pkt_and_read(struct brcmf_sdio *bus, u16 rdlen, | |||
1623 | brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n", | 1634 | brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n", |
1624 | rdlen, sdret); | 1635 | rdlen, sdret); |
1625 | brcmu_pkt_buf_free_skb(*pkt); | 1636 | brcmu_pkt_buf_free_skb(*pkt); |
1626 | bus->drvr->rx_errors++; | 1637 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1627 | /* Force retry w/normal header read. | 1638 | /* Force retry w/normal header read. |
1628 | * Don't attempt NAK for | 1639 | * Don't attempt NAK for |
1629 | * gSPI | 1640 | * gSPI |
@@ -1715,7 +1726,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) | |||
1715 | 1726 | ||
1716 | for (rxseq = bus->rx_seq, rxleft = maxframes; | 1727 | for (rxseq = bus->rx_seq, rxleft = maxframes; |
1717 | !bus->rxskip && rxleft && | 1728 | !bus->rxskip && rxleft && |
1718 | bus->drvr->bus_if->state != BRCMF_BUS_DOWN; | 1729 | bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN; |
1719 | rxseq++, rxleft--) { | 1730 | rxseq++, rxleft--) { |
1720 | 1731 | ||
1721 | /* Handle glomming separately */ | 1732 | /* Handle glomming separately */ |
@@ -1774,7 +1785,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) | |||
1774 | bus->nextlen = 0; | 1785 | bus->nextlen = 0; |
1775 | } | 1786 | } |
1776 | 1787 | ||
1777 | bus->drvr->rx_readahead_cnt++; | 1788 | bus->rx_readahead_cnt++; |
1778 | 1789 | ||
1779 | /* Handle Flow Control */ | 1790 | /* Handle Flow Control */ |
1780 | fcbits = SDPCM_FCMASK_VALUE( | 1791 | fcbits = SDPCM_FCMASK_VALUE( |
@@ -1972,7 +1983,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) | |||
1972 | /* Too long -- skip this frame */ | 1983 | /* Too long -- skip this frame */ |
1973 | brcmf_dbg(ERROR, "too long: len %d rdlen %d\n", | 1984 | brcmf_dbg(ERROR, "too long: len %d rdlen %d\n", |
1974 | len, rdlen); | 1985 | len, rdlen); |
1975 | bus->drvr->rx_errors++; | 1986 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1976 | bus->rx_toolong++; | 1987 | bus->rx_toolong++; |
1977 | brcmf_sdbrcm_rxfail(bus, false, false); | 1988 | brcmf_sdbrcm_rxfail(bus, false, false); |
1978 | continue; | 1989 | continue; |
@@ -1984,7 +1995,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) | |||
1984 | /* Give up on data, request rtx of events */ | 1995 | /* Give up on data, request rtx of events */ |
1985 | brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n", | 1996 | brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n", |
1986 | rdlen, chan); | 1997 | rdlen, chan); |
1987 | bus->drvr->rx_dropped++; | 1998 | bus->sdiodev->bus_if->dstats.rx_dropped++; |
1988 | brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan)); | 1999 | brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan)); |
1989 | continue; | 2000 | continue; |
1990 | } | 2001 | } |
@@ -2004,7 +2015,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) | |||
2004 | : ((chan == SDPCM_DATA_CHANNEL) ? "data" | 2015 | : ((chan == SDPCM_DATA_CHANNEL) ? "data" |
2005 | : "test")), sdret); | 2016 | : "test")), sdret); |
2006 | brcmu_pkt_buf_free_skb(pkt); | 2017 | brcmu_pkt_buf_free_skb(pkt); |
2007 | bus->drvr->rx_errors++; | 2018 | bus->sdiodev->bus_if->dstats.rx_errors++; |
2008 | brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan)); | 2019 | brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan)); |
2009 | continue; | 2020 | continue; |
2010 | } | 2021 | } |
@@ -2053,16 +2064,17 @@ deliver: | |||
2053 | if (pkt->len == 0) { | 2064 | if (pkt->len == 0) { |
2054 | brcmu_pkt_buf_free_skb(pkt); | 2065 | brcmu_pkt_buf_free_skb(pkt); |
2055 | continue; | 2066 | continue; |
2056 | } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pkt) != 0) { | 2067 | } else if (brcmf_proto_hdrpull(bus->sdiodev->dev, &ifidx, |
2068 | pkt) != 0) { | ||
2057 | brcmf_dbg(ERROR, "rx protocol error\n"); | 2069 | brcmf_dbg(ERROR, "rx protocol error\n"); |
2058 | brcmu_pkt_buf_free_skb(pkt); | 2070 | brcmu_pkt_buf_free_skb(pkt); |
2059 | bus->drvr->rx_errors++; | 2071 | bus->sdiodev->bus_if->dstats.rx_errors++; |
2060 | continue; | 2072 | continue; |
2061 | } | 2073 | } |
2062 | 2074 | ||
2063 | /* Unlock during rx call */ | 2075 | /* Unlock during rx call */ |
2064 | up(&bus->sdsem); | 2076 | up(&bus->sdsem); |
2065 | brcmf_rx_packet(bus->drvr, ifidx, pkt); | 2077 | brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); |
2066 | down(&bus->sdsem); | 2078 | down(&bus->sdsem); |
2067 | } | 2079 | } |
2068 | rxcount = maxframes - rxleft; | 2080 | rxcount = maxframes - rxleft; |
@@ -2122,7 +2134,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, | |||
2122 | if (skb_headroom(pkt) < pad) { | 2134 | if (skb_headroom(pkt) < pad) { |
2123 | brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n", | 2135 | brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n", |
2124 | skb_headroom(pkt), pad); | 2136 | skb_headroom(pkt), pad); |
2125 | bus->drvr->tx_realloc++; | 2137 | bus->sdiodev->bus_if->tx_realloc++; |
2126 | new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN); | 2138 | new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN); |
2127 | if (!new) { | 2139 | if (!new) { |
2128 | brcmf_dbg(ERROR, "couldn't allocate new %d-byte packet\n", | 2140 | brcmf_dbg(ERROR, "couldn't allocate new %d-byte packet\n", |
@@ -2230,7 +2242,7 @@ done: | |||
2230 | /* restore pkt buffer pointer before calling tx complete routine */ | 2242 | /* restore pkt buffer pointer before calling tx complete routine */ |
2231 | skb_pull(pkt, SDPCM_HDRLEN + pad); | 2243 | skb_pull(pkt, SDPCM_HDRLEN + pad); |
2232 | up(&bus->sdsem); | 2244 | up(&bus->sdsem); |
2233 | brcmf_txcomplete(bus->drvr, pkt, ret != 0); | 2245 | brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); |
2234 | down(&bus->sdsem); | 2246 | down(&bus->sdsem); |
2235 | 2247 | ||
2236 | if (free_pkt) | 2248 | if (free_pkt) |
@@ -2249,8 +2261,6 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
2249 | uint datalen; | 2261 | uint datalen; |
2250 | u8 tx_prec_map; | 2262 | u8 tx_prec_map; |
2251 | 2263 | ||
2252 | struct brcmf_pub *drvr = bus->drvr; | ||
2253 | |||
2254 | brcmf_dbg(TRACE, "Enter\n"); | 2264 | brcmf_dbg(TRACE, "Enter\n"); |
2255 | 2265 | ||
2256 | tx_prec_map = ~bus->flowcontrol; | 2266 | tx_prec_map = ~bus->flowcontrol; |
@@ -2268,9 +2278,9 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
2268 | 2278 | ||
2269 | ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); | 2279 | ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); |
2270 | if (ret) | 2280 | if (ret) |
2271 | bus->drvr->tx_errors++; | 2281 | bus->sdiodev->bus_if->dstats.tx_errors++; |
2272 | else | 2282 | else |
2273 | bus->drvr->dstats.tx_bytes += datalen; | 2283 | bus->sdiodev->bus_if->dstats.tx_bytes += datalen; |
2274 | 2284 | ||
2275 | /* In poll mode, need to check for other events */ | 2285 | /* In poll mode, need to check for other events */ |
2276 | if (!bus->intr && cnt) { | 2286 | if (!bus->intr && cnt) { |
@@ -2287,13 +2297,97 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
2287 | } | 2297 | } |
2288 | 2298 | ||
2289 | /* Deflow-control stack if needed */ | 2299 | /* Deflow-control stack if needed */ |
2290 | if (drvr->up && (drvr->bus_if->state == BRCMF_BUS_DATA) && | 2300 | if (bus->sdiodev->bus_if->drvr_up && |
2291 | drvr->txoff && (pktq_len(&bus->txq) < TXLOW)) | 2301 | (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) && |
2292 | brcmf_txflowcontrol(drvr, 0, OFF); | 2302 | bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { |
2303 | bus->txoff = OFF; | ||
2304 | brcmf_txflowcontrol(bus->sdiodev->dev, 0, OFF); | ||
2305 | } | ||
2293 | 2306 | ||
2294 | return cnt; | 2307 | return cnt; |
2295 | } | 2308 | } |
2296 | 2309 | ||
2310 | static void brcmf_sdbrcm_bus_stop(struct device *dev) | ||
2311 | { | ||
2312 | u32 local_hostintmask; | ||
2313 | u8 saveclk; | ||
2314 | uint retries; | ||
2315 | int err; | ||
2316 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
2317 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; | ||
2318 | struct brcmf_sdio *bus = sdiodev->bus; | ||
2319 | |||
2320 | brcmf_dbg(TRACE, "Enter\n"); | ||
2321 | |||
2322 | if (bus->watchdog_tsk) { | ||
2323 | send_sig(SIGTERM, bus->watchdog_tsk, 1); | ||
2324 | kthread_stop(bus->watchdog_tsk); | ||
2325 | bus->watchdog_tsk = NULL; | ||
2326 | } | ||
2327 | |||
2328 | if (bus->dpc_tsk && bus->dpc_tsk != current) { | ||
2329 | send_sig(SIGTERM, bus->dpc_tsk, 1); | ||
2330 | kthread_stop(bus->dpc_tsk); | ||
2331 | bus->dpc_tsk = NULL; | ||
2332 | } | ||
2333 | |||
2334 | down(&bus->sdsem); | ||
2335 | |||
2336 | bus_wake(bus); | ||
2337 | |||
2338 | /* Enable clock for device interrupts */ | ||
2339 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | ||
2340 | |||
2341 | /* Disable and clear interrupts at the chip level also */ | ||
2342 | w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries); | ||
2343 | local_hostintmask = bus->hostintmask; | ||
2344 | bus->hostintmask = 0; | ||
2345 | |||
2346 | /* Change our idea of bus state */ | ||
2347 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; | ||
2348 | |||
2349 | /* Force clocks on backplane to be sure F2 interrupt propagates */ | ||
2350 | saveclk = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | ||
2351 | SBSDIO_FUNC1_CHIPCLKCSR, &err); | ||
2352 | if (!err) { | ||
2353 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
2354 | SBSDIO_FUNC1_CHIPCLKCSR, | ||
2355 | (saveclk | SBSDIO_FORCE_HT), &err); | ||
2356 | } | ||
2357 | if (err) | ||
2358 | brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err); | ||
2359 | |||
2360 | /* Turn off the bus (F2), free any pending packets */ | ||
2361 | brcmf_dbg(INTR, "disable SDIO interrupts\n"); | ||
2362 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, | ||
2363 | SDIO_FUNC_ENABLE_1, NULL); | ||
2364 | |||
2365 | /* Clear any pending interrupts now that F2 is disabled */ | ||
2366 | w_sdreg32(bus, local_hostintmask, | ||
2367 | offsetof(struct sdpcmd_regs, intstatus), &retries); | ||
2368 | |||
2369 | /* Turn off the backplane clock (only) */ | ||
2370 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | ||
2371 | |||
2372 | /* Clear the data packet queues */ | ||
2373 | brcmu_pktq_flush(&bus->txq, true, NULL, NULL); | ||
2374 | |||
2375 | /* Clear any held glomming stuff */ | ||
2376 | if (bus->glomd) | ||
2377 | brcmu_pkt_buf_free_skb(bus->glomd); | ||
2378 | brcmf_sdbrcm_free_glom(bus); | ||
2379 | |||
2380 | /* Clear rx control and wake any waiters */ | ||
2381 | bus->rxlen = 0; | ||
2382 | brcmf_sdbrcm_dcmd_resp_wake(bus); | ||
2383 | |||
2384 | /* Reset some F2 state stuff */ | ||
2385 | bus->rxskip = false; | ||
2386 | bus->tx_seq = bus->rx_seq = 0; | ||
2387 | |||
2388 | up(&bus->sdsem); | ||
2389 | } | ||
2390 | |||
2297 | static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | 2391 | static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) |
2298 | { | 2392 | { |
2299 | u32 intstatus, newstatus = 0; | 2393 | u32 intstatus, newstatus = 0; |
@@ -2322,7 +2416,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2322 | SBSDIO_DEVICE_CTL, &err); | 2416 | SBSDIO_DEVICE_CTL, &err); |
2323 | if (err) { | 2417 | if (err) { |
2324 | brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); | 2418 | brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); |
2325 | bus->drvr->bus_if->state = BRCMF_BUS_DOWN; | 2419 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; |
2326 | } | 2420 | } |
2327 | #endif /* BCMDBG */ | 2421 | #endif /* BCMDBG */ |
2328 | 2422 | ||
@@ -2332,7 +2426,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2332 | if (err) { | 2426 | if (err) { |
2333 | brcmf_dbg(ERROR, "error reading CSR: %d\n", | 2427 | brcmf_dbg(ERROR, "error reading CSR: %d\n", |
2334 | err); | 2428 | err); |
2335 | bus->drvr->bus_if->state = BRCMF_BUS_DOWN; | 2429 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; |
2336 | } | 2430 | } |
2337 | 2431 | ||
2338 | brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", | 2432 | brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", |
@@ -2345,7 +2439,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2345 | if (err) { | 2439 | if (err) { |
2346 | brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", | 2440 | brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", |
2347 | err); | 2441 | err); |
2348 | bus->drvr->bus_if->state = BRCMF_BUS_DOWN; | 2442 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; |
2349 | } | 2443 | } |
2350 | devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; | 2444 | devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; |
2351 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | 2445 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, |
@@ -2353,7 +2447,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2353 | if (err) { | 2447 | if (err) { |
2354 | brcmf_dbg(ERROR, "error writing DEVCTL: %d\n", | 2448 | brcmf_dbg(ERROR, "error writing DEVCTL: %d\n", |
2355 | err); | 2449 | err); |
2356 | bus->drvr->bus_if->state = BRCMF_BUS_DOWN; | 2450 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; |
2357 | } | 2451 | } |
2358 | bus->clkstate = CLK_AVAIL; | 2452 | bus->clkstate = CLK_AVAIL; |
2359 | } else { | 2453 | } else { |
@@ -2509,11 +2603,11 @@ clkwait: | |||
2509 | else await next interrupt */ | 2603 | else await next interrupt */ |
2510 | /* On failed register access, all bets are off: | 2604 | /* On failed register access, all bets are off: |
2511 | no resched or interrupts */ | 2605 | no resched or interrupts */ |
2512 | if ((bus->drvr->bus_if->state == BRCMF_BUS_DOWN) || | 2606 | if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || |
2513 | brcmf_sdcard_regfail(bus->sdiodev)) { | 2607 | brcmf_sdcard_regfail(bus->sdiodev)) { |
2514 | brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation %d\n", | 2608 | brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation %d\n", |
2515 | brcmf_sdcard_regfail(bus->sdiodev)); | 2609 | brcmf_sdcard_regfail(bus->sdiodev)); |
2516 | bus->drvr->bus_if->state = BRCMF_BUS_DOWN; | 2610 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; |
2517 | bus->intstatus = 0; | 2611 | bus->intstatus = 0; |
2518 | } else if (bus->clkstate == CLK_PENDING) { | 2612 | } else if (bus->clkstate == CLK_PENDING) { |
2519 | brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n"); | 2613 | brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n"); |
@@ -2550,7 +2644,7 @@ static int brcmf_sdbrcm_dpc_thread(void *data) | |||
2550 | if (!wait_for_completion_interruptible(&bus->dpc_wait)) { | 2644 | if (!wait_for_completion_interruptible(&bus->dpc_wait)) { |
2551 | /* Call bus dpc unless it indicated down | 2645 | /* Call bus dpc unless it indicated down |
2552 | (then clean stop) */ | 2646 | (then clean stop) */ |
2553 | if (bus->drvr->bus_if->state != BRCMF_BUS_DOWN) { | 2647 | if (bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN) { |
2554 | if (brcmf_sdbrcm_dpc(bus)) | 2648 | if (brcmf_sdbrcm_dpc(bus)) |
2555 | complete(&bus->dpc_wait); | 2649 | complete(&bus->dpc_wait); |
2556 | } else { | 2650 | } else { |
@@ -2565,7 +2659,7 @@ static int brcmf_sdbrcm_dpc_thread(void *data) | |||
2565 | return 0; | 2659 | return 0; |
2566 | } | 2660 | } |
2567 | 2661 | ||
2568 | int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | 2662 | static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) |
2569 | { | 2663 | { |
2570 | int ret = -EBADE; | 2664 | int ret = -EBADE; |
2571 | uint datalen, prec; | 2665 | uint datalen, prec; |
@@ -2590,9 +2684,10 @@ int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | |||
2590 | 2684 | ||
2591 | /* Priority based enq */ | 2685 | /* Priority based enq */ |
2592 | spin_lock_bh(&bus->txqlock); | 2686 | spin_lock_bh(&bus->txqlock); |
2593 | if (brcmf_c_prec_enq(bus->drvr, &bus->txq, pkt, prec) == false) { | 2687 | if (brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec) == |
2688 | false) { | ||
2594 | skb_pull(pkt, SDPCM_HDRLEN); | 2689 | skb_pull(pkt, SDPCM_HDRLEN); |
2595 | brcmf_txcomplete(bus->drvr, pkt, false); | 2690 | brcmf_txcomplete(bus->sdiodev->dev, pkt, false); |
2596 | brcmu_pkt_buf_free_skb(pkt); | 2691 | brcmu_pkt_buf_free_skb(pkt); |
2597 | brcmf_dbg(ERROR, "out of bus->txq !!!\n"); | 2692 | brcmf_dbg(ERROR, "out of bus->txq !!!\n"); |
2598 | ret = -ENOSR; | 2693 | ret = -ENOSR; |
@@ -2601,8 +2696,10 @@ int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | |||
2601 | } | 2696 | } |
2602 | spin_unlock_bh(&bus->txqlock); | 2697 | spin_unlock_bh(&bus->txqlock); |
2603 | 2698 | ||
2604 | if (pktq_len(&bus->txq) >= TXHI) | 2699 | if (pktq_len(&bus->txq) >= TXHI) { |
2605 | brcmf_txflowcontrol(bus->drvr, 0, ON); | 2700 | bus->txoff = ON; |
2701 | brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON); | ||
2702 | } | ||
2606 | 2703 | ||
2607 | #ifdef BCMDBG | 2704 | #ifdef BCMDBG |
2608 | if (pktq_plen(&bus->txq, prec) > qcount[prec]) | 2705 | if (pktq_plen(&bus->txq, prec) > qcount[prec]) |
@@ -2799,7 +2896,7 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) | |||
2799 | return ret; | 2896 | return ret; |
2800 | } | 2897 | } |
2801 | 2898 | ||
2802 | int | 2899 | static int |
2803 | brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | 2900 | brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) |
2804 | { | 2901 | { |
2805 | u8 *frame; | 2902 | u8 *frame; |
@@ -2910,14 +3007,14 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2910 | up(&bus->sdsem); | 3007 | up(&bus->sdsem); |
2911 | 3008 | ||
2912 | if (ret) | 3009 | if (ret) |
2913 | bus->drvr->tx_ctlerrs++; | 3010 | bus->tx_ctlerrs++; |
2914 | else | 3011 | else |
2915 | bus->drvr->tx_ctlpkts++; | 3012 | bus->tx_ctlpkts++; |
2916 | 3013 | ||
2917 | return ret ? -EIO : 0; | 3014 | return ret ? -EIO : 0; |
2918 | } | 3015 | } |
2919 | 3016 | ||
2920 | int | 3017 | static int |
2921 | brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) | 3018 | brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) |
2922 | { | 3019 | { |
2923 | int timeleft; | 3020 | int timeleft; |
@@ -2951,9 +3048,9 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2951 | } | 3048 | } |
2952 | 3049 | ||
2953 | if (rxlen) | 3050 | if (rxlen) |
2954 | bus->drvr->rx_ctlpkts++; | 3051 | bus->rx_ctlpkts++; |
2955 | else | 3052 | else |
2956 | bus->drvr->rx_ctlerrs++; | 3053 | bus->rx_ctlerrs++; |
2957 | 3054 | ||
2958 | return rxlen ? (int)rxlen : -ETIMEDOUT; | 3055 | return rxlen ? (int)rxlen : -ETIMEDOUT; |
2959 | } | 3056 | } |
@@ -2965,7 +3062,7 @@ static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len) | |||
2965 | brcmf_dbg(TRACE, "Enter\n"); | 3062 | brcmf_dbg(TRACE, "Enter\n"); |
2966 | 3063 | ||
2967 | /* Basic sanity checks */ | 3064 | /* Basic sanity checks */ |
2968 | if (bus->drvr->up) { | 3065 | if (bus->sdiodev->bus_if->drvr_up) { |
2969 | bcmerror = -EISCONN; | 3066 | bcmerror = -EISCONN; |
2970 | goto err; | 3067 | goto err; |
2971 | } | 3068 | } |
@@ -3121,7 +3218,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) | |||
3121 | /* Allow HT Clock now that the ARM is running. */ | 3218 | /* Allow HT Clock now that the ARM is running. */ |
3122 | bus->alp_only = false; | 3219 | bus->alp_only = false; |
3123 | 3220 | ||
3124 | bus->drvr->bus_if->state = BRCMF_BUS_LOAD; | 3221 | bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; |
3125 | } | 3222 | } |
3126 | fail: | 3223 | fail: |
3127 | return bcmerror; | 3224 | return bcmerror; |
@@ -3330,88 +3427,7 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) | |||
3330 | return ret; | 3427 | return ret; |
3331 | } | 3428 | } |
3332 | 3429 | ||
3333 | void brcmf_sdbrcm_bus_stop(struct device *dev) | 3430 | static int brcmf_sdbrcm_bus_init(struct device *dev) |
3334 | { | ||
3335 | u32 local_hostintmask; | ||
3336 | u8 saveclk; | ||
3337 | uint retries; | ||
3338 | int err; | ||
3339 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||
3340 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; | ||
3341 | struct brcmf_sdio *bus = sdiodev->bus; | ||
3342 | |||
3343 | brcmf_dbg(TRACE, "Enter\n"); | ||
3344 | |||
3345 | if (bus->watchdog_tsk) { | ||
3346 | send_sig(SIGTERM, bus->watchdog_tsk, 1); | ||
3347 | kthread_stop(bus->watchdog_tsk); | ||
3348 | bus->watchdog_tsk = NULL; | ||
3349 | } | ||
3350 | |||
3351 | if (bus->dpc_tsk && bus->dpc_tsk != current) { | ||
3352 | send_sig(SIGTERM, bus->dpc_tsk, 1); | ||
3353 | kthread_stop(bus->dpc_tsk); | ||
3354 | bus->dpc_tsk = NULL; | ||
3355 | } | ||
3356 | |||
3357 | down(&bus->sdsem); | ||
3358 | |||
3359 | bus_wake(bus); | ||
3360 | |||
3361 | /* Enable clock for device interrupts */ | ||
3362 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | ||
3363 | |||
3364 | /* Disable and clear interrupts at the chip level also */ | ||
3365 | w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries); | ||
3366 | local_hostintmask = bus->hostintmask; | ||
3367 | bus->hostintmask = 0; | ||
3368 | |||
3369 | /* Change our idea of bus state */ | ||
3370 | bus->drvr->bus_if->state = BRCMF_BUS_DOWN; | ||
3371 | |||
3372 | /* Force clocks on backplane to be sure F2 interrupt propagates */ | ||
3373 | saveclk = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, | ||
3374 | SBSDIO_FUNC1_CHIPCLKCSR, &err); | ||
3375 | if (!err) { | ||
3376 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, | ||
3377 | SBSDIO_FUNC1_CHIPCLKCSR, | ||
3378 | (saveclk | SBSDIO_FORCE_HT), &err); | ||
3379 | } | ||
3380 | if (err) | ||
3381 | brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err); | ||
3382 | |||
3383 | /* Turn off the bus (F2), free any pending packets */ | ||
3384 | brcmf_dbg(INTR, "disable SDIO interrupts\n"); | ||
3385 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, | ||
3386 | SDIO_FUNC_ENABLE_1, NULL); | ||
3387 | |||
3388 | /* Clear any pending interrupts now that F2 is disabled */ | ||
3389 | w_sdreg32(bus, local_hostintmask, | ||
3390 | offsetof(struct sdpcmd_regs, intstatus), &retries); | ||
3391 | |||
3392 | /* Turn off the backplane clock (only) */ | ||
3393 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | ||
3394 | |||
3395 | /* Clear the data packet queues */ | ||
3396 | brcmu_pktq_flush(&bus->txq, true, NULL, NULL); | ||
3397 | |||
3398 | /* Clear any held glomming stuff */ | ||
3399 | if (bus->glomd) | ||
3400 | brcmu_pkt_buf_free_skb(bus->glomd); | ||
3401 | brcmf_sdbrcm_free_glom(bus); | ||
3402 | |||
3403 | /* Clear rx control and wake any waiters */ | ||
3404 | bus->rxlen = 0; | ||
3405 | brcmf_sdbrcm_dcmd_resp_wake(bus); | ||
3406 | |||
3407 | /* Reset some F2 state stuff */ | ||
3408 | bus->rxskip = false; | ||
3409 | bus->tx_seq = bus->rx_seq = 0; | ||
3410 | |||
3411 | up(&bus->sdsem); | ||
3412 | } | ||
3413 | |||
3414 | int brcmf_sdbrcm_bus_init(struct device *dev) | ||
3415 | { | 3431 | { |
3416 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 3432 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
3417 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; | 3433 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; |
@@ -3430,11 +3446,11 @@ int brcmf_sdbrcm_bus_init(struct device *dev) | |||
3430 | return -1; | 3446 | return -1; |
3431 | } | 3447 | } |
3432 | 3448 | ||
3433 | if (!bus->drvr) | 3449 | if (!bus->sdiodev->bus_if->drvr) |
3434 | return 0; | 3450 | return 0; |
3435 | 3451 | ||
3436 | /* Start the watchdog timer */ | 3452 | /* Start the watchdog timer */ |
3437 | bus->drvr->tickcnt = 0; | 3453 | bus->tickcnt = 0; |
3438 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); | 3454 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); |
3439 | 3455 | ||
3440 | down(&bus->sdsem); | 3456 | down(&bus->sdsem); |
@@ -3526,7 +3542,7 @@ void brcmf_sdbrcm_isr(void *arg) | |||
3526 | return; | 3542 | return; |
3527 | } | 3543 | } |
3528 | 3544 | ||
3529 | if (bus->drvr->bus_if->state == BRCMF_BUS_DOWN) { | 3545 | if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { |
3530 | brcmf_dbg(ERROR, "bus is down. we have nothing to do\n"); | 3546 | brcmf_dbg(ERROR, "bus is down. we have nothing to do\n"); |
3531 | return; | 3547 | return; |
3532 | } | 3548 | } |
@@ -3657,9 +3673,9 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) | |||
3657 | { | 3673 | { |
3658 | brcmf_dbg(TRACE, "Enter\n"); | 3674 | brcmf_dbg(TRACE, "Enter\n"); |
3659 | 3675 | ||
3660 | if (bus->drvr->maxctl) { | 3676 | if (bus->sdiodev->bus_if->maxctl) { |
3661 | bus->rxblen = | 3677 | bus->rxblen = |
3662 | roundup((bus->drvr->maxctl + SDPCM_HDRLEN), | 3678 | roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), |
3663 | ALIGNMENT) + BRCMF_SDALIGN; | 3679 | ALIGNMENT) + BRCMF_SDALIGN; |
3664 | bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); | 3680 | bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); |
3665 | if (!(bus->rxbuf)) | 3681 | if (!(bus->rxbuf)) |
@@ -3782,7 +3798,7 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) | |||
3782 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, | 3798 | brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, |
3783 | SDIO_FUNC_ENABLE_1, NULL); | 3799 | SDIO_FUNC_ENABLE_1, NULL); |
3784 | 3800 | ||
3785 | bus->drvr->bus_if->state = BRCMF_BUS_DOWN; | 3801 | bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; |
3786 | bus->sleeping = false; | 3802 | bus->sleeping = false; |
3787 | bus->rxflow = false; | 3803 | bus->rxflow = false; |
3788 | 3804 | ||
@@ -3819,7 +3835,7 @@ brcmf_sdbrcm_watchdog_thread(void *data) | |||
3819 | if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { | 3835 | if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { |
3820 | brcmf_sdbrcm_bus_watchdog(bus); | 3836 | brcmf_sdbrcm_bus_watchdog(bus); |
3821 | /* Count the tick for reference */ | 3837 | /* Count the tick for reference */ |
3822 | bus->drvr->tickcnt++; | 3838 | bus->tickcnt++; |
3823 | } else | 3839 | } else |
3824 | break; | 3840 | break; |
3825 | } | 3841 | } |
@@ -3865,10 +3881,9 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) | |||
3865 | /* De-register interrupt handler */ | 3881 | /* De-register interrupt handler */ |
3866 | brcmf_sdcard_intr_dereg(bus->sdiodev); | 3882 | brcmf_sdcard_intr_dereg(bus->sdiodev); |
3867 | 3883 | ||
3868 | if (bus->drvr) { | 3884 | if (bus->sdiodev->bus_if->drvr) { |
3869 | brcmf_detach(bus->drvr); | 3885 | brcmf_detach(bus->sdiodev->dev); |
3870 | brcmf_sdbrcm_release_dongle(bus); | 3886 | brcmf_sdbrcm_release_dongle(bus); |
3871 | bus->drvr = NULL; | ||
3872 | } | 3887 | } |
3873 | 3888 | ||
3874 | brcmf_sdbrcm_release_malloc(bus); | 3889 | brcmf_sdbrcm_release_malloc(bus); |
@@ -3941,9 +3956,15 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3941 | bus->dpc_tsk = NULL; | 3956 | bus->dpc_tsk = NULL; |
3942 | } | 3957 | } |
3943 | 3958 | ||
3959 | /* Assign bus interface call back */ | ||
3960 | bus->sdiodev->bus_if->brcmf_bus_stop = brcmf_sdbrcm_bus_stop; | ||
3961 | bus->sdiodev->bus_if->brcmf_bus_init = brcmf_sdbrcm_bus_init; | ||
3962 | bus->sdiodev->bus_if->brcmf_bus_txdata = brcmf_sdbrcm_bus_txdata; | ||
3963 | bus->sdiodev->bus_if->brcmf_bus_txctl = brcmf_sdbrcm_bus_txctl; | ||
3964 | bus->sdiodev->bus_if->brcmf_bus_rxctl = brcmf_sdbrcm_bus_rxctl; | ||
3944 | /* Attach to the brcmf/OS/network interface */ | 3965 | /* Attach to the brcmf/OS/network interface */ |
3945 | bus->drvr = brcmf_attach(bus, SDPCM_RESERVE, bus->sdiodev->dev); | 3966 | ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev); |
3946 | if (!bus->drvr) { | 3967 | if (ret != 0) { |
3947 | brcmf_dbg(ERROR, "brcmf_attach failed\n"); | 3968 | brcmf_dbg(ERROR, "brcmf_attach failed\n"); |
3948 | goto fail; | 3969 | goto fail; |
3949 | } | 3970 | } |
@@ -3971,7 +3992,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3971 | brcmf_dbg(INFO, "completed!!\n"); | 3992 | brcmf_dbg(INFO, "completed!!\n"); |
3972 | 3993 | ||
3973 | /* if firmware path present try to download and bring up bus */ | 3994 | /* if firmware path present try to download and bring up bus */ |
3974 | ret = brcmf_bus_start(bus->drvr); | 3995 | ret = brcmf_bus_start(bus->sdiodev->dev); |
3975 | if (ret != 0) { | 3996 | if (ret != 0) { |
3976 | if (ret == -ENOLINK) { | 3997 | if (ret == -ENOLINK) { |
3977 | brcmf_dbg(ERROR, "dongle is not responding\n"); | 3998 | brcmf_dbg(ERROR, "dongle is not responding\n"); |
@@ -3980,7 +4001,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3980 | } | 4001 | } |
3981 | 4002 | ||
3982 | /* add interface and open for business */ | 4003 | /* add interface and open for business */ |
3983 | if (brcmf_add_if((struct brcmf_info *)bus->drvr, 0, "wlan%d", NULL)) { | 4004 | if (brcmf_add_if(bus->sdiodev->dev, 0, "wlan%d", NULL)) { |
3984 | brcmf_dbg(ERROR, "Add primary net device interface failed!!\n"); | 4005 | brcmf_dbg(ERROR, "Add primary net device interface failed!!\n"); |
3985 | goto fail; | 4006 | goto fail; |
3986 | } | 4007 | } |
@@ -4016,7 +4037,7 @@ brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick) | |||
4016 | } | 4037 | } |
4017 | 4038 | ||
4018 | /* don't start the wd until fw is loaded */ | 4039 | /* don't start the wd until fw is loaded */ |
4019 | if (bus->drvr->bus_if->state == BRCMF_BUS_DOWN) | 4040 | if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) |
4020 | return; | 4041 | return; |
4021 | 4042 | ||
4022 | if (wdtick) { | 4043 | if (wdtick) { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index a6048d78d294..11b2d7c97ba2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <brcmu_wifi.h> | 26 | #include <brcmu_wifi.h> |
27 | #include <brcmu_utils.h> | 27 | #include <brcmu_utils.h> |
28 | #include <soc.h> | 28 | #include <soc.h> |
29 | #include "dhd.h" | ||
30 | #include "dhd_dbg.h" | 29 | #include "dhd_dbg.h" |
31 | #include "sdio_host.h" | 30 | #include "sdio_host.h" |
32 | #include "sdio_chip.h" | 31 | #include "sdio_chip.h" |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index d36a2a855a65..0281d207d998 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | |||
@@ -116,12 +116,20 @@ | |||
116 | #define SUCCESS 0 | 116 | #define SUCCESS 0 |
117 | #define ERROR 1 | 117 | #define ERROR 1 |
118 | 118 | ||
119 | /* Packet alignment for most efficient SDIO (can change based on platform) */ | ||
120 | #define BRCMF_SDALIGN (1 << 6) | ||
121 | |||
122 | /* watchdog polling interval in ms */ | ||
123 | #define BRCMF_WD_POLL_MS 10 | ||
124 | |||
119 | struct brcmf_sdreg { | 125 | struct brcmf_sdreg { |
120 | int func; | 126 | int func; |
121 | int offset; | 127 | int offset; |
122 | int value; | 128 | int value; |
123 | }; | 129 | }; |
124 | 130 | ||
131 | struct brcmf_sdio; | ||
132 | |||
125 | struct brcmf_sdio_dev { | 133 | struct brcmf_sdio_dev { |
126 | struct sdio_func *func[SDIO_MAX_FUNCS]; | 134 | struct sdio_func *func[SDIO_MAX_FUNCS]; |
127 | u8 num_funcs; /* Supported funcs on client */ | 135 | u8 num_funcs; /* Supported funcs on client */ |
@@ -262,4 +270,6 @@ extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, | |||
262 | extern void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); | 270 | extern void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); |
263 | extern void brcmf_sdbrcm_disconnect(void *ptr); | 271 | extern void brcmf_sdbrcm_disconnect(void *ptr); |
264 | extern void brcmf_sdbrcm_isr(void *arg); | 272 | extern void brcmf_sdbrcm_isr(void *arg); |
273 | |||
274 | extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); | ||
265 | #endif /* _BRCM_SDH_H_ */ | 275 | #endif /* _BRCM_SDH_H_ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 8d3bad7ea5d3..1ef7bfc2ab25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -124,10 +124,10 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) | |||
124 | { | 124 | { |
125 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | 125 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
126 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | 126 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
127 | priv->cfg->base_params->num_of_queues = | 127 | cfg(priv)->base_params->num_of_queues = |
128 | iwlagn_mod_params.num_of_queues; | 128 | iwlagn_mod_params.num_of_queues; |
129 | 129 | ||
130 | hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; | 130 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
131 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | 131 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; |
132 | 132 | ||
133 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; | 133 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; |
@@ -135,14 +135,14 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) | |||
135 | 135 | ||
136 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); | 136 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); |
137 | 137 | ||
138 | hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | 138 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); |
139 | if (priv->cfg->rx_with_siso_diversity) | 139 | if (cfg(priv)->rx_with_siso_diversity) |
140 | hw_params(priv).rx_chains_num = 1; | 140 | hw_params(priv).rx_chains_num = 1; |
141 | else | 141 | else |
142 | hw_params(priv).rx_chains_num = | 142 | hw_params(priv).rx_chains_num = |
143 | num_of_ant(priv->cfg->valid_rx_ant); | 143 | num_of_ant(cfg(priv)->valid_rx_ant); |
144 | hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant; | 144 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; |
145 | hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant; | 145 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; |
146 | 146 | ||
147 | iwl1000_set_ct_threshold(priv); | 147 | iwl1000_set_ct_threshold(priv); |
148 | 148 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 0c4688d95b65..094693328dbb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -86,7 +86,7 @@ static void iwl2000_nic_config(struct iwl_priv *priv) | |||
86 | { | 86 | { |
87 | iwl_rf_config(priv); | 87 | iwl_rf_config(priv); |
88 | 88 | ||
89 | if (priv->cfg->iq_invert) | 89 | if (cfg(priv)->iq_invert) |
90 | iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, | 90 | iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, |
91 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | 91 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); |
92 | } | 92 | } |
@@ -120,10 +120,10 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) | |||
120 | { | 120 | { |
121 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | 121 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
122 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | 122 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
123 | priv->cfg->base_params->num_of_queues = | 123 | cfg(priv)->base_params->num_of_queues = |
124 | iwlagn_mod_params.num_of_queues; | 124 | iwlagn_mod_params.num_of_queues; |
125 | 125 | ||
126 | hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; | 126 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
127 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | 127 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; |
128 | 128 | ||
129 | hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; | 129 | hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; |
@@ -131,14 +131,14 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) | |||
131 | 131 | ||
132 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); | 132 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); |
133 | 133 | ||
134 | hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | 134 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); |
135 | if (priv->cfg->rx_with_siso_diversity) | 135 | if (cfg(priv)->rx_with_siso_diversity) |
136 | hw_params(priv).rx_chains_num = 1; | 136 | hw_params(priv).rx_chains_num = 1; |
137 | else | 137 | else |
138 | hw_params(priv).rx_chains_num = | 138 | hw_params(priv).rx_chains_num = |
139 | num_of_ant(priv->cfg->valid_rx_ant); | 139 | num_of_ant(cfg(priv)->valid_rx_ant); |
140 | hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant; | 140 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; |
141 | hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant; | 141 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; |
142 | 142 | ||
143 | iwl2000_set_ct_threshold(priv); | 143 | iwl2000_set_ct_threshold(priv); |
144 | 144 | ||
@@ -254,13 +254,13 @@ static struct iwl_bt_params iwl2030_bt_params = { | |||
254 | .iq_invert = true \ | 254 | .iq_invert = true \ |
255 | 255 | ||
256 | struct iwl_cfg iwl2000_2bgn_cfg = { | 256 | struct iwl_cfg iwl2000_2bgn_cfg = { |
257 | .name = "2000 Series 2x2 BGN", | 257 | .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", |
258 | IWL_DEVICE_2000, | 258 | IWL_DEVICE_2000, |
259 | .ht_params = &iwl2000_ht_params, | 259 | .ht_params = &iwl2000_ht_params, |
260 | }; | 260 | }; |
261 | 261 | ||
262 | struct iwl_cfg iwl2000_2bgn_d_cfg = { | 262 | struct iwl_cfg iwl2000_2bgn_d_cfg = { |
263 | .name = "2000D Series 2x2 BGN", | 263 | .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", |
264 | IWL_DEVICE_2000, | 264 | IWL_DEVICE_2000, |
265 | .ht_params = &iwl2000_ht_params, | 265 | .ht_params = &iwl2000_ht_params, |
266 | }; | 266 | }; |
@@ -282,7 +282,7 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = { | |||
282 | .iq_invert = true \ | 282 | .iq_invert = true \ |
283 | 283 | ||
284 | struct iwl_cfg iwl2030_2bgn_cfg = { | 284 | struct iwl_cfg iwl2030_2bgn_cfg = { |
285 | .name = "2000 Series 2x2 BGN/BT", | 285 | .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", |
286 | IWL_DEVICE_2030, | 286 | IWL_DEVICE_2030, |
287 | .ht_params = &iwl2000_ht_params, | 287 | .ht_params = &iwl2000_ht_params, |
288 | }; | 288 | }; |
@@ -304,13 +304,13 @@ struct iwl_cfg iwl2030_2bgn_cfg = { | |||
304 | .iq_invert = true \ | 304 | .iq_invert = true \ |
305 | 305 | ||
306 | struct iwl_cfg iwl105_bgn_cfg = { | 306 | struct iwl_cfg iwl105_bgn_cfg = { |
307 | .name = "105 Series 1x1 BGN", | 307 | .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", |
308 | IWL_DEVICE_105, | 308 | IWL_DEVICE_105, |
309 | .ht_params = &iwl2000_ht_params, | 309 | .ht_params = &iwl2000_ht_params, |
310 | }; | 310 | }; |
311 | 311 | ||
312 | struct iwl_cfg iwl105_bgn_d_cfg = { | 312 | struct iwl_cfg iwl105_bgn_d_cfg = { |
313 | .name = "105D Series 1x1 BGN", | 313 | .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", |
314 | IWL_DEVICE_105, | 314 | IWL_DEVICE_105, |
315 | .ht_params = &iwl2000_ht_params, | 315 | .ht_params = &iwl2000_ht_params, |
316 | }; | 316 | }; |
@@ -333,7 +333,7 @@ struct iwl_cfg iwl105_bgn_d_cfg = { | |||
333 | .iq_invert = true \ | 333 | .iq_invert = true \ |
334 | 334 | ||
335 | struct iwl_cfg iwl135_bgn_cfg = { | 335 | struct iwl_cfg iwl135_bgn_cfg = { |
336 | .name = "135 Series 1x1 BGN/BT", | 336 | .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", |
337 | IWL_DEVICE_135, | 337 | IWL_DEVICE_135, |
338 | .ht_params = &iwl2000_ht_params, | 338 | .ht_params = &iwl2000_ht_params, |
339 | }; | 339 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 6706d7c10bd8..b3a365fea7bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -166,10 +166,10 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
166 | { | 166 | { |
167 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | 167 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
168 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | 168 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
169 | priv->cfg->base_params->num_of_queues = | 169 | cfg(priv)->base_params->num_of_queues = |
170 | iwlagn_mod_params.num_of_queues; | 170 | iwlagn_mod_params.num_of_queues; |
171 | 171 | ||
172 | hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; | 172 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
173 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | 173 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; |
174 | 174 | ||
175 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; | 175 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; |
@@ -178,10 +178,10 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
178 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 178 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
179 | BIT(IEEE80211_BAND_5GHZ); | 179 | BIT(IEEE80211_BAND_5GHZ); |
180 | 180 | ||
181 | hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | 181 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); |
182 | hw_params(priv).rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); | 182 | hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); |
183 | hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant; | 183 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; |
184 | hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant; | 184 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; |
185 | 185 | ||
186 | iwl5000_set_ct_threshold(priv); | 186 | iwl5000_set_ct_threshold(priv); |
187 | 187 | ||
@@ -195,10 +195,10 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) | |||
195 | { | 195 | { |
196 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | 196 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
197 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | 197 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
198 | priv->cfg->base_params->num_of_queues = | 198 | cfg(priv)->base_params->num_of_queues = |
199 | iwlagn_mod_params.num_of_queues; | 199 | iwlagn_mod_params.num_of_queues; |
200 | 200 | ||
201 | hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; | 201 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
202 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | 202 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; |
203 | 203 | ||
204 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; | 204 | hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; |
@@ -207,10 +207,10 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) | |||
207 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 207 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
208 | BIT(IEEE80211_BAND_5GHZ); | 208 | BIT(IEEE80211_BAND_5GHZ); |
209 | 209 | ||
210 | hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | 210 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); |
211 | hw_params(priv).rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); | 211 | hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); |
212 | hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant; | 212 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; |
213 | hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant; | 213 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; |
214 | 214 | ||
215 | iwl5150_set_ct_threshold(priv); | 215 | iwl5150_set_ct_threshold(priv); |
216 | 216 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 3e277b6774f1..54b753399e6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -102,14 +102,14 @@ static void iwl6000_nic_config(struct iwl_priv *priv) | |||
102 | iwl_rf_config(priv); | 102 | iwl_rf_config(priv); |
103 | 103 | ||
104 | /* no locking required for register write */ | 104 | /* no locking required for register write */ |
105 | if (priv->cfg->pa_type == IWL_PA_INTERNAL) { | 105 | if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { |
106 | /* 2x2 IPA phy type */ | 106 | /* 2x2 IPA phy type */ |
107 | iwl_write32(bus(priv), CSR_GP_DRIVER_REG, | 107 | iwl_write32(bus(priv), CSR_GP_DRIVER_REG, |
108 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | 108 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); |
109 | } | 109 | } |
110 | /* do additional nic configuration if needed */ | 110 | /* do additional nic configuration if needed */ |
111 | if (priv->cfg->additional_nic_config) | 111 | if (cfg(priv)->additional_nic_config) |
112 | priv->cfg->additional_nic_config(priv); | 112 | cfg(priv)->additional_nic_config(priv); |
113 | } | 113 | } |
114 | 114 | ||
115 | static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | 115 | static struct iwl_sensitivity_ranges iwl6000_sensitivity = { |
@@ -141,10 +141,10 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | |||
141 | { | 141 | { |
142 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | 142 | if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && |
143 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | 143 | iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) |
144 | priv->cfg->base_params->num_of_queues = | 144 | cfg(priv)->base_params->num_of_queues = |
145 | iwlagn_mod_params.num_of_queues; | 145 | iwlagn_mod_params.num_of_queues; |
146 | 146 | ||
147 | hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues; | 147 | hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; |
148 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | 148 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; |
149 | 149 | ||
150 | hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; | 150 | hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; |
@@ -153,14 +153,14 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | |||
153 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 153 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | |
154 | BIT(IEEE80211_BAND_5GHZ); | 154 | BIT(IEEE80211_BAND_5GHZ); |
155 | 155 | ||
156 | hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | 156 | hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); |
157 | if (priv->cfg->rx_with_siso_diversity) | 157 | if (cfg(priv)->rx_with_siso_diversity) |
158 | hw_params(priv).rx_chains_num = 1; | 158 | hw_params(priv).rx_chains_num = 1; |
159 | else | 159 | else |
160 | hw_params(priv).rx_chains_num = | 160 | hw_params(priv).rx_chains_num = |
161 | num_of_ant(priv->cfg->valid_rx_ant); | 161 | num_of_ant(cfg(priv)->valid_rx_ant); |
162 | hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant; | 162 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; |
163 | hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant; | 163 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; |
164 | 164 | ||
165 | iwl6000_set_ct_threshold(priv); | 165 | iwl6000_set_ct_threshold(priv); |
166 | 166 | ||
@@ -423,7 +423,7 @@ struct iwl_cfg iwl6030_2bg_cfg = { | |||
423 | }; | 423 | }; |
424 | 424 | ||
425 | struct iwl_cfg iwl6035_2agn_cfg = { | 425 | struct iwl_cfg iwl6035_2agn_cfg = { |
426 | .name = "6035 Series 2x2 AGN/BT", | 426 | .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", |
427 | IWL_DEVICE_6030, | 427 | IWL_DEVICE_6030, |
428 | .ht_params = &iwl6000_ht_params, | 428 | .ht_params = &iwl6000_ht_params, |
429 | }; | 429 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 16971a020297..50ff849c9f67 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c | |||
@@ -513,7 +513,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) | |||
513 | 513 | ||
514 | iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); | 514 | iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); |
515 | 515 | ||
516 | if (priv->cfg->base_params->hd_v2) { | 516 | if (cfg(priv)->base_params->hd_v2) { |
517 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = | 517 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = |
518 | HD_INA_NON_SQUARE_DET_OFDM_DATA_V2; | 518 | HD_INA_NON_SQUARE_DET_OFDM_DATA_V2; |
519 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = | 519 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = |
@@ -847,7 +847,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
847 | * connect the first valid tx chain | 847 | * connect the first valid tx chain |
848 | */ | 848 | */ |
849 | first_chain = | 849 | first_chain = |
850 | find_first_chain(priv->cfg->valid_tx_ant); | 850 | find_first_chain(cfg(priv)->valid_tx_ant); |
851 | data->disconn_array[first_chain] = 0; | 851 | data->disconn_array[first_chain] = 0; |
852 | active_chains |= BIT(first_chain); | 852 | active_chains |= BIT(first_chain); |
853 | IWL_DEBUG_CALIB(priv, | 853 | IWL_DEBUG_CALIB(priv, |
@@ -890,7 +890,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, | |||
890 | continue; | 890 | continue; |
891 | } | 891 | } |
892 | 892 | ||
893 | delta_g = (priv->cfg->base_params->chain_noise_scale * | 893 | delta_g = (cfg(priv)->base_params->chain_noise_scale * |
894 | ((s32)average_noise[default_chain] - | 894 | ((s32)average_noise[default_chain] - |
895 | (s32)average_noise[i])) / 1500; | 895 | (s32)average_noise[i])) / 1500; |
896 | 896 | ||
@@ -1047,8 +1047,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1047 | return; | 1047 | return; |
1048 | 1048 | ||
1049 | /* Analyze signal for disconnected antenna */ | 1049 | /* Analyze signal for disconnected antenna */ |
1050 | if (priv->cfg->bt_params && | 1050 | if (cfg(priv)->bt_params && |
1051 | priv->cfg->bt_params->advanced_bt_coexist) { | 1051 | cfg(priv)->bt_params->advanced_bt_coexist) { |
1052 | /* Disable disconnected antenna algorithm for advanced | 1052 | /* Disable disconnected antenna algorithm for advanced |
1053 | bt coex, assuming valid antennas are connected */ | 1053 | bt coex, assuming valid antennas are connected */ |
1054 | data->active_chains = hw_params(priv).valid_rx_ant; | 1054 | data->active_chains = hw_params(priv).valid_rx_ant; |
@@ -1082,7 +1082,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1082 | 1082 | ||
1083 | iwlagn_gain_computation(priv, average_noise, | 1083 | iwlagn_gain_computation(priv, average_noise, |
1084 | min_average_noise_antenna_i, min_average_noise, | 1084 | min_average_noise_antenna_i, min_average_noise, |
1085 | find_first_chain(priv->cfg->valid_rx_ant)); | 1085 | find_first_chain(cfg(priv)->valid_rx_ant)); |
1086 | 1086 | ||
1087 | /* Some power changes may have been made during the calibration. | 1087 | /* Some power changes may have been made during the calibration. |
1088 | * Update and commit the RXON | 1088 | * Update and commit the RXON |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 057f95233567..64cf439035c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | 34 | ||
35 | #include "iwl-wifi.h" | ||
35 | #include "iwl-dev.h" | 36 | #include "iwl-dev.h" |
36 | #include "iwl-core.h" | 37 | #include "iwl-core.h" |
37 | #include "iwl-io.h" | 38 | #include "iwl-io.h" |
@@ -150,7 +151,7 @@ static u32 eeprom_indirect_address(const struct iwl_shared *shrd, u32 address) | |||
150 | const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset) | 151 | const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset) |
151 | { | 152 | { |
152 | u32 address = eeprom_indirect_address(shrd, offset); | 153 | u32 address = eeprom_indirect_address(shrd, offset); |
153 | BUG_ON(address >= shrd->priv->cfg->base_params->eeprom_size); | 154 | BUG_ON(address >= shrd->cfg->base_params->eeprom_size); |
154 | return &shrd->eeprom[address]; | 155 | return &shrd->eeprom[address]; |
155 | } | 156 | } |
156 | 157 | ||
@@ -232,7 +233,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
232 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | | 233 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | |
233 | IWL_PAN_SCD_MULTICAST_MSK; | 234 | IWL_PAN_SCD_MULTICAST_MSK; |
234 | 235 | ||
235 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | 236 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) |
236 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; | 237 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; |
237 | 238 | ||
238 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", | 239 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", |
@@ -374,15 +375,15 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
374 | BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != | 375 | BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != |
375 | sizeof(basic.bt3_lookup_table)); | 376 | sizeof(basic.bt3_lookup_table)); |
376 | 377 | ||
377 | if (priv->cfg->bt_params) { | 378 | if (cfg(priv)->bt_params) { |
378 | if (priv->cfg->bt_params->bt_session_2) { | 379 | if (cfg(priv)->bt_params->bt_session_2) { |
379 | bt_cmd_2000.prio_boost = cpu_to_le32( | 380 | bt_cmd_2000.prio_boost = cpu_to_le32( |
380 | priv->cfg->bt_params->bt_prio_boost); | 381 | cfg(priv)->bt_params->bt_prio_boost); |
381 | bt_cmd_2000.tx_prio_boost = 0; | 382 | bt_cmd_2000.tx_prio_boost = 0; |
382 | bt_cmd_2000.rx_prio_boost = 0; | 383 | bt_cmd_2000.rx_prio_boost = 0; |
383 | } else { | 384 | } else { |
384 | bt_cmd_6000.prio_boost = | 385 | bt_cmd_6000.prio_boost = |
385 | priv->cfg->bt_params->bt_prio_boost; | 386 | cfg(priv)->bt_params->bt_prio_boost; |
386 | bt_cmd_6000.tx_prio_boost = 0; | 387 | bt_cmd_6000.tx_prio_boost = 0; |
387 | bt_cmd_6000.rx_prio_boost = 0; | 388 | bt_cmd_6000.rx_prio_boost = 0; |
388 | } | 389 | } |
@@ -430,7 +431,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
430 | priv->bt_full_concurrent ? | 431 | priv->bt_full_concurrent ? |
431 | "full concurrency" : "3-wire"); | 432 | "full concurrency" : "3-wire"); |
432 | 433 | ||
433 | if (priv->cfg->bt_params->bt_session_2) { | 434 | if (cfg(priv)->bt_params->bt_session_2) { |
434 | memcpy(&bt_cmd_2000.basic, &basic, | 435 | memcpy(&bt_cmd_2000.basic, &basic, |
435 | sizeof(basic)); | 436 | sizeof(basic)); |
436 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, | 437 | ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, |
@@ -799,8 +800,8 @@ static bool is_single_rx_stream(struct iwl_priv *priv) | |||
799 | */ | 800 | */ |
800 | static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) | 801 | static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) |
801 | { | 802 | { |
802 | if (priv->cfg->bt_params && | 803 | if (cfg(priv)->bt_params && |
803 | priv->cfg->bt_params->advanced_bt_coexist && | 804 | cfg(priv)->bt_params->advanced_bt_coexist && |
804 | (priv->bt_full_concurrent || | 805 | (priv->bt_full_concurrent || |
805 | priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { | 806 | priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { |
806 | /* | 807 | /* |
@@ -871,8 +872,8 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
871 | else | 872 | else |
872 | active_chains = hw_params(priv).valid_rx_ant; | 873 | active_chains = hw_params(priv).valid_rx_ant; |
873 | 874 | ||
874 | if (priv->cfg->bt_params && | 875 | if (cfg(priv)->bt_params && |
875 | priv->cfg->bt_params->advanced_bt_coexist && | 876 | cfg(priv)->bt_params->advanced_bt_coexist && |
876 | (priv->bt_full_concurrent || | 877 | (priv->bt_full_concurrent || |
877 | priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { | 878 | priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { |
878 | /* | 879 | /* |
@@ -1158,7 +1159,7 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1158 | * since the uCode will add 0x10 before using the value. | 1159 | * since the uCode will add 0x10 before using the value. |
1159 | */ | 1160 | */ |
1160 | for (i = 0; i < IWL_MAX_TID_COUNT; i++) { | 1161 | for (i = 0; i < IWL_MAX_TID_COUNT; i++) { |
1161 | seq = priv->shrd->tid_data[IWL_AP_ID][i].seq_number; | 1162 | seq = priv->tid_data[IWL_AP_ID][i].seq_number; |
1162 | seq -= 0x10; | 1163 | seq -= 0x10; |
1163 | wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq); | 1164 | wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq); |
1164 | } | 1165 | } |
@@ -1195,7 +1196,7 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1195 | 1196 | ||
1196 | priv->shrd->wowlan = true; | 1197 | priv->shrd->wowlan = true; |
1197 | 1198 | ||
1198 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); | 1199 | ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN); |
1199 | if (ret) | 1200 | if (ret) |
1200 | goto out; | 1201 | goto out; |
1201 | 1202 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index a23835a7797a..334b5ae8fdd4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -1086,7 +1086,7 @@ done: | |||
1086 | (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) | 1086 | (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) |
1087 | rs_program_fix_rate(priv, lq_sta); | 1087 | rs_program_fix_rate(priv, lq_sta); |
1088 | #endif | 1088 | #endif |
1089 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) | 1089 | if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist) |
1090 | rs_bt_update_lq(priv, ctx, lq_sta); | 1090 | rs_bt_update_lq(priv, ctx, lq_sta); |
1091 | } | 1091 | } |
1092 | 1092 | ||
@@ -2273,7 +2273,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2273 | tid = rs_tl_add_packet(lq_sta, hdr); | 2273 | tid = rs_tl_add_packet(lq_sta, hdr); |
2274 | if ((tid != IWL_MAX_TID_COUNT) && | 2274 | if ((tid != IWL_MAX_TID_COUNT) && |
2275 | (lq_sta->tx_agg_tid_en & (1 << tid))) { | 2275 | (lq_sta->tx_agg_tid_en & (1 << tid))) { |
2276 | tid_data = &priv->shrd->tid_data[lq_sta->lq.sta_id][tid]; | 2276 | tid_data = &priv->tid_data[lq_sta->lq.sta_id][tid]; |
2277 | if (tid_data->agg.state == IWL_AGG_OFF) | 2277 | if (tid_data->agg.state == IWL_AGG_OFF) |
2278 | lq_sta->is_agg = 0; | 2278 | lq_sta->is_agg = 0; |
2279 | else | 2279 | else |
@@ -2645,8 +2645,7 @@ lq_update: | |||
2645 | (lq_sta->tx_agg_tid_en & (1 << tid)) && | 2645 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
2646 | (tid != IWL_MAX_TID_COUNT)) { | 2646 | (tid != IWL_MAX_TID_COUNT)) { |
2647 | u8 sta_id = lq_sta->lq.sta_id; | 2647 | u8 sta_id = lq_sta->lq.sta_id; |
2648 | tid_data = | 2648 | tid_data = &priv->tid_data[sta_id][tid]; |
2649 | &priv->shrd->tid_data[sta_id][tid]; | ||
2650 | if (tid_data->agg.state == IWL_AGG_OFF) { | 2649 | if (tid_data->agg.state == IWL_AGG_OFF) { |
2651 | IWL_DEBUG_RATE(priv, | 2650 | IWL_DEBUG_RATE(priv, |
2652 | "try to aggregate tid %d\n", | 2651 | "try to aggregate tid %d\n", |
@@ -3055,11 +3054,11 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
3055 | * overwrite if needed, pass aggregation time limit | 3054 | * overwrite if needed, pass aggregation time limit |
3056 | * to uCode in uSec | 3055 | * to uCode in uSec |
3057 | */ | 3056 | */ |
3058 | if (priv && priv->cfg->bt_params && | 3057 | if (priv && cfg(priv)->bt_params && |
3059 | priv->cfg->bt_params->agg_time_limit && | 3058 | cfg(priv)->bt_params->agg_time_limit && |
3060 | priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) | 3059 | priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) |
3061 | lq_cmd->agg_params.agg_time_limit = | 3060 | lq_cmd->agg_params.agg_time_limit = |
3062 | cpu_to_le16(priv->cfg->bt_params->agg_time_limit); | 3061 | cpu_to_le16(cfg(priv)->bt_params->agg_time_limit); |
3063 | } | 3062 | } |
3064 | 3063 | ||
3065 | static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 3064 | static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 9001c23f27bb..b22b2976f899 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -318,7 +318,7 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv, | |||
318 | unsigned int msecs) | 318 | unsigned int msecs) |
319 | { | 319 | { |
320 | int delta; | 320 | int delta; |
321 | int threshold = priv->cfg->base_params->plcp_delta_threshold; | 321 | int threshold = cfg(priv)->base_params->plcp_delta_threshold; |
322 | 322 | ||
323 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | 323 | if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { |
324 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | 324 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); |
@@ -583,8 +583,8 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
583 | iwlagn_rx_calc_noise(priv); | 583 | iwlagn_rx_calc_noise(priv); |
584 | queue_work(priv->shrd->workqueue, &priv->run_time_calib_work); | 584 | queue_work(priv->shrd->workqueue, &priv->run_time_calib_work); |
585 | } | 585 | } |
586 | if (priv->cfg->lib->temperature && change) | 586 | if (cfg(priv)->lib->temperature && change) |
587 | priv->cfg->lib->temperature(priv); | 587 | cfg(priv)->lib->temperature(priv); |
588 | return 0; | 588 | return 0; |
589 | } | 589 | } |
590 | 590 | ||
@@ -1136,8 +1136,8 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
1136 | init_waitqueue_head(&priv->shrd->notif_waitq); | 1136 | init_waitqueue_head(&priv->shrd->notif_waitq); |
1137 | 1137 | ||
1138 | /* Set up BT Rx handlers */ | 1138 | /* Set up BT Rx handlers */ |
1139 | if (priv->cfg->lib->bt_rx_handler_setup) | 1139 | if (cfg(priv)->lib->bt_rx_handler_setup) |
1140 | priv->cfg->lib->bt_rx_handler_setup(priv); | 1140 | cfg(priv)->lib->bt_rx_handler_setup(priv); |
1141 | 1141 | ||
1142 | } | 1142 | } |
1143 | 1143 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index d21f535a3b4f..1c6659416621 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -296,9 +296,9 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, | |||
296 | } | 296 | } |
297 | 297 | ||
298 | if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION && | 298 | if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION && |
299 | priv->cfg->ht_params && priv->cfg->ht_params->smps_mode) | 299 | cfg(priv)->ht_params && cfg(priv)->ht_params->smps_mode) |
300 | ieee80211_request_smps(ctx->vif, | 300 | ieee80211_request_smps(ctx->vif, |
301 | priv->cfg->ht_params->smps_mode); | 301 | cfg(priv)->ht_params->smps_mode); |
302 | 302 | ||
303 | return 0; | 303 | return 0; |
304 | } | 304 | } |
@@ -445,8 +445,8 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
445 | * force CTS-to-self frames protection if RTS-CTS is not preferred | 445 | * force CTS-to-self frames protection if RTS-CTS is not preferred |
446 | * one aggregation protection method | 446 | * one aggregation protection method |
447 | */ | 447 | */ |
448 | if (!(priv->cfg->ht_params && | 448 | if (!(cfg(priv)->ht_params && |
449 | priv->cfg->ht_params->use_rts_for_aggregation)) | 449 | cfg(priv)->ht_params->use_rts_for_aggregation)) |
450 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; | 450 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; |
451 | 451 | ||
452 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || | 452 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 63d948d21c04..7353826095f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -130,25 +130,15 @@ int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
130 | return iwl_process_add_sta_resp(priv, addsta, pkt); | 130 | return iwl_process_add_sta_resp(priv, addsta, pkt); |
131 | } | 131 | } |
132 | 132 | ||
133 | static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | ||
134 | { | ||
135 | u16 size = (u16)sizeof(struct iwl_addsta_cmd); | ||
136 | struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data; | ||
137 | memcpy(addsta, cmd, size); | ||
138 | /* resrved in agn */ | ||
139 | addsta->legacy_reserved = cpu_to_le16(0); | ||
140 | return size; | ||
141 | } | ||
142 | |||
143 | int iwl_send_add_sta(struct iwl_priv *priv, | 133 | int iwl_send_add_sta(struct iwl_priv *priv, |
144 | struct iwl_addsta_cmd *sta, u8 flags) | 134 | struct iwl_addsta_cmd *sta, u8 flags) |
145 | { | 135 | { |
146 | int ret = 0; | 136 | int ret = 0; |
147 | u8 data[sizeof(*sta)]; | ||
148 | struct iwl_host_cmd cmd = { | 137 | struct iwl_host_cmd cmd = { |
149 | .id = REPLY_ADD_STA, | 138 | .id = REPLY_ADD_STA, |
150 | .flags = flags, | 139 | .flags = flags, |
151 | .data = { data, }, | 140 | .data = { sta, }, |
141 | .len = { sizeof(*sta), }, | ||
152 | }; | 142 | }; |
153 | u8 sta_id __maybe_unused = sta->sta.sta_id; | 143 | u8 sta_id __maybe_unused = sta->sta.sta_id; |
154 | 144 | ||
@@ -160,7 +150,6 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
160 | might_sleep(); | 150 | might_sleep(); |
161 | } | 151 | } |
162 | 152 | ||
163 | cmd.len[0] = iwlagn_build_addsta_hcmd(sta, data); | ||
164 | ret = iwl_trans_send_cmd(trans(priv), &cmd); | 153 | ret = iwl_trans_send_cmd(trans(priv), &cmd); |
165 | 154 | ||
166 | if (ret || (flags & CMD_ASYNC)) | 155 | if (ret || (flags & CMD_ASYNC)) |
@@ -463,6 +452,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | |||
463 | const u8 *addr) | 452 | const u8 *addr) |
464 | { | 453 | { |
465 | unsigned long flags; | 454 | unsigned long flags; |
455 | u8 tid; | ||
466 | 456 | ||
467 | if (!iwl_is_ready(priv->shrd)) { | 457 | if (!iwl_is_ready(priv->shrd)) { |
468 | IWL_DEBUG_INFO(priv, | 458 | IWL_DEBUG_INFO(priv, |
@@ -501,6 +491,10 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, | |||
501 | priv->stations[sta_id].lq = NULL; | 491 | priv->stations[sta_id].lq = NULL; |
502 | } | 492 | } |
503 | 493 | ||
494 | for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) | ||
495 | memset(&priv->tid_data[sta_id][tid], 0, | ||
496 | sizeof(priv->tid_data[sta_id][tid])); | ||
497 | |||
504 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 498 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
505 | 499 | ||
506 | priv->num_stations--; | 500 | priv->num_stations--; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index c27180a73351..b0dff7a753a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c | |||
@@ -633,7 +633,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) | |||
633 | INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); | 633 | INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); |
634 | INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); | 634 | INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); |
635 | 635 | ||
636 | if (priv->cfg->base_params->adv_thermal_throttle) { | 636 | if (cfg(priv)->base_params->adv_thermal_throttle) { |
637 | IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); | 637 | IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); |
638 | tt->restriction = kcalloc(IWL_TI_STATE_MAX, | 638 | tt->restriction = kcalloc(IWL_TI_STATE_MAX, |
639 | sizeof(struct iwl_tt_restriction), | 639 | sizeof(struct iwl_tt_restriction), |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 81754cddba73..c664c2726553 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -74,8 +74,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, | |||
74 | else if (ieee80211_is_back_req(fc)) | 74 | else if (ieee80211_is_back_req(fc)) |
75 | tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; | 75 | tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; |
76 | else if (info->band == IEEE80211_BAND_2GHZ && | 76 | else if (info->band == IEEE80211_BAND_2GHZ && |
77 | priv->cfg->bt_params && | 77 | cfg(priv)->bt_params && |
78 | priv->cfg->bt_params->advanced_bt_coexist && | 78 | cfg(priv)->bt_params->advanced_bt_coexist && |
79 | (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || | 79 | (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || |
80 | ieee80211_is_reassoc_req(fc) || | 80 | ieee80211_is_reassoc_req(fc) || |
81 | skb->protocol == cpu_to_be16(ETH_P_PAE))) | 81 | skb->protocol == cpu_to_be16(ETH_P_PAE))) |
@@ -191,8 +191,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
191 | rate_flags |= RATE_MCS_CCK_MSK; | 191 | rate_flags |= RATE_MCS_CCK_MSK; |
192 | 192 | ||
193 | /* Set up antennas */ | 193 | /* Set up antennas */ |
194 | if (priv->cfg->bt_params && | 194 | if (cfg(priv)->bt_params && |
195 | priv->cfg->bt_params->advanced_bt_coexist && | 195 | cfg(priv)->bt_params->advanced_bt_coexist && |
196 | priv->bt_full_concurrent) { | 196 | priv->bt_full_concurrent) { |
197 | /* operated as 1x1 in full concurrency mode */ | 197 | /* operated as 1x1 in full concurrency mode */ |
198 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 198 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
@@ -262,8 +262,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
262 | 262 | ||
263 | __le16 fc; | 263 | __le16 fc; |
264 | u8 hdr_len; | 264 | u8 hdr_len; |
265 | u16 len; | 265 | u16 len, seq_number = 0; |
266 | u8 sta_id; | 266 | u8 sta_id, tid = IWL_MAX_TID_COUNT; |
267 | unsigned long flags; | 267 | unsigned long flags; |
268 | bool is_agg = false; | 268 | bool is_agg = false; |
269 | 269 | ||
@@ -368,9 +368,51 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
368 | info->driver_data[0] = ctx; | 368 | info->driver_data[0] = ctx; |
369 | info->driver_data[1] = dev_cmd; | 369 | info->driver_data[1] = dev_cmd; |
370 | 370 | ||
371 | if (iwl_trans_tx(trans(priv), skb, dev_cmd, ctx->ctxid, sta_id)) | 371 | if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { |
372 | u8 *qc = NULL; | ||
373 | struct iwl_tid_data *tid_data; | ||
374 | qc = ieee80211_get_qos_ctl(hdr); | ||
375 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
376 | if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) | ||
377 | goto drop_unlock_sta; | ||
378 | tid_data = &priv->tid_data[sta_id][tid]; | ||
379 | |||
380 | /* aggregation is on for this <sta,tid> */ | ||
381 | if (info->flags & IEEE80211_TX_CTL_AMPDU && | ||
382 | tid_data->agg.state != IWL_AGG_ON) { | ||
383 | IWL_ERR(priv, "TX_CTL_AMPDU while not in AGG:" | ||
384 | " Tx flags = 0x%08x, agg.state = %d", | ||
385 | info->flags, tid_data->agg.state); | ||
386 | IWL_ERR(priv, "sta_id = %d, tid = %d seq_num = %d", | ||
387 | sta_id, tid, SEQ_TO_SN(tid_data->seq_number)); | ||
388 | goto drop_unlock_sta; | ||
389 | } | ||
390 | |||
391 | /* We can receive packets from the stack in IWL_AGG_{ON,OFF} | ||
392 | * only. Check this here. | ||
393 | */ | ||
394 | if (WARN_ONCE(tid_data->agg.state != IWL_AGG_ON && | ||
395 | tid_data->agg.state != IWL_AGG_OFF, | ||
396 | "Tx while agg.state = %d", tid_data->agg.state)) | ||
397 | goto drop_unlock_sta; | ||
398 | |||
399 | seq_number = tid_data->seq_number; | ||
400 | seq_number &= IEEE80211_SCTL_SEQ; | ||
401 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
402 | hdr->seq_ctrl |= cpu_to_le16(seq_number); | ||
403 | seq_number += 0x10; | ||
404 | } | ||
405 | |||
406 | /* Copy MAC header from skb into command buffer */ | ||
407 | memcpy(tx_cmd->hdr, hdr, hdr_len); | ||
408 | |||
409 | if (iwl_trans_tx(trans(priv), skb, dev_cmd, ctx->ctxid, sta_id, tid)) | ||
372 | goto drop_unlock_sta; | 410 | goto drop_unlock_sta; |
373 | 411 | ||
412 | if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc) && | ||
413 | !ieee80211_has_morefrags(fc)) | ||
414 | priv->tid_data[sta_id][tid].seq_number = seq_number; | ||
415 | |||
374 | spin_unlock(&priv->shrd->sta_lock); | 416 | spin_unlock(&priv->shrd->sta_lock); |
375 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 417 | spin_unlock_irqrestore(&priv->shrd->lock, flags); |
376 | 418 | ||
@@ -395,10 +437,81 @@ drop_unlock_priv: | |||
395 | return -1; | 437 | return -1; |
396 | } | 438 | } |
397 | 439 | ||
440 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | ||
441 | struct ieee80211_sta *sta, u16 tid) | ||
442 | { | ||
443 | struct iwl_tid_data *tid_data; | ||
444 | unsigned long flags; | ||
445 | int sta_id; | ||
446 | |||
447 | sta_id = iwl_sta_id(sta); | ||
448 | |||
449 | if (sta_id == IWL_INVALID_STATION) { | ||
450 | IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); | ||
451 | return -ENXIO; | ||
452 | } | ||
453 | |||
454 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | ||
455 | |||
456 | tid_data = &priv->tid_data[sta_id][tid]; | ||
457 | |||
458 | switch (priv->tid_data[sta_id][tid].agg.state) { | ||
459 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | ||
460 | /* | ||
461 | * This can happen if the peer stops aggregation | ||
462 | * again before we've had a chance to drain the | ||
463 | * queue we selected previously, i.e. before the | ||
464 | * session was really started completely. | ||
465 | */ | ||
466 | IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); | ||
467 | goto turn_off; | ||
468 | case IWL_AGG_ON: | ||
469 | break; | ||
470 | default: | ||
471 | IWL_WARN(priv, "Stopping AGG while state not ON " | ||
472 | "or starting for %d on %d (%d)\n", sta_id, tid, | ||
473 | priv->tid_data[sta_id][tid].agg.state); | ||
474 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); | ||
479 | |||
480 | /* There are still packets for this RA / TID in the HW */ | ||
481 | if (tid_data->agg.ssn != tid_data->next_reclaimed) { | ||
482 | IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " | ||
483 | "next_recl = %d", | ||
484 | tid_data->agg.ssn, | ||
485 | tid_data->next_reclaimed); | ||
486 | priv->tid_data[sta_id][tid].agg.state = | ||
487 | IWL_EMPTYING_HW_QUEUE_DELBA; | ||
488 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d", | ||
493 | tid_data->agg.ssn); | ||
494 | turn_off: | ||
495 | priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | ||
496 | |||
497 | /* do not restore/save irqs */ | ||
498 | spin_unlock(&priv->shrd->sta_lock); | ||
499 | spin_lock(&priv->shrd->lock); | ||
500 | |||
501 | iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); | ||
502 | |||
503 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | ||
504 | |||
505 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
506 | |||
507 | return 0; | ||
508 | } | ||
509 | |||
398 | int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | 510 | int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, |
399 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 511 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
400 | { | 512 | { |
401 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 513 | struct iwl_tid_data *tid_data; |
514 | unsigned long flags; | ||
402 | int sta_id; | 515 | int sta_id; |
403 | int ret; | 516 | int ret; |
404 | 517 | ||
@@ -413,7 +526,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
413 | if (unlikely(tid >= IWL_MAX_TID_COUNT)) | 526 | if (unlikely(tid >= IWL_MAX_TID_COUNT)) |
414 | return -EINVAL; | 527 | return -EINVAL; |
415 | 528 | ||
416 | if (priv->shrd->tid_data[sta_id][tid].agg.state != IWL_AGG_OFF) { | 529 | if (priv->tid_data[sta_id][tid].agg.state != IWL_AGG_OFF) { |
417 | IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); | 530 | IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); |
418 | return -ENXIO; | 531 | return -ENXIO; |
419 | } | 532 | } |
@@ -422,27 +535,136 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
422 | if (ret) | 535 | if (ret) |
423 | return ret; | 536 | return ret; |
424 | 537 | ||
425 | ret = iwl_trans_tx_agg_alloc(trans(priv), vif_priv->ctx->ctxid, sta_id, | 538 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); |
426 | tid, ssn); | 539 | |
540 | tid_data = &priv->tid_data[sta_id][tid]; | ||
541 | tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); | ||
542 | |||
543 | *ssn = tid_data->agg.ssn; | ||
544 | |||
545 | ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid); | ||
546 | if (ret) { | ||
547 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
548 | return ret; | ||
549 | } | ||
550 | |||
551 | if (*ssn == tid_data->next_reclaimed) { | ||
552 | IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d", | ||
553 | tid_data->agg.ssn); | ||
554 | tid_data->agg.state = IWL_AGG_ON; | ||
555 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
556 | } else { | ||
557 | IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " | ||
558 | "next_reclaimed = %d", | ||
559 | tid_data->agg.ssn, | ||
560 | tid_data->next_reclaimed); | ||
561 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; | ||
562 | } | ||
563 | |||
564 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | ||
427 | 565 | ||
428 | return ret; | 566 | return ret; |
429 | } | 567 | } |
430 | 568 | ||
431 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | 569 | int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, |
432 | struct ieee80211_sta *sta, u16 tid) | 570 | struct ieee80211_sta *sta, u16 tid, u8 buf_size) |
433 | { | 571 | { |
434 | int sta_id; | 572 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; |
435 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 573 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
574 | unsigned long flags; | ||
575 | u16 ssn; | ||
436 | 576 | ||
437 | sta_id = iwl_sta_id(sta); | 577 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); |
438 | 578 | ||
439 | if (sta_id == IWL_INVALID_STATION) { | 579 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); |
440 | IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); | 580 | ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; |
441 | return -ENXIO; | 581 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); |
582 | |||
583 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid, | ||
584 | buf_size, ssn); | ||
585 | |||
586 | /* | ||
587 | * If the limit is 0, then it wasn't initialised yet, | ||
588 | * use the default. We can do that since we take the | ||
589 | * minimum below, and we don't want to go above our | ||
590 | * default due to hardware restrictions. | ||
591 | */ | ||
592 | if (sta_priv->max_agg_bufsize == 0) | ||
593 | sta_priv->max_agg_bufsize = | ||
594 | LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
595 | |||
596 | /* | ||
597 | * Even though in theory the peer could have different | ||
598 | * aggregation reorder buffer sizes for different sessions, | ||
599 | * our ucode doesn't allow for that and has a global limit | ||
600 | * for each station. Therefore, use the minimum of all the | ||
601 | * aggregation sessions and our default value. | ||
602 | */ | ||
603 | sta_priv->max_agg_bufsize = | ||
604 | min(sta_priv->max_agg_bufsize, buf_size); | ||
605 | |||
606 | if (cfg(priv)->ht_params && | ||
607 | cfg(priv)->ht_params->use_rts_for_aggregation) { | ||
608 | /* | ||
609 | * switch to RTS/CTS if it is the prefer protection | ||
610 | * method for HT traffic | ||
611 | */ | ||
612 | |||
613 | sta_priv->lq_sta.lq.general_params.flags |= | ||
614 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
442 | } | 615 | } |
616 | priv->agg_tids_count++; | ||
617 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
618 | priv->agg_tids_count); | ||
443 | 619 | ||
444 | return iwl_trans_tx_agg_disable(trans(priv), vif_priv->ctx->ctxid, | 620 | sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = |
445 | sta_id, tid); | 621 | sta_priv->max_agg_bufsize; |
622 | |||
623 | IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n", | ||
624 | sta->addr, tid); | ||
625 | |||
626 | return iwl_send_lq_cmd(priv, ctx, | ||
627 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
628 | } | ||
629 | |||
630 | static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) | ||
631 | { | ||
632 | struct iwl_tid_data *tid_data = &priv->tid_data[sta_id][tid]; | ||
633 | enum iwl_rxon_context_id ctx; | ||
634 | struct ieee80211_vif *vif; | ||
635 | u8 *addr; | ||
636 | |||
637 | lockdep_assert_held(&priv->shrd->sta_lock); | ||
638 | |||
639 | addr = priv->stations[sta_id].sta.sta.addr; | ||
640 | ctx = priv->stations[sta_id].ctxid; | ||
641 | vif = priv->contexts[ctx].vif; | ||
642 | |||
643 | switch (priv->tid_data[sta_id][tid].agg.state) { | ||
644 | case IWL_EMPTYING_HW_QUEUE_DELBA: | ||
645 | /* There are no packets for this RA / TID in the HW any more */ | ||
646 | if (tid_data->agg.ssn == tid_data->next_reclaimed) { | ||
647 | IWL_DEBUG_TX_QUEUES(priv, | ||
648 | "Can continue DELBA flow ssn = next_recl =" | ||
649 | " %d", tid_data->next_reclaimed); | ||
650 | iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); | ||
651 | tid_data->agg.state = IWL_AGG_OFF; | ||
652 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); | ||
653 | } | ||
654 | break; | ||
655 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | ||
656 | /* There are no packets for this RA / TID in the HW any more */ | ||
657 | if (tid_data->agg.ssn == tid_data->next_reclaimed) { | ||
658 | IWL_DEBUG_TX_QUEUES(priv, | ||
659 | "Can continue ADDBA flow ssn = next_recl =" | ||
660 | " %d", tid_data->next_reclaimed); | ||
661 | tid_data->agg.state = IWL_AGG_ON; | ||
662 | ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); | ||
663 | } | ||
664 | break; | ||
665 | default: | ||
666 | break; | ||
667 | } | ||
446 | } | 668 | } |
447 | 669 | ||
448 | static void iwlagn_non_agg_tx_status(struct iwl_priv *priv, | 670 | static void iwlagn_non_agg_tx_status(struct iwl_priv *priv, |
@@ -582,7 +804,7 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, | |||
582 | IWLAGN_TX_RES_TID_POS; | 804 | IWLAGN_TX_RES_TID_POS; |
583 | int sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> | 805 | int sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> |
584 | IWLAGN_TX_RES_RA_POS; | 806 | IWLAGN_TX_RES_RA_POS; |
585 | struct iwl_ht_agg *agg = &priv->shrd->tid_data[sta_id][tid].agg; | 807 | struct iwl_ht_agg *agg = &priv->tid_data[sta_id][tid].agg; |
586 | u32 status = le16_to_cpu(tx_resp->status.status); | 808 | u32 status = le16_to_cpu(tx_resp->status.status); |
587 | int i; | 809 | int i; |
588 | 810 | ||
@@ -598,8 +820,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, | |||
598 | * notification again. | 820 | * notification again. |
599 | */ | 821 | */ |
600 | if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && | 822 | if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && |
601 | priv->cfg->bt_params && | 823 | cfg(priv)->bt_params && |
602 | priv->cfg->bt_params->advanced_bt_coexist) { | 824 | cfg(priv)->bt_params->advanced_bt_coexist) { |
603 | IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n"); | 825 | IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n"); |
604 | } | 826 | } |
605 | 827 | ||
@@ -772,7 +994,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
772 | struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 994 | struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
773 | struct ieee80211_hdr *hdr; | 995 | struct ieee80211_hdr *hdr; |
774 | u32 status = le16_to_cpu(tx_resp->status.status); | 996 | u32 status = le16_to_cpu(tx_resp->status.status); |
775 | u32 ssn = iwlagn_get_scd_ssn(tx_resp); | 997 | u16 ssn = iwlagn_get_scd_ssn(tx_resp); |
776 | int tid; | 998 | int tid; |
777 | int sta_id; | 999 | int sta_id; |
778 | int freed; | 1000 | int freed; |
@@ -794,11 +1016,34 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, | |||
794 | iwl_rx_reply_tx_agg(priv, tx_resp); | 1016 | iwl_rx_reply_tx_agg(priv, tx_resp); |
795 | 1017 | ||
796 | if (tx_resp->frame_count == 1) { | 1018 | if (tx_resp->frame_count == 1) { |
797 | IWL_DEBUG_TX_REPLY(priv, "Q %d, ssn %d", txq_id, ssn); | 1019 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); |
1020 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); | ||
1021 | |||
1022 | if (is_agg) { | ||
1023 | /* If this is an aggregation queue, we can rely on the | ||
1024 | * ssn since the wifi sequence number corresponds to | ||
1025 | * the index in the TFD ring (%256). | ||
1026 | * The seq_ctl is the sequence control of the packet | ||
1027 | * to which this Tx response relates. But if there is a | ||
1028 | * hole in the bitmap of the BA we received, this Tx | ||
1029 | * response may allow to reclaim the hole and all the | ||
1030 | * subsequent packets that were already acked. | ||
1031 | * In that case, seq_ctl != ssn, and the next packet | ||
1032 | * to be reclaimed will be ssn and not seq_ctl. | ||
1033 | */ | ||
1034 | next_reclaimed = ssn; | ||
1035 | } | ||
1036 | |||
798 | __skb_queue_head_init(&skbs); | 1037 | __skb_queue_head_init(&skbs); |
1038 | priv->tid_data[sta_id][tid].next_reclaimed = next_reclaimed; | ||
1039 | |||
1040 | IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d", | ||
1041 | next_reclaimed); | ||
1042 | |||
799 | /*we can free until ssn % q.n_bd not inclusive */ | 1043 | /*we can free until ssn % q.n_bd not inclusive */ |
800 | iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id, | 1044 | WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id, |
801 | ssn, status, &skbs); | 1045 | ssn, status, &skbs)); |
1046 | iwlagn_check_ratid_empty(priv, sta_id, tid); | ||
802 | freed = 0; | 1047 | freed = 0; |
803 | while (!skb_queue_empty(&skbs)) { | 1048 | while (!skb_queue_empty(&skbs)) { |
804 | skb = __skb_dequeue(&skbs); | 1049 | skb = __skb_dequeue(&skbs); |
@@ -893,27 +1138,24 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
893 | 1138 | ||
894 | sta_id = ba_resp->sta_id; | 1139 | sta_id = ba_resp->sta_id; |
895 | tid = ba_resp->tid; | 1140 | tid = ba_resp->tid; |
896 | agg = &priv->shrd->tid_data[sta_id][tid].agg; | 1141 | agg = &priv->tid_data[sta_id][tid].agg; |
897 | 1142 | ||
898 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); | 1143 | spin_lock_irqsave(&priv->shrd->sta_lock, flags); |
899 | 1144 | ||
900 | if (unlikely(agg->txq_id != scd_flow)) { | 1145 | if (unlikely(!agg->wait_for_ba)) { |
901 | /* | 1146 | if (unlikely(ba_resp->bitmap)) |
902 | * FIXME: this is a uCode bug which need to be addressed, | 1147 | IWL_ERR(priv, "Received BA when not expected\n"); |
903 | * log the information and return for now! | ||
904 | * since it is possible happen very often and in order | ||
905 | * not to fill the syslog, don't enable the logging by default | ||
906 | */ | ||
907 | IWL_DEBUG_TX_REPLY(priv, | ||
908 | "BA scd_flow %d does not match txq_id %d\n", | ||
909 | scd_flow, agg->txq_id); | ||
910 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1148 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); |
911 | return 0; | 1149 | return 0; |
912 | } | 1150 | } |
913 | 1151 | ||
914 | if (unlikely(!agg->wait_for_ba)) { | 1152 | __skb_queue_head_init(&reclaimed_skbs); |
915 | if (unlikely(ba_resp->bitmap)) | 1153 | |
916 | IWL_ERR(priv, "Received BA when not expected\n"); | 1154 | /* Release all TFDs before the SSN, i.e. all TFDs in front of |
1155 | * block-ack window (we assume that they've been successfully | ||
1156 | * transmitted ... if not, it's too late anyway). */ | ||
1157 | if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, | ||
1158 | ba_resp_scd_ssn, 0, &reclaimed_skbs)) { | ||
917 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); | 1159 | spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); |
918 | return 0; | 1160 | return 0; |
919 | } | 1161 | } |
@@ -925,7 +1167,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
925 | ba_resp->sta_id); | 1167 | ba_resp->sta_id); |
926 | IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, " | 1168 | IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, " |
927 | "scd_flow = %d, scd_ssn = %d\n", | 1169 | "scd_flow = %d, scd_ssn = %d\n", |
928 | ba_resp->tid, ba_resp->seq_ctl, | 1170 | ba_resp->tid, le16_to_cpu(ba_resp->seq_ctl), |
929 | (unsigned long long)le64_to_cpu(ba_resp->bitmap), | 1171 | (unsigned long long)le64_to_cpu(ba_resp->bitmap), |
930 | scd_flow, ba_resp_scd_ssn); | 1172 | scd_flow, ba_resp_scd_ssn); |
931 | 1173 | ||
@@ -946,13 +1188,9 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
946 | IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n", | 1188 | IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n", |
947 | ba_resp->txed, ba_resp->txed_2_done); | 1189 | ba_resp->txed, ba_resp->txed_2_done); |
948 | 1190 | ||
949 | __skb_queue_head_init(&reclaimed_skbs); | 1191 | priv->tid_data[sta_id][tid].next_reclaimed = ba_resp_scd_ssn; |
950 | 1192 | ||
951 | /* Release all TFDs before the SSN, i.e. all TFDs in front of | 1193 | iwlagn_check_ratid_empty(priv, sta_id, tid); |
952 | * block-ack window (we assume that they've been successfully | ||
953 | * transmitted ... if not, it's too late anyway). */ | ||
954 | iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, ba_resp_scd_ssn, | ||
955 | 0, &reclaimed_skbs); | ||
956 | freed = 0; | 1194 | freed = 0; |
957 | while (!skb_queue_empty(&reclaimed_skbs)) { | 1195 | while (!skb_queue_empty(&reclaimed_skbs)) { |
958 | 1196 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f5fe42dbb3b0..b5c7c5f0a753 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/div64.h> | 43 | #include <asm/div64.h> |
44 | 44 | ||
45 | #include "iwl-eeprom.h" | 45 | #include "iwl-eeprom.h" |
46 | #include "iwl-wifi.h" | ||
46 | #include "iwl-dev.h" | 47 | #include "iwl-dev.h" |
47 | #include "iwl-core.h" | 48 | #include "iwl-core.h" |
48 | #include "iwl-io.h" | 49 | #include "iwl-io.h" |
@@ -515,7 +516,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | |||
515 | 516 | ||
516 | static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) | 517 | static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) |
517 | { | 518 | { |
518 | const char *name_pre = priv->cfg->fw_name_pre; | 519 | const char *name_pre = cfg(priv)->fw_name_pre; |
519 | char tag[8]; | 520 | char tag[8]; |
520 | 521 | ||
521 | if (first) { | 522 | if (first) { |
@@ -524,14 +525,14 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) | |||
524 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | 525 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); |
525 | } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { | 526 | } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { |
526 | #endif | 527 | #endif |
527 | priv->fw_index = priv->cfg->ucode_api_max; | 528 | priv->fw_index = cfg(priv)->ucode_api_max; |
528 | sprintf(tag, "%d", priv->fw_index); | 529 | sprintf(tag, "%d", priv->fw_index); |
529 | } else { | 530 | } else { |
530 | priv->fw_index--; | 531 | priv->fw_index--; |
531 | sprintf(tag, "%d", priv->fw_index); | 532 | sprintf(tag, "%d", priv->fw_index); |
532 | } | 533 | } |
533 | 534 | ||
534 | if (priv->fw_index < priv->cfg->ucode_api_min) { | 535 | if (priv->fw_index < cfg(priv)->ucode_api_min) { |
535 | IWL_ERR(priv, "no suitable firmware found!\n"); | 536 | IWL_ERR(priv, "no suitable firmware found!\n"); |
536 | return -ENOENT; | 537 | return -ENOENT; |
537 | } | 538 | } |
@@ -836,9 +837,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
836 | struct iwl_ucode_header *ucode; | 837 | struct iwl_ucode_header *ucode; |
837 | int err; | 838 | int err; |
838 | struct iwlagn_firmware_pieces pieces; | 839 | struct iwlagn_firmware_pieces pieces; |
839 | const unsigned int api_max = priv->cfg->ucode_api_max; | 840 | const unsigned int api_max = cfg(priv)->ucode_api_max; |
840 | unsigned int api_ok = priv->cfg->ucode_api_ok; | 841 | unsigned int api_ok = cfg(priv)->ucode_api_ok; |
841 | const unsigned int api_min = priv->cfg->ucode_api_min; | 842 | const unsigned int api_min = cfg(priv)->ucode_api_min; |
842 | u32 api_ver; | 843 | u32 api_ver; |
843 | char buildstr[25]; | 844 | char buildstr[25]; |
844 | u32 build; | 845 | u32 build; |
@@ -1027,14 +1028,14 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1027 | priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | 1028 | priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; |
1028 | else | 1029 | else |
1029 | priv->init_evtlog_size = | 1030 | priv->init_evtlog_size = |
1030 | priv->cfg->base_params->max_event_log_size; | 1031 | cfg(priv)->base_params->max_event_log_size; |
1031 | priv->init_errlog_ptr = pieces.init_errlog_ptr; | 1032 | priv->init_errlog_ptr = pieces.init_errlog_ptr; |
1032 | priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | 1033 | priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; |
1033 | if (pieces.inst_evtlog_size) | 1034 | if (pieces.inst_evtlog_size) |
1034 | priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | 1035 | priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; |
1035 | else | 1036 | else |
1036 | priv->inst_evtlog_size = | 1037 | priv->inst_evtlog_size = |
1037 | priv->cfg->base_params->max_event_log_size; | 1038 | cfg(priv)->base_params->max_event_log_size; |
1038 | priv->inst_errlog_ptr = pieces.inst_errlog_ptr; | 1039 | priv->inst_errlog_ptr = pieces.inst_errlog_ptr; |
1039 | #ifndef CONFIG_IWLWIFI_P2P | 1040 | #ifndef CONFIG_IWLWIFI_P2P |
1040 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | 1041 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; |
@@ -1043,7 +1044,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1043 | priv->new_scan_threshold_behaviour = | 1044 | priv->new_scan_threshold_behaviour = |
1044 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | 1045 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); |
1045 | 1046 | ||
1046 | if (!(priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) | 1047 | if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) |
1047 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | 1048 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; |
1048 | 1049 | ||
1049 | /* | 1050 | /* |
@@ -1124,7 +1125,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
1124 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 1125 | spin_unlock_irqrestore(&priv->shrd->lock, flags); |
1125 | priv->thermal_throttle.ct_kill_toggle = false; | 1126 | priv->thermal_throttle.ct_kill_toggle = false; |
1126 | 1127 | ||
1127 | if (priv->cfg->base_params->support_ct_kill_exit) { | 1128 | if (cfg(priv)->base_params->support_ct_kill_exit) { |
1128 | adv_cmd.critical_temperature_enter = | 1129 | adv_cmd.critical_temperature_enter = |
1129 | cpu_to_le32(hw_params(priv).ct_kill_threshold); | 1130 | cpu_to_le32(hw_params(priv).ct_kill_threshold); |
1130 | adv_cmd.critical_temperature_exit = | 1131 | adv_cmd.critical_temperature_exit = |
@@ -1219,10 +1220,10 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
1219 | return -ERFKILL; | 1220 | return -ERFKILL; |
1220 | 1221 | ||
1221 | /* download priority table before any calibration request */ | 1222 | /* download priority table before any calibration request */ |
1222 | if (priv->cfg->bt_params && | 1223 | if (cfg(priv)->bt_params && |
1223 | priv->cfg->bt_params->advanced_bt_coexist) { | 1224 | cfg(priv)->bt_params->advanced_bt_coexist) { |
1224 | /* Configure Bluetooth device coexistence support */ | 1225 | /* Configure Bluetooth device coexistence support */ |
1225 | if (priv->cfg->bt_params->bt_sco_disable) | 1226 | if (cfg(priv)->bt_params->bt_sco_disable) |
1226 | priv->bt_enable_pspoll = false; | 1227 | priv->bt_enable_pspoll = false; |
1227 | else | 1228 | else |
1228 | priv->bt_enable_pspoll = true; | 1229 | priv->bt_enable_pspoll = true; |
@@ -1252,16 +1253,17 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
1252 | iwl_send_bt_config(priv); | 1253 | iwl_send_bt_config(priv); |
1253 | } | 1254 | } |
1254 | 1255 | ||
1255 | if (hw_params(priv).calib_rt_cfg) | 1256 | /* |
1256 | iwlagn_send_calib_cfg_rt(priv, | 1257 | * Perform runtime calibrations, including DC calibration. |
1257 | hw_params(priv).calib_rt_cfg); | 1258 | */ |
1259 | iwlagn_send_calib_cfg_rt(priv, IWL_CALIB_CFG_DC_IDX); | ||
1258 | 1260 | ||
1259 | ieee80211_wake_queues(priv->hw); | 1261 | ieee80211_wake_queues(priv->hw); |
1260 | 1262 | ||
1261 | priv->active_rate = IWL_RATES_MASK; | 1263 | priv->active_rate = IWL_RATES_MASK; |
1262 | 1264 | ||
1263 | /* Configure Tx antenna selection based on H/W config */ | 1265 | /* Configure Tx antenna selection based on H/W config */ |
1264 | iwlagn_send_tx_ant_config(priv, priv->cfg->valid_tx_ant); | 1266 | iwlagn_send_tx_ant_config(priv, cfg(priv)->valid_tx_ant); |
1265 | 1267 | ||
1266 | if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) { | 1268 | if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) { |
1267 | struct iwl_rxon_cmd *active_rxon = | 1269 | struct iwl_rxon_cmd *active_rxon = |
@@ -1330,9 +1332,9 @@ void __iwl_down(struct iwl_priv *priv) | |||
1330 | priv->bt_status = 0; | 1332 | priv->bt_status = 0; |
1331 | priv->cur_rssi_ctx = NULL; | 1333 | priv->cur_rssi_ctx = NULL; |
1332 | priv->bt_is_sco = 0; | 1334 | priv->bt_is_sco = 0; |
1333 | if (priv->cfg->bt_params) | 1335 | if (cfg(priv)->bt_params) |
1334 | priv->bt_traffic_load = | 1336 | priv->bt_traffic_load = |
1335 | priv->cfg->bt_params->bt_init_traffic_load; | 1337 | cfg(priv)->bt_params->bt_init_traffic_load; |
1336 | else | 1338 | else |
1337 | priv->bt_traffic_load = 0; | 1339 | priv->bt_traffic_load = 0; |
1338 | priv->bt_full_concurrent = false; | 1340 | priv->bt_full_concurrent = false; |
@@ -1514,8 +1516,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
1514 | 1516 | ||
1515 | iwl_setup_scan_deferred_work(priv); | 1517 | iwl_setup_scan_deferred_work(priv); |
1516 | 1518 | ||
1517 | if (priv->cfg->lib->bt_setup_deferred_work) | 1519 | if (cfg(priv)->lib->bt_setup_deferred_work) |
1518 | priv->cfg->lib->bt_setup_deferred_work(priv); | 1520 | cfg(priv)->lib->bt_setup_deferred_work(priv); |
1519 | 1521 | ||
1520 | init_timer(&priv->statistics_periodic); | 1522 | init_timer(&priv->statistics_periodic); |
1521 | priv->statistics_periodic.data = (unsigned long)priv; | 1523 | priv->statistics_periodic.data = (unsigned long)priv; |
@@ -1532,8 +1534,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
1532 | 1534 | ||
1533 | static void iwl_cancel_deferred_work(struct iwl_priv *priv) | 1535 | static void iwl_cancel_deferred_work(struct iwl_priv *priv) |
1534 | { | 1536 | { |
1535 | if (priv->cfg->lib->cancel_deferred_work) | 1537 | if (cfg(priv)->lib->cancel_deferred_work) |
1536 | priv->cfg->lib->cancel_deferred_work(priv); | 1538 | cfg(priv)->lib->cancel_deferred_work(priv); |
1537 | 1539 | ||
1538 | cancel_work_sync(&priv->run_time_calib_work); | 1540 | cancel_work_sync(&priv->run_time_calib_work); |
1539 | cancel_work_sync(&priv->beacon_update); | 1541 | cancel_work_sync(&priv->beacon_update); |
@@ -1602,8 +1604,8 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
1602 | iwl_init_scan_params(priv); | 1604 | iwl_init_scan_params(priv); |
1603 | 1605 | ||
1604 | /* init bt coex */ | 1606 | /* init bt coex */ |
1605 | if (priv->cfg->bt_params && | 1607 | if (cfg(priv)->bt_params && |
1606 | priv->cfg->bt_params->advanced_bt_coexist) { | 1608 | cfg(priv)->bt_params->advanced_bt_coexist) { |
1607 | priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; | 1609 | priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; |
1608 | priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; | 1610 | priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; |
1609 | priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; | 1611 | priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; |
@@ -1667,18 +1669,18 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
1667 | hw_params(priv).rx_page_order = | 1669 | hw_params(priv).rx_page_order = |
1668 | get_order(IWL_RX_BUF_SIZE_4K); | 1670 | get_order(IWL_RX_BUF_SIZE_4K); |
1669 | 1671 | ||
1670 | if (iwlagn_mod_params.disable_11n) | 1672 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) |
1671 | priv->cfg->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; | 1673 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; |
1672 | 1674 | ||
1673 | hw_params(priv).num_ampdu_queues = | 1675 | hw_params(priv).num_ampdu_queues = |
1674 | priv->cfg->base_params->num_of_ampdu_queues; | 1676 | cfg(priv)->base_params->num_of_ampdu_queues; |
1675 | hw_params(priv).shadow_reg_enable = | 1677 | hw_params(priv).shadow_reg_enable = |
1676 | priv->cfg->base_params->shadow_reg_enable; | 1678 | cfg(priv)->base_params->shadow_reg_enable; |
1677 | hw_params(priv).sku = priv->cfg->sku; | 1679 | hw_params(priv).sku = cfg(priv)->sku; |
1678 | hw_params(priv).wd_timeout = priv->cfg->base_params->wd_timeout; | 1680 | hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; |
1679 | 1681 | ||
1680 | /* Device-specific setup */ | 1682 | /* Device-specific setup */ |
1681 | return priv->cfg->lib->set_hw_params(priv); | 1683 | return cfg(priv)->lib->set_hw_params(priv); |
1682 | } | 1684 | } |
1683 | 1685 | ||
1684 | 1686 | ||
@@ -1757,7 +1759,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1757 | iwl_debug_config(priv); | 1759 | iwl_debug_config(priv); |
1758 | 1760 | ||
1759 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); | 1761 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); |
1760 | priv->cfg = cfg; | 1762 | cfg(priv) = cfg; |
1761 | 1763 | ||
1762 | /* is antenna coupling more than 35dB ? */ | 1764 | /* is antenna coupling more than 35dB ? */ |
1763 | priv->bt_ant_couple_ok = | 1765 | priv->bt_ant_couple_ok = |
@@ -1791,7 +1793,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1791 | ***********************/ | 1793 | ***********************/ |
1792 | hw_rev = iwl_hw_detect(priv); | 1794 | hw_rev = iwl_hw_detect(priv); |
1793 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", | 1795 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", |
1794 | priv->cfg->name, hw_rev); | 1796 | cfg(priv)->name, hw_rev); |
1795 | 1797 | ||
1796 | err = iwl_trans_request_irq(trans(priv)); | 1798 | err = iwl_trans_request_irq(trans(priv)); |
1797 | if (err) | 1799 | if (err) |
@@ -1915,12 +1917,7 @@ void __devexit iwl_remove(struct iwl_priv * priv) | |||
1915 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); | 1917 | set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); |
1916 | 1918 | ||
1917 | iwl_testmode_cleanup(priv); | 1919 | iwl_testmode_cleanup(priv); |
1918 | iwl_leds_exit(priv); | 1920 | iwlagn_mac_unregister(priv); |
1919 | |||
1920 | if (priv->mac80211_registered) { | ||
1921 | ieee80211_unregister_hw(priv->hw); | ||
1922 | priv->mac80211_registered = 0; | ||
1923 | } | ||
1924 | 1921 | ||
1925 | iwl_tt_exit(priv); | 1922 | iwl_tt_exit(priv); |
1926 | 1923 | ||
@@ -1999,8 +1996,9 @@ module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); | |||
1999 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1996 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
2000 | module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); | 1997 | module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); |
2001 | MODULE_PARM_DESC(queues_num, "number of hw queues."); | 1998 | MODULE_PARM_DESC(queues_num, "number of hw queues."); |
2002 | module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO); | 1999 | module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO); |
2003 | MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); | 2000 | MODULE_PARM_DESC(11n_disable, |
2001 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | ||
2004 | module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K, | 2002 | module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K, |
2005 | int, S_IRUGO); | 2003 | int, S_IRUGO); |
2006 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); | 2004 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index eb453ea41c41..f84fb3c53563 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -91,6 +91,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv); | |||
91 | struct ieee80211_hw *iwl_alloc_all(void); | 91 | struct ieee80211_hw *iwl_alloc_all(void); |
92 | int iwlagn_mac_setup_register(struct iwl_priv *priv, | 92 | int iwlagn_mac_setup_register(struct iwl_priv *priv, |
93 | struct iwlagn_ucode_capabilities *capa); | 93 | struct iwlagn_ucode_capabilities *capa); |
94 | void iwlagn_mac_unregister(struct iwl_priv *priv); | ||
94 | 95 | ||
95 | /* RXON */ | 96 | /* RXON */ |
96 | int iwlagn_set_pan_params(struct iwl_priv *priv); | 97 | int iwlagn_set_pan_params(struct iwl_priv *priv); |
@@ -108,11 +109,6 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, | |||
108 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 109 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
109 | struct iwl_rx_mem_buffer *rxb, | 110 | struct iwl_rx_mem_buffer *rxb, |
110 | struct iwl_device_cmd *cmd); | 111 | struct iwl_device_cmd *cmd); |
111 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); | ||
112 | void iwl_send_prio_tbl(struct iwl_trans *trans); | ||
113 | int iwlagn_run_init_ucode(struct iwl_priv *priv); | ||
114 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | ||
115 | enum iwl_ucode_type ucode_type); | ||
116 | 112 | ||
117 | /* lib */ | 113 | /* lib */ |
118 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 114 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
@@ -137,6 +133,8 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv); | |||
137 | int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); | 133 | int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); |
138 | int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | 134 | int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, |
139 | struct ieee80211_sta *sta, u16 tid, u16 *ssn); | 135 | struct ieee80211_sta *sta, u16 tid, u16 *ssn); |
136 | int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | ||
137 | struct ieee80211_sta *sta, u16 tid, u8 buf_size); | ||
140 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, | 138 | int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, |
141 | struct ieee80211_sta *sta, u16 tid); | 139 | struct ieee80211_sta *sta, u16 tid); |
142 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | 140 | int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, |
@@ -356,7 +354,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
356 | void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv); | 354 | void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv); |
357 | void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); | 355 | void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); |
358 | 356 | ||
359 | extern int iwlagn_init_alive_start(struct iwl_priv *priv); | ||
360 | extern int iwl_alive_start(struct iwl_priv *priv); | 357 | extern int iwl_alive_start(struct iwl_priv *priv); |
361 | /* svtool */ | 358 | /* svtool */ |
362 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | 359 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE |
diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 08b97594e305..940d5038b39c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h | |||
@@ -122,7 +122,8 @@ struct iwl_bus; | |||
122 | * struct iwl_bus_ops - bus specific operations | 122 | * struct iwl_bus_ops - bus specific operations |
123 | * @get_pm_support: must returns true if the bus can go to sleep | 123 | * @get_pm_support: must returns true if the bus can go to sleep |
124 | * @apm_config: will be called during the config of the APM | 124 | * @apm_config: will be called during the config of the APM |
125 | * @get_hw_id: prints the hw_id in the provided buffer | 125 | * @get_hw_id_string: prints the hw_id in the provided buffer |
126 | * @get_hw_id: get hw_id in u32 | ||
126 | * @write8: write a byte to register at offset ofs | 127 | * @write8: write a byte to register at offset ofs |
127 | * @write32: write a dword to register at offset ofs | 128 | * @write32: write a dword to register at offset ofs |
128 | * @wread32: read a dword at register at offset ofs | 129 | * @wread32: read a dword at register at offset ofs |
@@ -130,7 +131,8 @@ struct iwl_bus; | |||
130 | struct iwl_bus_ops { | 131 | struct iwl_bus_ops { |
131 | bool (*get_pm_support)(struct iwl_bus *bus); | 132 | bool (*get_pm_support)(struct iwl_bus *bus); |
132 | void (*apm_config)(struct iwl_bus *bus); | 133 | void (*apm_config)(struct iwl_bus *bus); |
133 | void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len); | 134 | void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); |
135 | u32 (*get_hw_id)(struct iwl_bus *bus); | ||
134 | void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); | 136 | void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); |
135 | void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); | 137 | void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); |
136 | u32 (*read32)(struct iwl_bus *bus, u32 ofs); | 138 | u32 (*read32)(struct iwl_bus *bus, u32 ofs); |
@@ -172,9 +174,15 @@ static inline void bus_apm_config(struct iwl_bus *bus) | |||
172 | bus->ops->apm_config(bus); | 174 | bus->ops->apm_config(bus); |
173 | } | 175 | } |
174 | 176 | ||
175 | static inline void bus_get_hw_id(struct iwl_bus *bus, char buf[], int buf_len) | 177 | static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], |
178 | int buf_len) | ||
176 | { | 179 | { |
177 | bus->ops->get_hw_id(bus, buf, buf_len); | 180 | bus->ops->get_hw_id_string(bus, buf, buf_len); |
181 | } | ||
182 | |||
183 | static inline u32 bus_get_hw_id(struct iwl_bus *bus) | ||
184 | { | ||
185 | return bus->ops->get_hw_id(bus); | ||
178 | } | 186 | } |
179 | 187 | ||
180 | static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val) | 188 | static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 3b6f48bfe0e3..7bcfa781e0b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -60,8 +60,8 @@ static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, | |||
60 | 60 | ||
61 | ht_info->ht_supported = true; | 61 | ht_info->ht_supported = true; |
62 | 62 | ||
63 | if (priv->cfg->ht_params && | 63 | if (cfg(priv)->ht_params && |
64 | priv->cfg->ht_params->ht_greenfield_support) | 64 | cfg(priv)->ht_params->ht_greenfield_support) |
65 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; | 65 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; |
66 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | 66 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; |
67 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | 67 | max_bit_rate = MAX_BIT_RATE_20_MHZ; |
@@ -76,11 +76,7 @@ static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, | |||
76 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | 76 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; |
77 | 77 | ||
78 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | 78 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; |
79 | if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_factor) | ||
80 | ht_info->ampdu_factor = priv->cfg->bt_params->ampdu_factor; | ||
81 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; | 79 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; |
82 | if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_density) | ||
83 | ht_info->ampdu_density = priv->cfg->bt_params->ampdu_density; | ||
84 | 80 | ||
85 | ht_info->mcs.rx_mask[0] = 0xFF; | 81 | ht_info->mcs.rx_mask[0] = 0xFF; |
86 | if (rx_chains_num >= 2) | 82 | if (rx_chains_num >= 2) |
@@ -141,7 +137,7 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
141 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | 137 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; |
142 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; | 138 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; |
143 | 139 | ||
144 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | 140 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) |
145 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | 141 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, |
146 | IEEE80211_BAND_5GHZ); | 142 | IEEE80211_BAND_5GHZ); |
147 | 143 | ||
@@ -151,7 +147,7 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
151 | sband->bitrates = rates; | 147 | sband->bitrates = rates; |
152 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; | 148 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; |
153 | 149 | ||
154 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | 150 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) |
155 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | 151 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, |
156 | IEEE80211_BAND_2GHZ); | 152 | IEEE80211_BAND_2GHZ); |
157 | 153 | ||
@@ -206,12 +202,12 @@ int iwl_init_geos(struct iwl_priv *priv) | |||
206 | priv->tx_power_next = max_tx_power; | 202 | priv->tx_power_next = max_tx_power; |
207 | 203 | ||
208 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | 204 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
209 | priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) { | 205 | cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { |
210 | char buf[32]; | 206 | char buf[32]; |
211 | bus_get_hw_id(bus(priv), buf, sizeof(buf)); | 207 | bus_get_hw_id_string(bus(priv), buf, sizeof(buf)); |
212 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | 208 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
213 | "Please send your %s to maintainer.\n", buf); | 209 | "Please send your %s to maintainer.\n", buf); |
214 | priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; | 210 | cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; |
215 | } | 211 | } |
216 | 212 | ||
217 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 213 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
@@ -966,9 +962,9 @@ int iwl_apm_init(struct iwl_priv *priv) | |||
966 | bus_apm_config(bus(priv)); | 962 | bus_apm_config(bus(priv)); |
967 | 963 | ||
968 | /* Configure analog phase-lock-loop before activating to D0A */ | 964 | /* Configure analog phase-lock-loop before activating to D0A */ |
969 | if (priv->cfg->base_params->pll_cfg_val) | 965 | if (cfg(priv)->base_params->pll_cfg_val) |
970 | iwl_set_bit(bus(priv), CSR_ANA_PLL_CFG, | 966 | iwl_set_bit(bus(priv), CSR_ANA_PLL_CFG, |
971 | priv->cfg->base_params->pll_cfg_val); | 967 | cfg(priv)->base_params->pll_cfg_val); |
972 | 968 | ||
973 | /* | 969 | /* |
974 | * Set "initialization complete" bit to move adapter from | 970 | * Set "initialization complete" bit to move adapter from |
@@ -1465,7 +1461,7 @@ void iwl_bg_watchdog(unsigned long data) | |||
1465 | if (iwl_is_rfkill(priv->shrd)) | 1461 | if (iwl_is_rfkill(priv->shrd)) |
1466 | return; | 1462 | return; |
1467 | 1463 | ||
1468 | timeout = priv->cfg->base_params->wd_timeout; | 1464 | timeout = cfg(priv)->base_params->wd_timeout; |
1469 | if (timeout == 0) | 1465 | if (timeout == 0) |
1470 | return; | 1466 | return; |
1471 | 1467 | ||
@@ -1490,11 +1486,11 @@ void iwl_bg_watchdog(unsigned long data) | |||
1490 | 1486 | ||
1491 | void iwl_setup_watchdog(struct iwl_priv *priv) | 1487 | void iwl_setup_watchdog(struct iwl_priv *priv) |
1492 | { | 1488 | { |
1493 | unsigned int timeout = priv->cfg->base_params->wd_timeout; | 1489 | unsigned int timeout = cfg(priv)->base_params->wd_timeout; |
1494 | 1490 | ||
1495 | if (!iwlagn_mod_params.wd_disable) { | 1491 | if (!iwlagn_mod_params.wd_disable) { |
1496 | /* use system default */ | 1492 | /* use system default */ |
1497 | if (timeout && !priv->cfg->base_params->wd_disable) | 1493 | if (timeout && !cfg(priv)->base_params->wd_disable) |
1498 | mod_timer(&priv->watchdog, | 1494 | mod_timer(&priv->watchdog, |
1499 | jiffies + | 1495 | jiffies + |
1500 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | 1496 | msecs_to_jiffies(IWL_WD_TICK(timeout))); |
@@ -1584,34 +1580,6 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, | |||
1584 | return cpu_to_le32(res); | 1580 | return cpu_to_le32(res); |
1585 | } | 1581 | } |
1586 | 1582 | ||
1587 | void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv, | ||
1588 | enum iwl_rxon_context_id ctx, | ||
1589 | u8 sta_id, u8 tid) | ||
1590 | { | ||
1591 | struct ieee80211_vif *vif; | ||
1592 | u8 *addr = priv->stations[sta_id].sta.sta.addr; | ||
1593 | |||
1594 | if (ctx == NUM_IWL_RXON_CTX) | ||
1595 | ctx = priv->stations[sta_id].ctxid; | ||
1596 | vif = priv->contexts[ctx].vif; | ||
1597 | |||
1598 | ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); | ||
1599 | } | ||
1600 | |||
1601 | void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv, | ||
1602 | enum iwl_rxon_context_id ctx, | ||
1603 | u8 sta_id, u8 tid) | ||
1604 | { | ||
1605 | struct ieee80211_vif *vif; | ||
1606 | u8 *addr = priv->stations[sta_id].sta.sta.addr; | ||
1607 | |||
1608 | if (ctx == NUM_IWL_RXON_CTX) | ||
1609 | ctx = priv->stations[sta_id].ctxid; | ||
1610 | vif = priv->contexts[ctx].vif; | ||
1611 | |||
1612 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); | ||
1613 | } | ||
1614 | |||
1615 | void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state) | 1583 | void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state) |
1616 | { | 1584 | { |
1617 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); | 1585 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); |
@@ -1619,8 +1587,7 @@ void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state) | |||
1619 | 1587 | ||
1620 | void iwl_nic_config(struct iwl_priv *priv) | 1588 | void iwl_nic_config(struct iwl_priv *priv) |
1621 | { | 1589 | { |
1622 | priv->cfg->lib->nic_config(priv); | 1590 | cfg(priv)->lib->nic_config(priv); |
1623 | |||
1624 | } | 1591 | } |
1625 | 1592 | ||
1626 | void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb) | 1593 | void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6da53a36c1be..7bf76ab94dd2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -142,8 +142,6 @@ struct iwl_base_params { | |||
142 | * @bt_init_traffic_load: specify initial bt traffic load | 142 | * @bt_init_traffic_load: specify initial bt traffic load |
143 | * @bt_prio_boost: default bt priority boost value | 143 | * @bt_prio_boost: default bt priority boost value |
144 | * @agg_time_limit: maximum number of uSec in aggregation | 144 | * @agg_time_limit: maximum number of uSec in aggregation |
145 | * @ampdu_factor: Maximum A-MPDU length factor | ||
146 | * @ampdu_density: Minimum A-MPDU spacing | ||
147 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | 145 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode |
148 | */ | 146 | */ |
149 | struct iwl_bt_params { | 147 | struct iwl_bt_params { |
@@ -151,8 +149,6 @@ struct iwl_bt_params { | |||
151 | u8 bt_init_traffic_load; | 149 | u8 bt_init_traffic_load; |
152 | u8 bt_prio_boost; | 150 | u8 bt_prio_boost; |
153 | u16 agg_time_limit; | 151 | u16 agg_time_limit; |
154 | u8 ampdu_factor; | ||
155 | u8 ampdu_density; | ||
156 | bool bt_sco_disable; | 152 | bool bt_sco_disable; |
157 | bool bt_session_2; | 153 | bool bt_session_2; |
158 | }; | 154 | }; |
@@ -165,77 +161,6 @@ struct iwl_ht_params { | |||
165 | enum ieee80211_smps_mode smps_mode; | 161 | enum ieee80211_smps_mode smps_mode; |
166 | }; | 162 | }; |
167 | 163 | ||
168 | /** | ||
169 | * struct iwl_cfg | ||
170 | * @name: Offical name of the device | ||
171 | * @fw_name_pre: Firmware filename prefix. The api version and extension | ||
172 | * (.ucode) will be added to filename before loading from disk. The | ||
173 | * filename is constructed as fw_name_pre<api>.ucode. | ||
174 | * @ucode_api_max: Highest version of uCode API supported by driver. | ||
175 | * @ucode_api_ok: oldest version of the uCode API that is OK to load | ||
176 | * without a warning, for use in transitions | ||
177 | * @ucode_api_min: Lowest version of uCode API supported by driver. | ||
178 | * @valid_tx_ant: valid transmit antenna | ||
179 | * @valid_rx_ant: valid receive antenna | ||
180 | * @sku: sku information from EEPROM | ||
181 | * @eeprom_ver: EEPROM version | ||
182 | * @eeprom_calib_ver: EEPROM calibration version | ||
183 | * @lib: pointer to the lib ops | ||
184 | * @additional_nic_config: additional nic configuration | ||
185 | * @base_params: pointer to basic parameters | ||
186 | * @ht_params: point to ht patameters | ||
187 | * @bt_params: pointer to bt parameters | ||
188 | * @pa_type: used by 6000 series only to identify the type of Power Amplifier | ||
189 | * @need_temp_offset_calib: need to perform temperature offset calibration | ||
190 | * @no_xtal_calib: some devices do not need crystal calibration data, | ||
191 | * don't send it to those | ||
192 | * @scan_antennas: available antenna for scan operation | ||
193 | * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) | ||
194 | * @adv_pm: advance power management | ||
195 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity | ||
196 | * @internal_wimax_coex: internal wifi/wimax combo device | ||
197 | * @iq_invert: I/Q inversion | ||
198 | * @temp_offset_v2: support v2 of temperature offset calibration | ||
199 | * | ||
200 | * We enable the driver to be backward compatible wrt API version. The | ||
201 | * driver specifies which APIs it supports (with @ucode_api_max being the | ||
202 | * highest and @ucode_api_min the lowest). Firmware will only be loaded if | ||
203 | * it has a supported API version. | ||
204 | * | ||
205 | * The ideal usage of this infrastructure is to treat a new ucode API | ||
206 | * release as a new hardware revision. | ||
207 | */ | ||
208 | struct iwl_cfg { | ||
209 | /* params specific to an individual device within a device family */ | ||
210 | const char *name; | ||
211 | const char *fw_name_pre; | ||
212 | const unsigned int ucode_api_max; | ||
213 | const unsigned int ucode_api_ok; | ||
214 | const unsigned int ucode_api_min; | ||
215 | u8 valid_tx_ant; | ||
216 | u8 valid_rx_ant; | ||
217 | u16 sku; | ||
218 | u16 eeprom_ver; | ||
219 | u16 eeprom_calib_ver; | ||
220 | const struct iwl_lib_ops *lib; | ||
221 | void (*additional_nic_config)(struct iwl_priv *priv); | ||
222 | /* params not likely to change within a device family */ | ||
223 | struct iwl_base_params *base_params; | ||
224 | /* params likely to change within a device family */ | ||
225 | struct iwl_ht_params *ht_params; | ||
226 | struct iwl_bt_params *bt_params; | ||
227 | enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ | ||
228 | const bool need_temp_offset_calib; /* if used set to true */ | ||
229 | const bool no_xtal_calib; | ||
230 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | ||
231 | enum iwl_led_mode led_mode; | ||
232 | const bool adv_pm; | ||
233 | const bool rx_with_siso_diversity; | ||
234 | const bool internal_wimax_coex; | ||
235 | const bool iq_invert; | ||
236 | const bool temp_offset_v2; | ||
237 | }; | ||
238 | |||
239 | /*************************** | 164 | /*************************** |
240 | * L i b * | 165 | * L i b * |
241 | ***************************/ | 166 | ***************************/ |
@@ -368,8 +293,8 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode( | |||
368 | 293 | ||
369 | static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) | 294 | static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) |
370 | { | 295 | { |
371 | return priv->cfg->bt_params && | 296 | return cfg(priv)->bt_params && |
372 | priv->cfg->bt_params->advanced_bt_coexist; | 297 | cfg(priv)->bt_params->advanced_bt_coexist; |
373 | } | 298 | } |
374 | 299 | ||
375 | static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) | 300 | static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 6bf6845e1a51..04a3343f4610 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -372,15 +372,13 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
372 | i, station->sta.sta.addr, | 372 | i, station->sta.sta.addr, |
373 | station->sta.station_flags_msk); | 373 | station->sta.station_flags_msk); |
374 | pos += scnprintf(buf + pos, bufsz - pos, | 374 | pos += scnprintf(buf + pos, bufsz - pos, |
375 | "TID\tseq_num\ttxq_id\ttfds\trate_n_flags\n"); | 375 | "TID\tseq_num\trate_n_flags\n"); |
376 | 376 | ||
377 | for (j = 0; j < IWL_MAX_TID_COUNT; j++) { | 377 | for (j = 0; j < IWL_MAX_TID_COUNT; j++) { |
378 | tid_data = &priv->shrd->tid_data[i][j]; | 378 | tid_data = &priv->tid_data[i][j]; |
379 | pos += scnprintf(buf + pos, bufsz - pos, | 379 | pos += scnprintf(buf + pos, bufsz - pos, |
380 | "%d:\t%#x\t%#x\t%u\t%#x", | 380 | "%d:\t%#x\t%#x", |
381 | j, tid_data->seq_number, | 381 | j, tid_data->seq_number, |
382 | tid_data->agg.txq_id, | ||
383 | tid_data->tfds_in_queue, | ||
384 | tid_data->agg.rate_n_flags); | 382 | tid_data->agg.rate_n_flags); |
385 | 383 | ||
386 | if (tid_data->agg.wait_for_ba) | 384 | if (tid_data->agg.wait_for_ba) |
@@ -408,7 +406,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
408 | const u8 *ptr; | 406 | const u8 *ptr; |
409 | char *buf; | 407 | char *buf; |
410 | u16 eeprom_ver; | 408 | u16 eeprom_ver; |
411 | size_t eeprom_len = priv->cfg->base_params->eeprom_size; | 409 | size_t eeprom_len = cfg(priv)->base_params->eeprom_size; |
412 | buf_size = 4 * eeprom_len + 256; | 410 | buf_size = 4 * eeprom_len + 256; |
413 | 411 | ||
414 | if (eeprom_len % 16) { | 412 | if (eeprom_len % 16) { |
@@ -1542,15 +1540,15 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1542 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { | 1540 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { |
1543 | pos += scnprintf(buf + pos, bufsz - pos, | 1541 | pos += scnprintf(buf + pos, bufsz - pos, |
1544 | "tx power: (1/2 dB step)\n"); | 1542 | "tx power: (1/2 dB step)\n"); |
1545 | if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) | 1543 | if ((cfg(priv)->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) |
1546 | pos += scnprintf(buf + pos, bufsz - pos, | 1544 | pos += scnprintf(buf + pos, bufsz - pos, |
1547 | fmt_hex, "antenna A:", | 1545 | fmt_hex, "antenna A:", |
1548 | tx->tx_power.ant_a); | 1546 | tx->tx_power.ant_a); |
1549 | if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) | 1547 | if ((cfg(priv)->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) |
1550 | pos += scnprintf(buf + pos, bufsz - pos, | 1548 | pos += scnprintf(buf + pos, bufsz - pos, |
1551 | fmt_hex, "antenna B:", | 1549 | fmt_hex, "antenna B:", |
1552 | tx->tx_power.ant_b); | 1550 | tx->tx_power.ant_b); |
1553 | if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) | 1551 | if ((cfg(priv)->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) |
1554 | pos += scnprintf(buf + pos, bufsz - pos, | 1552 | pos += scnprintf(buf + pos, bufsz - pos, |
1555 | fmt_hex, "antenna C:", | 1553 | fmt_hex, "antenna C:", |
1556 | tx->tx_power.ant_c); | 1554 | tx->tx_power.ant_c); |
@@ -2221,7 +2219,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, | |||
2221 | const size_t bufsz = sizeof(buf); | 2219 | const size_t bufsz = sizeof(buf); |
2222 | 2220 | ||
2223 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", | 2221 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", |
2224 | priv->cfg->base_params->plcp_delta_threshold); | 2222 | cfg(priv)->base_params->plcp_delta_threshold); |
2225 | 2223 | ||
2226 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2224 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
2227 | } | 2225 | } |
@@ -2243,10 +2241,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, | |||
2243 | return -EINVAL; | 2241 | return -EINVAL; |
2244 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || | 2242 | if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || |
2245 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) | 2243 | (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) |
2246 | priv->cfg->base_params->plcp_delta_threshold = | 2244 | cfg(priv)->base_params->plcp_delta_threshold = |
2247 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; | 2245 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; |
2248 | else | 2246 | else |
2249 | priv->cfg->base_params->plcp_delta_threshold = plcp; | 2247 | cfg(priv)->base_params->plcp_delta_threshold = plcp; |
2250 | return count; | 2248 | return count; |
2251 | } | 2249 | } |
2252 | 2250 | ||
@@ -2348,7 +2346,7 @@ static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, | |||
2348 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) | 2346 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) |
2349 | timeout = IWL_DEF_WD_TIMEOUT; | 2347 | timeout = IWL_DEF_WD_TIMEOUT; |
2350 | 2348 | ||
2351 | priv->cfg->base_params->wd_timeout = timeout; | 2349 | cfg(priv)->base_params->wd_timeout = timeout; |
2352 | iwl_setup_watchdog(priv); | 2350 | iwl_setup_watchdog(priv); |
2353 | return count; | 2351 | return count; |
2354 | } | 2352 | } |
@@ -2408,10 +2406,10 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, | |||
2408 | char buf[40]; | 2406 | char buf[40]; |
2409 | const size_t bufsz = sizeof(buf); | 2407 | const size_t bufsz = sizeof(buf); |
2410 | 2408 | ||
2411 | if (priv->cfg->ht_params) | 2409 | if (cfg(priv)->ht_params) |
2412 | pos += scnprintf(buf + pos, bufsz - pos, | 2410 | pos += scnprintf(buf + pos, bufsz - pos, |
2413 | "use %s for aggregation\n", | 2411 | "use %s for aggregation\n", |
2414 | (priv->cfg->ht_params->use_rts_for_aggregation) ? | 2412 | (cfg(priv)->ht_params->use_rts_for_aggregation) ? |
2415 | "rts/cts" : "cts-to-self"); | 2413 | "rts/cts" : "cts-to-self"); |
2416 | else | 2414 | else |
2417 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); | 2415 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); |
@@ -2428,7 +2426,7 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, | |||
2428 | int buf_size; | 2426 | int buf_size; |
2429 | int rts; | 2427 | int rts; |
2430 | 2428 | ||
2431 | if (!priv->cfg->ht_params) | 2429 | if (!cfg(priv)->ht_params) |
2432 | return -EINVAL; | 2430 | return -EINVAL; |
2433 | 2431 | ||
2434 | memset(buf, 0, sizeof(buf)); | 2432 | memset(buf, 0, sizeof(buf)); |
@@ -2438,9 +2436,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, | |||
2438 | if (sscanf(buf, "%d", &rts) != 1) | 2436 | if (sscanf(buf, "%d", &rts) != 1) |
2439 | return -EINVAL; | 2437 | return -EINVAL; |
2440 | if (rts) | 2438 | if (rts) |
2441 | priv->cfg->ht_params->use_rts_for_aggregation = true; | 2439 | cfg(priv)->ht_params->use_rts_for_aggregation = true; |
2442 | else | 2440 | else |
2443 | priv->cfg->ht_params->use_rts_for_aggregation = false; | 2441 | cfg(priv)->ht_params->use_rts_for_aggregation = false; |
2444 | return count; | 2442 | return count; |
2445 | } | 2443 | } |
2446 | 2444 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 69ecf6e2e658..e54a4d11e584 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -189,6 +189,69 @@ struct iwl_qos_info { | |||
189 | struct iwl_qosparam_cmd def_qos_parm; | 189 | struct iwl_qosparam_cmd def_qos_parm; |
190 | }; | 190 | }; |
191 | 191 | ||
192 | /** | ||
193 | * enum iwl_agg_state | ||
194 | * | ||
195 | * The state machine of the BA agreement establishment / tear down. | ||
196 | * These states relate to a specific RA / TID. | ||
197 | * | ||
198 | * @IWL_AGG_OFF: aggregation is not used | ||
199 | * @IWL_AGG_ON: aggregation session is up | ||
200 | * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the | ||
201 | * HW queue to be empty from packets for this RA /TID. | ||
202 | * @IWL_EMPTYING_HW_QUEUE_DELBA: tearing down a BA session - waiting for the | ||
203 | * HW queue to be empty from packets for this RA /TID. | ||
204 | */ | ||
205 | enum iwl_agg_state { | ||
206 | IWL_AGG_OFF = 0, | ||
207 | IWL_AGG_ON, | ||
208 | IWL_EMPTYING_HW_QUEUE_ADDBA, | ||
209 | IWL_EMPTYING_HW_QUEUE_DELBA, | ||
210 | }; | ||
211 | |||
212 | /** | ||
213 | * struct iwl_ht_agg - aggregation state machine | ||
214 | |||
215 | * This structs holds the states for the BA agreement establishment and tear | ||
216 | * down. It also holds the state during the BA session itself. This struct is | ||
217 | * duplicated for each RA / TID. | ||
218 | |||
219 | * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the | ||
220 | * Tx response (REPLY_TX), and the block ack notification | ||
221 | * (REPLY_COMPRESSED_BA). | ||
222 | * @state: state of the BA agreement establishment / tear down. | ||
223 | * @txq_id: Tx queue used by the BA session - used by the transport layer. | ||
224 | * Needed by the upper layer for debugfs only. | ||
225 | * @ssn: the first packet to be sent in AGG HW queue in Tx AGG start flow, or | ||
226 | * the first packet to be sent in legacy HW queue in Tx AGG stop flow. | ||
227 | * Basically when next_reclaimed reaches ssn, we can tell mac80211 that | ||
228 | * we are ready to finish the Tx AGG stop / start flow. | ||
229 | * @wait_for_ba: Expect block-ack before next Tx reply | ||
230 | */ | ||
231 | struct iwl_ht_agg { | ||
232 | u32 rate_n_flags; | ||
233 | enum iwl_agg_state state; | ||
234 | u16 txq_id; | ||
235 | u16 ssn; | ||
236 | bool wait_for_ba; | ||
237 | }; | ||
238 | |||
239 | /** | ||
240 | * struct iwl_tid_data - one for each RA / TID | ||
241 | |||
242 | * This structs holds the states for each RA / TID. | ||
243 | |||
244 | * @seq_number: the next WiFi sequence number to use | ||
245 | * @next_reclaimed: the WiFi sequence number of the next packet to be acked. | ||
246 | * This is basically (last acked packet++). | ||
247 | * @agg: aggregation state machine | ||
248 | */ | ||
249 | struct iwl_tid_data { | ||
250 | u16 seq_number; | ||
251 | u16 next_reclaimed; | ||
252 | struct iwl_ht_agg agg; | ||
253 | }; | ||
254 | |||
192 | /* | 255 | /* |
193 | * Structure should be accessed with sta_lock held. When station addition | 256 | * Structure should be accessed with sta_lock held. When station addition |
194 | * is in progress (IWL_STA_UCODE_INPROGRESS) it is possible to access only | 257 | * is in progress (IWL_STA_UCODE_INPROGRESS) it is possible to access only |
@@ -512,16 +575,6 @@ enum iwl_access_mode { | |||
512 | IWL_OTP_ACCESS_RELATIVE, | 575 | IWL_OTP_ACCESS_RELATIVE, |
513 | }; | 576 | }; |
514 | 577 | ||
515 | /** | ||
516 | * enum iwl_pa_type - Power Amplifier type | ||
517 | * @IWL_PA_SYSTEM: based on uCode configuration | ||
518 | * @IWL_PA_INTERNAL: use Internal only | ||
519 | */ | ||
520 | enum iwl_pa_type { | ||
521 | IWL_PA_SYSTEM = 0, | ||
522 | IWL_PA_INTERNAL = 1, | ||
523 | }; | ||
524 | |||
525 | /* reply_tx_statistics (for _agn devices) */ | 578 | /* reply_tx_statistics (for _agn devices) */ |
526 | struct reply_tx_error_statistics { | 579 | struct reply_tx_error_statistics { |
527 | u32 pp_delay; | 580 | u32 pp_delay; |
@@ -776,7 +829,6 @@ struct iwl_priv { | |||
776 | struct ieee80211_channel *ieee_channels; | 829 | struct ieee80211_channel *ieee_channels; |
777 | struct ieee80211_rate *ieee_rates; | 830 | struct ieee80211_rate *ieee_rates; |
778 | struct kmem_cache *tx_cmd_pool; | 831 | struct kmem_cache *tx_cmd_pool; |
779 | struct iwl_cfg *cfg; | ||
780 | 832 | ||
781 | enum ieee80211_band band; | 833 | enum ieee80211_band band; |
782 | 834 | ||
@@ -880,6 +932,7 @@ struct iwl_priv { | |||
880 | int num_stations; | 932 | int num_stations; |
881 | struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; | 933 | struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; |
882 | unsigned long ucode_key_table; | 934 | unsigned long ucode_key_table; |
935 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; | ||
883 | 936 | ||
884 | u8 mac80211_registered; | 937 | u8 mac80211_registered; |
885 | 938 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index f9d3319ecad5..9b212a8f30bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -90,6 +90,35 @@ TRACE_EVENT(iwlwifi_dev_iowrite32, | |||
90 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) | 90 | TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) |
91 | ); | 91 | ); |
92 | 92 | ||
93 | TRACE_EVENT(iwlwifi_dev_irq, | ||
94 | TP_PROTO(void *priv), | ||
95 | TP_ARGS(priv), | ||
96 | TP_STRUCT__entry( | ||
97 | PRIV_ENTRY | ||
98 | ), | ||
99 | TP_fast_assign( | ||
100 | PRIV_ASSIGN; | ||
101 | ), | ||
102 | /* TP_printk("") doesn't compile */ | ||
103 | TP_printk("%d", 0) | ||
104 | ); | ||
105 | |||
106 | TRACE_EVENT(iwlwifi_dev_ict_read, | ||
107 | TP_PROTO(void *priv, u32 index, u32 value), | ||
108 | TP_ARGS(priv, index, value), | ||
109 | TP_STRUCT__entry( | ||
110 | PRIV_ENTRY | ||
111 | __field(u32, index) | ||
112 | __field(u32, value) | ||
113 | ), | ||
114 | TP_fast_assign( | ||
115 | PRIV_ASSIGN; | ||
116 | __entry->index = index; | ||
117 | __entry->value = value; | ||
118 | ), | ||
119 | TP_printk("read ict[%d] = %#.8x", __entry->index, __entry->value) | ||
120 | ); | ||
121 | |||
93 | #undef TRACE_SYSTEM | 122 | #undef TRACE_SYSTEM |
94 | #define TRACE_SYSTEM iwlwifi_ucode | 123 | #define TRACE_SYSTEM iwlwifi_ucode |
95 | 124 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 6fcc7d586b24..c1eda9724f42 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -230,8 +230,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) | |||
230 | eeprom_ver = iwl_eeprom_query16(priv->shrd, EEPROM_VERSION); | 230 | eeprom_ver = iwl_eeprom_query16(priv->shrd, EEPROM_VERSION); |
231 | calib_ver = iwl_eeprom_calib_version(priv->shrd); | 231 | calib_ver = iwl_eeprom_calib_version(priv->shrd); |
232 | 232 | ||
233 | if (eeprom_ver < priv->cfg->eeprom_ver || | 233 | if (eeprom_ver < cfg(priv)->eeprom_ver || |
234 | calib_ver < priv->cfg->eeprom_calib_ver) | 234 | calib_ver < cfg(priv)->eeprom_calib_ver) |
235 | goto err; | 235 | goto err; |
236 | 236 | ||
237 | IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", | 237 | IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", |
@@ -241,8 +241,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) | |||
241 | err: | 241 | err: |
242 | IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " | 242 | IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " |
243 | "CALIB=0x%x < 0x%x\n", | 243 | "CALIB=0x%x < 0x%x\n", |
244 | eeprom_ver, priv->cfg->eeprom_ver, | 244 | eeprom_ver, cfg(priv)->eeprom_ver, |
245 | calib_ver, priv->cfg->eeprom_calib_ver); | 245 | calib_ver, cfg(priv)->eeprom_calib_ver); |
246 | return -EINVAL; | 246 | return -EINVAL; |
247 | 247 | ||
248 | } | 248 | } |
@@ -252,35 +252,35 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv) | |||
252 | struct iwl_shared *shrd = priv->shrd; | 252 | struct iwl_shared *shrd = priv->shrd; |
253 | u16 radio_cfg; | 253 | u16 radio_cfg; |
254 | 254 | ||
255 | if (!priv->cfg->sku) { | 255 | if (!cfg(priv)->sku) { |
256 | /* not using sku overwrite */ | 256 | /* not using sku overwrite */ |
257 | priv->cfg->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); | 257 | cfg(priv)->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); |
258 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE && | 258 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE && |
259 | !priv->cfg->ht_params) { | 259 | !cfg(priv)->ht_params) { |
260 | IWL_ERR(priv, "Invalid 11n configuration\n"); | 260 | IWL_ERR(priv, "Invalid 11n configuration\n"); |
261 | return -EINVAL; | 261 | return -EINVAL; |
262 | } | 262 | } |
263 | } | 263 | } |
264 | if (!priv->cfg->sku) { | 264 | if (!cfg(priv)->sku) { |
265 | IWL_ERR(priv, "Invalid device sku\n"); | 265 | IWL_ERR(priv, "Invalid device sku\n"); |
266 | return -EINVAL; | 266 | return -EINVAL; |
267 | } | 267 | } |
268 | 268 | ||
269 | IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku); | 269 | IWL_INFO(priv, "Device SKU: 0x%X\n", cfg(priv)->sku); |
270 | 270 | ||
271 | if (!priv->cfg->valid_tx_ant && !priv->cfg->valid_rx_ant) { | 271 | if (!cfg(priv)->valid_tx_ant && !cfg(priv)->valid_rx_ant) { |
272 | /* not using .cfg overwrite */ | 272 | /* not using .cfg overwrite */ |
273 | radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); | 273 | radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); |
274 | priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); | 274 | cfg(priv)->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); |
275 | priv->cfg->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); | 275 | cfg(priv)->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); |
276 | if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) { | 276 | if (!cfg(priv)->valid_tx_ant || !cfg(priv)->valid_rx_ant) { |
277 | IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n", | 277 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", |
278 | priv->cfg->valid_tx_ant, | 278 | cfg(priv)->valid_tx_ant, |
279 | priv->cfg->valid_rx_ant); | 279 | cfg(priv)->valid_rx_ant); |
280 | return -EINVAL; | 280 | return -EINVAL; |
281 | } | 281 | } |
282 | IWL_INFO(priv, "Valid Tx ant: 0X%x, Valid Rx ant: 0X%x\n", | 282 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", |
283 | priv->cfg->valid_tx_ant, priv->cfg->valid_rx_ant); | 283 | cfg(priv)->valid_tx_ant, cfg(priv)->valid_rx_ant); |
284 | } | 284 | } |
285 | /* | 285 | /* |
286 | * for some special cases, | 286 | * for some special cases, |
@@ -369,7 +369,7 @@ static int iwl_init_otp_access(struct iwl_bus *bus) | |||
369 | * CSR auto clock gate disable bit - | 369 | * CSR auto clock gate disable bit - |
370 | * this is only applicable for HW with OTP shadow RAM | 370 | * this is only applicable for HW with OTP shadow RAM |
371 | */ | 371 | */ |
372 | if (priv(bus)->cfg->base_params->shadow_ram_support) | 372 | if (cfg(bus)->base_params->shadow_ram_support) |
373 | iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG, | 373 | iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG, |
374 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | 374 | CSR_RESET_LINK_PWR_MGMT_DISABLED); |
375 | } | 375 | } |
@@ -489,7 +489,7 @@ static int iwl_find_otp_image(struct iwl_bus *bus, | |||
489 | } | 489 | } |
490 | /* more in the link list, continue */ | 490 | /* more in the link list, continue */ |
491 | usedblocks++; | 491 | usedblocks++; |
492 | } while (usedblocks <= priv(bus)->cfg->base_params->max_ll_items); | 492 | } while (usedblocks <= cfg(bus)->base_params->max_ll_items); |
493 | 493 | ||
494 | /* OTP has no valid blocks */ | 494 | /* OTP has no valid blocks */ |
495 | IWL_DEBUG_EEPROM(bus, "OTP has no valid blocks\n"); | 495 | IWL_DEBUG_EEPROM(bus, "OTP has no valid blocks\n"); |
@@ -629,7 +629,7 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
629 | ((txp->delta_20_in_40 & 0xf0) >> 4), | 629 | ((txp->delta_20_in_40 & 0xf0) >> 4), |
630 | (txp->delta_20_in_40 & 0x0f)); | 630 | (txp->delta_20_in_40 & 0x0f)); |
631 | 631 | ||
632 | max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx, | 632 | max_txp_avg = iwl_get_max_txpower_avg(cfg(priv), txp_array, idx, |
633 | &max_txp_avg_halfdbm); | 633 | &max_txp_avg_halfdbm); |
634 | 634 | ||
635 | /* | 635 | /* |
@@ -667,7 +667,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
667 | if (trans(priv)->nvm_device_type == -ENOENT) | 667 | if (trans(priv)->nvm_device_type == -ENOENT) |
668 | return -ENOENT; | 668 | return -ENOENT; |
669 | /* allocate eeprom */ | 669 | /* allocate eeprom */ |
670 | sz = priv->cfg->base_params->eeprom_size; | 670 | sz = cfg(priv)->base_params->eeprom_size; |
671 | IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); | 671 | IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); |
672 | shrd->eeprom = kzalloc(sz, GFP_KERNEL); | 672 | shrd->eeprom = kzalloc(sz, GFP_KERNEL); |
673 | if (!shrd->eeprom) { | 673 | if (!shrd->eeprom) { |
@@ -709,7 +709,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
709 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | | 709 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | |
710 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 710 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
711 | /* traversing the linked list if no shadow ram supported */ | 711 | /* traversing the linked list if no shadow ram supported */ |
712 | if (!priv->cfg->base_params->shadow_ram_support) { | 712 | if (!cfg(priv)->base_params->shadow_ram_support) { |
713 | if (iwl_find_otp_image(bus(priv), &validblockaddr)) { | 713 | if (iwl_find_otp_image(bus(priv), &validblockaddr)) { |
714 | ret = -ENOENT; | 714 | ret = -ENOENT; |
715 | goto done; | 715 | goto done; |
@@ -776,7 +776,7 @@ static void iwl_init_band_reference(const struct iwl_priv *priv, | |||
776 | const u8 **eeprom_ch_index) | 776 | const u8 **eeprom_ch_index) |
777 | { | 777 | { |
778 | struct iwl_shared *shrd = priv->shrd; | 778 | struct iwl_shared *shrd = priv->shrd; |
779 | u32 offset = priv->cfg->lib-> | 779 | u32 offset = cfg(priv)->lib-> |
780 | eeprom_ops.regulatory_bands[eep_band - 1]; | 780 | eeprom_ops.regulatory_bands[eep_band - 1]; |
781 | switch (eep_band) { | 781 | switch (eep_band) { |
782 | case 1: /* 2.4GHz band */ | 782 | case 1: /* 2.4GHz band */ |
@@ -983,9 +983,9 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
983 | } | 983 | } |
984 | 984 | ||
985 | /* Check if we do have HT40 channels */ | 985 | /* Check if we do have HT40 channels */ |
986 | if (priv->cfg->lib->eeprom_ops.regulatory_bands[5] == | 986 | if (cfg(priv)->lib->eeprom_ops.regulatory_bands[5] == |
987 | EEPROM_REGULATORY_BAND_NO_HT40 && | 987 | EEPROM_REGULATORY_BAND_NO_HT40 && |
988 | priv->cfg->lib->eeprom_ops.regulatory_bands[6] == | 988 | cfg(priv)->lib->eeprom_ops.regulatory_bands[6] == |
989 | EEPROM_REGULATORY_BAND_NO_HT40) | 989 | EEPROM_REGULATORY_BAND_NO_HT40) |
990 | return 0; | 990 | return 0; |
991 | 991 | ||
@@ -1021,8 +1021,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
1021 | * driver need to process addition information | 1021 | * driver need to process addition information |
1022 | * to determine the max channel tx power limits | 1022 | * to determine the max channel tx power limits |
1023 | */ | 1023 | */ |
1024 | if (priv->cfg->lib->eeprom_ops.update_enhanced_txpower) | 1024 | if (cfg(priv)->lib->eeprom_ops.update_enhanced_txpower) |
1025 | priv->cfg->lib->eeprom_ops.update_enhanced_txpower(priv); | 1025 | cfg(priv)->lib->eeprom_ops.update_enhanced_txpower(priv); |
1026 | 1026 | ||
1027 | return 0; | 1027 | return 0; |
1028 | } | 1028 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 3464cad7e38c..d57ea6484bbe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -283,16 +283,29 @@ u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr) | |||
283 | return value; | 283 | return value; |
284 | } | 284 | } |
285 | 285 | ||
286 | void iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val) | 286 | int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, |
287 | void *buf, int words) | ||
287 | { | 288 | { |
288 | unsigned long flags; | 289 | unsigned long flags; |
290 | int offs, result = 0; | ||
291 | u32 *vals = buf; | ||
289 | 292 | ||
290 | spin_lock_irqsave(&bus->reg_lock, flags); | 293 | spin_lock_irqsave(&bus->reg_lock, flags); |
291 | if (!iwl_grab_nic_access(bus)) { | 294 | if (!iwl_grab_nic_access(bus)) { |
292 | iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr); | 295 | iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr); |
293 | wmb(); | 296 | wmb(); |
294 | iwl_write32(bus, HBUS_TARG_MEM_WDAT, val); | 297 | |
298 | for (offs = 0; offs < words; offs++) | ||
299 | iwl_write32(bus, HBUS_TARG_MEM_WDAT, vals[offs]); | ||
295 | iwl_release_nic_access(bus); | 300 | iwl_release_nic_access(bus); |
296 | } | 301 | } else |
302 | result = -EBUSY; | ||
297 | spin_unlock_irqrestore(&bus->reg_lock, flags); | 303 | spin_unlock_irqrestore(&bus->reg_lock, flags); |
304 | |||
305 | return result; | ||
306 | } | ||
307 | |||
308 | int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val) | ||
309 | { | ||
310 | return _iwl_write_targ_mem_words(bus, addr, &val, 1); | ||
298 | } | 311 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index ced2cbeb6eae..aae2eeb331a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -85,6 +85,9 @@ void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, | |||
85 | (bufsize) / sizeof(u32));\ | 85 | (bufsize) / sizeof(u32));\ |
86 | } while (0) | 86 | } while (0) |
87 | 87 | ||
88 | int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, | ||
89 | void *buf, int words); | ||
90 | |||
88 | u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr); | 91 | u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr); |
89 | void iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val); | 92 | int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val); |
90 | #endif | 93 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index eb541735296c..14dcbfcdc0fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -137,11 +137,11 @@ static int iwl_led_cmd(struct iwl_priv *priv, | |||
137 | } | 137 | } |
138 | 138 | ||
139 | IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", | 139 | IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", |
140 | priv->cfg->base_params->led_compensation); | 140 | cfg(priv)->base_params->led_compensation); |
141 | led_cmd.on = iwl_blink_compensation(priv, on, | 141 | led_cmd.on = iwl_blink_compensation(priv, on, |
142 | priv->cfg->base_params->led_compensation); | 142 | cfg(priv)->base_params->led_compensation); |
143 | led_cmd.off = iwl_blink_compensation(priv, off, | 143 | led_cmd.off = iwl_blink_compensation(priv, off, |
144 | priv->cfg->base_params->led_compensation); | 144 | cfg(priv)->base_params->led_compensation); |
145 | 145 | ||
146 | ret = iwl_send_led_cmd(priv, &led_cmd); | 146 | ret = iwl_send_led_cmd(priv, &led_cmd); |
147 | if (!ret) { | 147 | if (!ret) { |
@@ -178,7 +178,7 @@ void iwl_leds_init(struct iwl_priv *priv) | |||
178 | int ret; | 178 | int ret; |
179 | 179 | ||
180 | if (mode == IWL_LED_DEFAULT) | 180 | if (mode == IWL_LED_DEFAULT) |
181 | mode = priv->cfg->led_mode; | 181 | mode = cfg(priv)->led_mode; |
182 | 182 | ||
183 | priv->led.name = kasprintf(GFP_KERNEL, "%s-led", | 183 | priv->led.name = kasprintf(GFP_KERNEL, "%s-led", |
184 | wiphy_name(priv->hw->wiphy)); | 184 | wiphy_name(priv->hw->wiphy)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 1c93dfef6933..2550b3c7dcbf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h | |||
@@ -36,20 +36,6 @@ struct iwl_priv; | |||
36 | #define IWL_LED_ACTIVITY (0<<1) | 36 | #define IWL_LED_ACTIVITY (0<<1) |
37 | #define IWL_LED_LINK (1<<1) | 37 | #define IWL_LED_LINK (1<<1) |
38 | 38 | ||
39 | /* | ||
40 | * LED mode | ||
41 | * IWL_LED_DEFAULT: use device default | ||
42 | * IWL_LED_RF_STATE: turn LED on/off based on RF state | ||
43 | * LED ON = RF ON | ||
44 | * LED OFF = RF OFF | ||
45 | * IWL_LED_BLINK: adjust led blink rate based on blink table | ||
46 | */ | ||
47 | enum iwl_led_mode { | ||
48 | IWL_LED_DEFAULT, | ||
49 | IWL_LED_RF_STATE, | ||
50 | IWL_LED_BLINK, | ||
51 | }; | ||
52 | |||
53 | void iwlagn_led_enable(struct iwl_priv *priv); | 39 | void iwlagn_led_enable(struct iwl_priv *priv); |
54 | void iwl_leds_init(struct iwl_priv *priv); | 40 | void iwl_leds_init(struct iwl_priv *priv); |
55 | void iwl_leds_exit(struct iwl_priv *priv); | 41 | void iwl_leds_exit(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index e3944f4e4fd6..f980e574e1f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/div64.h> | 44 | #include <asm/div64.h> |
45 | 45 | ||
46 | #include "iwl-eeprom.h" | 46 | #include "iwl-eeprom.h" |
47 | #include "iwl-wifi.h" | ||
47 | #include "iwl-dev.h" | 48 | #include "iwl-dev.h" |
48 | #include "iwl-core.h" | 49 | #include "iwl-core.h" |
49 | #include "iwl-io.h" | 50 | #include "iwl-io.h" |
@@ -160,7 +161,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
160 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | | 161 | hw->flags |= IEEE80211_HW_SUPPORTS_PS | |
161 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 162 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; |
162 | 163 | ||
163 | if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE) | 164 | if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) |
164 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 165 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
165 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | 166 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; |
166 | 167 | ||
@@ -233,6 +234,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
233 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 234 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
234 | &priv->bands[IEEE80211_BAND_5GHZ]; | 235 | &priv->bands[IEEE80211_BAND_5GHZ]; |
235 | 236 | ||
237 | hw->wiphy->hw_version = bus_get_hw_id(bus(priv)); | ||
238 | |||
236 | iwl_leds_init(priv); | 239 | iwl_leds_init(priv); |
237 | 240 | ||
238 | ret = ieee80211_register_hw(priv->hw); | 241 | ret = ieee80211_register_hw(priv->hw); |
@@ -245,6 +248,15 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
245 | return 0; | 248 | return 0; |
246 | } | 249 | } |
247 | 250 | ||
251 | void iwlagn_mac_unregister(struct iwl_priv *priv) | ||
252 | { | ||
253 | if (!priv->mac80211_registered) | ||
254 | return; | ||
255 | iwl_leds_exit(priv); | ||
256 | ieee80211_unregister_hw(priv->hw); | ||
257 | priv->mac80211_registered = 0; | ||
258 | } | ||
259 | |||
248 | static int __iwl_up(struct iwl_priv *priv) | 260 | static int __iwl_up(struct iwl_priv *priv) |
249 | { | 261 | { |
250 | struct iwl_rxon_context *ctx; | 262 | struct iwl_rxon_context *ctx; |
@@ -265,13 +277,13 @@ static int __iwl_up(struct iwl_priv *priv) | |||
265 | } | 277 | } |
266 | } | 278 | } |
267 | 279 | ||
268 | ret = iwlagn_run_init_ucode(priv); | 280 | ret = iwl_run_init_ucode(trans(priv)); |
269 | if (ret) { | 281 | if (ret) { |
270 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); | 282 | IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); |
271 | goto error; | 283 | goto error; |
272 | } | 284 | } |
273 | 285 | ||
274 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); | 286 | ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_REGULAR); |
275 | if (ret) { | 287 | if (ret) { |
276 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | 288 | IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); |
277 | goto error; | 289 | goto error; |
@@ -611,12 +623,11 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
611 | struct iwl_priv *priv = hw->priv; | 623 | struct iwl_priv *priv = hw->priv; |
612 | int ret = -EINVAL; | 624 | int ret = -EINVAL; |
613 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; | 625 | struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; |
614 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||
615 | 626 | ||
616 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | 627 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", |
617 | sta->addr, tid); | 628 | sta->addr, tid); |
618 | 629 | ||
619 | if (!(priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)) | 630 | if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)) |
620 | return -EACCES; | 631 | return -EACCES; |
621 | 632 | ||
622 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 633 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
@@ -624,6 +635,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
624 | 635 | ||
625 | switch (action) { | 636 | switch (action) { |
626 | case IEEE80211_AMPDU_RX_START: | 637 | case IEEE80211_AMPDU_RX_START: |
638 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
639 | break; | ||
627 | IWL_DEBUG_HT(priv, "start Rx\n"); | 640 | IWL_DEBUG_HT(priv, "start Rx\n"); |
628 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | 641 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); |
629 | break; | 642 | break; |
@@ -634,6 +647,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
634 | ret = 0; | 647 | ret = 0; |
635 | break; | 648 | break; |
636 | case IEEE80211_AMPDU_TX_START: | 649 | case IEEE80211_AMPDU_TX_START: |
650 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
651 | break; | ||
637 | IWL_DEBUG_HT(priv, "start Tx\n"); | 652 | IWL_DEBUG_HT(priv, "start Tx\n"); |
638 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 653 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
639 | break; | 654 | break; |
@@ -647,8 +662,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
647 | } | 662 | } |
648 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) | 663 | if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) |
649 | ret = 0; | 664 | ret = 0; |
650 | if (!priv->agg_tids_count && priv->cfg->ht_params && | 665 | if (!priv->agg_tids_count && cfg(priv)->ht_params && |
651 | priv->cfg->ht_params->use_rts_for_aggregation) { | 666 | cfg(priv)->ht_params->use_rts_for_aggregation) { |
652 | /* | 667 | /* |
653 | * switch off RTS/CTS if it was previously enabled | 668 | * switch off RTS/CTS if it was previously enabled |
654 | */ | 669 | */ |
@@ -659,54 +674,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
659 | } | 674 | } |
660 | break; | 675 | break; |
661 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 676 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
662 | buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); | 677 | ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); |
663 | |||
664 | iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, iwl_sta_id(sta), | ||
665 | tid, buf_size); | ||
666 | |||
667 | /* | ||
668 | * If the limit is 0, then it wasn't initialised yet, | ||
669 | * use the default. We can do that since we take the | ||
670 | * minimum below, and we don't want to go above our | ||
671 | * default due to hardware restrictions. | ||
672 | */ | ||
673 | if (sta_priv->max_agg_bufsize == 0) | ||
674 | sta_priv->max_agg_bufsize = | ||
675 | LINK_QUAL_AGG_FRAME_LIMIT_DEF; | ||
676 | |||
677 | /* | ||
678 | * Even though in theory the peer could have different | ||
679 | * aggregation reorder buffer sizes for different sessions, | ||
680 | * our ucode doesn't allow for that and has a global limit | ||
681 | * for each station. Therefore, use the minimum of all the | ||
682 | * aggregation sessions and our default value. | ||
683 | */ | ||
684 | sta_priv->max_agg_bufsize = | ||
685 | min(sta_priv->max_agg_bufsize, buf_size); | ||
686 | |||
687 | if (priv->cfg->ht_params && | ||
688 | priv->cfg->ht_params->use_rts_for_aggregation) { | ||
689 | /* | ||
690 | * switch to RTS/CTS if it is the prefer protection | ||
691 | * method for HT traffic | ||
692 | */ | ||
693 | |||
694 | sta_priv->lq_sta.lq.general_params.flags |= | ||
695 | LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | ||
696 | } | ||
697 | priv->agg_tids_count++; | ||
698 | IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", | ||
699 | priv->agg_tids_count); | ||
700 | |||
701 | sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = | ||
702 | sta_priv->max_agg_bufsize; | ||
703 | |||
704 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | ||
705 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | ||
706 | |||
707 | IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n", | ||
708 | sta->addr, tid); | ||
709 | ret = 0; | ||
710 | break; | 678 | break; |
711 | } | 679 | } |
712 | mutex_unlock(&priv->shrd->mutex); | 680 | mutex_unlock(&priv->shrd->mutex); |
@@ -792,7 +760,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
792 | if (!iwl_is_associated_ctx(ctx)) | 760 | if (!iwl_is_associated_ctx(ctx)) |
793 | goto out; | 761 | goto out; |
794 | 762 | ||
795 | if (!priv->cfg->lib->set_channel_switch) | 763 | if (!cfg(priv)->lib->set_channel_switch) |
796 | goto out; | 764 | goto out; |
797 | 765 | ||
798 | ch = channel->hw_value; | 766 | ch = channel->hw_value; |
@@ -832,7 +800,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
832 | */ | 800 | */ |
833 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | 801 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); |
834 | priv->switch_channel = cpu_to_le16(ch); | 802 | priv->switch_channel = cpu_to_le16(ch); |
835 | if (priv->cfg->lib->set_channel_switch(priv, ch_switch)) { | 803 | if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { |
836 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); | 804 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); |
837 | priv->switch_channel = 0; | 805 | priv->switch_channel = 0; |
838 | ieee80211_chswitch_done(ctx->vif, false); | 806 | ieee80211_chswitch_done(ctx->vif, false); |
@@ -1125,8 +1093,8 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | |||
1125 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 1093 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
1126 | mutex_lock(&priv->shrd->mutex); | 1094 | mutex_lock(&priv->shrd->mutex); |
1127 | 1095 | ||
1128 | if (priv->cfg->bt_params && | 1096 | if (cfg(priv)->bt_params && |
1129 | priv->cfg->bt_params->advanced_bt_coexist) { | 1097 | cfg(priv)->bt_params->advanced_bt_coexist) { |
1130 | if (rssi_event == RSSI_EVENT_LOW) | 1098 | if (rssi_event == RSSI_EVENT_LOW) |
1131 | priv->bt_enable_pspoll = true; | 1099 | priv->bt_enable_pspoll = true; |
1132 | else if (rssi_event == RSSI_EVENT_HIGH) | 1100 | else if (rssi_event == RSSI_EVENT_HIGH) |
@@ -1237,7 +1205,7 @@ static int iwl_setup_interface(struct iwl_priv *priv, | |||
1237 | return err; | 1205 | return err; |
1238 | } | 1206 | } |
1239 | 1207 | ||
1240 | if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && | 1208 | if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist && |
1241 | vif->type == NL80211_IFTYPE_ADHOC) { | 1209 | vif->type == NL80211_IFTYPE_ADHOC) { |
1242 | /* | 1210 | /* |
1243 | * pretend to have high BT traffic as long as we | 1211 | * pretend to have high BT traffic as long as we |
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 850ec8e51b17..fb30ea7ca96b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
@@ -135,7 +135,7 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) | |||
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
138 | static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], | 138 | static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[], |
139 | int buf_len) | 139 | int buf_len) |
140 | { | 140 | { |
141 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | 141 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); |
@@ -144,6 +144,13 @@ static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], | |||
144 | pci_dev->subsystem_device); | 144 | pci_dev->subsystem_device); |
145 | } | 145 | } |
146 | 146 | ||
147 | static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) | ||
148 | { | ||
149 | struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); | ||
150 | |||
151 | return (pci_dev->device << 16) + pci_dev->subsystem_device; | ||
152 | } | ||
153 | |||
147 | static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) | 154 | static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) |
148 | { | 155 | { |
149 | iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); | 156 | iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); |
@@ -163,6 +170,7 @@ static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) | |||
163 | static const struct iwl_bus_ops bus_ops_pci = { | 170 | static const struct iwl_bus_ops bus_ops_pci = { |
164 | .get_pm_support = iwl_pci_is_pm_supported, | 171 | .get_pm_support = iwl_pci_is_pm_supported, |
165 | .apm_config = iwl_pci_apm_config, | 172 | .apm_config = iwl_pci_apm_config, |
173 | .get_hw_id_string = iwl_pci_get_hw_id_string, | ||
166 | .get_hw_id = iwl_pci_get_hw_id, | 174 | .get_hw_id = iwl_pci_get_hw_id, |
167 | .write8 = iwl_pci_write8, | 175 | .write8 = iwl_pci_write8, |
168 | .write32 = iwl_pci_write32, | 176 | .write32 = iwl_pci_write32, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 4eaab204322d..2b188a6025b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -167,7 +167,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
167 | u8 skip; | 167 | u8 skip; |
168 | u32 slp_itrvl; | 168 | u32 slp_itrvl; |
169 | 169 | ||
170 | if (priv->cfg->adv_pm) { | 170 | if (cfg(priv)->adv_pm) { |
171 | table = apm_range_2; | 171 | table = apm_range_2; |
172 | if (period <= IWL_DTIM_RANGE_1_MAX) | 172 | if (period <= IWL_DTIM_RANGE_1_MAX) |
173 | table = apm_range_1; | 173 | table = apm_range_1; |
@@ -221,7 +221,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, | |||
221 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | 221 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; |
222 | 222 | ||
223 | if (iwl_advanced_bt_coexist(priv)) { | 223 | if (iwl_advanced_bt_coexist(priv)) { |
224 | if (!priv->cfg->bt_params->bt_sco_disable) | 224 | if (!cfg(priv)->bt_params->bt_sco_disable) |
225 | cmd->flags |= IWL_POWER_BT_SCO_ENA; | 225 | cmd->flags |= IWL_POWER_BT_SCO_ENA; |
226 | else | 226 | else |
227 | cmd->flags &= ~IWL_POWER_BT_SCO_ENA; | 227 | cmd->flags &= ~IWL_POWER_BT_SCO_ENA; |
@@ -307,7 +307,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, | |||
307 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | 307 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; |
308 | 308 | ||
309 | if (iwl_advanced_bt_coexist(priv)) { | 309 | if (iwl_advanced_bt_coexist(priv)) { |
310 | if (!priv->cfg->bt_params->bt_sco_disable) | 310 | if (!cfg(priv)->bt_params->bt_sco_disable) |
311 | cmd->flags |= IWL_POWER_BT_SCO_ENA; | 311 | cmd->flags |= IWL_POWER_BT_SCO_ENA; |
312 | else | 312 | else |
313 | cmd->flags &= ~IWL_POWER_BT_SCO_ENA; | 313 | cmd->flags &= ~IWL_POWER_BT_SCO_ENA; |
@@ -350,7 +350,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, | |||
350 | 350 | ||
351 | if (priv->shrd->wowlan) | 351 | if (priv->shrd->wowlan) |
352 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); | 352 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); |
353 | else if (!priv->cfg->base_params->no_idle_support && | 353 | else if (!cfg(priv)->base_params->no_idle_support && |
354 | priv->hw->conf.flags & IEEE80211_CONF_IDLE) | 354 | priv->hw->conf.flags & IEEE80211_CONF_IDLE) |
355 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); | 355 | iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); |
356 | else if (iwl_tt_is_low_power_state(priv)) { | 356 | else if (iwl_tt_is_low_power_state(priv)) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 359d2182757b..084aa2c4ccfb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -691,8 +691,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
691 | * Internal scans are passive, so we can indiscriminately set | 691 | * Internal scans are passive, so we can indiscriminately set |
692 | * the BT ignore flag on 2.4 GHz since it applies to TX only. | 692 | * the BT ignore flag on 2.4 GHz since it applies to TX only. |
693 | */ | 693 | */ |
694 | if (priv->cfg->bt_params && | 694 | if (cfg(priv)->bt_params && |
695 | priv->cfg->bt_params->advanced_bt_coexist) | 695 | cfg(priv)->bt_params->advanced_bt_coexist) |
696 | scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; | 696 | scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; |
697 | break; | 697 | break; |
698 | case IEEE80211_BAND_5GHZ: | 698 | case IEEE80211_BAND_5GHZ: |
@@ -733,12 +733,12 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
733 | 733 | ||
734 | band = priv->scan_band; | 734 | band = priv->scan_band; |
735 | 735 | ||
736 | if (priv->cfg->scan_rx_antennas[band]) | 736 | if (cfg(priv)->scan_rx_antennas[band]) |
737 | rx_ant = priv->cfg->scan_rx_antennas[band]; | 737 | rx_ant = cfg(priv)->scan_rx_antennas[band]; |
738 | 738 | ||
739 | if (band == IEEE80211_BAND_2GHZ && | 739 | if (band == IEEE80211_BAND_2GHZ && |
740 | priv->cfg->bt_params && | 740 | cfg(priv)->bt_params && |
741 | priv->cfg->bt_params->advanced_bt_coexist) { | 741 | cfg(priv)->bt_params->advanced_bt_coexist) { |
742 | /* transmit 2.4 GHz probes only on first antenna */ | 742 | /* transmit 2.4 GHz probes only on first antenna */ |
743 | scan_tx_antennas = first_antenna(scan_tx_antennas); | 743 | scan_tx_antennas = first_antenna(scan_tx_antennas); |
744 | } | 744 | } |
@@ -762,8 +762,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
762 | 762 | ||
763 | rx_ant = first_antenna(active_chains); | 763 | rx_ant = first_antenna(active_chains); |
764 | } | 764 | } |
765 | if (priv->cfg->bt_params && | 765 | if (cfg(priv)->bt_params && |
766 | priv->cfg->bt_params->advanced_bt_coexist && | 766 | cfg(priv)->bt_params->advanced_bt_coexist && |
767 | priv->bt_full_concurrent) { | 767 | priv->bt_full_concurrent) { |
768 | /* operated as 1x1 in full concurrency mode */ | 768 | /* operated as 1x1 in full concurrency mode */ |
769 | rx_ant = first_antenna(rx_ant); | 769 | rx_ant = first_antenna(rx_ant); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 29a7284aa3ef..dc55cc4a8108 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -94,7 +94,6 @@ | |||
94 | * This implementation is iwl-pci.c | 94 | * This implementation is iwl-pci.c |
95 | */ | 95 | */ |
96 | 96 | ||
97 | struct iwl_cfg; | ||
98 | struct iwl_bus; | 97 | struct iwl_bus; |
99 | struct iwl_priv; | 98 | struct iwl_priv; |
100 | struct iwl_trans; | 99 | struct iwl_trans; |
@@ -108,6 +107,10 @@ struct iwl_trans_ops; | |||
108 | 107 | ||
109 | extern struct iwl_mod_params iwlagn_mod_params; | 108 | extern struct iwl_mod_params iwlagn_mod_params; |
110 | 109 | ||
110 | #define IWL_DISABLE_HT_ALL BIT(0) | ||
111 | #define IWL_DISABLE_HT_TXAGG BIT(1) | ||
112 | #define IWL_DISABLE_HT_RXAGG BIT(2) | ||
113 | |||
111 | /** | 114 | /** |
112 | * struct iwl_mod_params | 115 | * struct iwl_mod_params |
113 | * | 116 | * |
@@ -115,7 +118,8 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
115 | * | 118 | * |
116 | * @sw_crypto: using hardware encryption, default = 0 | 119 | * @sw_crypto: using hardware encryption, default = 0 |
117 | * @num_of_queues: number of tx queue, HW dependent | 120 | * @num_of_queues: number of tx queue, HW dependent |
118 | * @disable_11n: 11n capabilities enabled, default = 0 | 121 | * @disable_11n: disable 11n capabilities, default = 0, |
122 | * use IWL_DISABLE_HT_* constants | ||
119 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 | 123 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 |
120 | * @antenna: both antennas (use diversity), default = 0 | 124 | * @antenna: both antennas (use diversity), default = 0 |
121 | * @restart_fw: restart firmware, default = 1 | 125 | * @restart_fw: restart firmware, default = 1 |
@@ -136,7 +140,7 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
136 | struct iwl_mod_params { | 140 | struct iwl_mod_params { |
137 | int sw_crypto; | 141 | int sw_crypto; |
138 | int num_of_queues; | 142 | int num_of_queues; |
139 | int disable_11n; | 143 | unsigned int disable_11n; |
140 | int amsdu_size_8K; | 144 | int amsdu_size_8K; |
141 | int antenna; | 145 | int antenna; |
142 | int restart_fw; | 146 | int restart_fw; |
@@ -175,7 +179,6 @@ struct iwl_mod_params { | |||
175 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit | 179 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit |
176 | * relevant for 1000, 6000 and up | 180 | * relevant for 1000, 6000 and up |
177 | * @wd_timeout: TX queues watchdog timeout | 181 | * @wd_timeout: TX queues watchdog timeout |
178 | * @calib_rt_cfg: setup runtime calibrations for the hw | ||
179 | * @struct iwl_sensitivity_ranges: range of sensitivity values | 182 | * @struct iwl_sensitivity_ranges: range of sensitivity values |
180 | */ | 183 | */ |
181 | struct iwl_hw_params { | 184 | struct iwl_hw_params { |
@@ -195,69 +198,10 @@ struct iwl_hw_params { | |||
195 | u32 ct_kill_exit_threshold; | 198 | u32 ct_kill_exit_threshold; |
196 | unsigned int wd_timeout; | 199 | unsigned int wd_timeout; |
197 | 200 | ||
198 | u32 calib_rt_cfg; | ||
199 | const struct iwl_sensitivity_ranges *sens; | 201 | const struct iwl_sensitivity_ranges *sens; |
200 | }; | 202 | }; |
201 | 203 | ||
202 | /** | 204 | /** |
203 | * enum iwl_agg_state | ||
204 | * | ||
205 | * The state machine of the BA agreement establishment / tear down. | ||
206 | * These states relate to a specific RA / TID. | ||
207 | * | ||
208 | * @IWL_AGG_OFF: aggregation is not used | ||
209 | * @IWL_AGG_ON: aggregation session is up | ||
210 | * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the | ||
211 | * HW queue to be empty from packets for this RA /TID. | ||
212 | * @IWL_EMPTYING_HW_QUEUE_DELBA: tearing down a BA session - waiting for the | ||
213 | * HW queue to be empty from packets for this RA /TID. | ||
214 | */ | ||
215 | enum iwl_agg_state { | ||
216 | IWL_AGG_OFF = 0, | ||
217 | IWL_AGG_ON, | ||
218 | IWL_EMPTYING_HW_QUEUE_ADDBA, | ||
219 | IWL_EMPTYING_HW_QUEUE_DELBA, | ||
220 | }; | ||
221 | |||
222 | /** | ||
223 | * struct iwl_ht_agg - aggregation state machine | ||
224 | |||
225 | * This structs holds the states for the BA agreement establishment and tear | ||
226 | * down. It also holds the state during the BA session itself. This struct is | ||
227 | * duplicated for each RA / TID. | ||
228 | |||
229 | * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the | ||
230 | * Tx response (REPLY_TX), and the block ack notification | ||
231 | * (REPLY_COMPRESSED_BA). | ||
232 | * @state: state of the BA agreement establishment / tear down. | ||
233 | * @txq_id: Tx queue used by the BA session - used by the transport layer. | ||
234 | * Needed by the upper layer for debugfs only. | ||
235 | * @wait_for_ba: Expect block-ack before next Tx reply | ||
236 | */ | ||
237 | struct iwl_ht_agg { | ||
238 | u32 rate_n_flags; | ||
239 | enum iwl_agg_state state; | ||
240 | u16 txq_id; | ||
241 | bool wait_for_ba; | ||
242 | }; | ||
243 | |||
244 | /** | ||
245 | * struct iwl_tid_data - one for each RA / TID | ||
246 | |||
247 | * This structs holds the states for each RA / TID. | ||
248 | |||
249 | * @seq_number: the next WiFi sequence number to use | ||
250 | * @tfds_in_queue: number of packets sent to the HW queues. | ||
251 | * Exported for debugfs only | ||
252 | * @agg: aggregation state machine | ||
253 | */ | ||
254 | struct iwl_tid_data { | ||
255 | u16 seq_number; | ||
256 | u16 tfds_in_queue; | ||
257 | struct iwl_ht_agg agg; | ||
258 | }; | ||
259 | |||
260 | /** | ||
261 | * enum iwl_ucode_type | 205 | * enum iwl_ucode_type |
262 | * | 206 | * |
263 | * The type of ucode currently loaded on the hardware. | 207 | * The type of ucode currently loaded on the hardware. |
@@ -304,6 +248,101 @@ struct iwl_notification_wait { | |||
304 | }; | 248 | }; |
305 | 249 | ||
306 | /** | 250 | /** |
251 | * enum iwl_pa_type - Power Amplifier type | ||
252 | * @IWL_PA_SYSTEM: based on uCode configuration | ||
253 | * @IWL_PA_INTERNAL: use Internal only | ||
254 | */ | ||
255 | enum iwl_pa_type { | ||
256 | IWL_PA_SYSTEM = 0, | ||
257 | IWL_PA_INTERNAL = 1, | ||
258 | }; | ||
259 | |||
260 | /* | ||
261 | * LED mode | ||
262 | * IWL_LED_DEFAULT: use device default | ||
263 | * IWL_LED_RF_STATE: turn LED on/off based on RF state | ||
264 | * LED ON = RF ON | ||
265 | * LED OFF = RF OFF | ||
266 | * IWL_LED_BLINK: adjust led blink rate based on blink table | ||
267 | */ | ||
268 | enum iwl_led_mode { | ||
269 | IWL_LED_DEFAULT, | ||
270 | IWL_LED_RF_STATE, | ||
271 | IWL_LED_BLINK, | ||
272 | }; | ||
273 | |||
274 | /** | ||
275 | * struct iwl_cfg | ||
276 | * @name: Offical name of the device | ||
277 | * @fw_name_pre: Firmware filename prefix. The api version and extension | ||
278 | * (.ucode) will be added to filename before loading from disk. The | ||
279 | * filename is constructed as fw_name_pre<api>.ucode. | ||
280 | * @ucode_api_max: Highest version of uCode API supported by driver. | ||
281 | * @ucode_api_ok: oldest version of the uCode API that is OK to load | ||
282 | * without a warning, for use in transitions | ||
283 | * @ucode_api_min: Lowest version of uCode API supported by driver. | ||
284 | * @valid_tx_ant: valid transmit antenna | ||
285 | * @valid_rx_ant: valid receive antenna | ||
286 | * @sku: sku information from EEPROM | ||
287 | * @eeprom_ver: EEPROM version | ||
288 | * @eeprom_calib_ver: EEPROM calibration version | ||
289 | * @lib: pointer to the lib ops | ||
290 | * @additional_nic_config: additional nic configuration | ||
291 | * @base_params: pointer to basic parameters | ||
292 | * @ht_params: point to ht patameters | ||
293 | * @bt_params: pointer to bt parameters | ||
294 | * @pa_type: used by 6000 series only to identify the type of Power Amplifier | ||
295 | * @need_temp_offset_calib: need to perform temperature offset calibration | ||
296 | * @no_xtal_calib: some devices do not need crystal calibration data, | ||
297 | * don't send it to those | ||
298 | * @scan_rx_antennas: available antenna for scan operation | ||
299 | * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) | ||
300 | * @adv_pm: advance power management | ||
301 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity | ||
302 | * @internal_wimax_coex: internal wifi/wimax combo device | ||
303 | * @iq_invert: I/Q inversion | ||
304 | * @temp_offset_v2: support v2 of temperature offset calibration | ||
305 | * | ||
306 | * We enable the driver to be backward compatible wrt API version. The | ||
307 | * driver specifies which APIs it supports (with @ucode_api_max being the | ||
308 | * highest and @ucode_api_min the lowest). Firmware will only be loaded if | ||
309 | * it has a supported API version. | ||
310 | * | ||
311 | * The ideal usage of this infrastructure is to treat a new ucode API | ||
312 | * release as a new hardware revision. | ||
313 | */ | ||
314 | struct iwl_cfg { | ||
315 | /* params specific to an individual device within a device family */ | ||
316 | const char *name; | ||
317 | const char *fw_name_pre; | ||
318 | const unsigned int ucode_api_max; | ||
319 | const unsigned int ucode_api_ok; | ||
320 | const unsigned int ucode_api_min; | ||
321 | u8 valid_tx_ant; | ||
322 | u8 valid_rx_ant; | ||
323 | u16 sku; | ||
324 | u16 eeprom_ver; | ||
325 | u16 eeprom_calib_ver; | ||
326 | const struct iwl_lib_ops *lib; | ||
327 | void (*additional_nic_config)(struct iwl_priv *priv); | ||
328 | /* params not likely to change within a device family */ | ||
329 | struct iwl_base_params *base_params; | ||
330 | /* params likely to change within a device family */ | ||
331 | struct iwl_ht_params *ht_params; | ||
332 | struct iwl_bt_params *bt_params; | ||
333 | enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ | ||
334 | const bool need_temp_offset_calib; /* if used set to true */ | ||
335 | const bool no_xtal_calib; | ||
336 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | ||
337 | enum iwl_led_mode led_mode; | ||
338 | const bool adv_pm; | ||
339 | const bool rx_with_siso_diversity; | ||
340 | const bool internal_wimax_coex; | ||
341 | const bool iq_invert; | ||
342 | const bool temp_offset_v2; | ||
343 | }; | ||
344 | |||
345 | /** | ||
307 | * struct iwl_shared - shared fields for all the layers of the driver | 346 | * struct iwl_shared - shared fields for all the layers of the driver |
308 | * | 347 | * |
309 | * @dbg_level_dev: dbg level set per device. Prevails on | 348 | * @dbg_level_dev: dbg level set per device. Prevails on |
@@ -311,15 +350,20 @@ struct iwl_notification_wait { | |||
311 | * @ucode_owner: IWL_OWNERSHIP_* | 350 | * @ucode_owner: IWL_OWNERSHIP_* |
312 | * @cmd_queue: command queue number | 351 | * @cmd_queue: command queue number |
313 | * @status: STATUS_* | 352 | * @status: STATUS_* |
353 | * @wowlan: are we running wowlan uCode | ||
314 | * @valid_contexts: microcode/device supports multiple contexts | 354 | * @valid_contexts: microcode/device supports multiple contexts |
315 | * @bus: pointer to the bus layer data | 355 | * @bus: pointer to the bus layer data |
356 | * @cfg: see struct iwl_cfg | ||
316 | * @priv: pointer to the upper layer data | 357 | * @priv: pointer to the upper layer data |
358 | * @trans: pointer to the transport layer data | ||
317 | * @hw_params: see struct iwl_hw_params | 359 | * @hw_params: see struct iwl_hw_params |
318 | * @workqueue: the workqueue used by all the layers of the driver | 360 | * @workqueue: the workqueue used by all the layers of the driver |
319 | * @lock: protect general shared data | 361 | * @lock: protect general shared data |
320 | * @sta_lock: protects the station table. | 362 | * @sta_lock: protects the station table. |
321 | * If lock and sta_lock are needed, lock must be acquired first. | 363 | * If lock and sta_lock are needed, lock must be acquired first. |
322 | * @mutex: | 364 | * @mutex: |
365 | * @wait_command_queue: the wait_queue for SYNC host command nad uCode load | ||
366 | * @eeprom: pointer to the eeprom/OTP image | ||
323 | * @ucode_type: indicator of loaded ucode image | 367 | * @ucode_type: indicator of loaded ucode image |
324 | * @notif_waits: things waiting for notification | 368 | * @notif_waits: things waiting for notification |
325 | * @notif_wait_lock: lock protecting notification | 369 | * @notif_wait_lock: lock protecting notification |
@@ -340,6 +384,7 @@ struct iwl_shared { | |||
340 | u8 valid_contexts; | 384 | u8 valid_contexts; |
341 | 385 | ||
342 | struct iwl_bus *bus; | 386 | struct iwl_bus *bus; |
387 | struct iwl_cfg *cfg; | ||
343 | struct iwl_priv *priv; | 388 | struct iwl_priv *priv; |
344 | struct iwl_trans *trans; | 389 | struct iwl_trans *trans; |
345 | struct iwl_hw_params hw_params; | 390 | struct iwl_hw_params hw_params; |
@@ -349,8 +394,6 @@ struct iwl_shared { | |||
349 | spinlock_t sta_lock; | 394 | spinlock_t sta_lock; |
350 | struct mutex mutex; | 395 | struct mutex mutex; |
351 | 396 | ||
352 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; | ||
353 | |||
354 | wait_queue_head_t wait_command_queue; | 397 | wait_queue_head_t wait_command_queue; |
355 | 398 | ||
356 | /* eeprom -- this is in the card's little endian byte order */ | 399 | /* eeprom -- this is in the card's little endian byte order */ |
@@ -373,6 +416,7 @@ struct iwl_shared { | |||
373 | 416 | ||
374 | /*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */ | 417 | /*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */ |
375 | #define priv(_m) ((_m)->shrd->priv) | 418 | #define priv(_m) ((_m)->shrd->priv) |
419 | #define cfg(_m) ((_m)->shrd->cfg) | ||
376 | #define bus(_m) ((_m)->shrd->bus) | 420 | #define bus(_m) ((_m)->shrd->bus) |
377 | #define trans(_m) ((_m)->shrd->trans) | 421 | #define trans(_m) ((_m)->shrd->trans) |
378 | #define hw_params(_m) ((_m)->shrd->hw_params) | 422 | #define hw_params(_m) ((_m)->shrd->hw_params) |
@@ -494,12 +538,6 @@ int __must_check iwl_rx_dispatch(struct iwl_priv *priv, | |||
494 | struct iwl_device_cmd *cmd); | 538 | struct iwl_device_cmd *cmd); |
495 | 539 | ||
496 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); | 540 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); |
497 | void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv, | ||
498 | enum iwl_rxon_context_id ctx, | ||
499 | u8 sta_id, u8 tid); | ||
500 | void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv, | ||
501 | enum iwl_rxon_context_id ctx, | ||
502 | u8 sta_id, u8 tid); | ||
503 | void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); | 541 | void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); |
504 | void iwl_nic_config(struct iwl_priv *priv); | 542 | void iwl_nic_config(struct iwl_priv *priv); |
505 | void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); | 543 | void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index a874eb7b5f8e..4a5cddd2d56b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include <net/mac80211.h> | 70 | #include <net/mac80211.h> |
71 | #include <net/netlink.h> | 71 | #include <net/netlink.h> |
72 | 72 | ||
73 | #include "iwl-wifi.h" | ||
73 | #include "iwl-dev.h" | 74 | #include "iwl-dev.h" |
74 | #include "iwl-core.h" | 75 | #include "iwl-core.h" |
75 | #include "iwl-debug.h" | 76 | #include "iwl-debug.h" |
@@ -380,7 +381,7 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) | |||
380 | iwl_init_notification_wait(priv->shrd, &calib_wait, | 381 | iwl_init_notification_wait(priv->shrd, &calib_wait, |
381 | CALIBRATION_COMPLETE_NOTIFICATION, | 382 | CALIBRATION_COMPLETE_NOTIFICATION, |
382 | NULL, NULL); | 383 | NULL, NULL); |
383 | ret = iwlagn_init_alive_start(priv); | 384 | ret = iwl_init_alive_start(trans(priv)); |
384 | if (ret) { | 385 | if (ret) { |
385 | IWL_DEBUG_INFO(priv, | 386 | IWL_DEBUG_INFO(priv, |
386 | "Error configuring init calibration: %d\n", ret); | 387 | "Error configuring init calibration: %d\n", ret); |
@@ -417,16 +418,16 @@ cfg_init_calib_error: | |||
417 | static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | 418 | static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) |
418 | { | 419 | { |
419 | struct iwl_priv *priv = hw->priv; | 420 | struct iwl_priv *priv = hw->priv; |
421 | struct iwl_trans *trans = trans(priv); | ||
420 | struct sk_buff *skb; | 422 | struct sk_buff *skb; |
421 | unsigned char *rsp_data_ptr = NULL; | 423 | unsigned char *rsp_data_ptr = NULL; |
422 | int status = 0, rsp_data_len = 0; | 424 | int status = 0, rsp_data_len = 0; |
423 | char buf[32], *ptr = NULL; | 425 | u32 devid; |
424 | unsigned int num, devid; | ||
425 | 426 | ||
426 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { | 427 | switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { |
427 | case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: | 428 | case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: |
428 | rsp_data_ptr = (unsigned char *)priv->cfg->name; | 429 | rsp_data_ptr = (unsigned char *)cfg(priv)->name; |
429 | rsp_data_len = strlen(priv->cfg->name); | 430 | rsp_data_len = strlen(cfg(priv)->name); |
430 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | 431 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, |
431 | rsp_data_len + 20); | 432 | rsp_data_len + 20); |
432 | if (!skb) { | 433 | if (!skb) { |
@@ -445,7 +446,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
445 | break; | 446 | break; |
446 | 447 | ||
447 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: | 448 | case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: |
448 | status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_INIT); | 449 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); |
449 | if (status) | 450 | if (status) |
450 | IWL_DEBUG_INFO(priv, | 451 | IWL_DEBUG_INFO(priv, |
451 | "Error loading init ucode: %d\n", status); | 452 | "Error loading init ucode: %d\n", status); |
@@ -453,11 +454,11 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
453 | 454 | ||
454 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: | 455 | case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: |
455 | iwl_testmode_cfg_init_calib(priv); | 456 | iwl_testmode_cfg_init_calib(priv); |
456 | iwl_trans_stop_device(trans(priv)); | 457 | iwl_trans_stop_device(trans); |
457 | break; | 458 | break; |
458 | 459 | ||
459 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: | 460 | case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: |
460 | status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); | 461 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR); |
461 | if (status) { | 462 | if (status) { |
462 | IWL_DEBUG_INFO(priv, | 463 | IWL_DEBUG_INFO(priv, |
463 | "Error loading runtime ucode: %d\n", status); | 464 | "Error loading runtime ucode: %d\n", status); |
@@ -471,8 +472,8 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
471 | 472 | ||
472 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: | 473 | case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: |
473 | iwl_scan_cancel_timeout(priv, 200); | 474 | iwl_scan_cancel_timeout(priv, 200); |
474 | iwl_trans_stop_device(trans(priv)); | 475 | iwl_trans_stop_device(trans); |
475 | status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); | 476 | status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN); |
476 | if (status) { | 477 | if (status) { |
477 | IWL_DEBUG_INFO(priv, | 478 | IWL_DEBUG_INFO(priv, |
478 | "Error loading WOWLAN ucode: %d\n", status); | 479 | "Error loading WOWLAN ucode: %d\n", status); |
@@ -487,7 +488,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
487 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | 488 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: |
488 | if (priv->shrd->eeprom) { | 489 | if (priv->shrd->eeprom) { |
489 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | 490 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, |
490 | priv->cfg->base_params->eeprom_size + 20); | 491 | cfg(priv)->base_params->eeprom_size + 20); |
491 | if (!skb) { | 492 | if (!skb) { |
492 | IWL_DEBUG_INFO(priv, | 493 | IWL_DEBUG_INFO(priv, |
493 | "Error allocating memory\n"); | 494 | "Error allocating memory\n"); |
@@ -496,7 +497,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
496 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, | 497 | NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, |
497 | IWL_TM_CMD_DEV2APP_EEPROM_RSP); | 498 | IWL_TM_CMD_DEV2APP_EEPROM_RSP); |
498 | NLA_PUT(skb, IWL_TM_ATTR_EEPROM, | 499 | NLA_PUT(skb, IWL_TM_ATTR_EEPROM, |
499 | priv->cfg->base_params->eeprom_size, | 500 | cfg(priv)->base_params->eeprom_size, |
500 | priv->shrd->eeprom); | 501 | priv->shrd->eeprom); |
501 | status = cfg80211_testmode_reply(skb); | 502 | status = cfg80211_testmode_reply(skb); |
502 | if (status < 0) | 503 | if (status < 0) |
@@ -532,14 +533,8 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
532 | break; | 533 | break; |
533 | 534 | ||
534 | case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: | 535 | case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: |
535 | bus_get_hw_id(bus(priv), buf, sizeof(buf)); | 536 | devid = bus_get_hw_id(bus(priv)); |
536 | ptr = buf; | 537 | IWL_INFO(priv, "hw version: 0x%x\n", devid); |
537 | strsep(&ptr, ":"); | ||
538 | sscanf(strsep(&ptr, ":"), "%x", &num); | ||
539 | sscanf(strsep(&ptr, ":"), "%x", &devid); | ||
540 | IWL_INFO(priv, "Device ID = 0x%04x, SubDevice ID= 0x%04x\n", | ||
541 | num, devid); | ||
542 | devid |= (num << 16); | ||
543 | 538 | ||
544 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); | 539 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); |
545 | if (!skb) { | 540 | if (!skb) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 5a384b309b09..f6debf91d7b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
@@ -219,9 +219,7 @@ struct iwl_trans_pcie { | |||
219 | 219 | ||
220 | /* INT ICT Table */ | 220 | /* INT ICT Table */ |
221 | __le32 *ict_tbl; | 221 | __le32 *ict_tbl; |
222 | void *ict_tbl_vir; | ||
223 | dma_addr_t ict_tbl_dma; | 222 | dma_addr_t ict_tbl_dma; |
224 | dma_addr_t aligned_ict_tbl_dma; | ||
225 | int ict_index; | 223 | int ict_index; |
226 | u32 inta; | 224 | u32 inta; |
227 | bool use_ict; | 225 | bool use_ict; |
@@ -236,6 +234,7 @@ struct iwl_trans_pcie { | |||
236 | const u8 *ac_to_fifo[NUM_IWL_RXON_CTX]; | 234 | const u8 *ac_to_fifo[NUM_IWL_RXON_CTX]; |
237 | const u8 *ac_to_queue[NUM_IWL_RXON_CTX]; | 235 | const u8 *ac_to_queue[NUM_IWL_RXON_CTX]; |
238 | u8 mcast_queue[NUM_IWL_RXON_CTX]; | 236 | u8 mcast_queue[NUM_IWL_RXON_CTX]; |
237 | u8 agg_txq[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; | ||
239 | 238 | ||
240 | struct iwl_tx_queue *txq; | 239 | struct iwl_tx_queue *txq; |
241 | unsigned long txq_ctx_active_msk; | 240 | unsigned long txq_ctx_active_msk; |
@@ -280,20 +279,16 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, | |||
280 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 279 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
281 | struct iwl_tx_queue *txq, | 280 | struct iwl_tx_queue *txq, |
282 | u16 byte_cnt); | 281 | u16 byte_cnt); |
283 | void iwl_trans_pcie_txq_agg_disable(struct iwl_trans *trans, int txq_id); | ||
284 | int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, | 282 | int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, |
285 | enum iwl_rxon_context_id ctx, int sta_id, | 283 | int sta_id, int tid); |
286 | int tid); | ||
287 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); | 284 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); |
288 | void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | 285 | void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, |
289 | struct iwl_tx_queue *txq, | 286 | struct iwl_tx_queue *txq, |
290 | int tx_fifo_id, int scd_retry); | 287 | int tx_fifo_id, int scd_retry); |
291 | int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, | 288 | int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, int sta_id, int tid); |
292 | enum iwl_rxon_context_id ctx, int sta_id, | ||
293 | int tid, u16 *ssn); | ||
294 | void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, | 289 | void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, |
295 | enum iwl_rxon_context_id ctx, | 290 | enum iwl_rxon_context_id ctx, |
296 | int sta_id, int tid, int frame_limit); | 291 | int sta_id, int tid, int frame_limit, u16 ssn); |
297 | void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | 292 | void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, |
298 | int index, enum dma_data_direction dma_dir); | 293 | int index, enum dma_data_direction dma_dir); |
299 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | 294 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2ee00e0f39d3..752493f00406 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
@@ -672,7 +672,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
672 | { | 672 | { |
673 | struct iwl_priv *priv = priv(trans); | 673 | struct iwl_priv *priv = priv(trans); |
674 | /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ | 674 | /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ |
675 | if (priv->cfg->internal_wimax_coex && | 675 | if (cfg(priv)->internal_wimax_coex && |
676 | (!(iwl_read_prph(bus(trans), APMG_CLK_CTRL_REG) & | 676 | (!(iwl_read_prph(bus(trans), APMG_CLK_CTRL_REG) & |
677 | APMS_CLK_VAL_MRB_FUNC_MODE) || | 677 | APMS_CLK_VAL_MRB_FUNC_MODE) || |
678 | (iwl_read_prph(bus(trans), APMG_PS_CTRL_REG) & | 678 | (iwl_read_prph(bus(trans), APMG_PS_CTRL_REG) & |
@@ -1151,7 +1151,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
1151 | * ICT functions | 1151 | * ICT functions |
1152 | * | 1152 | * |
1153 | ******************************************************************************/ | 1153 | ******************************************************************************/ |
1154 | #define ICT_COUNT (PAGE_SIZE/sizeof(u32)) | 1154 | |
1155 | /* a device (PCI-E) page is 4096 bytes long */ | ||
1156 | #define ICT_SHIFT 12 | ||
1157 | #define ICT_SIZE (1 << ICT_SHIFT) | ||
1158 | #define ICT_COUNT (ICT_SIZE / sizeof(u32)) | ||
1155 | 1159 | ||
1156 | /* Free dram table */ | 1160 | /* Free dram table */ |
1157 | void iwl_free_isr_ict(struct iwl_trans *trans) | 1161 | void iwl_free_isr_ict(struct iwl_trans *trans) |
@@ -1159,21 +1163,19 @@ void iwl_free_isr_ict(struct iwl_trans *trans) | |||
1159 | struct iwl_trans_pcie *trans_pcie = | 1163 | struct iwl_trans_pcie *trans_pcie = |
1160 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1164 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1161 | 1165 | ||
1162 | if (trans_pcie->ict_tbl_vir) { | 1166 | if (trans_pcie->ict_tbl) { |
1163 | dma_free_coherent(bus(trans)->dev, | 1167 | dma_free_coherent(bus(trans)->dev, ICT_SIZE, |
1164 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, | 1168 | trans_pcie->ict_tbl, |
1165 | trans_pcie->ict_tbl_vir, | ||
1166 | trans_pcie->ict_tbl_dma); | 1169 | trans_pcie->ict_tbl_dma); |
1167 | trans_pcie->ict_tbl_vir = NULL; | 1170 | trans_pcie->ict_tbl = NULL; |
1168 | memset(&trans_pcie->ict_tbl_dma, 0, | 1171 | trans_pcie->ict_tbl_dma = 0; |
1169 | sizeof(trans_pcie->ict_tbl_dma)); | ||
1170 | memset(&trans_pcie->aligned_ict_tbl_dma, 0, | ||
1171 | sizeof(trans_pcie->aligned_ict_tbl_dma)); | ||
1172 | } | 1172 | } |
1173 | } | 1173 | } |
1174 | 1174 | ||
1175 | 1175 | ||
1176 | /* allocate dram shared table it is a PAGE_SIZE aligned | 1176 | /* |
1177 | * allocate dram shared table, it is an aligned memory | ||
1178 | * block of ICT_SIZE. | ||
1177 | * also reset all data related to ICT table interrupt. | 1179 | * also reset all data related to ICT table interrupt. |
1178 | */ | 1180 | */ |
1179 | int iwl_alloc_isr_ict(struct iwl_trans *trans) | 1181 | int iwl_alloc_isr_ict(struct iwl_trans *trans) |
@@ -1181,36 +1183,26 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) | |||
1181 | struct iwl_trans_pcie *trans_pcie = | 1183 | struct iwl_trans_pcie *trans_pcie = |
1182 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1184 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1183 | 1185 | ||
1184 | /* allocate shrared data table */ | 1186 | trans_pcie->ict_tbl = |
1185 | trans_pcie->ict_tbl_vir = | 1187 | dma_alloc_coherent(bus(trans)->dev, ICT_SIZE, |
1186 | dma_alloc_coherent(bus(trans)->dev, | 1188 | &trans_pcie->ict_tbl_dma, |
1187 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, | 1189 | GFP_KERNEL); |
1188 | &trans_pcie->ict_tbl_dma, GFP_KERNEL); | 1190 | if (!trans_pcie->ict_tbl) |
1189 | if (!trans_pcie->ict_tbl_vir) | ||
1190 | return -ENOMEM; | 1191 | return -ENOMEM; |
1191 | 1192 | ||
1192 | /* align table to PAGE_SIZE boundary */ | 1193 | /* just an API sanity check ... it is guaranteed to be aligned */ |
1193 | trans_pcie->aligned_ict_tbl_dma = | 1194 | if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) { |
1194 | ALIGN(trans_pcie->ict_tbl_dma, PAGE_SIZE); | 1195 | iwl_free_isr_ict(trans); |
1195 | 1196 | return -EINVAL; | |
1196 | IWL_DEBUG_ISR(trans, "ict dma addr %Lx dma aligned %Lx diff %d\n", | 1197 | } |
1197 | (unsigned long long)trans_pcie->ict_tbl_dma, | ||
1198 | (unsigned long long)trans_pcie->aligned_ict_tbl_dma, | ||
1199 | (int)(trans_pcie->aligned_ict_tbl_dma - | ||
1200 | trans_pcie->ict_tbl_dma)); | ||
1201 | 1198 | ||
1202 | trans_pcie->ict_tbl = trans_pcie->ict_tbl_vir + | 1199 | IWL_DEBUG_ISR(trans, "ict dma addr %Lx\n", |
1203 | (trans_pcie->aligned_ict_tbl_dma - | 1200 | (unsigned long long)trans_pcie->ict_tbl_dma); |
1204 | trans_pcie->ict_tbl_dma); | ||
1205 | 1201 | ||
1206 | IWL_DEBUG_ISR(trans, "ict vir addr %p vir aligned %p diff %d\n", | 1202 | IWL_DEBUG_ISR(trans, "ict vir addr %p\n", trans_pcie->ict_tbl); |
1207 | trans_pcie->ict_tbl, trans_pcie->ict_tbl_vir, | ||
1208 | (int)(trans_pcie->aligned_ict_tbl_dma - | ||
1209 | trans_pcie->ict_tbl_dma)); | ||
1210 | 1203 | ||
1211 | /* reset table and index to all 0 */ | 1204 | /* reset table and index to all 0 */ |
1212 | memset(trans_pcie->ict_tbl_vir, 0, | 1205 | memset(trans_pcie->ict_tbl, 0, ICT_SIZE); |
1213 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE); | ||
1214 | trans_pcie->ict_index = 0; | 1206 | trans_pcie->ict_index = 0; |
1215 | 1207 | ||
1216 | /* add periodic RX interrupt */ | 1208 | /* add periodic RX interrupt */ |
@@ -1228,23 +1220,20 @@ int iwl_reset_ict(struct iwl_trans *trans) | |||
1228 | struct iwl_trans_pcie *trans_pcie = | 1220 | struct iwl_trans_pcie *trans_pcie = |
1229 | IWL_TRANS_GET_PCIE_TRANS(trans); | 1221 | IWL_TRANS_GET_PCIE_TRANS(trans); |
1230 | 1222 | ||
1231 | if (!trans_pcie->ict_tbl_vir) | 1223 | if (!trans_pcie->ict_tbl) |
1232 | return 0; | 1224 | return 0; |
1233 | 1225 | ||
1234 | spin_lock_irqsave(&trans->shrd->lock, flags); | 1226 | spin_lock_irqsave(&trans->shrd->lock, flags); |
1235 | iwl_disable_interrupts(trans); | 1227 | iwl_disable_interrupts(trans); |
1236 | 1228 | ||
1237 | memset(&trans_pcie->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT); | 1229 | memset(trans_pcie->ict_tbl, 0, ICT_SIZE); |
1238 | 1230 | ||
1239 | val = trans_pcie->aligned_ict_tbl_dma >> PAGE_SHIFT; | 1231 | val = trans_pcie->ict_tbl_dma >> ICT_SHIFT; |
1240 | 1232 | ||
1241 | val |= CSR_DRAM_INT_TBL_ENABLE; | 1233 | val |= CSR_DRAM_INT_TBL_ENABLE; |
1242 | val |= CSR_DRAM_INIT_TBL_WRAP_CHECK; | 1234 | val |= CSR_DRAM_INIT_TBL_WRAP_CHECK; |
1243 | 1235 | ||
1244 | IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%X " | 1236 | IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val); |
1245 | "aligned dma address %Lx\n", | ||
1246 | val, | ||
1247 | (unsigned long long)trans_pcie->aligned_ict_tbl_dma); | ||
1248 | 1237 | ||
1249 | iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val); | 1238 | iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val); |
1250 | trans_pcie->use_ict = true; | 1239 | trans_pcie->use_ict = true; |
@@ -1281,6 +1270,8 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1281 | if (!trans) | 1270 | if (!trans) |
1282 | return IRQ_NONE; | 1271 | return IRQ_NONE; |
1283 | 1272 | ||
1273 | trace_iwlwifi_dev_irq(priv(trans)); | ||
1274 | |||
1284 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1275 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1285 | 1276 | ||
1286 | spin_lock_irqsave(&trans->shrd->lock, flags); | 1277 | spin_lock_irqsave(&trans->shrd->lock, flags); |
@@ -1355,6 +1346,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1355 | struct iwl_trans_pcie *trans_pcie; | 1346 | struct iwl_trans_pcie *trans_pcie; |
1356 | u32 inta, inta_mask; | 1347 | u32 inta, inta_mask; |
1357 | u32 val = 0; | 1348 | u32 val = 0; |
1349 | u32 read; | ||
1358 | unsigned long flags; | 1350 | unsigned long flags; |
1359 | 1351 | ||
1360 | if (!trans) | 1352 | if (!trans) |
@@ -1368,6 +1360,8 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1368 | if (!trans_pcie->use_ict) | 1360 | if (!trans_pcie->use_ict) |
1369 | return iwl_isr(irq, data); | 1361 | return iwl_isr(irq, data); |
1370 | 1362 | ||
1363 | trace_iwlwifi_dev_irq(priv(trans)); | ||
1364 | |||
1371 | spin_lock_irqsave(&trans->shrd->lock, flags); | 1365 | spin_lock_irqsave(&trans->shrd->lock, flags); |
1372 | 1366 | ||
1373 | /* Disable (but don't clear!) interrupts here to avoid | 1367 | /* Disable (but don't clear!) interrupts here to avoid |
@@ -1382,24 +1376,29 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1382 | /* Ignore interrupt if there's nothing in NIC to service. | 1376 | /* Ignore interrupt if there's nothing in NIC to service. |
1383 | * This may be due to IRQ shared with another device, | 1377 | * This may be due to IRQ shared with another device, |
1384 | * or due to sporadic interrupts thrown from our NIC. */ | 1378 | * or due to sporadic interrupts thrown from our NIC. */ |
1385 | if (!trans_pcie->ict_tbl[trans_pcie->ict_index]) { | 1379 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); |
1380 | trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, read); | ||
1381 | if (!read) { | ||
1386 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); | 1382 | IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); |
1387 | goto none; | 1383 | goto none; |
1388 | } | 1384 | } |
1389 | 1385 | ||
1390 | /* read all entries that not 0 start with ict_index */ | 1386 | /* |
1391 | while (trans_pcie->ict_tbl[trans_pcie->ict_index]) { | 1387 | * Collect all entries up to the first 0, starting from ict_index; |
1392 | 1388 | * note we already read at ict_index. | |
1393 | val |= le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); | 1389 | */ |
1390 | do { | ||
1391 | val |= read; | ||
1394 | IWL_DEBUG_ISR(trans, "ICT index %d value 0x%08X\n", | 1392 | IWL_DEBUG_ISR(trans, "ICT index %d value 0x%08X\n", |
1395 | trans_pcie->ict_index, | 1393 | trans_pcie->ict_index, read); |
1396 | le32_to_cpu( | ||
1397 | trans_pcie->ict_tbl[trans_pcie->ict_index])); | ||
1398 | trans_pcie->ict_tbl[trans_pcie->ict_index] = 0; | 1394 | trans_pcie->ict_tbl[trans_pcie->ict_index] = 0; |
1399 | trans_pcie->ict_index = | 1395 | trans_pcie->ict_index = |
1400 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); | 1396 | iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); |
1401 | 1397 | ||
1402 | } | 1398 | read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); |
1399 | trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, | ||
1400 | read); | ||
1401 | } while (read); | ||
1403 | 1402 | ||
1404 | /* We should not get this value, just ignore it. */ | 1403 | /* We should not get this value, just ignore it. */ |
1405 | if (val == 0xffffffff) | 1404 | if (val == 0xffffffff) |
@@ -1426,7 +1425,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1426 | if (likely(inta)) | 1425 | if (likely(inta)) |
1427 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1426 | tasklet_schedule(&trans_pcie->irq_tasklet); |
1428 | else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1427 | else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && |
1429 | !trans_pcie->inta) { | 1428 | !trans_pcie->inta) { |
1430 | /* Allow interrupt if was disabled by this handler and | 1429 | /* Allow interrupt if was disabled by this handler and |
1431 | * no tasklet was schedules, We should not enable interrupt, | 1430 | * no tasklet was schedules, We should not enable interrupt, |
1432 | * tasklet will enable it. | 1431 | * tasklet will enable it. |
@@ -1442,7 +1441,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1442 | * only Re-enable if disabled by irq. | 1441 | * only Re-enable if disabled by irq. |
1443 | */ | 1442 | */ |
1444 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && | 1443 | if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && |
1445 | !trans_pcie->inta) | 1444 | !trans_pcie->inta) |
1446 | iwl_enable_interrupts(trans); | 1445 | iwl_enable_interrupts(trans); |
1447 | 1446 | ||
1448 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 1447 | spin_unlock_irqrestore(&trans->shrd->lock, flags); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 79331fb10aa5..bd29568177e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | |||
@@ -408,6 +408,7 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) | |||
408 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, | 408 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, |
409 | int txq_id, u32 index) | 409 | int txq_id, u32 index) |
410 | { | 410 | { |
411 | IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d", txq_id, index & 0xff); | ||
411 | iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, | 412 | iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, |
412 | (index & 0xff) | (txq_id << 8)); | 413 | (index & 0xff) | (txq_id << 8)); |
413 | iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(txq_id), index); | 414 | iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(txq_id), index); |
@@ -446,14 +447,21 @@ static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, | |||
446 | return -EINVAL; | 447 | return -EINVAL; |
447 | } | 448 | } |
448 | 449 | ||
450 | static inline bool is_agg_txqid_valid(struct iwl_trans *trans, int txq_id) | ||
451 | { | ||
452 | if (txq_id < IWLAGN_FIRST_AMPDU_QUEUE) | ||
453 | return false; | ||
454 | return txq_id < (IWLAGN_FIRST_AMPDU_QUEUE + | ||
455 | hw_params(trans).num_ampdu_queues); | ||
456 | } | ||
457 | |||
449 | void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, | 458 | void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, |
450 | enum iwl_rxon_context_id ctx, int sta_id, | 459 | enum iwl_rxon_context_id ctx, int sta_id, |
451 | int tid, int frame_limit) | 460 | int tid, int frame_limit, u16 ssn) |
452 | { | 461 | { |
453 | int tx_fifo, txq_id, ssn_idx; | 462 | int tx_fifo, txq_id; |
454 | u16 ra_tid; | 463 | u16 ra_tid; |
455 | unsigned long flags; | 464 | unsigned long flags; |
456 | struct iwl_tid_data *tid_data; | ||
457 | 465 | ||
458 | struct iwl_trans_pcie *trans_pcie = | 466 | struct iwl_trans_pcie *trans_pcie = |
459 | IWL_TRANS_GET_PCIE_TRANS(trans); | 467 | IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -469,11 +477,15 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, | |||
469 | return; | 477 | return; |
470 | } | 478 | } |
471 | 479 | ||
472 | spin_lock_irqsave(&trans->shrd->sta_lock, flags); | 480 | txq_id = trans_pcie->agg_txq[sta_id][tid]; |
473 | tid_data = &trans->shrd->tid_data[sta_id][tid]; | 481 | if (WARN_ON_ONCE(is_agg_txqid_valid(trans, txq_id) == false)) { |
474 | ssn_idx = SEQ_TO_SN(tid_data->seq_number); | 482 | IWL_ERR(trans, |
475 | txq_id = tid_data->agg.txq_id; | 483 | "queue number out of range: %d, must be %d to %d\n", |
476 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | 484 | txq_id, IWLAGN_FIRST_AMPDU_QUEUE, |
485 | IWLAGN_FIRST_AMPDU_QUEUE + | ||
486 | hw_params(trans).num_ampdu_queues - 1); | ||
487 | return; | ||
488 | } | ||
477 | 489 | ||
478 | ra_tid = BUILD_RAxTID(sta_id, tid); | 490 | ra_tid = BUILD_RAxTID(sta_id, tid); |
479 | 491 | ||
@@ -493,9 +505,9 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, | |||
493 | 505 | ||
494 | /* Place first TFD at index corresponding to start sequence number. | 506 | /* Place first TFD at index corresponding to start sequence number. |
495 | * Assumes that ssn_idx is valid (!= 0xFFF) */ | 507 | * Assumes that ssn_idx is valid (!= 0xFFF) */ |
496 | trans_pcie->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); | 508 | trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); |
497 | trans_pcie->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); | 509 | trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); |
498 | iwl_trans_set_wr_ptrs(trans, txq_id, ssn_idx); | 510 | iwl_trans_set_wr_ptrs(trans, txq_id, ssn); |
499 | 511 | ||
500 | /* Set up Tx window size and frame limit for this queue */ | 512 | /* Set up Tx window size and frame limit for this queue */ |
501 | iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + | 513 | iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + |
@@ -539,12 +551,9 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_trans *trans) | |||
539 | } | 551 | } |
540 | 552 | ||
541 | int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, | 553 | int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, |
542 | enum iwl_rxon_context_id ctx, int sta_id, | 554 | int sta_id, int tid) |
543 | int tid, u16 *ssn) | ||
544 | { | 555 | { |
545 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 556 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
546 | struct iwl_tid_data *tid_data; | ||
547 | unsigned long flags; | ||
548 | int txq_id; | 557 | int txq_id; |
549 | 558 | ||
550 | txq_id = iwlagn_txq_ctx_activate_free(trans); | 559 | txq_id = iwlagn_txq_ctx_activate_free(trans); |
@@ -553,118 +562,39 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, | |||
553 | return -ENXIO; | 562 | return -ENXIO; |
554 | } | 563 | } |
555 | 564 | ||
556 | spin_lock_irqsave(&trans->shrd->sta_lock, flags); | 565 | trans_pcie->agg_txq[sta_id][tid] = txq_id; |
557 | tid_data = &trans->shrd->tid_data[sta_id][tid]; | ||
558 | *ssn = SEQ_TO_SN(tid_data->seq_number); | ||
559 | tid_data->agg.txq_id = txq_id; | ||
560 | iwl_set_swq_id(&trans_pcie->txq[txq_id], get_ac_from_tid(tid), txq_id); | 566 | iwl_set_swq_id(&trans_pcie->txq[txq_id], get_ac_from_tid(tid), txq_id); |
561 | 567 | ||
562 | if (tid_data->tfds_in_queue == 0) { | ||
563 | IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n"); | ||
564 | tid_data->agg.state = IWL_AGG_ON; | ||
565 | iwl_start_tx_ba_trans_ready(priv(trans), ctx, sta_id, tid); | ||
566 | } else { | ||
567 | IWL_DEBUG_TX_QUEUES(trans, | ||
568 | "HW queue is NOT empty: %d packets in HW" | ||
569 | " queue\n", tid_data->tfds_in_queue); | ||
570 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; | ||
571 | } | ||
572 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | ||
573 | |||
574 | return 0; | 568 | return 0; |
575 | } | 569 | } |
576 | 570 | ||
577 | void iwl_trans_pcie_txq_agg_disable(struct iwl_trans *trans, int txq_id) | 571 | int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) |
578 | { | 572 | { |
579 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 573 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
580 | iwlagn_tx_queue_stop_scheduler(trans, txq_id); | 574 | u8 txq_id = trans_pcie->agg_txq[sta_id][tid]; |
581 | |||
582 | iwl_clear_bits_prph(bus(trans), SCD_AGGR_SEL, (1 << txq_id)); | ||
583 | |||
584 | trans_pcie->txq[txq_id].q.read_ptr = 0; | ||
585 | trans_pcie->txq[txq_id].q.write_ptr = 0; | ||
586 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | ||
587 | iwl_trans_set_wr_ptrs(trans, txq_id, 0); | ||
588 | 575 | ||
589 | iwl_clear_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); | 576 | if (WARN_ON_ONCE(is_agg_txqid_valid(trans, txq_id) == false)) { |
590 | iwl_txq_ctx_deactivate(trans_pcie, txq_id); | ||
591 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0); | ||
592 | } | ||
593 | |||
594 | int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, | ||
595 | enum iwl_rxon_context_id ctx, int sta_id, | ||
596 | int tid) | ||
597 | { | ||
598 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
599 | unsigned long flags; | ||
600 | int read_ptr, write_ptr; | ||
601 | struct iwl_tid_data *tid_data; | ||
602 | int txq_id; | ||
603 | |||
604 | spin_lock_irqsave(&trans->shrd->sta_lock, flags); | ||
605 | |||
606 | tid_data = &trans->shrd->tid_data[sta_id][tid]; | ||
607 | txq_id = tid_data->agg.txq_id; | ||
608 | |||
609 | if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || | ||
610 | (IWLAGN_FIRST_AMPDU_QUEUE + | ||
611 | hw_params(trans).num_ampdu_queues <= txq_id)) { | ||
612 | IWL_ERR(trans, | 577 | IWL_ERR(trans, |
613 | "queue number out of range: %d, must be %d to %d\n", | 578 | "queue number out of range: %d, must be %d to %d\n", |
614 | txq_id, IWLAGN_FIRST_AMPDU_QUEUE, | 579 | txq_id, IWLAGN_FIRST_AMPDU_QUEUE, |
615 | IWLAGN_FIRST_AMPDU_QUEUE + | 580 | IWLAGN_FIRST_AMPDU_QUEUE + |
616 | hw_params(trans).num_ampdu_queues - 1); | 581 | hw_params(trans).num_ampdu_queues - 1); |
617 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | ||
618 | return -EINVAL; | 582 | return -EINVAL; |
619 | } | 583 | } |
620 | 584 | ||
621 | switch (trans->shrd->tid_data[sta_id][tid].agg.state) { | 585 | iwlagn_tx_queue_stop_scheduler(trans, txq_id); |
622 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | ||
623 | /* | ||
624 | * This can happen if the peer stops aggregation | ||
625 | * again before we've had a chance to drain the | ||
626 | * queue we selected previously, i.e. before the | ||
627 | * session was really started completely. | ||
628 | */ | ||
629 | IWL_DEBUG_HT(trans, "AGG stop before setup done\n"); | ||
630 | goto turn_off; | ||
631 | case IWL_AGG_ON: | ||
632 | break; | ||
633 | default: | ||
634 | IWL_WARN(trans, "Stopping AGG while state not ON " | ||
635 | "or starting for %d on %d (%d)\n", sta_id, tid, | ||
636 | trans->shrd->tid_data[sta_id][tid].agg.state); | ||
637 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | write_ptr = trans_pcie->txq[txq_id].q.write_ptr; | ||
642 | read_ptr = trans_pcie->txq[txq_id].q.read_ptr; | ||
643 | |||
644 | /* The queue is not empty */ | ||
645 | if (write_ptr != read_ptr) { | ||
646 | IWL_DEBUG_TX_QUEUES(trans, | ||
647 | "Stopping a non empty AGG HW QUEUE\n"); | ||
648 | trans->shrd->tid_data[sta_id][tid].agg.state = | ||
649 | IWL_EMPTYING_HW_QUEUE_DELBA; | ||
650 | spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); | ||
651 | return 0; | ||
652 | } | ||
653 | |||
654 | IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n"); | ||
655 | turn_off: | ||
656 | trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; | ||
657 | |||
658 | /* do not restore/save irqs */ | ||
659 | spin_unlock(&trans->shrd->sta_lock); | ||
660 | spin_lock(&trans->shrd->lock); | ||
661 | |||
662 | iwl_trans_pcie_txq_agg_disable(trans, txq_id); | ||
663 | 586 | ||
664 | spin_unlock_irqrestore(&trans->shrd->lock, flags); | 587 | iwl_clear_bits_prph(bus(trans), SCD_AGGR_SEL, (1 << txq_id)); |
665 | 588 | ||
666 | iwl_stop_tx_ba_trans_ready(priv(trans), ctx, sta_id, tid); | 589 | trans_pcie->agg_txq[sta_id][tid] = 0; |
590 | trans_pcie->txq[txq_id].q.read_ptr = 0; | ||
591 | trans_pcie->txq[txq_id].q.write_ptr = 0; | ||
592 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | ||
593 | iwl_trans_set_wr_ptrs(trans, txq_id, 0); | ||
667 | 594 | ||
595 | iwl_clear_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
596 | iwl_txq_ctx_deactivate(trans_pcie, txq_id); | ||
597 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0); | ||
668 | return 0; | 598 | return 0; |
669 | } | 599 | } |
670 | 600 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 3cf62c363bc0..cb9da25bd81d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -1044,7 +1044,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1044 | 1044 | ||
1045 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | 1045 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
1046 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 1046 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
1047 | u8 sta_id) | 1047 | u8 sta_id, u8 tid) |
1048 | { | 1048 | { |
1049 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1049 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1050 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1050 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
@@ -1058,13 +1058,12 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1058 | dma_addr_t txcmd_phys; | 1058 | dma_addr_t txcmd_phys; |
1059 | dma_addr_t scratch_phys; | 1059 | dma_addr_t scratch_phys; |
1060 | u16 len, firstlen, secondlen; | 1060 | u16 len, firstlen, secondlen; |
1061 | u16 seq_number = 0; | ||
1062 | u8 wait_write_ptr = 0; | 1061 | u8 wait_write_ptr = 0; |
1063 | u8 txq_id; | 1062 | u8 txq_id; |
1064 | u8 tid = 0; | ||
1065 | bool is_agg = false; | 1063 | bool is_agg = false; |
1066 | __le16 fc = hdr->frame_control; | 1064 | __le16 fc = hdr->frame_control; |
1067 | u8 hdr_len = ieee80211_hdrlen(fc); | 1065 | u8 hdr_len = ieee80211_hdrlen(fc); |
1066 | u16 __maybe_unused wifi_seq; | ||
1068 | 1067 | ||
1069 | /* | 1068 | /* |
1070 | * Send this frame after DTIM -- there's a special queue | 1069 | * Send this frame after DTIM -- there's a special queue |
@@ -1085,44 +1084,28 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1085 | txq_id = | 1084 | txq_id = |
1086 | trans_pcie->ac_to_queue[ctx][skb_get_queue_mapping(skb)]; | 1085 | trans_pcie->ac_to_queue[ctx][skb_get_queue_mapping(skb)]; |
1087 | 1086 | ||
1088 | if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { | 1087 | /* aggregation is on for this <sta,tid> */ |
1089 | u8 *qc = NULL; | 1088 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { |
1090 | struct iwl_tid_data *tid_data; | 1089 | WARN_ON(tid >= IWL_MAX_TID_COUNT); |
1091 | qc = ieee80211_get_qos_ctl(hdr); | 1090 | txq_id = trans_pcie->agg_txq[sta_id][tid]; |
1092 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 1091 | is_agg = true; |
1093 | tid_data = &trans->shrd->tid_data[sta_id][tid]; | ||
1094 | |||
1095 | if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) | ||
1096 | return -1; | ||
1097 | |||
1098 | seq_number = tid_data->seq_number; | ||
1099 | seq_number &= IEEE80211_SCTL_SEQ; | ||
1100 | hdr->seq_ctrl = hdr->seq_ctrl & | ||
1101 | cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
1102 | hdr->seq_ctrl |= cpu_to_le16(seq_number); | ||
1103 | /* aggregation is on for this <sta,tid> */ | ||
1104 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
1105 | if (WARN_ON_ONCE(tid_data->agg.state != IWL_AGG_ON)) { | ||
1106 | IWL_ERR(trans, "TX_CTL_AMPDU while not in AGG:" | ||
1107 | " Tx flags = 0x%08x, agg.state = %d", | ||
1108 | info->flags, tid_data->agg.state); | ||
1109 | IWL_ERR(trans, "sta_id = %d, tid = %d " | ||
1110 | "txq_id = %d, seq_num = %d", sta_id, | ||
1111 | tid, tid_data->agg.txq_id, | ||
1112 | seq_number >> 4); | ||
1113 | } | ||
1114 | txq_id = tid_data->agg.txq_id; | ||
1115 | is_agg = true; | ||
1116 | } | ||
1117 | seq_number += 0x10; | ||
1118 | } | 1092 | } |
1119 | 1093 | ||
1120 | /* Copy MAC header from skb into command buffer */ | ||
1121 | memcpy(tx_cmd->hdr, hdr, hdr_len); | ||
1122 | |||
1123 | txq = &trans_pcie->txq[txq_id]; | 1094 | txq = &trans_pcie->txq[txq_id]; |
1124 | q = &txq->q; | 1095 | q = &txq->q; |
1125 | 1096 | ||
1097 | /* In AGG mode, the index in the ring must correspond to the WiFi | ||
1098 | * sequence number. This is a HW requirements to help the SCD to parse | ||
1099 | * the BA. | ||
1100 | * Check here that the packets are in the right place on the ring. | ||
1101 | */ | ||
1102 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1103 | wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); | ||
1104 | WARN_ONCE(is_agg && ((wifi_seq & 0xff) != q->write_ptr), | ||
1105 | "Q: %d WiFi Seq %d tfdNum %d", | ||
1106 | txq_id, wifi_seq, q->write_ptr); | ||
1107 | #endif | ||
1108 | |||
1126 | /* Set up driver data for this TFD */ | 1109 | /* Set up driver data for this TFD */ |
1127 | txq->skbs[q->write_ptr] = skb; | 1110 | txq->skbs[q->write_ptr] = skb; |
1128 | txq->cmd[q->write_ptr] = dev_cmd; | 1111 | txq->cmd[q->write_ptr] = dev_cmd; |
@@ -1220,13 +1203,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1220 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1203 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
1221 | iwl_txq_update_write_ptr(trans, txq); | 1204 | iwl_txq_update_write_ptr(trans, txq); |
1222 | 1205 | ||
1223 | if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { | ||
1224 | trans->shrd->tid_data[sta_id][tid].tfds_in_queue++; | ||
1225 | if (!ieee80211_has_morefrags(fc)) | ||
1226 | trans->shrd->tid_data[sta_id][tid].seq_number = | ||
1227 | seq_number; | ||
1228 | } | ||
1229 | |||
1230 | /* | 1206 | /* |
1231 | * At this point the frame is "transmitted" successfully | 1207 | * At this point the frame is "transmitted" successfully |
1232 | * and we will get a TX status notification eventually, | 1208 | * and we will get a TX status notification eventually, |
@@ -1275,85 +1251,30 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) | |||
1275 | return 0; | 1251 | return 0; |
1276 | } | 1252 | } |
1277 | 1253 | ||
1278 | static int iwlagn_txq_check_empty(struct iwl_trans *trans, | 1254 | static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, |
1279 | int sta_id, u8 tid, int txq_id) | ||
1280 | { | ||
1281 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1282 | struct iwl_queue *q = &trans_pcie->txq[txq_id].q; | ||
1283 | struct iwl_tid_data *tid_data = &trans->shrd->tid_data[sta_id][tid]; | ||
1284 | |||
1285 | lockdep_assert_held(&trans->shrd->sta_lock); | ||
1286 | |||
1287 | switch (trans->shrd->tid_data[sta_id][tid].agg.state) { | ||
1288 | case IWL_EMPTYING_HW_QUEUE_DELBA: | ||
1289 | /* We are reclaiming the last packet of the */ | ||
1290 | /* aggregated HW queue */ | ||
1291 | if ((txq_id == tid_data->agg.txq_id) && | ||
1292 | (q->read_ptr == q->write_ptr)) { | ||
1293 | IWL_DEBUG_TX_QUEUES(trans, | ||
1294 | "HW queue empty: continue DELBA flow\n"); | ||
1295 | iwl_trans_pcie_txq_agg_disable(trans, txq_id); | ||
1296 | tid_data->agg.state = IWL_AGG_OFF; | ||
1297 | iwl_stop_tx_ba_trans_ready(priv(trans), | ||
1298 | NUM_IWL_RXON_CTX, | ||
1299 | sta_id, tid); | ||
1300 | iwl_wake_queue(trans, &trans_pcie->txq[txq_id], | ||
1301 | "DELBA flow complete"); | ||
1302 | } | ||
1303 | break; | ||
1304 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | ||
1305 | /* We are reclaiming the last packet of the queue */ | ||
1306 | if (tid_data->tfds_in_queue == 0) { | ||
1307 | IWL_DEBUG_TX_QUEUES(trans, | ||
1308 | "HW queue empty: continue ADDBA flow\n"); | ||
1309 | tid_data->agg.state = IWL_AGG_ON; | ||
1310 | iwl_start_tx_ba_trans_ready(priv(trans), | ||
1311 | NUM_IWL_RXON_CTX, | ||
1312 | sta_id, tid); | ||
1313 | } | ||
1314 | break; | ||
1315 | default: | ||
1316 | break; | ||
1317 | } | ||
1318 | |||
1319 | return 0; | ||
1320 | } | ||
1321 | |||
1322 | static void iwl_free_tfds_in_queue(struct iwl_trans *trans, | ||
1323 | int sta_id, int tid, int freed) | ||
1324 | { | ||
1325 | lockdep_assert_held(&trans->shrd->sta_lock); | ||
1326 | |||
1327 | if (trans->shrd->tid_data[sta_id][tid].tfds_in_queue >= freed) | ||
1328 | trans->shrd->tid_data[sta_id][tid].tfds_in_queue -= freed; | ||
1329 | else { | ||
1330 | IWL_DEBUG_TX(trans, "free more than tfds_in_queue (%u:%d)\n", | ||
1331 | trans->shrd->tid_data[sta_id][tid].tfds_in_queue, | ||
1332 | freed); | ||
1333 | trans->shrd->tid_data[sta_id][tid].tfds_in_queue = 0; | ||
1334 | } | ||
1335 | } | ||
1336 | |||
1337 | static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | ||
1338 | int txq_id, int ssn, u32 status, | 1255 | int txq_id, int ssn, u32 status, |
1339 | struct sk_buff_head *skbs) | 1256 | struct sk_buff_head *skbs) |
1340 | { | 1257 | { |
1341 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1258 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1342 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 1259 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
1343 | enum iwl_agg_state agg_state; | ||
1344 | /* n_bd is usually 256 => n_bd - 1 = 0xff */ | 1260 | /* n_bd is usually 256 => n_bd - 1 = 0xff */ |
1345 | int tfd_num = ssn & (txq->q.n_bd - 1); | 1261 | int tfd_num = ssn & (txq->q.n_bd - 1); |
1346 | int freed = 0; | 1262 | int freed = 0; |
1347 | bool cond; | ||
1348 | 1263 | ||
1349 | txq->time_stamp = jiffies; | 1264 | txq->time_stamp = jiffies; |
1350 | 1265 | ||
1351 | if (txq->sched_retry) { | 1266 | if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE && |
1352 | agg_state = | 1267 | txq_id != trans_pcie->agg_txq[sta_id][tid])) { |
1353 | trans->shrd->tid_data[txq->sta_id][txq->tid].agg.state; | 1268 | /* |
1354 | cond = (agg_state != IWL_EMPTYING_HW_QUEUE_DELBA); | 1269 | * FIXME: this is a uCode bug which need to be addressed, |
1355 | } else { | 1270 | * log the information and return for now. |
1356 | cond = (status != TX_STATUS_FAIL_PASSIVE_NO_RX); | 1271 | * Since it is can possibly happen very often and in order |
1272 | * not to fill the syslog, don't use IWL_ERR or IWL_WARN | ||
1273 | */ | ||
1274 | IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, " | ||
1275 | "agg_txq[sta_id[tid] %d", txq_id, | ||
1276 | trans_pcie->agg_txq[sta_id][tid]); | ||
1277 | return 1; | ||
1357 | } | 1278 | } |
1358 | 1279 | ||
1359 | if (txq->q.read_ptr != tfd_num) { | 1280 | if (txq->q.read_ptr != tfd_num) { |
@@ -1361,12 +1282,12 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, | |||
1361 | txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr, | 1282 | txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr, |
1362 | tfd_num, ssn); | 1283 | tfd_num, ssn); |
1363 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); | 1284 | freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); |
1364 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && cond) | 1285 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && |
1286 | (!txq->sched_retry || | ||
1287 | status != TX_STATUS_FAIL_PASSIVE_NO_RX)) | ||
1365 | iwl_wake_queue(trans, txq, "Packets reclaimed"); | 1288 | iwl_wake_queue(trans, txq, "Packets reclaimed"); |
1366 | } | 1289 | } |
1367 | 1290 | return 0; | |
1368 | iwl_free_tfds_in_queue(trans, sta_id, tid, freed); | ||
1369 | iwlagn_txq_check_empty(trans, sta_id, tid, txq_id); | ||
1370 | } | 1291 | } |
1371 | 1292 | ||
1372 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1293 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index f94a6ee5f82f..e6bf3f554772 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -178,20 +178,18 @@ struct iwl_trans_ops { | |||
178 | 178 | ||
179 | int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, | 179 | int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, |
180 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 180 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
181 | u8 sta_id); | 181 | u8 sta_id, u8 tid); |
182 | void (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, | 182 | int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, |
183 | int txq_id, int ssn, u32 status, | 183 | int txq_id, int ssn, u32 status, |
184 | struct sk_buff_head *skbs); | 184 | struct sk_buff_head *skbs); |
185 | 185 | ||
186 | int (*tx_agg_disable)(struct iwl_trans *trans, | 186 | int (*tx_agg_disable)(struct iwl_trans *trans, |
187 | enum iwl_rxon_context_id ctx, int sta_id, | 187 | int sta_id, int tid); |
188 | int tid); | ||
189 | int (*tx_agg_alloc)(struct iwl_trans *trans, | 188 | int (*tx_agg_alloc)(struct iwl_trans *trans, |
190 | enum iwl_rxon_context_id ctx, int sta_id, int tid, | 189 | int sta_id, int tid); |
191 | u16 *ssn); | ||
192 | void (*tx_agg_setup)(struct iwl_trans *trans, | 190 | void (*tx_agg_setup)(struct iwl_trans *trans, |
193 | enum iwl_rxon_context_id ctx, int sta_id, int tid, | 191 | enum iwl_rxon_context_id ctx, int sta_id, int tid, |
194 | int frame_limit); | 192 | int frame_limit, u16 ssn); |
195 | 193 | ||
196 | void (*kick_nic)(struct iwl_trans *trans); | 194 | void (*kick_nic)(struct iwl_trans *trans); |
197 | 195 | ||
@@ -305,39 +303,38 @@ int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, | |||
305 | 303 | ||
306 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | 304 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, |
307 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, | 305 | struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, |
308 | u8 sta_id) | 306 | u8 sta_id, u8 tid) |
309 | { | 307 | { |
310 | return trans->ops->tx(trans, skb, dev_cmd, ctx, sta_id); | 308 | return trans->ops->tx(trans, skb, dev_cmd, ctx, sta_id, tid); |
311 | } | 309 | } |
312 | 310 | ||
313 | static inline void iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, | 311 | static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, |
314 | int tid, int txq_id, int ssn, u32 status, | 312 | int tid, int txq_id, int ssn, u32 status, |
315 | struct sk_buff_head *skbs) | 313 | struct sk_buff_head *skbs) |
316 | { | 314 | { |
317 | trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, status, skbs); | 315 | return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, |
316 | status, skbs); | ||
318 | } | 317 | } |
319 | 318 | ||
320 | static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, | 319 | static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, |
321 | enum iwl_rxon_context_id ctx, | ||
322 | int sta_id, int tid) | 320 | int sta_id, int tid) |
323 | { | 321 | { |
324 | return trans->ops->tx_agg_disable(trans, ctx, sta_id, tid); | 322 | return trans->ops->tx_agg_disable(trans, sta_id, tid); |
325 | } | 323 | } |
326 | 324 | ||
327 | static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, | 325 | static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, |
328 | enum iwl_rxon_context_id ctx, | 326 | int sta_id, int tid) |
329 | int sta_id, int tid, u16 *ssn) | ||
330 | { | 327 | { |
331 | return trans->ops->tx_agg_alloc(trans, ctx, sta_id, tid, ssn); | 328 | return trans->ops->tx_agg_alloc(trans, sta_id, tid); |
332 | } | 329 | } |
333 | 330 | ||
334 | 331 | ||
335 | static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, | 332 | static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, |
336 | enum iwl_rxon_context_id ctx, | 333 | enum iwl_rxon_context_id ctx, |
337 | int sta_id, int tid, | 334 | int sta_id, int tid, |
338 | int frame_limit) | 335 | int frame_limit, u16 ssn) |
339 | { | 336 | { |
340 | trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit); | 337 | trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); |
341 | } | 338 | } |
342 | 339 | ||
343 | static inline void iwl_trans_kick_nic(struct iwl_trans *trans) | 340 | static inline void iwl_trans_kick_nic(struct iwl_trans *trans) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 0577212ad3f3..36a1b5b25858 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | 35 | ||
36 | #include "iwl-wifi.h" | ||
36 | #include "iwl-dev.h" | 37 | #include "iwl-dev.h" |
37 | #include "iwl-core.h" | 38 | #include "iwl-core.h" |
38 | #include "iwl-io.h" | 39 | #include "iwl-io.h" |
@@ -213,23 +214,23 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, | |||
213 | /* | 214 | /* |
214 | * Calibration | 215 | * Calibration |
215 | */ | 216 | */ |
216 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) | 217 | static int iwl_set_Xtal_calib(struct iwl_trans *trans) |
217 | { | 218 | { |
218 | struct iwl_calib_xtal_freq_cmd cmd; | 219 | struct iwl_calib_xtal_freq_cmd cmd; |
219 | __le16 *xtal_calib = | 220 | __le16 *xtal_calib = |
220 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL); | 221 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, EEPROM_XTAL); |
221 | 222 | ||
222 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); | 223 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); |
223 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | 224 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
224 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); | 225 | cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]); |
225 | return iwl_calib_set(trans(priv), (void *)&cmd, sizeof(cmd)); | 226 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); |
226 | } | 227 | } |
227 | 228 | ||
228 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) | 229 | static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) |
229 | { | 230 | { |
230 | struct iwl_calib_temperature_offset_cmd cmd; | 231 | struct iwl_calib_temperature_offset_cmd cmd; |
231 | __le16 *offset_calib = | 232 | __le16 *offset_calib = |
232 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, | 233 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, |
233 | EEPROM_RAW_TEMPERATURE); | 234 | EEPROM_RAW_TEMPERATURE); |
234 | 235 | ||
235 | memset(&cmd, 0, sizeof(cmd)); | 236 | memset(&cmd, 0, sizeof(cmd)); |
@@ -238,45 +239,45 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) | |||
238 | if (!(cmd.radio_sensor_offset)) | 239 | if (!(cmd.radio_sensor_offset)) |
239 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; | 240 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; |
240 | 241 | ||
241 | IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", | 242 | IWL_DEBUG_CALIB(trans, "Radio sensor offset: %d\n", |
242 | le16_to_cpu(cmd.radio_sensor_offset)); | 243 | le16_to_cpu(cmd.radio_sensor_offset)); |
243 | return iwl_calib_set(trans(priv), (void *)&cmd, sizeof(cmd)); | 244 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); |
244 | } | 245 | } |
245 | 246 | ||
246 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) | 247 | static int iwl_set_temperature_offset_calib_v2(struct iwl_trans *trans) |
247 | { | 248 | { |
248 | struct iwl_calib_temperature_offset_v2_cmd cmd; | 249 | struct iwl_calib_temperature_offset_v2_cmd cmd; |
249 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd, | 250 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(trans->shrd, |
250 | EEPROM_KELVIN_TEMPERATURE); | 251 | EEPROM_KELVIN_TEMPERATURE); |
251 | __le16 *offset_calib_low = | 252 | __le16 *offset_calib_low = |
252 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, | 253 | (__le16 *)iwl_eeprom_query_addr(trans->shrd, |
253 | EEPROM_RAW_TEMPERATURE); | 254 | EEPROM_RAW_TEMPERATURE); |
254 | struct iwl_eeprom_calib_hdr *hdr; | 255 | struct iwl_eeprom_calib_hdr *hdr; |
255 | 256 | ||
256 | memset(&cmd, 0, sizeof(cmd)); | 257 | memset(&cmd, 0, sizeof(cmd)); |
257 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 258 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
258 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd, | 259 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(trans->shrd, |
259 | EEPROM_CALIB_ALL); | 260 | EEPROM_CALIB_ALL); |
260 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, | 261 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, |
261 | sizeof(*offset_calib_high)); | 262 | sizeof(*offset_calib_high)); |
262 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, | 263 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, |
263 | sizeof(*offset_calib_low)); | 264 | sizeof(*offset_calib_low)); |
264 | if (!(cmd.radio_sensor_offset_low)) { | 265 | if (!(cmd.radio_sensor_offset_low)) { |
265 | IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); | 266 | IWL_DEBUG_CALIB(trans, "no info in EEPROM, use default\n"); |
266 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; | 267 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; |
267 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; | 268 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; |
268 | } | 269 | } |
269 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, | 270 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, |
270 | sizeof(hdr->voltage)); | 271 | sizeof(hdr->voltage)); |
271 | 272 | ||
272 | IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", | 273 | IWL_DEBUG_CALIB(trans, "Radio sensor offset high: %d\n", |
273 | le16_to_cpu(cmd.radio_sensor_offset_high)); | 274 | le16_to_cpu(cmd.radio_sensor_offset_high)); |
274 | IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", | 275 | IWL_DEBUG_CALIB(trans, "Radio sensor offset low: %d\n", |
275 | le16_to_cpu(cmd.radio_sensor_offset_low)); | 276 | le16_to_cpu(cmd.radio_sensor_offset_low)); |
276 | IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", | 277 | IWL_DEBUG_CALIB(trans, "Voltage Ref: %d\n", |
277 | le16_to_cpu(cmd.burntVoltageRef)); | 278 | le16_to_cpu(cmd.burntVoltageRef)); |
278 | 279 | ||
279 | return iwl_calib_set(trans(priv), (void *)&cmd, sizeof(cmd)); | 280 | return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); |
280 | } | 281 | } |
281 | 282 | ||
282 | static int iwl_send_calib_cfg(struct iwl_trans *trans) | 283 | static int iwl_send_calib_cfg(struct iwl_trans *trans) |
@@ -316,26 +317,26 @@ int iwlagn_rx_calib_result(struct iwl_priv *priv, | |||
316 | return 0; | 317 | return 0; |
317 | } | 318 | } |
318 | 319 | ||
319 | int iwlagn_init_alive_start(struct iwl_priv *priv) | 320 | int iwl_init_alive_start(struct iwl_trans *trans) |
320 | { | 321 | { |
321 | int ret; | 322 | int ret; |
322 | 323 | ||
323 | if (priv->cfg->bt_params && | 324 | if (cfg(trans)->bt_params && |
324 | priv->cfg->bt_params->advanced_bt_coexist) { | 325 | cfg(trans)->bt_params->advanced_bt_coexist) { |
325 | /* | 326 | /* |
326 | * Tell uCode we are ready to perform calibration | 327 | * Tell uCode we are ready to perform calibration |
327 | * need to perform this before any calibration | 328 | * need to perform this before any calibration |
328 | * no need to close the envlope since we are going | 329 | * no need to close the envlope since we are going |
329 | * to load the runtime uCode later. | 330 | * to load the runtime uCode later. |
330 | */ | 331 | */ |
331 | ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN, | 332 | ret = iwl_send_bt_env(trans, IWL_BT_COEX_ENV_OPEN, |
332 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | 333 | BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); |
333 | if (ret) | 334 | if (ret) |
334 | return ret; | 335 | return ret; |
335 | 336 | ||
336 | } | 337 | } |
337 | 338 | ||
338 | ret = iwl_send_calib_cfg(trans(priv)); | 339 | ret = iwl_send_calib_cfg(trans); |
339 | if (ret) | 340 | if (ret) |
340 | return ret; | 341 | return ret; |
341 | 342 | ||
@@ -343,21 +344,21 @@ int iwlagn_init_alive_start(struct iwl_priv *priv) | |||
343 | * temperature offset calibration is only needed for runtime ucode, | 344 | * temperature offset calibration is only needed for runtime ucode, |
344 | * so prepare the value now. | 345 | * so prepare the value now. |
345 | */ | 346 | */ |
346 | if (priv->cfg->need_temp_offset_calib) { | 347 | if (cfg(trans)->need_temp_offset_calib) { |
347 | if (priv->cfg->temp_offset_v2) | 348 | if (cfg(trans)->temp_offset_v2) |
348 | return iwl_set_temperature_offset_calib_v2(priv); | 349 | return iwl_set_temperature_offset_calib_v2(trans); |
349 | else | 350 | else |
350 | return iwl_set_temperature_offset_calib(priv); | 351 | return iwl_set_temperature_offset_calib(trans); |
351 | } | 352 | } |
352 | 353 | ||
353 | return 0; | 354 | return 0; |
354 | } | 355 | } |
355 | 356 | ||
356 | static int iwl_send_wimax_coex(struct iwl_priv *priv) | 357 | static int iwl_send_wimax_coex(struct iwl_trans *trans) |
357 | { | 358 | { |
358 | struct iwl_wimax_coex_cmd coex_cmd; | 359 | struct iwl_wimax_coex_cmd coex_cmd; |
359 | 360 | ||
360 | if (priv->cfg->base_params->support_wimax_coexist) { | 361 | if (cfg(trans)->base_params->support_wimax_coexist) { |
361 | /* UnMask wake up src at associated sleep */ | 362 | /* UnMask wake up src at associated sleep */ |
362 | coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; | 363 | coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; |
363 | 364 | ||
@@ -376,7 +377,7 @@ static int iwl_send_wimax_coex(struct iwl_priv *priv) | |||
376 | /* coexistence is disabled */ | 377 | /* coexistence is disabled */ |
377 | memset(&coex_cmd, 0, sizeof(coex_cmd)); | 378 | memset(&coex_cmd, 0, sizeof(coex_cmd)); |
378 | } | 379 | } |
379 | return iwl_trans_send_cmd_pdu(trans(priv), | 380 | return iwl_trans_send_cmd_pdu(trans, |
380 | COEX_PRIORITY_TABLE_CMD, CMD_SYNC, | 381 | COEX_PRIORITY_TABLE_CMD, CMD_SYNC, |
381 | sizeof(coex_cmd), &coex_cmd); | 382 | sizeof(coex_cmd), &coex_cmd); |
382 | } | 383 | } |
@@ -431,8 +432,9 @@ int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type) | |||
431 | } | 432 | } |
432 | 433 | ||
433 | 434 | ||
434 | static int iwl_alive_notify(struct iwl_priv *priv) | 435 | static int iwl_alive_notify(struct iwl_trans *trans) |
435 | { | 436 | { |
437 | struct iwl_priv *priv = priv(trans); | ||
436 | struct iwl_rxon_context *ctx; | 438 | struct iwl_rxon_context *ctx; |
437 | int ret; | 439 | int ret; |
438 | 440 | ||
@@ -445,21 +447,21 @@ static int iwl_alive_notify(struct iwl_priv *priv) | |||
445 | if (!priv->tx_cmd_pool) | 447 | if (!priv->tx_cmd_pool) |
446 | return -ENOMEM; | 448 | return -ENOMEM; |
447 | 449 | ||
448 | iwl_trans_tx_start(trans(priv)); | 450 | iwl_trans_tx_start(trans); |
449 | for_each_context(priv, ctx) | 451 | for_each_context(priv, ctx) |
450 | ctx->last_tx_rejected = false; | 452 | ctx->last_tx_rejected = false; |
451 | 453 | ||
452 | ret = iwl_send_wimax_coex(priv); | 454 | ret = iwl_send_wimax_coex(trans); |
453 | if (ret) | 455 | if (ret) |
454 | return ret; | 456 | return ret; |
455 | 457 | ||
456 | if (!priv->cfg->no_xtal_calib) { | 458 | if (!cfg(priv)->no_xtal_calib) { |
457 | ret = iwl_set_Xtal_calib(priv); | 459 | ret = iwl_set_Xtal_calib(trans); |
458 | if (ret) | 460 | if (ret) |
459 | return ret; | 461 | return ret; |
460 | } | 462 | } |
461 | 463 | ||
462 | return iwl_send_calib_results(trans(priv)); | 464 | return iwl_send_calib_results(trans); |
463 | } | 465 | } |
464 | 466 | ||
465 | 467 | ||
@@ -545,7 +547,7 @@ static int iwl_verify_ucode(struct iwl_trans *trans, | |||
545 | return -EIO; | 547 | return -EIO; |
546 | } | 548 | } |
547 | 549 | ||
548 | struct iwlagn_alive_data { | 550 | struct iwl_alive_data { |
549 | bool valid; | 551 | bool valid; |
550 | u8 subtype; | 552 | u8 subtype; |
551 | }; | 553 | }; |
@@ -554,7 +556,7 @@ static void iwl_alive_fn(struct iwl_trans *trans, | |||
554 | struct iwl_rx_packet *pkt, | 556 | struct iwl_rx_packet *pkt, |
555 | void *data) | 557 | void *data) |
556 | { | 558 | { |
557 | struct iwlagn_alive_data *alive_data = data; | 559 | struct iwl_alive_data *alive_data = data; |
558 | struct iwl_alive_resp *palive; | 560 | struct iwl_alive_resp *palive; |
559 | 561 | ||
560 | palive = &pkt->u.alive_frame; | 562 | palive = &pkt->u.alive_frame; |
@@ -640,12 +642,11 @@ void iwl_abort_notification_waits(struct iwl_shared *shrd) | |||
640 | #define UCODE_ALIVE_TIMEOUT HZ | 642 | #define UCODE_ALIVE_TIMEOUT HZ |
641 | #define UCODE_CALIB_TIMEOUT (2*HZ) | 643 | #define UCODE_CALIB_TIMEOUT (2*HZ) |
642 | 644 | ||
643 | int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | 645 | int iwl_load_ucode_wait_alive(struct iwl_trans *trans, |
644 | enum iwl_ucode_type ucode_type) | 646 | enum iwl_ucode_type ucode_type) |
645 | { | 647 | { |
646 | struct iwl_notification_wait alive_wait; | 648 | struct iwl_notification_wait alive_wait; |
647 | struct iwlagn_alive_data alive_data; | 649 | struct iwl_alive_data alive_data; |
648 | struct iwl_trans *trans = trans(priv); | ||
649 | int ret; | 650 | int ret; |
650 | enum iwl_ucode_type old_type; | 651 | enum iwl_ucode_type old_type; |
651 | 652 | ||
@@ -680,7 +681,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
680 | } | 681 | } |
681 | 682 | ||
682 | if (!alive_data.valid) { | 683 | if (!alive_data.valid) { |
683 | IWL_ERR(priv, "Loaded ucode is not valid!\n"); | 684 | IWL_ERR(trans, "Loaded ucode is not valid!\n"); |
684 | trans->shrd->ucode_type = old_type; | 685 | trans->shrd->ucode_type = old_type; |
685 | return -EIO; | 686 | return -EIO; |
686 | } | 687 | } |
@@ -701,9 +702,9 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
701 | msleep(5); | 702 | msleep(5); |
702 | } | 703 | } |
703 | 704 | ||
704 | ret = iwl_alive_notify(priv); | 705 | ret = iwl_alive_notify(trans); |
705 | if (ret) { | 706 | if (ret) { |
706 | IWL_WARN(priv, | 707 | IWL_WARN(trans, |
707 | "Could not complete ALIVE transition: %d\n", ret); | 708 | "Could not complete ALIVE transition: %d\n", ret); |
708 | trans->shrd->ucode_type = old_type; | 709 | trans->shrd->ucode_type = old_type; |
709 | return ret; | 710 | return ret; |
@@ -712,30 +713,30 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | |||
712 | return 0; | 713 | return 0; |
713 | } | 714 | } |
714 | 715 | ||
715 | int iwlagn_run_init_ucode(struct iwl_priv *priv) | 716 | int iwl_run_init_ucode(struct iwl_trans *trans) |
716 | { | 717 | { |
717 | struct iwl_notification_wait calib_wait; | 718 | struct iwl_notification_wait calib_wait; |
718 | int ret; | 719 | int ret; |
719 | 720 | ||
720 | lockdep_assert_held(&priv->shrd->mutex); | 721 | lockdep_assert_held(&trans->shrd->mutex); |
721 | 722 | ||
722 | /* No init ucode required? Curious, but maybe ok */ | 723 | /* No init ucode required? Curious, but maybe ok */ |
723 | if (!trans(priv)->ucode_init.code.len) | 724 | if (!trans->ucode_init.code.len) |
724 | return 0; | 725 | return 0; |
725 | 726 | ||
726 | if (priv->shrd->ucode_type != IWL_UCODE_NONE) | 727 | if (trans->shrd->ucode_type != IWL_UCODE_NONE) |
727 | return 0; | 728 | return 0; |
728 | 729 | ||
729 | iwl_init_notification_wait(priv->shrd, &calib_wait, | 730 | iwl_init_notification_wait(trans->shrd, &calib_wait, |
730 | CALIBRATION_COMPLETE_NOTIFICATION, | 731 | CALIBRATION_COMPLETE_NOTIFICATION, |
731 | NULL, NULL); | 732 | NULL, NULL); |
732 | 733 | ||
733 | /* Will also start the device */ | 734 | /* Will also start the device */ |
734 | ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_INIT); | 735 | ret = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); |
735 | if (ret) | 736 | if (ret) |
736 | goto error; | 737 | goto error; |
737 | 738 | ||
738 | ret = iwlagn_init_alive_start(priv); | 739 | ret = iwl_init_alive_start(trans); |
739 | if (ret) | 740 | if (ret) |
740 | goto error; | 741 | goto error; |
741 | 742 | ||
@@ -743,15 +744,15 @@ int iwlagn_run_init_ucode(struct iwl_priv *priv) | |||
743 | * Some things may run in the background now, but we | 744 | * Some things may run in the background now, but we |
744 | * just wait for the calibration complete notification. | 745 | * just wait for the calibration complete notification. |
745 | */ | 746 | */ |
746 | ret = iwl_wait_notification(priv->shrd, &calib_wait, | 747 | ret = iwl_wait_notification(trans->shrd, &calib_wait, |
747 | UCODE_CALIB_TIMEOUT); | 748 | UCODE_CALIB_TIMEOUT); |
748 | 749 | ||
749 | goto out; | 750 | goto out; |
750 | 751 | ||
751 | error: | 752 | error: |
752 | iwl_remove_notification(priv->shrd, &calib_wait); | 753 | iwl_remove_notification(trans->shrd, &calib_wait); |
753 | out: | 754 | out: |
754 | /* Whatever happened, stop the device */ | 755 | /* Whatever happened, stop the device */ |
755 | iwl_trans_stop_device(trans(priv)); | 756 | iwl_trans_stop_device(trans); |
756 | return ret; | 757 | return ret; |
757 | } | 758 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h new file mode 100644 index 000000000000..18501101a530 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-wifi.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | |||
63 | #ifndef __iwl_wifi_h__ | ||
64 | #define __iwl_wifi_h__ | ||
65 | |||
66 | #include "iwl-shared.h" | ||
67 | |||
68 | int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); | ||
69 | void iwl_send_prio_tbl(struct iwl_trans *trans); | ||
70 | int iwl_init_alive_start(struct iwl_trans *trans); | ||
71 | int iwl_run_init_ucode(struct iwl_trans *trans); | ||
72 | int iwl_load_ucode_wait_alive(struct iwl_trans *trans, | ||
73 | enum iwl_ucode_type ucode_type); | ||
74 | #endif /* __iwl_wifi_h__ */ | ||
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index d1d84e0e30fc..a7cd311cb1b7 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -731,9 +731,11 @@ static void lbs_scan_worker(struct work_struct *work) | |||
731 | le16_to_cpu(scan_cmd->hdr.size), | 731 | le16_to_cpu(scan_cmd->hdr.size), |
732 | lbs_ret_scan, 0); | 732 | lbs_ret_scan, 0); |
733 | 733 | ||
734 | if (priv->scan_channel >= priv->scan_req->n_channels) | 734 | if (priv->scan_channel >= priv->scan_req->n_channels) { |
735 | /* Mark scan done */ | 735 | /* Mark scan done */ |
736 | cancel_delayed_work(&priv->scan_work); | ||
736 | lbs_scan_done(priv); | 737 | lbs_scan_done(priv); |
738 | } | ||
737 | 739 | ||
738 | /* Restart network */ | 740 | /* Restart network */ |
739 | if (carrier) | 741 | if (carrier) |
@@ -762,12 +764,12 @@ static void _internal_start_scan(struct lbs_private *priv, bool internal, | |||
762 | request->n_ssids, request->n_channels, request->ie_len); | 764 | request->n_ssids, request->n_channels, request->ie_len); |
763 | 765 | ||
764 | priv->scan_channel = 0; | 766 | priv->scan_channel = 0; |
765 | queue_delayed_work(priv->work_thread, &priv->scan_work, | ||
766 | msecs_to_jiffies(50)); | ||
767 | |||
768 | priv->scan_req = request; | 767 | priv->scan_req = request; |
769 | priv->internal_scan = internal; | 768 | priv->internal_scan = internal; |
770 | 769 | ||
770 | queue_delayed_work(priv->work_thread, &priv->scan_work, | ||
771 | msecs_to_jiffies(50)); | ||
772 | |||
771 | lbs_deb_leave(LBS_DEB_CFG80211); | 773 | lbs_deb_leave(LBS_DEB_CFG80211); |
772 | } | 774 | } |
773 | 775 | ||
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 787dbe2aa408..c3b6c4652cd6 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -24,50 +24,26 @@ | |||
24 | * This function maps the nl802.11 channel type into driver channel type. | 24 | * This function maps the nl802.11 channel type into driver channel type. |
25 | * | 25 | * |
26 | * The mapping is as follows - | 26 | * The mapping is as follows - |
27 | * NL80211_CHAN_NO_HT -> NO_SEC_CHANNEL | 27 | * NL80211_CHAN_NO_HT -> IEEE80211_HT_PARAM_CHA_SEC_NONE |
28 | * NL80211_CHAN_HT20 -> NO_SEC_CHANNEL | 28 | * NL80211_CHAN_HT20 -> IEEE80211_HT_PARAM_CHA_SEC_NONE |
29 | * NL80211_CHAN_HT40PLUS -> SEC_CHANNEL_ABOVE | 29 | * NL80211_CHAN_HT40PLUS -> IEEE80211_HT_PARAM_CHA_SEC_ABOVE |
30 | * NL80211_CHAN_HT40MINUS -> SEC_CHANNEL_BELOW | 30 | * NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW |
31 | * Others -> NO_SEC_CHANNEL | 31 | * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE |
32 | */ | 32 | */ |
33 | static int | 33 | static u8 |
34 | mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type | 34 | mwifiex_cfg80211_channel_type_to_sec_chan_offset(enum nl80211_channel_type |
35 | channel_type) | 35 | channel_type) |
36 | { | 36 | { |
37 | switch (channel_type) { | 37 | switch (channel_type) { |
38 | case NL80211_CHAN_NO_HT: | 38 | case NL80211_CHAN_NO_HT: |
39 | case NL80211_CHAN_HT20: | 39 | case NL80211_CHAN_HT20: |
40 | return NO_SEC_CHANNEL; | 40 | return IEEE80211_HT_PARAM_CHA_SEC_NONE; |
41 | case NL80211_CHAN_HT40PLUS: | 41 | case NL80211_CHAN_HT40PLUS: |
42 | return SEC_CHANNEL_ABOVE; | 42 | return IEEE80211_HT_PARAM_CHA_SEC_ABOVE; |
43 | case NL80211_CHAN_HT40MINUS: | 43 | case NL80211_CHAN_HT40MINUS: |
44 | return SEC_CHANNEL_BELOW; | 44 | return IEEE80211_HT_PARAM_CHA_SEC_BELOW; |
45 | default: | 45 | default: |
46 | return NO_SEC_CHANNEL; | 46 | return IEEE80211_HT_PARAM_CHA_SEC_NONE; |
47 | } | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * This function maps the driver channel type into nl802.11 channel type. | ||
52 | * | ||
53 | * The mapping is as follows - | ||
54 | * NO_SEC_CHANNEL -> NL80211_CHAN_HT20 | ||
55 | * SEC_CHANNEL_ABOVE -> NL80211_CHAN_HT40PLUS | ||
56 | * SEC_CHANNEL_BELOW -> NL80211_CHAN_HT40MINUS | ||
57 | * Others -> NL80211_CHAN_HT20 | ||
58 | */ | ||
59 | static enum nl80211_channel_type | ||
60 | mwifiex_channels_to_cfg80211_channel_type(int channel_type) | ||
61 | { | ||
62 | switch (channel_type) { | ||
63 | case NO_SEC_CHANNEL: | ||
64 | return NL80211_CHAN_HT20; | ||
65 | case SEC_CHANNEL_ABOVE: | ||
66 | return NL80211_CHAN_HT40PLUS; | ||
67 | case SEC_CHANNEL_BELOW: | ||
68 | return NL80211_CHAN_HT40MINUS; | ||
69 | default: | ||
70 | return NL80211_CHAN_HT20; | ||
71 | } | 47 | } |
72 | } | 48 | } |
73 | 49 | ||
@@ -331,37 +307,51 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, | |||
331 | enum nl80211_channel_type channel_type) | 307 | enum nl80211_channel_type channel_type) |
332 | { | 308 | { |
333 | struct mwifiex_chan_freq_power cfp; | 309 | struct mwifiex_chan_freq_power cfp; |
334 | struct mwifiex_ds_band_cfg band_cfg; | ||
335 | u32 config_bands = 0; | 310 | u32 config_bands = 0; |
336 | struct wiphy *wiphy = priv->wdev->wiphy; | 311 | struct wiphy *wiphy = priv->wdev->wiphy; |
312 | struct mwifiex_adapter *adapter = priv->adapter; | ||
337 | 313 | ||
338 | if (chan) { | 314 | if (chan) { |
339 | memset(&band_cfg, 0, sizeof(band_cfg)); | ||
340 | /* Set appropriate bands */ | 315 | /* Set appropriate bands */ |
341 | if (chan->band == IEEE80211_BAND_2GHZ) | 316 | if (chan->band == IEEE80211_BAND_2GHZ) { |
342 | config_bands = BAND_B | BAND_G | BAND_GN; | 317 | if (channel_type == NL80211_CHAN_NO_HT) |
343 | else | 318 | if (priv->adapter->config_bands == BAND_B || |
344 | config_bands = BAND_AN | BAND_A; | 319 | priv->adapter->config_bands == BAND_G) |
345 | if (priv->bss_mode == NL80211_IFTYPE_STATION | 320 | config_bands = |
346 | || priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED) { | 321 | priv->adapter->config_bands; |
347 | band_cfg.config_bands = config_bands; | 322 | else |
348 | } else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | 323 | config_bands = BAND_B | BAND_G; |
349 | band_cfg.config_bands = config_bands; | 324 | else |
350 | band_cfg.adhoc_start_band = config_bands; | 325 | config_bands = BAND_B | BAND_G | BAND_GN; |
326 | } else { | ||
327 | if (channel_type == NL80211_CHAN_NO_HT) | ||
328 | config_bands = BAND_A; | ||
329 | else | ||
330 | config_bands = BAND_AN | BAND_A; | ||
351 | } | 331 | } |
352 | 332 | ||
353 | band_cfg.sec_chan_offset = | 333 | if (!((config_bands | adapter->fw_bands) & |
354 | mwifiex_cfg80211_channel_type_to_mwifiex_channels | 334 | ~adapter->fw_bands)) { |
335 | adapter->config_bands = config_bands; | ||
336 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | ||
337 | adapter->adhoc_start_band = config_bands; | ||
338 | if ((config_bands & BAND_GN) || | ||
339 | (config_bands & BAND_AN)) | ||
340 | adapter->adhoc_11n_enabled = true; | ||
341 | else | ||
342 | adapter->adhoc_11n_enabled = false; | ||
343 | } | ||
344 | } | ||
345 | adapter->sec_chan_offset = | ||
346 | mwifiex_cfg80211_channel_type_to_sec_chan_offset | ||
355 | (channel_type); | 347 | (channel_type); |
356 | 348 | adapter->channel_type = channel_type; | |
357 | if (mwifiex_set_radio_band_cfg(priv, &band_cfg)) | ||
358 | return -EFAULT; | ||
359 | 349 | ||
360 | mwifiex_send_domain_info_cmd_fw(wiphy); | 350 | mwifiex_send_domain_info_cmd_fw(wiphy); |
361 | } | 351 | } |
362 | 352 | ||
363 | wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " | 353 | wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " |
364 | "mode %d\n", config_bands, band_cfg.sec_chan_offset, | 354 | "mode %d\n", config_bands, adapter->sec_chan_offset, |
365 | priv->bss_mode); | 355 | priv->bss_mode); |
366 | if (!chan) | 356 | if (!chan) |
367 | return 0; | 357 | return 0; |
@@ -697,9 +687,9 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, | |||
697 | const u8 *peer, | 687 | const u8 *peer, |
698 | const struct cfg80211_bitrate_mask *mask) | 688 | const struct cfg80211_bitrate_mask *mask) |
699 | { | 689 | { |
700 | struct mwifiex_ds_band_cfg band_cfg; | ||
701 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 690 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
702 | int index = 0, mode = 0, i; | 691 | int index = 0, mode = 0, i; |
692 | struct mwifiex_adapter *adapter = priv->adapter; | ||
703 | 693 | ||
704 | /* Currently only 2.4GHz is supported */ | 694 | /* Currently only 2.4GHz is supported */ |
705 | for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) { | 695 | for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) { |
@@ -721,16 +711,15 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, | |||
721 | mode |= BAND_B; | 711 | mode |= BAND_B; |
722 | } | 712 | } |
723 | 713 | ||
724 | memset(&band_cfg, 0, sizeof(band_cfg)); | 714 | if (!((mode | adapter->fw_bands) & ~adapter->fw_bands)) { |
725 | band_cfg.config_bands = mode; | 715 | adapter->config_bands = mode; |
726 | 716 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | |
727 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) | 717 | adapter->adhoc_start_band = mode; |
728 | band_cfg.adhoc_start_band = mode; | 718 | adapter->adhoc_11n_enabled = false; |
729 | 719 | } | |
730 | band_cfg.sec_chan_offset = NO_SEC_CHANNEL; | 720 | } |
731 | 721 | adapter->sec_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; | |
732 | if (mwifiex_set_radio_band_cfg(priv, &band_cfg)) | 722 | adapter->channel_type = NL80211_CHAN_NO_HT; |
733 | return -EFAULT; | ||
734 | 723 | ||
735 | wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", | 724 | wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", |
736 | (mode & BAND_B) ? "b" : "", | 725 | (mode & BAND_B) ? "b" : "", |
@@ -850,8 +839,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
850 | 839 | ||
851 | if (channel) | 840 | if (channel) |
852 | ret = mwifiex_set_rf_channel(priv, channel, | 841 | ret = mwifiex_set_rf_channel(priv, channel, |
853 | mwifiex_channels_to_cfg80211_channel_type | 842 | priv->adapter->channel_type); |
854 | (priv->adapter->chan_offset)); | ||
855 | 843 | ||
856 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */ | 844 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */ |
857 | 845 | ||
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 62b863907698..51c5417c569c 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -376,8 +376,6 @@ enum mwifiex_chan_scan_mode_bitmasks { | |||
376 | MWIFIEX_DISABLE_CHAN_FILT = BIT(1), | 376 | MWIFIEX_DISABLE_CHAN_FILT = BIT(1), |
377 | }; | 377 | }; |
378 | 378 | ||
379 | #define SECOND_CHANNEL_BELOW 0x30 | ||
380 | #define SECOND_CHANNEL_ABOVE 0x10 | ||
381 | struct mwifiex_chan_scan_param_set { | 379 | struct mwifiex_chan_scan_param_set { |
382 | u8 radio_type; | 380 | u8 radio_type; |
383 | u8 chan_number; | 381 | u8 chan_number; |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 244c728ef9dc..e05b417a3fae 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -246,7 +246,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
246 | memset(adapter->event_body, 0, sizeof(adapter->event_body)); | 246 | memset(adapter->event_body, 0, sizeof(adapter->event_body)); |
247 | adapter->hw_dot_11n_dev_cap = 0; | 247 | adapter->hw_dot_11n_dev_cap = 0; |
248 | adapter->hw_dev_mcs_support = 0; | 248 | adapter->hw_dev_mcs_support = 0; |
249 | adapter->chan_offset = 0; | 249 | adapter->sec_chan_offset = 0; |
250 | adapter->adhoc_11n_enabled = false; | 250 | adapter->adhoc_11n_enabled = false; |
251 | 251 | ||
252 | mwifiex_wmm_init(adapter); | 252 | mwifiex_wmm_init(adapter); |
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index e0b68e7c8ca2..d5d81f1fe41c 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h | |||
@@ -62,17 +62,6 @@ enum { | |||
62 | BAND_AN = 16, | 62 | BAND_AN = 16, |
63 | }; | 63 | }; |
64 | 64 | ||
65 | #define NO_SEC_CHANNEL 0 | ||
66 | #define SEC_CHANNEL_ABOVE 1 | ||
67 | #define SEC_CHANNEL_BELOW 3 | ||
68 | |||
69 | struct mwifiex_ds_band_cfg { | ||
70 | u32 config_bands; | ||
71 | u32 adhoc_start_band; | ||
72 | u32 adhoc_channel; | ||
73 | u32 sec_chan_offset; | ||
74 | }; | ||
75 | |||
76 | enum { | 65 | enum { |
77 | ADHOC_IDLE, | 66 | ADHOC_IDLE, |
78 | ADHOC_STARTED, | 67 | ADHOC_STARTED, |
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 1c4981367e50..0b0eb5efba9d 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -885,12 +885,14 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
885 | = mwifiex_band_to_radio_type(priv->curr_bss_params.band); | 885 | = mwifiex_band_to_radio_type(priv->curr_bss_params.band); |
886 | if (adapter->adhoc_start_band & BAND_GN | 886 | if (adapter->adhoc_start_band & BAND_GN |
887 | || adapter->adhoc_start_band & BAND_AN) { | 887 | || adapter->adhoc_start_band & BAND_AN) { |
888 | if (adapter->chan_offset == SEC_CHANNEL_ABOVE) | 888 | if (adapter->sec_chan_offset == |
889 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE) | ||
889 | chan_tlv->chan_scan_param[0].radio_type |= | 890 | chan_tlv->chan_scan_param[0].radio_type |= |
890 | SECOND_CHANNEL_ABOVE; | 891 | (IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4); |
891 | else if (adapter->chan_offset == SEC_CHANNEL_BELOW) | 892 | else if (adapter->sec_chan_offset == |
893 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE) | ||
892 | chan_tlv->chan_scan_param[0].radio_type |= | 894 | chan_tlv->chan_scan_param[0].radio_type |= |
893 | SECOND_CHANNEL_BELOW; | 895 | (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4); |
894 | } | 896 | } |
895 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n", | 897 | dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n", |
896 | chan_tlv->chan_scan_param[0].radio_type); | 898 | chan_tlv->chan_scan_param[0].radio_type); |
@@ -936,8 +938,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, | |||
936 | 938 | ||
937 | ht_info->ht_info.control_chan = | 939 | ht_info->ht_info.control_chan = |
938 | (u8) priv->curr_bss_params.bss_descriptor.channel; | 940 | (u8) priv->curr_bss_params.bss_descriptor.channel; |
939 | if (adapter->chan_offset) { | 941 | if (adapter->sec_chan_offset) { |
940 | ht_info->ht_info.ht_param = adapter->chan_offset; | 942 | ht_info->ht_info.ht_param = adapter->sec_chan_offset; |
941 | ht_info->ht_info.ht_param |= | 943 | ht_info->ht_info.ht_param |= |
942 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; | 944 | IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; |
943 | } | 945 | } |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 9207fc64641e..3186aa437f42 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -640,7 +640,8 @@ struct mwifiex_adapter { | |||
640 | u32 hw_dot_11n_dev_cap; | 640 | u32 hw_dot_11n_dev_cap; |
641 | u8 hw_dev_mcs_support; | 641 | u8 hw_dev_mcs_support; |
642 | u8 adhoc_11n_enabled; | 642 | u8 adhoc_11n_enabled; |
643 | u8 chan_offset; | 643 | u8 sec_chan_offset; |
644 | enum nl80211_channel_type channel_type; | ||
644 | struct mwifiex_dbg dbg; | 645 | struct mwifiex_dbg dbg; |
645 | u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; | 646 | u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; |
646 | u32 arp_filter_size; | 647 | u32 arp_filter_size; |
@@ -954,8 +955,6 @@ int mwifiex_main_process(struct mwifiex_adapter *); | |||
954 | 955 | ||
955 | int mwifiex_bss_set_channel(struct mwifiex_private *, | 956 | int mwifiex_bss_set_channel(struct mwifiex_private *, |
956 | struct mwifiex_chan_freq_power *cfp); | 957 | struct mwifiex_chan_freq_power *cfp); |
957 | int mwifiex_set_radio_band_cfg(struct mwifiex_private *, | ||
958 | struct mwifiex_ds_band_cfg *); | ||
959 | int mwifiex_get_bss_info(struct mwifiex_private *, | 958 | int mwifiex_get_bss_info(struct mwifiex_private *, |
960 | struct mwifiex_bss_info *); | 959 | struct mwifiex_bss_info *); |
961 | int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | 960 | int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index e2e715666bca..6396d3318ead 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -500,7 +500,6 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | |||
500 | struct ieee80211_channel *ch; | 500 | struct ieee80211_channel *ch; |
501 | struct mwifiex_adapter *adapter = priv->adapter; | 501 | struct mwifiex_adapter *adapter = priv->adapter; |
502 | int chan_idx = 0, i; | 502 | int chan_idx = 0, i; |
503 | u8 scan_type; | ||
504 | 503 | ||
505 | for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) { | 504 | for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) { |
506 | 505 | ||
@@ -514,19 +513,20 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | |||
514 | if (ch->flags & IEEE80211_CHAN_DISABLED) | 513 | if (ch->flags & IEEE80211_CHAN_DISABLED) |
515 | continue; | 514 | continue; |
516 | scan_chan_list[chan_idx].radio_type = band; | 515 | scan_chan_list[chan_idx].radio_type = band; |
517 | scan_type = ch->flags & IEEE80211_CHAN_PASSIVE_SCAN; | 516 | |
518 | if (user_scan_in && | 517 | if (user_scan_in && |
519 | user_scan_in->chan_list[0].scan_time) | 518 | user_scan_in->chan_list[0].scan_time) |
520 | scan_chan_list[chan_idx].max_scan_time = | 519 | scan_chan_list[chan_idx].max_scan_time = |
521 | cpu_to_le16((u16) user_scan_in-> | 520 | cpu_to_le16((u16) user_scan_in-> |
522 | chan_list[0].scan_time); | 521 | chan_list[0].scan_time); |
523 | else if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE) | 522 | else if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
524 | scan_chan_list[chan_idx].max_scan_time = | 523 | scan_chan_list[chan_idx].max_scan_time = |
525 | cpu_to_le16(adapter->passive_scan_time); | 524 | cpu_to_le16(adapter->passive_scan_time); |
526 | else | 525 | else |
527 | scan_chan_list[chan_idx].max_scan_time = | 526 | scan_chan_list[chan_idx].max_scan_time = |
528 | cpu_to_le16(adapter->active_scan_time); | 527 | cpu_to_le16(adapter->active_scan_time); |
529 | if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE) | 528 | |
529 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) | ||
530 | scan_chan_list[chan_idx].chan_scan_mode_bitmap | 530 | scan_chan_list[chan_idx].chan_scan_mode_bitmap |
531 | |= MWIFIEX_PASSIVE_SCAN; | 531 | |= MWIFIEX_PASSIVE_SCAN; |
532 | else | 532 | else |
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index ea6518d1c9e3..6e443ffa0465 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -748,7 +748,7 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, | |||
748 | cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); | 748 | cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); |
749 | 749 | ||
750 | rf_type = le16_to_cpu(rf_chan->rf_type); | 750 | rf_type = le16_to_cpu(rf_chan->rf_type); |
751 | SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset); | 751 | SET_SECONDARYCHAN(rf_type, priv->adapter->sec_chan_offset); |
752 | rf_chan->current_channel = cpu_to_le16(*channel); | 752 | rf_chan->current_channel = cpu_to_le16(*channel); |
753 | } | 753 | } |
754 | rf_chan->action = cpu_to_le16(cmd_action); | 754 | rf_chan->action = cpu_to_le16(cmd_action); |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 6d990c798a20..e40196dfdea0 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -472,67 +472,6 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, | |||
472 | } | 472 | } |
473 | 473 | ||
474 | /* | 474 | /* |
475 | * The function sets band configurations. | ||
476 | * | ||
477 | * it performs extra checks to make sure the Ad-Hoc | ||
478 | * band and channel are compatible. Otherwise it returns an error. | ||
479 | * | ||
480 | */ | ||
481 | int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv, | ||
482 | struct mwifiex_ds_band_cfg *radio_cfg) | ||
483 | { | ||
484 | struct mwifiex_adapter *adapter = priv->adapter; | ||
485 | u8 infra_band, adhoc_band; | ||
486 | u32 adhoc_channel; | ||
487 | |||
488 | infra_band = (u8) radio_cfg->config_bands; | ||
489 | adhoc_band = (u8) radio_cfg->adhoc_start_band; | ||
490 | adhoc_channel = radio_cfg->adhoc_channel; | ||
491 | |||
492 | /* SET Infra band */ | ||
493 | if ((infra_band | adapter->fw_bands) & ~adapter->fw_bands) | ||
494 | return -1; | ||
495 | |||
496 | adapter->config_bands = infra_band; | ||
497 | |||
498 | /* SET Ad-hoc Band */ | ||
499 | if ((adhoc_band | adapter->fw_bands) & ~adapter->fw_bands) | ||
500 | return -1; | ||
501 | |||
502 | if (adhoc_band) | ||
503 | adapter->adhoc_start_band = adhoc_band; | ||
504 | adapter->chan_offset = (u8) radio_cfg->sec_chan_offset; | ||
505 | /* | ||
506 | * If no adhoc_channel is supplied verify if the existing adhoc | ||
507 | * channel compiles with new adhoc_band | ||
508 | */ | ||
509 | if (!adhoc_channel) { | ||
510 | if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 | ||
511 | (priv, adapter->adhoc_start_band, | ||
512 | priv->adhoc_channel)) { | ||
513 | /* Pass back the default channel */ | ||
514 | radio_cfg->adhoc_channel = DEFAULT_AD_HOC_CHANNEL; | ||
515 | if ((adapter->adhoc_start_band & BAND_A) | ||
516 | || (adapter->adhoc_start_band & BAND_AN)) | ||
517 | radio_cfg->adhoc_channel = | ||
518 | DEFAULT_AD_HOC_CHANNEL_A; | ||
519 | } | ||
520 | } else { /* Retrurn error if adhoc_band and | ||
521 | adhoc_channel combination is invalid */ | ||
522 | if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 | ||
523 | (priv, adapter->adhoc_start_band, (u16) adhoc_channel)) | ||
524 | return -1; | ||
525 | priv->adhoc_channel = (u8) adhoc_channel; | ||
526 | } | ||
527 | if ((adhoc_band & BAND_GN) || (adhoc_band & BAND_AN)) | ||
528 | adapter->adhoc_11n_enabled = true; | ||
529 | else | ||
530 | adapter->adhoc_11n_enabled = false; | ||
531 | |||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | /* | ||
536 | * The function disables auto deep sleep mode. | 475 | * The function disables auto deep sleep mode. |
537 | */ | 476 | */ |
538 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv) | 477 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv) |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index e75d5c8d62cc..036491f08e9b 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -5044,14 +5044,14 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5044 | ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); | 5044 | ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); |
5045 | break; | 5045 | break; |
5046 | case IEEE80211_AMPDU_TX_STOP: | 5046 | case IEEE80211_AMPDU_TX_STOP: |
5047 | if (stream == NULL) | 5047 | if (stream) { |
5048 | break; | 5048 | if (stream->state == AMPDU_STREAM_ACTIVE) { |
5049 | if (stream->state == AMPDU_STREAM_ACTIVE) { | 5049 | spin_unlock(&priv->stream_lock); |
5050 | spin_unlock(&priv->stream_lock); | 5050 | mwl8k_destroy_ba(hw, stream); |
5051 | mwl8k_destroy_ba(hw, stream); | 5051 | spin_lock(&priv->stream_lock); |
5052 | spin_lock(&priv->stream_lock); | 5052 | } |
5053 | mwl8k_remove_stream(hw, stream); | ||
5053 | } | 5054 | } |
5054 | mwl8k_remove_stream(hw, stream); | ||
5055 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); | 5055 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); |
5056 | break; | 5056 | break; |
5057 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 5057 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index b1df1a774948..ee01d2e883a0 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -1159,6 +1159,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1159 | { USB_DEVICE(0x7392, 0x7722) }, | 1159 | { USB_DEVICE(0x7392, 0x7722) }, |
1160 | /* Encore */ | 1160 | /* Encore */ |
1161 | { USB_DEVICE(0x203d, 0x14a1) }, | 1161 | { USB_DEVICE(0x203d, 0x14a1) }, |
1162 | /* Fujitsu Stylistic 550 */ | ||
1163 | { USB_DEVICE(0x1690, 0x0761) }, | ||
1162 | /* Gemtek */ | 1164 | /* Gemtek */ |
1163 | { USB_DEVICE(0x15a9, 0x0010) }, | 1165 | { USB_DEVICE(0x15a9, 0x0010) }, |
1164 | /* Gigabyte */ | 1166 | /* Gigabyte */ |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 74c021436704..8d6eb0f56c03 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -449,6 +449,7 @@ int rtl_init_core(struct ieee80211_hw *hw) | |||
449 | /* <4> locks */ | 449 | /* <4> locks */ |
450 | mutex_init(&rtlpriv->locks.conf_mutex); | 450 | mutex_init(&rtlpriv->locks.conf_mutex); |
451 | mutex_init(&rtlpriv->locks.ps_mutex); | 451 | mutex_init(&rtlpriv->locks.ps_mutex); |
452 | spin_lock_init(&rtlpriv->locks.ips_lock); | ||
452 | spin_lock_init(&rtlpriv->locks.irq_th_lock); | 453 | spin_lock_init(&rtlpriv->locks.irq_th_lock); |
453 | spin_lock_init(&rtlpriv->locks.h2c_lock); | 454 | spin_lock_init(&rtlpriv->locks.h2c_lock); |
454 | spin_lock_init(&rtlpriv->locks.rf_ps_lock); | 455 | spin_lock_init(&rtlpriv->locks.rf_ps_lock); |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index a14a68b24635..130fdd99d573 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -237,11 +237,12 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) | |||
237 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 237 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
238 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 238 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
239 | enum rf_pwrstate rtstate; | 239 | enum rf_pwrstate rtstate; |
240 | unsigned long flags; | ||
240 | 241 | ||
241 | if (mac->opmode != NL80211_IFTYPE_STATION) | 242 | if (mac->opmode != NL80211_IFTYPE_STATION) |
242 | return; | 243 | return; |
243 | 244 | ||
244 | mutex_lock(&rtlpriv->locks.ps_mutex); | 245 | spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); |
245 | 246 | ||
246 | if (ppsc->inactiveps) { | 247 | if (ppsc->inactiveps) { |
247 | rtstate = ppsc->rfpwr_state; | 248 | rtstate = ppsc->rfpwr_state; |
@@ -257,7 +258,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) | |||
257 | } | 258 | } |
258 | } | 259 | } |
259 | 260 | ||
260 | mutex_unlock(&rtlpriv->locks.ps_mutex); | 261 | spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags); |
261 | } | 262 | } |
262 | 263 | ||
263 | /*for FW LPS*/ | 264 | /*for FW LPS*/ |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 9b7d60c0bf80..cdaf1429fa0b 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -1547,6 +1547,7 @@ struct rtl_locks { | |||
1547 | struct mutex ps_mutex; | 1547 | struct mutex ps_mutex; |
1548 | 1548 | ||
1549 | /*spin lock */ | 1549 | /*spin lock */ |
1550 | spinlock_t ips_lock; | ||
1550 | spinlock_t irq_th_lock; | 1551 | spinlock_t irq_th_lock; |
1551 | spinlock_t h2c_lock; | 1552 | spinlock_t h2c_lock; |
1552 | spinlock_t rf_ps_lock; | 1553 | spinlock_t rf_ps_lock; |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index e0d217979485..25990bd38be6 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -1835,6 +1835,9 @@ int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
1835 | wlvif->bss_type == BSS_TYPE_IBSS))) | 1835 | wlvif->bss_type == BSS_TYPE_IBSS))) |
1836 | return -EINVAL; | 1836 | return -EINVAL; |
1837 | 1837 | ||
1838 | /* flush all pending packets */ | ||
1839 | wl1271_tx_work_locked(wl); | ||
1840 | |||
1838 | if (test_bit(wlvif->dev_role_id, wl->roc_map)) { | 1841 | if (test_bit(wlvif->dev_role_id, wl->roc_map)) { |
1839 | ret = wl12xx_croc(wl, wlvif->dev_role_id); | 1842 | ret = wl12xx_croc(wl, wlvif->dev_role_id); |
1840 | if (ret < 0) | 1843 | if (ret < 0) |
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 00ce794eebae..d3280df68f5d 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c | |||
@@ -267,8 +267,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
267 | wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT " | 267 | wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT " |
268 | "(status 0x%0x)", mbox->scheduled_scan_status); | 268 | "(status 0x%0x)", mbox->scheduled_scan_status); |
269 | if (wl->sched_scanning) { | 269 | if (wl->sched_scanning) { |
270 | wl1271_scan_sched_scan_stop(wl); | ||
271 | ieee80211_sched_scan_stopped(wl->hw); | 270 | ieee80211_sched_scan_stopped(wl->hw); |
271 | wl->sched_scanning = false; | ||
272 | } | 272 | } |
273 | } | 273 | } |
274 | 274 | ||
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index c3058419e227..d5f55a149de5 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -450,7 +450,16 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, | |||
450 | if (wl->state == WL1271_STATE_OFF) | 450 | if (wl->state == WL1271_STATE_OFF) |
451 | goto out; | 451 | goto out; |
452 | 452 | ||
453 | if (dev->operstate != IF_OPER_UP) | ||
454 | goto out; | ||
455 | /* | ||
456 | * The correct behavior should be just getting the appropriate wlvif | ||
457 | * from the given dev, but currently we don't have a mac80211 | ||
458 | * interface for it. | ||
459 | */ | ||
453 | wl12xx_for_each_wlvif_sta(wl, wlvif) { | 460 | wl12xx_for_each_wlvif_sta(wl, wlvif) { |
461 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | ||
462 | |||
454 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) | 463 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) |
455 | continue; | 464 | continue; |
456 | 465 | ||
@@ -458,7 +467,8 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, | |||
458 | if (ret < 0) | 467 | if (ret < 0) |
459 | goto out; | 468 | goto out; |
460 | 469 | ||
461 | wl1271_check_operstate(wl, wlvif, dev->operstate); | 470 | wl1271_check_operstate(wl, wlvif, |
471 | ieee80211_get_operstate(vif)); | ||
462 | 472 | ||
463 | wl1271_ps_elp_sleep(wl); | 473 | wl1271_ps_elp_sleep(wl); |
464 | } | 474 | } |
@@ -2036,6 +2046,11 @@ out: | |||
2036 | return booted; | 2046 | return booted; |
2037 | } | 2047 | } |
2038 | 2048 | ||
2049 | static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif) | ||
2050 | { | ||
2051 | return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID; | ||
2052 | } | ||
2053 | |||
2039 | static int wl1271_op_add_interface(struct ieee80211_hw *hw, | 2054 | static int wl1271_op_add_interface(struct ieee80211_hw *hw, |
2040 | struct ieee80211_vif *vif) | 2055 | struct ieee80211_vif *vif) |
2041 | { | 2056 | { |
@@ -2184,7 +2199,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, | |||
2184 | if (ret < 0) | 2199 | if (ret < 0) |
2185 | goto deinit; | 2200 | goto deinit; |
2186 | 2201 | ||
2187 | if (wlvif->bss_type == BSS_TYPE_STA_BSS) { | 2202 | if (wlvif->bss_type == BSS_TYPE_STA_BSS || |
2203 | wlvif->bss_type == BSS_TYPE_IBSS) { | ||
2204 | if (wl12xx_dev_role_started(wlvif)) | ||
2205 | wl12xx_stop_dev(wl, wlvif); | ||
2206 | |||
2188 | ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id); | 2207 | ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id); |
2189 | if (ret < 0) | 2208 | if (ret < 0) |
2190 | goto deinit; | 2209 | goto deinit; |
@@ -2269,6 +2288,17 @@ out: | |||
2269 | cancel_work_sync(&wl->recovery_work); | 2288 | cancel_work_sync(&wl->recovery_work); |
2270 | } | 2289 | } |
2271 | 2290 | ||
2291 | static int wl12xx_op_change_interface(struct ieee80211_hw *hw, | ||
2292 | struct ieee80211_vif *vif, | ||
2293 | enum nl80211_iftype new_type, bool p2p) | ||
2294 | { | ||
2295 | wl1271_op_remove_interface(hw, vif); | ||
2296 | |||
2297 | vif->type = ieee80211_iftype_p2p(new_type, p2p); | ||
2298 | vif->p2p = p2p; | ||
2299 | return wl1271_op_add_interface(hw, vif); | ||
2300 | } | ||
2301 | |||
2272 | static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 2302 | static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
2273 | bool set_assoc) | 2303 | bool set_assoc) |
2274 | { | 2304 | { |
@@ -2358,25 +2388,18 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
2358 | wlvif->rate_set = wlvif->basic_rate_set; | 2388 | wlvif->rate_set = wlvif->basic_rate_set; |
2359 | } | 2389 | } |
2360 | 2390 | ||
2361 | static bool wl12xx_is_roc(struct wl1271 *wl) | ||
2362 | { | ||
2363 | u8 role_id; | ||
2364 | |||
2365 | role_id = find_first_bit(wl->roc_map, WL12XX_MAX_ROLES); | ||
2366 | if (role_id >= WL12XX_MAX_ROLES) | ||
2367 | return false; | ||
2368 | |||
2369 | return true; | ||
2370 | } | ||
2371 | |||
2372 | static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 2391 | static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
2373 | bool idle) | 2392 | bool idle) |
2374 | { | 2393 | { |
2375 | int ret; | 2394 | int ret; |
2395 | bool cur_idle = !test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); | ||
2396 | |||
2397 | if (idle == cur_idle) | ||
2398 | return 0; | ||
2376 | 2399 | ||
2377 | if (idle) { | 2400 | if (idle) { |
2378 | /* no need to croc if we weren't busy (e.g. during boot) */ | 2401 | /* no need to croc if we weren't busy (e.g. during boot) */ |
2379 | if (wl12xx_is_roc(wl)) { | 2402 | if (wl12xx_dev_role_started(wlvif)) { |
2380 | ret = wl12xx_stop_dev(wl, wlvif); | 2403 | ret = wl12xx_stop_dev(wl, wlvif); |
2381 | if (ret < 0) | 2404 | if (ret < 0) |
2382 | goto out; | 2405 | goto out; |
@@ -2391,7 +2414,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2391 | ACX_KEEP_ALIVE_TPL_INVALID); | 2414 | ACX_KEEP_ALIVE_TPL_INVALID); |
2392 | if (ret < 0) | 2415 | if (ret < 0) |
2393 | goto out; | 2416 | goto out; |
2394 | set_bit(WL1271_FLAG_IDLE, &wl->flags); | 2417 | clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); |
2395 | } else { | 2418 | } else { |
2396 | /* The current firmware only supports sched_scan in idle */ | 2419 | /* The current firmware only supports sched_scan in idle */ |
2397 | if (wl->sched_scanning) { | 2420 | if (wl->sched_scanning) { |
@@ -2402,7 +2425,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2402 | ret = wl12xx_start_dev(wl, wlvif); | 2425 | ret = wl12xx_start_dev(wl, wlvif); |
2403 | if (ret < 0) | 2426 | if (ret < 0) |
2404 | goto out; | 2427 | goto out; |
2405 | clear_bit(WL1271_FLAG_IDLE, &wl->flags); | 2428 | set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); |
2406 | } | 2429 | } |
2407 | 2430 | ||
2408 | out: | 2431 | out: |
@@ -2446,7 +2469,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2446 | 2469 | ||
2447 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, | 2470 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, |
2448 | &wlvif->flags)) { | 2471 | &wlvif->flags)) { |
2449 | if (wl12xx_is_roc(wl)) { | 2472 | if (wl12xx_dev_role_started(wlvif)) { |
2450 | /* roaming */ | 2473 | /* roaming */ |
2451 | ret = wl12xx_croc(wl, | 2474 | ret = wl12xx_croc(wl, |
2452 | wlvif->dev_role_id); | 2475 | wlvif->dev_role_id); |
@@ -2463,7 +2486,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2463 | * not idle. otherwise, CROC will be called | 2486 | * not idle. otherwise, CROC will be called |
2464 | * anyway. | 2487 | * anyway. |
2465 | */ | 2488 | */ |
2466 | if (wl12xx_is_roc(wl) && | 2489 | if (wl12xx_dev_role_started(wlvif) && |
2467 | !(conf->flags & IEEE80211_CONF_IDLE)) { | 2490 | !(conf->flags & IEEE80211_CONF_IDLE)) { |
2468 | ret = wl12xx_stop_dev(wl, wlvif); | 2491 | ret = wl12xx_stop_dev(wl, wlvif); |
2469 | if (ret < 0) | 2492 | if (ret < 0) |
@@ -3010,15 +3033,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
3010 | if (ret < 0) | 3033 | if (ret < 0) |
3011 | goto out; | 3034 | goto out; |
3012 | 3035 | ||
3036 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && | ||
3037 | test_bit(wlvif->role_id, wl->roc_map)) { | ||
3038 | /* don't allow scanning right now */ | ||
3039 | ret = -EBUSY; | ||
3040 | goto out_sleep; | ||
3041 | } | ||
3042 | |||
3013 | /* cancel ROC before scanning */ | 3043 | /* cancel ROC before scanning */ |
3014 | if (wl12xx_is_roc(wl)) { | 3044 | if (wl12xx_dev_role_started(wlvif)) |
3015 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { | ||
3016 | /* don't allow scanning right now */ | ||
3017 | ret = -EBUSY; | ||
3018 | goto out_sleep; | ||
3019 | } | ||
3020 | wl12xx_stop_dev(wl, wlvif); | 3045 | wl12xx_stop_dev(wl, wlvif); |
3021 | } | ||
3022 | 3046 | ||
3023 | ret = wl1271_scan(hw->priv, vif, ssid, len, req); | 3047 | ret = wl1271_scan(hw->priv, vif, ssid, len, req); |
3024 | out_sleep: | 3048 | out_sleep: |
@@ -3829,9 +3853,9 @@ sta_not_found: | |||
3829 | } | 3853 | } |
3830 | /* | 3854 | /* |
3831 | * stop device role if started (we might already be in | 3855 | * stop device role if started (we might already be in |
3832 | * STA role). TODO: make it better. | 3856 | * STA/IBSS role). |
3833 | */ | 3857 | */ |
3834 | if (wlvif->dev_role_id != WL12XX_INVALID_ROLE_ID) { | 3858 | if (wl12xx_dev_role_started(wlvif)) { |
3835 | ret = wl12xx_stop_dev(wl, wlvif); | 3859 | ret = wl12xx_stop_dev(wl, wlvif); |
3836 | if (ret < 0) | 3860 | if (ret < 0) |
3837 | goto out; | 3861 | goto out; |
@@ -3948,31 +3972,8 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, | |||
3948 | else | 3972 | else |
3949 | ps_scheme = CONF_PS_SCHEME_LEGACY; | 3973 | ps_scheme = CONF_PS_SCHEME_LEGACY; |
3950 | 3974 | ||
3951 | if (wl->state == WL1271_STATE_OFF) { | 3975 | if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) |
3952 | /* | ||
3953 | * If the state is off, the parameters will be recorded and | ||
3954 | * configured on init. This happens in AP-mode. | ||
3955 | */ | ||
3956 | struct conf_tx_ac_category *conf_ac = | ||
3957 | &wl->conf.tx.ac_conf[wl1271_tx_get_queue(queue)]; | ||
3958 | struct conf_tx_tid *conf_tid = | ||
3959 | &wl->conf.tx.tid_conf[wl1271_tx_get_queue(queue)]; | ||
3960 | |||
3961 | conf_ac->ac = wl1271_tx_get_queue(queue); | ||
3962 | conf_ac->cw_min = (u8)params->cw_min; | ||
3963 | conf_ac->cw_max = params->cw_max; | ||
3964 | conf_ac->aifsn = params->aifs; | ||
3965 | conf_ac->tx_op_limit = params->txop << 5; | ||
3966 | |||
3967 | conf_tid->queue_id = wl1271_tx_get_queue(queue); | ||
3968 | conf_tid->channel_type = CONF_CHANNEL_TYPE_EDCF; | ||
3969 | conf_tid->tsid = wl1271_tx_get_queue(queue); | ||
3970 | conf_tid->ps_scheme = ps_scheme; | ||
3971 | conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY; | ||
3972 | conf_tid->apsd_conf[0] = 0; | ||
3973 | conf_tid->apsd_conf[1] = 0; | ||
3974 | goto out; | 3976 | goto out; |
3975 | } | ||
3976 | 3977 | ||
3977 | ret = wl1271_ps_elp_wakeup(wl); | 3978 | ret = wl1271_ps_elp_wakeup(wl); |
3978 | if (ret < 0) | 3979 | if (ret < 0) |
@@ -4629,6 +4630,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
4629 | .stop = wl1271_op_stop, | 4630 | .stop = wl1271_op_stop, |
4630 | .add_interface = wl1271_op_add_interface, | 4631 | .add_interface = wl1271_op_add_interface, |
4631 | .remove_interface = wl1271_op_remove_interface, | 4632 | .remove_interface = wl1271_op_remove_interface, |
4633 | .change_interface = wl12xx_op_change_interface, | ||
4632 | #ifdef CONFIG_PM | 4634 | #ifdef CONFIG_PM |
4633 | .suspend = wl1271_op_suspend, | 4635 | .suspend = wl1271_op_suspend, |
4634 | .resume = wl1271_op_resume, | 4636 | .resume = wl1271_op_resume, |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index a7a11088dd31..a2bdacdd7e1d 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c | |||
@@ -53,8 +53,11 @@ void wl1271_elp_work(struct work_struct *work) | |||
53 | goto out; | 53 | goto out; |
54 | 54 | ||
55 | wl12xx_for_each_wlvif(wl, wlvif) { | 55 | wl12xx_for_each_wlvif(wl, wlvif) { |
56 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) | ||
57 | goto out; | ||
58 | |||
56 | if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && | 59 | if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && |
57 | !test_bit(WL1271_FLAG_IDLE, &wl->flags)) | 60 | test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) |
58 | goto out; | 61 | goto out; |
59 | } | 62 | } |
60 | 63 | ||
@@ -78,8 +81,11 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) | |||
78 | return; | 81 | return; |
79 | 82 | ||
80 | wl12xx_for_each_wlvif(wl, wlvif) { | 83 | wl12xx_for_each_wlvif(wl, wlvif) { |
84 | if (wlvif->bss_type == BSS_TYPE_AP_BSS) | ||
85 | return; | ||
86 | |||
81 | if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && | 87 | if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && |
82 | !test_bit(WL1271_FLAG_IDLE, &wl->flags)) | 88 | test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) |
83 | return; | 89 | return; |
84 | } | 90 | } |
85 | 91 | ||
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 8599dab1fe2a..e24111ececc5 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -437,18 +437,19 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, | |||
437 | 437 | ||
438 | if (flags & IEEE80211_CHAN_RADAR) { | 438 | if (flags & IEEE80211_CHAN_RADAR) { |
439 | channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; | 439 | channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; |
440 | |||
440 | channels[j].passive_duration = | 441 | channels[j].passive_duration = |
441 | cpu_to_le16(c->dwell_time_dfs); | 442 | cpu_to_le16(c->dwell_time_dfs); |
442 | } | 443 | } else { |
443 | else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) { | ||
444 | channels[j].passive_duration = | 444 | channels[j].passive_duration = |
445 | cpu_to_le16(c->dwell_time_passive); | 445 | cpu_to_le16(c->dwell_time_passive); |
446 | } else { | ||
447 | channels[j].min_duration = | ||
448 | cpu_to_le16(c->min_dwell_time_active); | ||
449 | channels[j].max_duration = | ||
450 | cpu_to_le16(c->max_dwell_time_active); | ||
451 | } | 446 | } |
447 | |||
448 | channels[j].min_duration = | ||
449 | cpu_to_le16(c->min_dwell_time_active); | ||
450 | channels[j].max_duration = | ||
451 | cpu_to_le16(c->max_dwell_time_active); | ||
452 | |||
452 | channels[j].tx_power_att = req->channels[i]->max_power; | 453 | channels[j].tx_power_att = req->channels[i]->max_power; |
453 | channels[j].channel = req->channels[i]->hw_value; | 454 | channels[j].channel = req->channels[i]->hw_value; |
454 | 455 | ||
@@ -703,7 +704,7 @@ int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
703 | if (wlvif->bss_type != BSS_TYPE_STA_BSS) | 704 | if (wlvif->bss_type != BSS_TYPE_STA_BSS) |
704 | return -EOPNOTSUPP; | 705 | return -EOPNOTSUPP; |
705 | 706 | ||
706 | if (!test_bit(WL1271_FLAG_IDLE, &wl->flags)) | 707 | if (test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) |
707 | return -EBUSY; | 708 | return -EBUSY; |
708 | 709 | ||
709 | start = kzalloc(sizeof(*start), GFP_KERNEL); | 710 | start = kzalloc(sizeof(*start), GFP_KERNEL); |
@@ -753,7 +754,6 @@ void wl1271_scan_sched_scan_stop(struct wl1271 *wl) | |||
753 | wl1271_error("failed to send sched scan stop command"); | 754 | wl1271_error("failed to send sched scan stop command"); |
754 | goto out_free; | 755 | goto out_free; |
755 | } | 756 | } |
756 | wl->sched_scanning = false; | ||
757 | 757 | ||
758 | out_free: | 758 | out_free: |
759 | kfree(stop); | 759 | kfree(stop); |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index d21f71ff6f64..b2b09cd02022 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -241,7 +241,6 @@ enum wl12xx_flags { | |||
241 | WL1271_FLAG_IN_ELP, | 241 | WL1271_FLAG_IN_ELP, |
242 | WL1271_FLAG_ELP_REQUESTED, | 242 | WL1271_FLAG_ELP_REQUESTED, |
243 | WL1271_FLAG_IRQ_RUNNING, | 243 | WL1271_FLAG_IRQ_RUNNING, |
244 | WL1271_FLAG_IDLE, | ||
245 | WL1271_FLAG_FW_TX_BUSY, | 244 | WL1271_FLAG_FW_TX_BUSY, |
246 | WL1271_FLAG_DUMMY_PACKET_PENDING, | 245 | WL1271_FLAG_DUMMY_PACKET_PENDING, |
247 | WL1271_FLAG_SUSPENDED, | 246 | WL1271_FLAG_SUSPENDED, |
@@ -262,6 +261,7 @@ enum wl12xx_vif_flags { | |||
262 | WLVIF_FLAG_PSPOLL_FAILURE, | 261 | WLVIF_FLAG_PSPOLL_FAILURE, |
263 | WLVIF_FLAG_CS_PROGRESS, | 262 | WLVIF_FLAG_CS_PROGRESS, |
264 | WLVIF_FLAG_AP_PROBE_RESP_SET, | 263 | WLVIF_FLAG_AP_PROBE_RESP_SET, |
264 | WLVIF_FLAG_IN_USE, | ||
265 | }; | 265 | }; |
266 | 266 | ||
267 | struct wl1271_link { | 267 | struct wl1271_link { |
diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c index 3c96b332184e..998e95895f9d 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c +++ b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c | |||
@@ -1,3 +1,24 @@ | |||
1 | /* | ||
2 | * This file is part of wl12xx | ||
3 | * | ||
4 | * Copyright (C) 2010-2011 Texas Instruments, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
1 | #include <linux/module.h> | 22 | #include <linux/module.h> |
2 | #include <linux/err.h> | 23 | #include <linux/err.h> |
3 | #include <linux/wl12xx.h> | 24 | #include <linux/wl12xx.h> |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index f795cb7dccdd..0f5ff3739820 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -1655,6 +1655,7 @@ enum nl80211_sta_bss_param { | |||
1655 | * containing info as possible, see &enum nl80211_sta_bss_param | 1655 | * containing info as possible, see &enum nl80211_sta_bss_param |
1656 | * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected | 1656 | * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected |
1657 | * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update. | 1657 | * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update. |
1658 | * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32) | ||
1658 | * @__NL80211_STA_INFO_AFTER_LAST: internal | 1659 | * @__NL80211_STA_INFO_AFTER_LAST: internal |
1659 | * @NL80211_STA_INFO_MAX: highest possible station info attribute | 1660 | * @NL80211_STA_INFO_MAX: highest possible station info attribute |
1660 | */ | 1661 | */ |
@@ -1677,6 +1678,7 @@ enum nl80211_sta_info { | |||
1677 | NL80211_STA_INFO_BSS_PARAM, | 1678 | NL80211_STA_INFO_BSS_PARAM, |
1678 | NL80211_STA_INFO_CONNECTED_TIME, | 1679 | NL80211_STA_INFO_CONNECTED_TIME, |
1679 | NL80211_STA_INFO_STA_FLAGS, | 1680 | NL80211_STA_INFO_STA_FLAGS, |
1681 | NL80211_STA_INFO_BEACON_LOSS, | ||
1680 | 1682 | ||
1681 | /* keep last */ | 1683 | /* keep last */ |
1682 | __NL80211_STA_INFO_AFTER_LAST, | 1684 | __NL80211_STA_INFO_AFTER_LAST, |
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 980e59f37d4f..abaad6ed9b83 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -250,32 +250,10 @@ extern void bt_sysfs_cleanup(void); | |||
250 | 250 | ||
251 | extern struct dentry *bt_debugfs; | 251 | extern struct dentry *bt_debugfs; |
252 | 252 | ||
253 | #ifdef CONFIG_BT_L2CAP | ||
254 | int l2cap_init(void); | 253 | int l2cap_init(void); |
255 | void l2cap_exit(void); | 254 | void l2cap_exit(void); |
256 | #else | ||
257 | static inline int l2cap_init(void) | ||
258 | { | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static inline void l2cap_exit(void) | ||
263 | { | ||
264 | } | ||
265 | #endif | ||
266 | 255 | ||
267 | #ifdef CONFIG_BT_SCO | ||
268 | int sco_init(void); | 256 | int sco_init(void); |
269 | void sco_exit(void); | 257 | void sco_exit(void); |
270 | #else | ||
271 | static inline int sco_init(void) | ||
272 | { | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static inline void sco_exit(void) | ||
277 | { | ||
278 | } | ||
279 | #endif | ||
280 | 258 | ||
281 | #endif /* __BLUETOOTH_H */ | 259 | #endif /* __BLUETOOTH_H */ |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 67ad98430348..5b2fed5eebf2 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -210,6 +210,7 @@ enum { | |||
210 | 210 | ||
211 | #define LMP_EV4 0x01 | 211 | #define LMP_EV4 0x01 |
212 | #define LMP_EV5 0x02 | 212 | #define LMP_EV5 0x02 |
213 | #define LMP_NO_BREDR 0x20 | ||
213 | #define LMP_LE 0x40 | 214 | #define LMP_LE 0x40 |
214 | 215 | ||
215 | #define LMP_SNIFF_SUBR 0x02 | 216 | #define LMP_SNIFF_SUBR 0x02 |
@@ -279,6 +280,10 @@ enum { | |||
279 | #define HCI_ERROR_LOCAL_HOST_TERM 0x16 | 280 | #define HCI_ERROR_LOCAL_HOST_TERM 0x16 |
280 | #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 | 281 | #define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18 |
281 | 282 | ||
283 | /* Flow control modes */ | ||
284 | #define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00 | ||
285 | #define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01 | ||
286 | |||
282 | /* ----- HCI Commands ---- */ | 287 | /* ----- HCI Commands ---- */ |
283 | #define HCI_OP_NOP 0x0000 | 288 | #define HCI_OP_NOP 0x0000 |
284 | 289 | ||
@@ -745,6 +750,14 @@ struct hci_rp_read_bd_addr { | |||
745 | bdaddr_t bdaddr; | 750 | bdaddr_t bdaddr; |
746 | } __packed; | 751 | } __packed; |
747 | 752 | ||
753 | #define HCI_OP_READ_DATA_BLOCK_SIZE 0x100a | ||
754 | struct hci_rp_read_data_block_size { | ||
755 | __u8 status; | ||
756 | __le16 max_acl_len; | ||
757 | __le16 block_len; | ||
758 | __le16 num_blocks; | ||
759 | } __packed; | ||
760 | |||
748 | #define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY 0x0c1c | 761 | #define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY 0x0c1c |
749 | struct hci_cp_write_page_scan_activity { | 762 | struct hci_cp_write_page_scan_activity { |
750 | __le16 interval; | 763 | __le16 interval; |
@@ -791,6 +804,9 @@ struct hci_cp_le_set_scan_param { | |||
791 | __u8 filter_policy; | 804 | __u8 filter_policy; |
792 | } __packed; | 805 | } __packed; |
793 | 806 | ||
807 | #define LE_SCANNING_DISABLED 0x00 | ||
808 | #define LE_SCANNING_ENABLED 0x01 | ||
809 | |||
794 | #define HCI_OP_LE_SET_SCAN_ENABLE 0x200c | 810 | #define HCI_OP_LE_SET_SCAN_ENABLE 0x200c |
795 | struct hci_cp_le_set_scan_enable { | 811 | struct hci_cp_le_set_scan_enable { |
796 | __u8 enable; | 812 | __u8 enable; |
@@ -966,9 +982,14 @@ struct hci_ev_role_change { | |||
966 | } __packed; | 982 | } __packed; |
967 | 983 | ||
968 | #define HCI_EV_NUM_COMP_PKTS 0x13 | 984 | #define HCI_EV_NUM_COMP_PKTS 0x13 |
985 | struct hci_comp_pkts_info { | ||
986 | __le16 handle; | ||
987 | __le16 count; | ||
988 | } __packed; | ||
989 | |||
969 | struct hci_ev_num_comp_pkts { | 990 | struct hci_ev_num_comp_pkts { |
970 | __u8 num_hndl; | 991 | __u8 num_hndl; |
971 | /* variable length part */ | 992 | struct hci_comp_pkts_info handles[0]; |
972 | } __packed; | 993 | } __packed; |
973 | 994 | ||
974 | #define HCI_EV_MODE_CHANGE 0x14 | 995 | #define HCI_EV_MODE_CHANGE 0x14 |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index ea4395f1d260..5e2e98458496 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -28,10 +28,6 @@ | |||
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <net/bluetooth/hci.h> | 29 | #include <net/bluetooth/hci.h> |
30 | 30 | ||
31 | /* HCI upper protocols */ | ||
32 | #define HCI_PROTO_L2CAP 0 | ||
33 | #define HCI_PROTO_SCO 1 | ||
34 | |||
35 | /* HCI priority */ | 31 | /* HCI priority */ |
36 | #define HCI_PRIO_MAX 7 | 32 | #define HCI_PRIO_MAX 7 |
37 | 33 | ||
@@ -54,25 +50,17 @@ struct inquiry_entry { | |||
54 | }; | 50 | }; |
55 | 51 | ||
56 | struct inquiry_cache { | 52 | struct inquiry_cache { |
57 | spinlock_t lock; | ||
58 | __u32 timestamp; | 53 | __u32 timestamp; |
59 | struct inquiry_entry *list; | 54 | struct inquiry_entry *list; |
60 | }; | 55 | }; |
61 | 56 | ||
62 | struct hci_conn_hash { | 57 | struct hci_conn_hash { |
63 | struct list_head list; | 58 | struct list_head list; |
64 | spinlock_t lock; | ||
65 | unsigned int acl_num; | 59 | unsigned int acl_num; |
66 | unsigned int sco_num; | 60 | unsigned int sco_num; |
67 | unsigned int le_num; | 61 | unsigned int le_num; |
68 | }; | 62 | }; |
69 | 63 | ||
70 | struct hci_chan_hash { | ||
71 | struct list_head list; | ||
72 | spinlock_t lock; | ||
73 | unsigned int num; | ||
74 | }; | ||
75 | |||
76 | struct bdaddr_list { | 64 | struct bdaddr_list { |
77 | struct list_head list; | 65 | struct list_head list; |
78 | bdaddr_t bdaddr; | 66 | bdaddr_t bdaddr; |
@@ -124,7 +112,7 @@ struct adv_entry { | |||
124 | #define NUM_REASSEMBLY 4 | 112 | #define NUM_REASSEMBLY 4 |
125 | struct hci_dev { | 113 | struct hci_dev { |
126 | struct list_head list; | 114 | struct list_head list; |
127 | spinlock_t lock; | 115 | struct mutex lock; |
128 | atomic_t refcnt; | 116 | atomic_t refcnt; |
129 | 117 | ||
130 | char name[8]; | 118 | char name[8]; |
@@ -188,6 +176,11 @@ struct hci_dev { | |||
188 | unsigned int sco_pkts; | 176 | unsigned int sco_pkts; |
189 | unsigned int le_pkts; | 177 | unsigned int le_pkts; |
190 | 178 | ||
179 | __u16 block_len; | ||
180 | __u16 block_mtu; | ||
181 | __u16 num_blocks; | ||
182 | __u16 block_cnt; | ||
183 | |||
191 | unsigned long acl_last_tx; | 184 | unsigned long acl_last_tx; |
192 | unsigned long sco_last_tx; | 185 | unsigned long sco_last_tx; |
193 | unsigned long le_last_tx; | 186 | unsigned long le_last_tx; |
@@ -200,10 +193,13 @@ struct hci_dev { | |||
200 | __u16 discov_timeout; | 193 | __u16 discov_timeout; |
201 | struct delayed_work discov_off; | 194 | struct delayed_work discov_off; |
202 | 195 | ||
196 | struct delayed_work service_cache; | ||
197 | |||
203 | struct timer_list cmd_timer; | 198 | struct timer_list cmd_timer; |
204 | struct tasklet_struct cmd_task; | 199 | |
205 | struct tasklet_struct rx_task; | 200 | struct work_struct rx_work; |
206 | struct tasklet_struct tx_task; | 201 | struct work_struct cmd_work; |
202 | struct work_struct tx_work; | ||
207 | 203 | ||
208 | struct sk_buff_head rx_q; | 204 | struct sk_buff_head rx_q; |
209 | struct sk_buff_head raw_q; | 205 | struct sk_buff_head raw_q; |
@@ -232,7 +228,7 @@ struct hci_dev { | |||
232 | struct list_head remote_oob_data; | 228 | struct list_head remote_oob_data; |
233 | 229 | ||
234 | struct list_head adv_entries; | 230 | struct list_head adv_entries; |
235 | struct timer_list adv_timer; | 231 | struct delayed_work adv_work; |
236 | 232 | ||
237 | struct hci_dev_stats stat; | 233 | struct hci_dev_stats stat; |
238 | 234 | ||
@@ -301,21 +297,19 @@ struct hci_conn { | |||
301 | unsigned int sent; | 297 | unsigned int sent; |
302 | 298 | ||
303 | struct sk_buff_head data_q; | 299 | struct sk_buff_head data_q; |
304 | struct hci_chan_hash chan_hash; | 300 | struct list_head chan_list; |
305 | 301 | ||
306 | struct timer_list disc_timer; | 302 | struct delayed_work disc_work; |
307 | struct timer_list idle_timer; | 303 | struct timer_list idle_timer; |
308 | struct timer_list auto_accept_timer; | 304 | struct timer_list auto_accept_timer; |
309 | 305 | ||
310 | struct work_struct work_add; | ||
311 | struct work_struct work_del; | ||
312 | |||
313 | struct device dev; | 306 | struct device dev; |
314 | atomic_t devref; | 307 | atomic_t devref; |
315 | 308 | ||
316 | struct hci_dev *hdev; | 309 | struct hci_dev *hdev; |
317 | void *l2cap_data; | 310 | void *l2cap_data; |
318 | void *sco_data; | 311 | void *sco_data; |
312 | void *smp_conn; | ||
319 | 313 | ||
320 | struct hci_conn *link; | 314 | struct hci_conn *link; |
321 | 315 | ||
@@ -332,25 +326,31 @@ struct hci_chan { | |||
332 | unsigned int sent; | 326 | unsigned int sent; |
333 | }; | 327 | }; |
334 | 328 | ||
335 | extern struct hci_proto *hci_proto[]; | ||
336 | extern struct list_head hci_dev_list; | 329 | extern struct list_head hci_dev_list; |
337 | extern struct list_head hci_cb_list; | 330 | extern struct list_head hci_cb_list; |
338 | extern rwlock_t hci_dev_list_lock; | 331 | extern rwlock_t hci_dev_list_lock; |
339 | extern rwlock_t hci_cb_list_lock; | 332 | extern rwlock_t hci_cb_list_lock; |
340 | 333 | ||
334 | /* ----- HCI interface to upper protocols ----- */ | ||
335 | extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
336 | extern int l2cap_connect_cfm(struct hci_conn *hcon, u8 status); | ||
337 | extern int l2cap_disconn_ind(struct hci_conn *hcon); | ||
338 | extern int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); | ||
339 | extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); | ||
340 | extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); | ||
341 | |||
342 | extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
343 | extern int sco_connect_cfm(struct hci_conn *hcon, __u8 status); | ||
344 | extern int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); | ||
345 | extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); | ||
346 | |||
341 | /* ----- Inquiry cache ----- */ | 347 | /* ----- Inquiry cache ----- */ |
342 | #define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ | 348 | #define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ |
343 | #define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ | 349 | #define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ |
344 | 350 | ||
345 | #define inquiry_cache_lock(c) spin_lock(&c->lock) | ||
346 | #define inquiry_cache_unlock(c) spin_unlock(&c->lock) | ||
347 | #define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock) | ||
348 | #define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock) | ||
349 | |||
350 | static inline void inquiry_cache_init(struct hci_dev *hdev) | 351 | static inline void inquiry_cache_init(struct hci_dev *hdev) |
351 | { | 352 | { |
352 | struct inquiry_cache *c = &hdev->inq_cache; | 353 | struct inquiry_cache *c = &hdev->inq_cache; |
353 | spin_lock_init(&c->lock); | ||
354 | c->list = NULL; | 354 | c->list = NULL; |
355 | } | 355 | } |
356 | 356 | ||
@@ -390,15 +390,15 @@ static inline void hci_conn_hash_init(struct hci_dev *hdev) | |||
390 | { | 390 | { |
391 | struct hci_conn_hash *h = &hdev->conn_hash; | 391 | struct hci_conn_hash *h = &hdev->conn_hash; |
392 | INIT_LIST_HEAD(&h->list); | 392 | INIT_LIST_HEAD(&h->list); |
393 | spin_lock_init(&h->lock); | ||
394 | h->acl_num = 0; | 393 | h->acl_num = 0; |
395 | h->sco_num = 0; | 394 | h->sco_num = 0; |
395 | h->le_num = 0; | ||
396 | } | 396 | } |
397 | 397 | ||
398 | static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) | 398 | static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) |
399 | { | 399 | { |
400 | struct hci_conn_hash *h = &hdev->conn_hash; | 400 | struct hci_conn_hash *h = &hdev->conn_hash; |
401 | list_add(&c->list, &h->list); | 401 | list_add_rcu(&c->list, &h->list); |
402 | switch (c->type) { | 402 | switch (c->type) { |
403 | case ACL_LINK: | 403 | case ACL_LINK: |
404 | h->acl_num++; | 404 | h->acl_num++; |
@@ -416,7 +416,10 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) | |||
416 | static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) | 416 | static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) |
417 | { | 417 | { |
418 | struct hci_conn_hash *h = &hdev->conn_hash; | 418 | struct hci_conn_hash *h = &hdev->conn_hash; |
419 | list_del(&c->list); | 419 | |
420 | list_del_rcu(&c->list); | ||
421 | synchronize_rcu(); | ||
422 | |||
420 | switch (c->type) { | 423 | switch (c->type) { |
421 | case ACL_LINK: | 424 | case ACL_LINK: |
422 | h->acl_num--; | 425 | h->acl_num--; |
@@ -451,14 +454,18 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, | |||
451 | __u16 handle) | 454 | __u16 handle) |
452 | { | 455 | { |
453 | struct hci_conn_hash *h = &hdev->conn_hash; | 456 | struct hci_conn_hash *h = &hdev->conn_hash; |
454 | struct list_head *p; | ||
455 | struct hci_conn *c; | 457 | struct hci_conn *c; |
456 | 458 | ||
457 | list_for_each(p, &h->list) { | 459 | rcu_read_lock(); |
458 | c = list_entry(p, struct hci_conn, list); | 460 | |
459 | if (c->handle == handle) | 461 | list_for_each_entry_rcu(c, &h->list, list) { |
462 | if (c->handle == handle) { | ||
463 | rcu_read_unlock(); | ||
460 | return c; | 464 | return c; |
465 | } | ||
461 | } | 466 | } |
467 | rcu_read_unlock(); | ||
468 | |||
462 | return NULL; | 469 | return NULL; |
463 | } | 470 | } |
464 | 471 | ||
@@ -466,14 +473,19 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, | |||
466 | __u8 type, bdaddr_t *ba) | 473 | __u8 type, bdaddr_t *ba) |
467 | { | 474 | { |
468 | struct hci_conn_hash *h = &hdev->conn_hash; | 475 | struct hci_conn_hash *h = &hdev->conn_hash; |
469 | struct list_head *p; | ||
470 | struct hci_conn *c; | 476 | struct hci_conn *c; |
471 | 477 | ||
472 | list_for_each(p, &h->list) { | 478 | rcu_read_lock(); |
473 | c = list_entry(p, struct hci_conn, list); | 479 | |
474 | if (c->type == type && !bacmp(&c->dst, ba)) | 480 | list_for_each_entry_rcu(c, &h->list, list) { |
481 | if (c->type == type && !bacmp(&c->dst, ba)) { | ||
482 | rcu_read_unlock(); | ||
475 | return c; | 483 | return c; |
484 | } | ||
476 | } | 485 | } |
486 | |||
487 | rcu_read_unlock(); | ||
488 | |||
477 | return NULL; | 489 | return NULL; |
478 | } | 490 | } |
479 | 491 | ||
@@ -481,37 +493,20 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, | |||
481 | __u8 type, __u16 state) | 493 | __u8 type, __u16 state) |
482 | { | 494 | { |
483 | struct hci_conn_hash *h = &hdev->conn_hash; | 495 | struct hci_conn_hash *h = &hdev->conn_hash; |
484 | struct list_head *p; | ||
485 | struct hci_conn *c; | 496 | struct hci_conn *c; |
486 | 497 | ||
487 | list_for_each(p, &h->list) { | 498 | rcu_read_lock(); |
488 | c = list_entry(p, struct hci_conn, list); | 499 | |
489 | if (c->type == type && c->state == state) | 500 | list_for_each_entry_rcu(c, &h->list, list) { |
501 | if (c->type == type && c->state == state) { | ||
502 | rcu_read_unlock(); | ||
490 | return c; | 503 | return c; |
504 | } | ||
491 | } | 505 | } |
492 | return NULL; | ||
493 | } | ||
494 | 506 | ||
495 | static inline void hci_chan_hash_init(struct hci_conn *c) | 507 | rcu_read_unlock(); |
496 | { | ||
497 | struct hci_chan_hash *h = &c->chan_hash; | ||
498 | INIT_LIST_HEAD(&h->list); | ||
499 | spin_lock_init(&h->lock); | ||
500 | h->num = 0; | ||
501 | } | ||
502 | 508 | ||
503 | static inline void hci_chan_hash_add(struct hci_conn *c, struct hci_chan *chan) | 509 | return NULL; |
504 | { | ||
505 | struct hci_chan_hash *h = &c->chan_hash; | ||
506 | list_add(&chan->list, &h->list); | ||
507 | h->num++; | ||
508 | } | ||
509 | |||
510 | static inline void hci_chan_hash_del(struct hci_conn *c, struct hci_chan *chan) | ||
511 | { | ||
512 | struct hci_chan_hash *h = &c->chan_hash; | ||
513 | list_del(&chan->list); | ||
514 | h->num--; | ||
515 | } | 510 | } |
516 | 511 | ||
517 | void hci_acl_connect(struct hci_conn *conn); | 512 | void hci_acl_connect(struct hci_conn *conn); |
@@ -527,7 +522,7 @@ void hci_conn_check_pending(struct hci_dev *hdev); | |||
527 | 522 | ||
528 | struct hci_chan *hci_chan_create(struct hci_conn *conn); | 523 | struct hci_chan *hci_chan_create(struct hci_conn *conn); |
529 | int hci_chan_del(struct hci_chan *chan); | 524 | int hci_chan_del(struct hci_chan *chan); |
530 | void hci_chan_hash_flush(struct hci_conn *conn); | 525 | void hci_chan_list_flush(struct hci_conn *conn); |
531 | 526 | ||
532 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | 527 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, |
533 | __u8 sec_level, __u8 auth_type); | 528 | __u8 sec_level, __u8 auth_type); |
@@ -538,7 +533,6 @@ int hci_conn_change_link_key(struct hci_conn *conn); | |||
538 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role); | 533 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role); |
539 | 534 | ||
540 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); | 535 | void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); |
541 | void hci_conn_enter_sniff_mode(struct hci_conn *conn); | ||
542 | 536 | ||
543 | void hci_conn_hold_device(struct hci_conn *conn); | 537 | void hci_conn_hold_device(struct hci_conn *conn); |
544 | void hci_conn_put_device(struct hci_conn *conn); | 538 | void hci_conn_put_device(struct hci_conn *conn); |
@@ -546,7 +540,7 @@ void hci_conn_put_device(struct hci_conn *conn); | |||
546 | static inline void hci_conn_hold(struct hci_conn *conn) | 540 | static inline void hci_conn_hold(struct hci_conn *conn) |
547 | { | 541 | { |
548 | atomic_inc(&conn->refcnt); | 542 | atomic_inc(&conn->refcnt); |
549 | del_timer(&conn->disc_timer); | 543 | cancel_delayed_work_sync(&conn->disc_work); |
550 | } | 544 | } |
551 | 545 | ||
552 | static inline void hci_conn_put(struct hci_conn *conn) | 546 | static inline void hci_conn_put(struct hci_conn *conn) |
@@ -565,7 +559,9 @@ static inline void hci_conn_put(struct hci_conn *conn) | |||
565 | } else { | 559 | } else { |
566 | timeo = msecs_to_jiffies(10); | 560 | timeo = msecs_to_jiffies(10); |
567 | } | 561 | } |
568 | mod_timer(&conn->disc_timer, jiffies + timeo); | 562 | cancel_delayed_work_sync(&conn->disc_work); |
563 | queue_delayed_work(conn->hdev->workqueue, | ||
564 | &conn->disc_work, jiffies + timeo); | ||
569 | } | 565 | } |
570 | } | 566 | } |
571 | 567 | ||
@@ -597,10 +593,8 @@ static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d) | |||
597 | try_module_get(d->owner) ? __hci_dev_hold(d) : NULL; \ | 593 | try_module_get(d->owner) ? __hci_dev_hold(d) : NULL; \ |
598 | }) | 594 | }) |
599 | 595 | ||
600 | #define hci_dev_lock(d) spin_lock(&d->lock) | 596 | #define hci_dev_lock(d) mutex_lock(&d->lock) |
601 | #define hci_dev_unlock(d) spin_unlock(&d->lock) | 597 | #define hci_dev_unlock(d) mutex_unlock(&d->lock) |
602 | #define hci_dev_lock_bh(d) spin_lock_bh(&d->lock) | ||
603 | #define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock) | ||
604 | 598 | ||
605 | struct hci_dev *hci_dev_get(int index); | 599 | struct hci_dev *hci_dev_get(int index); |
606 | struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); | 600 | struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); |
@@ -685,53 +679,40 @@ void hci_conn_del_sysfs(struct hci_conn *conn); | |||
685 | #define lmp_host_le_capable(dev) ((dev)->extfeatures[0] & LMP_HOST_LE) | 679 | #define lmp_host_le_capable(dev) ((dev)->extfeatures[0] & LMP_HOST_LE) |
686 | 680 | ||
687 | /* ----- HCI protocols ----- */ | 681 | /* ----- HCI protocols ----- */ |
688 | struct hci_proto { | ||
689 | char *name; | ||
690 | unsigned int id; | ||
691 | unsigned long flags; | ||
692 | |||
693 | void *priv; | ||
694 | |||
695 | int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, | ||
696 | __u8 type); | ||
697 | int (*connect_cfm) (struct hci_conn *conn, __u8 status); | ||
698 | int (*disconn_ind) (struct hci_conn *conn); | ||
699 | int (*disconn_cfm) (struct hci_conn *conn, __u8 reason); | ||
700 | int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, | ||
701 | __u16 flags); | ||
702 | int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); | ||
703 | int (*security_cfm) (struct hci_conn *conn, __u8 status, | ||
704 | __u8 encrypt); | ||
705 | }; | ||
706 | |||
707 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, | 682 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, |
708 | __u8 type) | 683 | __u8 type) |
709 | { | 684 | { |
710 | register struct hci_proto *hp; | 685 | switch (type) { |
711 | int mask = 0; | 686 | case ACL_LINK: |
712 | 687 | return l2cap_connect_ind(hdev, bdaddr); | |
713 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
714 | if (hp && hp->connect_ind) | ||
715 | mask |= hp->connect_ind(hdev, bdaddr, type); | ||
716 | 688 | ||
717 | hp = hci_proto[HCI_PROTO_SCO]; | 689 | case SCO_LINK: |
718 | if (hp && hp->connect_ind) | 690 | case ESCO_LINK: |
719 | mask |= hp->connect_ind(hdev, bdaddr, type); | 691 | return sco_connect_ind(hdev, bdaddr); |
720 | 692 | ||
721 | return mask; | 693 | default: |
694 | BT_ERR("unknown link type %d", type); | ||
695 | return -EINVAL; | ||
696 | } | ||
722 | } | 697 | } |
723 | 698 | ||
724 | static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) | 699 | static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) |
725 | { | 700 | { |
726 | register struct hci_proto *hp; | 701 | switch (conn->type) { |
702 | case ACL_LINK: | ||
703 | case LE_LINK: | ||
704 | l2cap_connect_cfm(conn, status); | ||
705 | break; | ||
727 | 706 | ||
728 | hp = hci_proto[HCI_PROTO_L2CAP]; | 707 | case SCO_LINK: |
729 | if (hp && hp->connect_cfm) | 708 | case ESCO_LINK: |
730 | hp->connect_cfm(conn, status); | 709 | sco_connect_cfm(conn, status); |
710 | break; | ||
731 | 711 | ||
732 | hp = hci_proto[HCI_PROTO_SCO]; | 712 | default: |
733 | if (hp && hp->connect_cfm) | 713 | BT_ERR("unknown link type %d", conn->type); |
734 | hp->connect_cfm(conn, status); | 714 | break; |
715 | } | ||
735 | 716 | ||
736 | if (conn->connect_cfm_cb) | 717 | if (conn->connect_cfm_cb) |
737 | conn->connect_cfm_cb(conn, status); | 718 | conn->connect_cfm_cb(conn, status); |
@@ -739,31 +720,29 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status) | |||
739 | 720 | ||
740 | static inline int hci_proto_disconn_ind(struct hci_conn *conn) | 721 | static inline int hci_proto_disconn_ind(struct hci_conn *conn) |
741 | { | 722 | { |
742 | register struct hci_proto *hp; | 723 | if (conn->type != ACL_LINK && conn->type != LE_LINK) |
743 | int reason = HCI_ERROR_REMOTE_USER_TERM; | 724 | return HCI_ERROR_REMOTE_USER_TERM; |
744 | |||
745 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
746 | if (hp && hp->disconn_ind) | ||
747 | reason = hp->disconn_ind(conn); | ||
748 | 725 | ||
749 | hp = hci_proto[HCI_PROTO_SCO]; | 726 | return l2cap_disconn_ind(conn); |
750 | if (hp && hp->disconn_ind) | ||
751 | reason = hp->disconn_ind(conn); | ||
752 | |||
753 | return reason; | ||
754 | } | 727 | } |
755 | 728 | ||
756 | static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) | 729 | static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) |
757 | { | 730 | { |
758 | register struct hci_proto *hp; | 731 | switch (conn->type) { |
732 | case ACL_LINK: | ||
733 | case LE_LINK: | ||
734 | l2cap_disconn_cfm(conn, reason); | ||
735 | break; | ||
759 | 736 | ||
760 | hp = hci_proto[HCI_PROTO_L2CAP]; | 737 | case SCO_LINK: |
761 | if (hp && hp->disconn_cfm) | 738 | case ESCO_LINK: |
762 | hp->disconn_cfm(conn, reason); | 739 | sco_disconn_cfm(conn, reason); |
740 | break; | ||
763 | 741 | ||
764 | hp = hci_proto[HCI_PROTO_SCO]; | 742 | default: |
765 | if (hp && hp->disconn_cfm) | 743 | BT_ERR("unknown link type %d", conn->type); |
766 | hp->disconn_cfm(conn, reason); | 744 | break; |
745 | } | ||
767 | 746 | ||
768 | if (conn->disconn_cfm_cb) | 747 | if (conn->disconn_cfm_cb) |
769 | conn->disconn_cfm_cb(conn, reason); | 748 | conn->disconn_cfm_cb(conn, reason); |
@@ -771,21 +750,16 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason) | |||
771 | 750 | ||
772 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | 751 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) |
773 | { | 752 | { |
774 | register struct hci_proto *hp; | ||
775 | __u8 encrypt; | 753 | __u8 encrypt; |
776 | 754 | ||
755 | if (conn->type != ACL_LINK && conn->type != LE_LINK) | ||
756 | return; | ||
757 | |||
777 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 758 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
778 | return; | 759 | return; |
779 | 760 | ||
780 | encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; | 761 | encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; |
781 | 762 | l2cap_security_cfm(conn, status, encrypt); | |
782 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
783 | if (hp && hp->security_cfm) | ||
784 | hp->security_cfm(conn, status, encrypt); | ||
785 | |||
786 | hp = hci_proto[HCI_PROTO_SCO]; | ||
787 | if (hp && hp->security_cfm) | ||
788 | hp->security_cfm(conn, status, encrypt); | ||
789 | 763 | ||
790 | if (conn->security_cfm_cb) | 764 | if (conn->security_cfm_cb) |
791 | conn->security_cfm_cb(conn, status); | 765 | conn->security_cfm_cb(conn, status); |
@@ -794,23 +768,15 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | |||
794 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, | 768 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, |
795 | __u8 encrypt) | 769 | __u8 encrypt) |
796 | { | 770 | { |
797 | register struct hci_proto *hp; | 771 | if (conn->type != ACL_LINK && conn->type != LE_LINK) |
798 | 772 | return; | |
799 | hp = hci_proto[HCI_PROTO_L2CAP]; | ||
800 | if (hp && hp->security_cfm) | ||
801 | hp->security_cfm(conn, status, encrypt); | ||
802 | 773 | ||
803 | hp = hci_proto[HCI_PROTO_SCO]; | 774 | l2cap_security_cfm(conn, status, encrypt); |
804 | if (hp && hp->security_cfm) | ||
805 | hp->security_cfm(conn, status, encrypt); | ||
806 | 775 | ||
807 | if (conn->security_cfm_cb) | 776 | if (conn->security_cfm_cb) |
808 | conn->security_cfm_cb(conn, status); | 777 | conn->security_cfm_cb(conn, status); |
809 | } | 778 | } |
810 | 779 | ||
811 | int hci_register_proto(struct hci_proto *hproto); | ||
812 | int hci_unregister_proto(struct hci_proto *hproto); | ||
813 | |||
814 | /* ----- HCI callbacks ----- */ | 780 | /* ----- HCI callbacks ----- */ |
815 | struct hci_cb { | 781 | struct hci_cb { |
816 | struct list_head list; | 782 | struct list_head list; |
@@ -835,13 +801,13 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) | |||
835 | 801 | ||
836 | encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; | 802 | encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; |
837 | 803 | ||
838 | read_lock_bh(&hci_cb_list_lock); | 804 | read_lock(&hci_cb_list_lock); |
839 | list_for_each(p, &hci_cb_list) { | 805 | list_for_each(p, &hci_cb_list) { |
840 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | 806 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); |
841 | if (cb->security_cfm) | 807 | if (cb->security_cfm) |
842 | cb->security_cfm(conn, status, encrypt); | 808 | cb->security_cfm(conn, status, encrypt); |
843 | } | 809 | } |
844 | read_unlock_bh(&hci_cb_list_lock); | 810 | read_unlock(&hci_cb_list_lock); |
845 | } | 811 | } |
846 | 812 | ||
847 | static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, | 813 | static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, |
@@ -857,26 +823,26 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, | |||
857 | 823 | ||
858 | hci_proto_encrypt_cfm(conn, status, encrypt); | 824 | hci_proto_encrypt_cfm(conn, status, encrypt); |
859 | 825 | ||
860 | read_lock_bh(&hci_cb_list_lock); | 826 | read_lock(&hci_cb_list_lock); |
861 | list_for_each(p, &hci_cb_list) { | 827 | list_for_each(p, &hci_cb_list) { |
862 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | 828 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); |
863 | if (cb->security_cfm) | 829 | if (cb->security_cfm) |
864 | cb->security_cfm(conn, status, encrypt); | 830 | cb->security_cfm(conn, status, encrypt); |
865 | } | 831 | } |
866 | read_unlock_bh(&hci_cb_list_lock); | 832 | read_unlock(&hci_cb_list_lock); |
867 | } | 833 | } |
868 | 834 | ||
869 | static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) | 835 | static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) |
870 | { | 836 | { |
871 | struct list_head *p; | 837 | struct list_head *p; |
872 | 838 | ||
873 | read_lock_bh(&hci_cb_list_lock); | 839 | read_lock(&hci_cb_list_lock); |
874 | list_for_each(p, &hci_cb_list) { | 840 | list_for_each(p, &hci_cb_list) { |
875 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | 841 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); |
876 | if (cb->key_change_cfm) | 842 | if (cb->key_change_cfm) |
877 | cb->key_change_cfm(conn, status); | 843 | cb->key_change_cfm(conn, status); |
878 | } | 844 | } |
879 | read_unlock_bh(&hci_cb_list_lock); | 845 | read_unlock(&hci_cb_list_lock); |
880 | } | 846 | } |
881 | 847 | ||
882 | static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, | 848 | static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, |
@@ -884,13 +850,13 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, | |||
884 | { | 850 | { |
885 | struct list_head *p; | 851 | struct list_head *p; |
886 | 852 | ||
887 | read_lock_bh(&hci_cb_list_lock); | 853 | read_lock(&hci_cb_list_lock); |
888 | list_for_each(p, &hci_cb_list) { | 854 | list_for_each(p, &hci_cb_list) { |
889 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | 855 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); |
890 | if (cb->role_switch_cfm) | 856 | if (cb->role_switch_cfm) |
891 | cb->role_switch_cfm(conn, status, role); | 857 | cb->role_switch_cfm(conn, status, role); |
892 | } | 858 | } |
893 | read_unlock_bh(&hci_cb_list_lock); | 859 | read_unlock(&hci_cb_list_lock); |
894 | } | 860 | } |
895 | 861 | ||
896 | int hci_register_cb(struct hci_cb *hcb); | 862 | int hci_register_cb(struct hci_cb *hcb); |
@@ -960,12 +926,16 @@ int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr); | |||
960 | /* HCI info for socket */ | 926 | /* HCI info for socket */ |
961 | #define hci_pi(sk) ((struct hci_pinfo *) sk) | 927 | #define hci_pi(sk) ((struct hci_pinfo *) sk) |
962 | 928 | ||
929 | /* HCI socket flags */ | ||
930 | #define HCI_PI_MGMT_INIT 0 | ||
931 | |||
963 | struct hci_pinfo { | 932 | struct hci_pinfo { |
964 | struct bt_sock bt; | 933 | struct bt_sock bt; |
965 | struct hci_dev *hdev; | 934 | struct hci_dev *hdev; |
966 | struct hci_filter filter; | 935 | struct hci_filter filter; |
967 | __u32 cmsg_mask; | 936 | __u32 cmsg_mask; |
968 | unsigned short channel; | 937 | unsigned short channel; |
938 | unsigned long flags; | ||
969 | }; | 939 | }; |
970 | 940 | ||
971 | /* HCI security filter */ | 941 | /* HCI security filter */ |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 72632f155e43..68f589150692 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -482,10 +482,11 @@ struct l2cap_chan { | |||
482 | __u32 remote_acc_lat; | 482 | __u32 remote_acc_lat; |
483 | __u32 remote_flush_to; | 483 | __u32 remote_flush_to; |
484 | 484 | ||
485 | struct timer_list chan_timer; | 485 | struct delayed_work chan_timer; |
486 | struct timer_list retrans_timer; | 486 | struct delayed_work retrans_timer; |
487 | struct timer_list monitor_timer; | 487 | struct delayed_work monitor_timer; |
488 | struct timer_list ack_timer; | 488 | struct delayed_work ack_timer; |
489 | |||
489 | struct sk_buff *tx_send_head; | 490 | struct sk_buff *tx_send_head; |
490 | struct sk_buff_head tx_q; | 491 | struct sk_buff_head tx_q; |
491 | struct sk_buff_head srej_q; | 492 | struct sk_buff_head srej_q; |
@@ -521,7 +522,7 @@ struct l2cap_conn { | |||
521 | __u8 info_state; | 522 | __u8 info_state; |
522 | __u8 info_ident; | 523 | __u8 info_ident; |
523 | 524 | ||
524 | struct timer_list info_timer; | 525 | struct delayed_work info_timer; |
525 | 526 | ||
526 | spinlock_t lock; | 527 | spinlock_t lock; |
527 | 528 | ||
@@ -531,11 +532,11 @@ struct l2cap_conn { | |||
531 | 532 | ||
532 | __u8 disc_reason; | 533 | __u8 disc_reason; |
533 | 534 | ||
534 | struct timer_list security_timer; | 535 | struct delayed_work security_timer; |
535 | struct smp_chan *smp_chan; | 536 | struct smp_chan *smp_chan; |
536 | 537 | ||
537 | struct list_head chan_l; | 538 | struct list_head chan_l; |
538 | rwlock_t chan_lock; | 539 | struct mutex chan_lock; |
539 | }; | 540 | }; |
540 | 541 | ||
541 | #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 | 542 | #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 |
@@ -594,6 +595,34 @@ enum { | |||
594 | FLAG_EFS_ENABLE, | 595 | FLAG_EFS_ENABLE, |
595 | }; | 596 | }; |
596 | 597 | ||
598 | static inline void l2cap_chan_hold(struct l2cap_chan *c) | ||
599 | { | ||
600 | atomic_inc(&c->refcnt); | ||
601 | } | ||
602 | |||
603 | static inline void l2cap_chan_put(struct l2cap_chan *c) | ||
604 | { | ||
605 | if (atomic_dec_and_test(&c->refcnt)) | ||
606 | kfree(c); | ||
607 | } | ||
608 | |||
609 | static inline void l2cap_set_timer(struct l2cap_chan *chan, | ||
610 | struct delayed_work *work, long timeout) | ||
611 | { | ||
612 | BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); | ||
613 | |||
614 | if (!__cancel_delayed_work(work)) | ||
615 | l2cap_chan_hold(chan); | ||
616 | schedule_delayed_work(work, timeout); | ||
617 | } | ||
618 | |||
619 | static inline void l2cap_clear_timer(struct l2cap_chan *chan, | ||
620 | struct delayed_work *work) | ||
621 | { | ||
622 | if (__cancel_delayed_work(work)) | ||
623 | l2cap_chan_put(chan); | ||
624 | } | ||
625 | |||
597 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) | 626 | #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) |
598 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) | 627 | #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) |
599 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ | 628 | #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ |
@@ -805,7 +834,8 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); | |||
805 | struct l2cap_chan *l2cap_chan_create(struct sock *sk); | 834 | struct l2cap_chan *l2cap_chan_create(struct sock *sk); |
806 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); | 835 | void l2cap_chan_close(struct l2cap_chan *chan, int reason); |
807 | void l2cap_chan_destroy(struct l2cap_chan *chan); | 836 | void l2cap_chan_destroy(struct l2cap_chan *chan); |
808 | int l2cap_chan_connect(struct l2cap_chan *chan); | 837 | inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, |
838 | bdaddr_t *dst); | ||
809 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, | 839 | int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, |
810 | u32 priority); | 840 | u32 priority); |
811 | void l2cap_chan_busy(struct l2cap_chan *chan, int busy); | 841 | void l2cap_chan_busy(struct l2cap_chan *chan, int busy); |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 3b6880690a78..be65d3417883 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -61,22 +61,29 @@ struct mgmt_rp_read_index_list { | |||
61 | /* Reserve one extra byte for names in management messages so that they | 61 | /* Reserve one extra byte for names in management messages so that they |
62 | * are always guaranteed to be nul-terminated */ | 62 | * are always guaranteed to be nul-terminated */ |
63 | #define MGMT_MAX_NAME_LENGTH (HCI_MAX_NAME_LENGTH + 1) | 63 | #define MGMT_MAX_NAME_LENGTH (HCI_MAX_NAME_LENGTH + 1) |
64 | #define MGMT_MAX_SHORT_NAME_LENGTH (10 + 1) | ||
65 | |||
66 | #define MGMT_SETTING_POWERED 0x00000001 | ||
67 | #define MGMT_SETTING_CONNECTABLE 0x00000002 | ||
68 | #define MGMT_SETTING_FAST_CONNECTABLE 0x00000004 | ||
69 | #define MGMT_SETTING_DISCOVERABLE 0x00000008 | ||
70 | #define MGMT_SETTING_PAIRABLE 0x00000010 | ||
71 | #define MGMT_SETTING_LINK_SECURITY 0x00000020 | ||
72 | #define MGMT_SETTING_SSP 0x00000040 | ||
73 | #define MGMT_SETTING_BREDR 0x00000080 | ||
74 | #define MGMT_SETTING_HS 0x00000100 | ||
75 | #define MGMT_SETTING_LE 0x00000200 | ||
64 | 76 | ||
65 | #define MGMT_OP_READ_INFO 0x0004 | 77 | #define MGMT_OP_READ_INFO 0x0004 |
66 | struct mgmt_rp_read_info { | 78 | struct mgmt_rp_read_info { |
67 | __u8 type; | ||
68 | __u8 powered; | ||
69 | __u8 connectable; | ||
70 | __u8 discoverable; | ||
71 | __u8 pairable; | ||
72 | __u8 sec_mode; | ||
73 | bdaddr_t bdaddr; | 79 | bdaddr_t bdaddr; |
80 | __u8 version; | ||
81 | __le16 manufacturer; | ||
82 | __le32 supported_settings; | ||
83 | __le32 current_settings; | ||
74 | __u8 dev_class[3]; | 84 | __u8 dev_class[3]; |
75 | __u8 features[8]; | ||
76 | __u16 manufacturer; | ||
77 | __u8 hci_ver; | ||
78 | __u16 hci_rev; | ||
79 | __u8 name[MGMT_MAX_NAME_LENGTH]; | 85 | __u8 name[MGMT_MAX_NAME_LENGTH]; |
86 | __u8 short_name[MGMT_MAX_SHORT_NAME_LENGTH]; | ||
80 | } __packed; | 87 | } __packed; |
81 | 88 | ||
82 | struct mgmt_mode { | 89 | struct mgmt_mode { |
@@ -93,28 +100,38 @@ struct mgmt_cp_set_discoverable { | |||
93 | 100 | ||
94 | #define MGMT_OP_SET_CONNECTABLE 0x0007 | 101 | #define MGMT_OP_SET_CONNECTABLE 0x0007 |
95 | 102 | ||
96 | #define MGMT_OP_SET_PAIRABLE 0x0008 | 103 | #define MGMT_OP_SET_FAST_CONNECTABLE 0x0008 |
97 | 104 | ||
98 | #define MGMT_OP_ADD_UUID 0x0009 | 105 | #define MGMT_OP_SET_PAIRABLE 0x0009 |
99 | struct mgmt_cp_add_uuid { | ||
100 | __u8 uuid[16]; | ||
101 | __u8 svc_hint; | ||
102 | } __packed; | ||
103 | 106 | ||
104 | #define MGMT_OP_REMOVE_UUID 0x000A | 107 | #define MGMT_OP_SET_LINK_SECURITY 0x000A |
105 | struct mgmt_cp_remove_uuid { | ||
106 | __u8 uuid[16]; | ||
107 | } __packed; | ||
108 | 108 | ||
109 | #define MGMT_OP_SET_DEV_CLASS 0x000B | 109 | #define MGMT_OP_SET_SSP 0x000B |
110 | |||
111 | #define MGMT_OP_SET_HS 0x000C | ||
112 | |||
113 | #define MGMT_OP_SET_LE 0x000D | ||
114 | |||
115 | #define MGMT_OP_SET_DEV_CLASS 0x000E | ||
110 | struct mgmt_cp_set_dev_class { | 116 | struct mgmt_cp_set_dev_class { |
111 | __u8 major; | 117 | __u8 major; |
112 | __u8 minor; | 118 | __u8 minor; |
113 | } __packed; | 119 | } __packed; |
114 | 120 | ||
115 | #define MGMT_OP_SET_SERVICE_CACHE 0x000C | 121 | #define MGMT_OP_SET_LOCAL_NAME 0x000F |
116 | struct mgmt_cp_set_service_cache { | 122 | struct mgmt_cp_set_local_name { |
117 | __u8 enable; | 123 | __u8 name[MGMT_MAX_NAME_LENGTH]; |
124 | } __packed; | ||
125 | |||
126 | #define MGMT_OP_ADD_UUID 0x0010 | ||
127 | struct mgmt_cp_add_uuid { | ||
128 | __u8 uuid[16]; | ||
129 | __u8 svc_hint; | ||
130 | } __packed; | ||
131 | |||
132 | #define MGMT_OP_REMOVE_UUID 0x0011 | ||
133 | struct mgmt_cp_remove_uuid { | ||
134 | __u8 uuid[16]; | ||
118 | } __packed; | 135 | } __packed; |
119 | 136 | ||
120 | struct mgmt_link_key_info { | 137 | struct mgmt_link_key_info { |
@@ -124,14 +141,14 @@ struct mgmt_link_key_info { | |||
124 | u8 pin_len; | 141 | u8 pin_len; |
125 | } __packed; | 142 | } __packed; |
126 | 143 | ||
127 | #define MGMT_OP_LOAD_LINK_KEYS 0x000D | 144 | #define MGMT_OP_LOAD_LINK_KEYS 0x0012 |
128 | struct mgmt_cp_load_link_keys { | 145 | struct mgmt_cp_load_link_keys { |
129 | __u8 debug_keys; | 146 | __u8 debug_keys; |
130 | __le16 key_count; | 147 | __le16 key_count; |
131 | struct mgmt_link_key_info keys[0]; | 148 | struct mgmt_link_key_info keys[0]; |
132 | } __packed; | 149 | } __packed; |
133 | 150 | ||
134 | #define MGMT_OP_REMOVE_KEYS 0x000E | 151 | #define MGMT_OP_REMOVE_KEYS 0x0013 |
135 | struct mgmt_cp_remove_keys { | 152 | struct mgmt_cp_remove_keys { |
136 | bdaddr_t bdaddr; | 153 | bdaddr_t bdaddr; |
137 | __u8 disconnect; | 154 | __u8 disconnect; |
@@ -141,7 +158,7 @@ struct mgmt_rp_remove_keys { | |||
141 | __u8 status; | 158 | __u8 status; |
142 | }; | 159 | }; |
143 | 160 | ||
144 | #define MGMT_OP_DISCONNECT 0x000F | 161 | #define MGMT_OP_DISCONNECT 0x0014 |
145 | struct mgmt_cp_disconnect { | 162 | struct mgmt_cp_disconnect { |
146 | bdaddr_t bdaddr; | 163 | bdaddr_t bdaddr; |
147 | } __packed; | 164 | } __packed; |
@@ -160,13 +177,13 @@ struct mgmt_addr_info { | |||
160 | __u8 type; | 177 | __u8 type; |
161 | } __packed; | 178 | } __packed; |
162 | 179 | ||
163 | #define MGMT_OP_GET_CONNECTIONS 0x0010 | 180 | #define MGMT_OP_GET_CONNECTIONS 0x0015 |
164 | struct mgmt_rp_get_connections { | 181 | struct mgmt_rp_get_connections { |
165 | __le16 conn_count; | 182 | __le16 conn_count; |
166 | struct mgmt_addr_info addr[0]; | 183 | struct mgmt_addr_info addr[0]; |
167 | } __packed; | 184 | } __packed; |
168 | 185 | ||
169 | #define MGMT_OP_PIN_CODE_REPLY 0x0011 | 186 | #define MGMT_OP_PIN_CODE_REPLY 0x0016 |
170 | struct mgmt_cp_pin_code_reply { | 187 | struct mgmt_cp_pin_code_reply { |
171 | bdaddr_t bdaddr; | 188 | bdaddr_t bdaddr; |
172 | __u8 pin_len; | 189 | __u8 pin_len; |
@@ -177,17 +194,17 @@ struct mgmt_rp_pin_code_reply { | |||
177 | uint8_t status; | 194 | uint8_t status; |
178 | } __packed; | 195 | } __packed; |
179 | 196 | ||
180 | #define MGMT_OP_PIN_CODE_NEG_REPLY 0x0012 | 197 | #define MGMT_OP_PIN_CODE_NEG_REPLY 0x0017 |
181 | struct mgmt_cp_pin_code_neg_reply { | 198 | struct mgmt_cp_pin_code_neg_reply { |
182 | bdaddr_t bdaddr; | 199 | bdaddr_t bdaddr; |
183 | } __packed; | 200 | } __packed; |
184 | 201 | ||
185 | #define MGMT_OP_SET_IO_CAPABILITY 0x0013 | 202 | #define MGMT_OP_SET_IO_CAPABILITY 0x0018 |
186 | struct mgmt_cp_set_io_capability { | 203 | struct mgmt_cp_set_io_capability { |
187 | __u8 io_capability; | 204 | __u8 io_capability; |
188 | } __packed; | 205 | } __packed; |
189 | 206 | ||
190 | #define MGMT_OP_PAIR_DEVICE 0x0014 | 207 | #define MGMT_OP_PAIR_DEVICE 0x0019 |
191 | struct mgmt_cp_pair_device { | 208 | struct mgmt_cp_pair_device { |
192 | struct mgmt_addr_info addr; | 209 | struct mgmt_addr_info addr; |
193 | __u8 io_cap; | 210 | __u8 io_cap; |
@@ -197,7 +214,7 @@ struct mgmt_rp_pair_device { | |||
197 | __u8 status; | 214 | __u8 status; |
198 | } __packed; | 215 | } __packed; |
199 | 216 | ||
200 | #define MGMT_OP_USER_CONFIRM_REPLY 0x0015 | 217 | #define MGMT_OP_USER_CONFIRM_REPLY 0x001A |
201 | struct mgmt_cp_user_confirm_reply { | 218 | struct mgmt_cp_user_confirm_reply { |
202 | bdaddr_t bdaddr; | 219 | bdaddr_t bdaddr; |
203 | } __packed; | 220 | } __packed; |
@@ -206,61 +223,68 @@ struct mgmt_rp_user_confirm_reply { | |||
206 | __u8 status; | 223 | __u8 status; |
207 | } __packed; | 224 | } __packed; |
208 | 225 | ||
209 | #define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x0016 | 226 | #define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x001B |
227 | struct mgmt_cp_user_confirm_neg_reply { | ||
228 | bdaddr_t bdaddr; | ||
229 | } __packed; | ||
210 | 230 | ||
211 | #define MGMT_OP_SET_LOCAL_NAME 0x0017 | 231 | #define MGMT_OP_USER_PASSKEY_REPLY 0x001C |
212 | struct mgmt_cp_set_local_name { | 232 | struct mgmt_cp_user_passkey_reply { |
213 | __u8 name[MGMT_MAX_NAME_LENGTH]; | 233 | bdaddr_t bdaddr; |
234 | __le32 passkey; | ||
235 | } __packed; | ||
236 | struct mgmt_rp_user_passkey_reply { | ||
237 | bdaddr_t bdaddr; | ||
238 | __u8 status; | ||
214 | } __packed; | 239 | } __packed; |
215 | 240 | ||
216 | #define MGMT_OP_READ_LOCAL_OOB_DATA 0x0018 | 241 | #define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x001D |
242 | struct mgmt_cp_user_passkey_neg_reply { | ||
243 | bdaddr_t bdaddr; | ||
244 | } __packed; | ||
245 | |||
246 | #define MGMT_OP_READ_LOCAL_OOB_DATA 0x001E | ||
217 | struct mgmt_rp_read_local_oob_data { | 247 | struct mgmt_rp_read_local_oob_data { |
218 | __u8 hash[16]; | 248 | __u8 hash[16]; |
219 | __u8 randomizer[16]; | 249 | __u8 randomizer[16]; |
220 | } __packed; | 250 | } __packed; |
221 | 251 | ||
222 | #define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0019 | 252 | #define MGMT_OP_ADD_REMOTE_OOB_DATA 0x001F |
223 | struct mgmt_cp_add_remote_oob_data { | 253 | struct mgmt_cp_add_remote_oob_data { |
224 | bdaddr_t bdaddr; | 254 | bdaddr_t bdaddr; |
225 | __u8 hash[16]; | 255 | __u8 hash[16]; |
226 | __u8 randomizer[16]; | 256 | __u8 randomizer[16]; |
227 | } __packed; | 257 | } __packed; |
228 | 258 | ||
229 | #define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x001A | 259 | #define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x0020 |
230 | struct mgmt_cp_remove_remote_oob_data { | 260 | struct mgmt_cp_remove_remote_oob_data { |
231 | bdaddr_t bdaddr; | 261 | bdaddr_t bdaddr; |
232 | } __packed; | 262 | } __packed; |
233 | 263 | ||
234 | #define MGMT_OP_START_DISCOVERY 0x001B | 264 | #define MGMT_OP_START_DISCOVERY 0x0021 |
235 | struct mgmt_cp_start_discovery { | 265 | struct mgmt_cp_start_discovery { |
236 | __u8 type; | 266 | __u8 type; |
237 | } __packed; | 267 | } __packed; |
238 | 268 | ||
239 | #define MGMT_OP_STOP_DISCOVERY 0x001C | 269 | #define MGMT_OP_STOP_DISCOVERY 0x0022 |
240 | 270 | ||
241 | #define MGMT_OP_BLOCK_DEVICE 0x001D | 271 | #define MGMT_OP_CONFIRM_NAME 0x0023 |
242 | struct mgmt_cp_block_device { | 272 | struct mgmt_cp_confirm_name { |
243 | bdaddr_t bdaddr; | 273 | bdaddr_t bdaddr; |
274 | __u8 name_known; | ||
244 | } __packed; | 275 | } __packed; |
245 | 276 | struct mgmt_rp_confirm_name { | |
246 | #define MGMT_OP_UNBLOCK_DEVICE 0x001E | ||
247 | struct mgmt_cp_unblock_device { | ||
248 | bdaddr_t bdaddr; | 277 | bdaddr_t bdaddr; |
278 | __u8 status; | ||
249 | } __packed; | 279 | } __packed; |
250 | 280 | ||
251 | #define MGMT_OP_SET_FAST_CONNECTABLE 0x001F | 281 | #define MGMT_OP_BLOCK_DEVICE 0x0024 |
252 | struct mgmt_cp_set_fast_connectable { | 282 | struct mgmt_cp_block_device { |
253 | __u8 enable; | ||
254 | } __packed; | ||
255 | |||
256 | #define MGMT_OP_USER_PASSKEY_REPLY 0x0020 | ||
257 | struct mgmt_cp_user_passkey_reply { | ||
258 | bdaddr_t bdaddr; | 283 | bdaddr_t bdaddr; |
259 | __le32 passkey; | ||
260 | } __packed; | 284 | } __packed; |
261 | 285 | ||
262 | #define MGMT_OP_USER_PASSKEY_NEG_REPLY 0x0021 | 286 | #define MGMT_OP_UNBLOCK_DEVICE 0x0025 |
263 | struct mgmt_cp_user_passkey_neg_reply { | 287 | struct mgmt_cp_unblock_device { |
264 | bdaddr_t bdaddr; | 288 | bdaddr_t bdaddr; |
265 | } __packed; | 289 | } __packed; |
266 | 290 | ||
@@ -285,81 +309,82 @@ struct mgmt_ev_controller_error { | |||
285 | 309 | ||
286 | #define MGMT_EV_INDEX_REMOVED 0x0005 | 310 | #define MGMT_EV_INDEX_REMOVED 0x0005 |
287 | 311 | ||
288 | #define MGMT_EV_POWERED 0x0006 | 312 | #define MGMT_EV_NEW_SETTINGS 0x0006 |
289 | 313 | ||
290 | #define MGMT_EV_DISCOVERABLE 0x0007 | 314 | #define MGMT_EV_CLASS_OF_DEV_CHANGED 0x0007 |
291 | 315 | struct mgmt_ev_class_of_dev_changed { | |
292 | #define MGMT_EV_CONNECTABLE 0x0008 | 316 | __u8 dev_class[3]; |
317 | }; | ||
293 | 318 | ||
294 | #define MGMT_EV_PAIRABLE 0x0009 | 319 | #define MGMT_EV_LOCAL_NAME_CHANGED 0x0008 |
320 | struct mgmt_ev_local_name_changed { | ||
321 | __u8 name[MGMT_MAX_NAME_LENGTH]; | ||
322 | __u8 short_name[MGMT_MAX_SHORT_NAME_LENGTH]; | ||
323 | } __packed; | ||
295 | 324 | ||
296 | #define MGMT_EV_NEW_LINK_KEY 0x000A | 325 | #define MGMT_EV_NEW_LINK_KEY 0x0009 |
297 | struct mgmt_ev_new_link_key { | 326 | struct mgmt_ev_new_link_key { |
298 | __u8 store_hint; | 327 | __u8 store_hint; |
299 | struct mgmt_link_key_info key; | 328 | struct mgmt_link_key_info key; |
300 | } __packed; | 329 | } __packed; |
301 | 330 | ||
302 | #define MGMT_EV_CONNECTED 0x000B | 331 | #define MGMT_EV_CONNECTED 0x000A |
303 | 332 | ||
304 | #define MGMT_EV_DISCONNECTED 0x000C | 333 | #define MGMT_EV_DISCONNECTED 0x000B |
305 | 334 | ||
306 | #define MGMT_EV_CONNECT_FAILED 0x000D | 335 | #define MGMT_EV_CONNECT_FAILED 0x000C |
307 | struct mgmt_ev_connect_failed { | 336 | struct mgmt_ev_connect_failed { |
308 | struct mgmt_addr_info addr; | 337 | struct mgmt_addr_info addr; |
309 | __u8 status; | 338 | __u8 status; |
310 | } __packed; | 339 | } __packed; |
311 | 340 | ||
312 | #define MGMT_EV_PIN_CODE_REQUEST 0x000E | 341 | #define MGMT_EV_PIN_CODE_REQUEST 0x000D |
313 | struct mgmt_ev_pin_code_request { | 342 | struct mgmt_ev_pin_code_request { |
314 | bdaddr_t bdaddr; | 343 | bdaddr_t bdaddr; |
315 | __u8 secure; | 344 | __u8 secure; |
316 | } __packed; | 345 | } __packed; |
317 | 346 | ||
318 | #define MGMT_EV_USER_CONFIRM_REQUEST 0x000F | 347 | #define MGMT_EV_USER_CONFIRM_REQUEST 0x000E |
319 | struct mgmt_ev_user_confirm_request { | 348 | struct mgmt_ev_user_confirm_request { |
320 | bdaddr_t bdaddr; | 349 | bdaddr_t bdaddr; |
321 | __u8 confirm_hint; | 350 | __u8 confirm_hint; |
322 | __le32 value; | 351 | __le32 value; |
323 | } __packed; | 352 | } __packed; |
324 | 353 | ||
354 | #define MGMT_EV_USER_PASSKEY_REQUEST 0x000F | ||
355 | struct mgmt_ev_user_passkey_request { | ||
356 | bdaddr_t bdaddr; | ||
357 | } __packed; | ||
358 | |||
325 | #define MGMT_EV_AUTH_FAILED 0x0010 | 359 | #define MGMT_EV_AUTH_FAILED 0x0010 |
326 | struct mgmt_ev_auth_failed { | 360 | struct mgmt_ev_auth_failed { |
327 | bdaddr_t bdaddr; | 361 | bdaddr_t bdaddr; |
328 | __u8 status; | 362 | __u8 status; |
329 | } __packed; | 363 | } __packed; |
330 | 364 | ||
331 | #define MGMT_EV_LOCAL_NAME_CHANGED 0x0011 | 365 | #define MGMT_EV_DEVICE_FOUND 0x0011 |
332 | struct mgmt_ev_local_name_changed { | ||
333 | __u8 name[MGMT_MAX_NAME_LENGTH]; | ||
334 | } __packed; | ||
335 | |||
336 | #define MGMT_EV_DEVICE_FOUND 0x0012 | ||
337 | struct mgmt_ev_device_found { | 366 | struct mgmt_ev_device_found { |
338 | struct mgmt_addr_info addr; | 367 | struct mgmt_addr_info addr; |
339 | __u8 dev_class[3]; | 368 | __u8 dev_class[3]; |
340 | __s8 rssi; | 369 | __s8 rssi; |
370 | __u8 confirm_name; | ||
341 | __u8 eir[HCI_MAX_EIR_LENGTH]; | 371 | __u8 eir[HCI_MAX_EIR_LENGTH]; |
342 | } __packed; | 372 | } __packed; |
343 | 373 | ||
344 | #define MGMT_EV_REMOTE_NAME 0x0013 | 374 | #define MGMT_EV_REMOTE_NAME 0x0012 |
345 | struct mgmt_ev_remote_name { | 375 | struct mgmt_ev_remote_name { |
346 | bdaddr_t bdaddr; | 376 | bdaddr_t bdaddr; |
347 | __u8 name[MGMT_MAX_NAME_LENGTH]; | 377 | __u8 name[MGMT_MAX_NAME_LENGTH]; |
348 | } __packed; | 378 | } __packed; |
349 | 379 | ||
350 | #define MGMT_EV_DISCOVERING 0x0014 | 380 | #define MGMT_EV_DISCOVERING 0x0013 |
351 | 381 | ||
352 | #define MGMT_EV_DEVICE_BLOCKED 0x0015 | 382 | #define MGMT_EV_DEVICE_BLOCKED 0x0014 |
353 | struct mgmt_ev_device_blocked { | 383 | struct mgmt_ev_device_blocked { |
354 | bdaddr_t bdaddr; | 384 | bdaddr_t bdaddr; |
355 | } __packed; | 385 | } __packed; |
356 | 386 | ||
357 | #define MGMT_EV_DEVICE_UNBLOCKED 0x0016 | 387 | #define MGMT_EV_DEVICE_UNBLOCKED 0x0015 |
358 | struct mgmt_ev_device_unblocked { | 388 | struct mgmt_ev_device_unblocked { |
359 | bdaddr_t bdaddr; | 389 | bdaddr_t bdaddr; |
360 | } __packed; | 390 | } __packed; |
361 | |||
362 | #define MGMT_EV_USER_PASSKEY_REQUEST 0x0017 | ||
363 | struct mgmt_ev_user_passkey_request { | ||
364 | bdaddr_t bdaddr; | ||
365 | } __packed; | ||
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h index 15b97d549441..aeaf5fa2b9f1 100644 --- a/include/net/bluetooth/smp.h +++ b/include/net/bluetooth/smp.h | |||
@@ -115,6 +115,10 @@ struct smp_cmd_security_req { | |||
115 | #define SMP_MIN_ENC_KEY_SIZE 7 | 115 | #define SMP_MIN_ENC_KEY_SIZE 7 |
116 | #define SMP_MAX_ENC_KEY_SIZE 16 | 116 | #define SMP_MAX_ENC_KEY_SIZE 16 |
117 | 117 | ||
118 | #define SMP_FLAG_TK_VALID 1 | ||
119 | #define SMP_FLAG_CFM_PENDING 2 | ||
120 | #define SMP_FLAG_MITM_AUTH 3 | ||
121 | |||
118 | struct smp_chan { | 122 | struct smp_chan { |
119 | struct l2cap_conn *conn; | 123 | struct l2cap_conn *conn; |
120 | u8 preq[7]; /* SMP Pairing Request */ | 124 | u8 preq[7]; /* SMP Pairing Request */ |
@@ -124,6 +128,7 @@ struct smp_chan { | |||
124 | u8 pcnf[16]; /* SMP Pairing Confirm */ | 128 | u8 pcnf[16]; /* SMP Pairing Confirm */ |
125 | u8 tk[16]; /* SMP Temporary Key */ | 129 | u8 tk[16]; /* SMP Temporary Key */ |
126 | u8 smp_key_size; | 130 | u8 smp_key_size; |
131 | unsigned long smp_flags; | ||
127 | struct crypto_blkcipher *tfm; | 132 | struct crypto_blkcipher *tfm; |
128 | struct work_struct confirm; | 133 | struct work_struct confirm; |
129 | struct work_struct random; | 134 | struct work_struct random; |
@@ -134,6 +139,7 @@ struct smp_chan { | |||
134 | int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level); | 139 | int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level); |
135 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); | 140 | int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); |
136 | int smp_distribute_keys(struct l2cap_conn *conn, __u8 force); | 141 | int smp_distribute_keys(struct l2cap_conn *conn, __u8 force); |
142 | int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); | ||
137 | 143 | ||
138 | void smp_chan_destroy(struct l2cap_conn *conn); | 144 | void smp_chan_destroy(struct l2cap_conn *conn); |
139 | 145 | ||
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9f85fca0b676..15f4be7d768e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -505,6 +505,7 @@ struct station_parameters { | |||
505 | * @STATION_INFO_CONNECTED_TIME: @connected_time filled | 505 | * @STATION_INFO_CONNECTED_TIME: @connected_time filled |
506 | * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled | 506 | * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled |
507 | * @STATION_INFO_STA_FLAGS: @sta_flags filled | 507 | * @STATION_INFO_STA_FLAGS: @sta_flags filled |
508 | * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled | ||
508 | */ | 509 | */ |
509 | enum station_info_flags { | 510 | enum station_info_flags { |
510 | STATION_INFO_INACTIVE_TIME = 1<<0, | 511 | STATION_INFO_INACTIVE_TIME = 1<<0, |
@@ -525,7 +526,8 @@ enum station_info_flags { | |||
525 | STATION_INFO_BSS_PARAM = 1<<15, | 526 | STATION_INFO_BSS_PARAM = 1<<15, |
526 | STATION_INFO_CONNECTED_TIME = 1<<16, | 527 | STATION_INFO_CONNECTED_TIME = 1<<16, |
527 | STATION_INFO_ASSOC_REQ_IES = 1<<17, | 528 | STATION_INFO_ASSOC_REQ_IES = 1<<17, |
528 | STATION_INFO_STA_FLAGS = 1<<18 | 529 | STATION_INFO_STA_FLAGS = 1<<18, |
530 | STATION_INFO_BEACON_LOSS_COUNT = 1<<19 | ||
529 | }; | 531 | }; |
530 | 532 | ||
531 | /** | 533 | /** |
@@ -623,6 +625,7 @@ struct sta_bss_parameters { | |||
623 | * the cfg80211_new_sta() calls to notify user space of the IEs. | 625 | * the cfg80211_new_sta() calls to notify user space of the IEs. |
624 | * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. | 626 | * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. |
625 | * @sta_flags: station flags mask & values | 627 | * @sta_flags: station flags mask & values |
628 | * @beacon_loss_count: Number of times beacon loss event has triggered. | ||
626 | */ | 629 | */ |
627 | struct station_info { | 630 | struct station_info { |
628 | u32 filled; | 631 | u32 filled; |
@@ -650,6 +653,8 @@ struct station_info { | |||
650 | const u8 *assoc_req_ies; | 653 | const u8 *assoc_req_ies; |
651 | size_t assoc_req_ies_len; | 654 | size_t assoc_req_ies_len; |
652 | 655 | ||
656 | u32 beacon_loss_count; | ||
657 | |||
653 | /* | 658 | /* |
654 | * Note: Add a new enum station_info_flags value for each new field and | 659 | * Note: Add a new enum station_info_flags value for each new field and |
655 | * use it to check which fields are initialized. | 660 | * use it to check which fields are initialized. |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5b5c8a7e26d7..2a7523edd9b5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -3502,9 +3502,12 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn); | |||
3502 | * | 3502 | * |
3503 | * @IEEE80211_RC_HT_CHANGED: The HT parameters of the operating channel have | 3503 | * @IEEE80211_RC_HT_CHANGED: The HT parameters of the operating channel have |
3504 | * changed, rate control algorithm can update its internal state if needed. | 3504 | * changed, rate control algorithm can update its internal state if needed. |
3505 | * @IEEE80211_RC_SMPS_CHANGED: The SMPS state of the station changed, the rate | ||
3506 | * control algorithm needs to adjust accordingly. | ||
3505 | */ | 3507 | */ |
3506 | enum rate_control_changed { | 3508 | enum rate_control_changed { |
3507 | IEEE80211_RC_HT_CHANGED = BIT(0) | 3509 | IEEE80211_RC_HT_CHANGED = BIT(0), |
3510 | IEEE80211_RC_SMPS_CHANGED = BIT(1), | ||
3508 | }; | 3511 | }; |
3509 | 3512 | ||
3510 | /** | 3513 | /** |
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index bfb3dc03c9de..9ec85eb8853d 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig | |||
@@ -6,7 +6,11 @@ menuconfig BT | |||
6 | tristate "Bluetooth subsystem support" | 6 | tristate "Bluetooth subsystem support" |
7 | depends on NET && !S390 | 7 | depends on NET && !S390 |
8 | depends on RFKILL || !RFKILL | 8 | depends on RFKILL || !RFKILL |
9 | select CRC16 | ||
9 | select CRYPTO | 10 | select CRYPTO |
11 | select CRYPTO_BLKCIPHER | ||
12 | select CRYPTO_AES | ||
13 | select CRYPTO_ECB | ||
10 | help | 14 | help |
11 | Bluetooth is low-cost, low-power, short-range wireless technology. | 15 | Bluetooth is low-cost, low-power, short-range wireless technology. |
12 | It was designed as a replacement for cables and other short-range | 16 | It was designed as a replacement for cables and other short-range |
@@ -15,10 +19,12 @@ menuconfig BT | |||
15 | Bluetooth can be found at <http://www.bluetooth.com/>. | 19 | Bluetooth can be found at <http://www.bluetooth.com/>. |
16 | 20 | ||
17 | Linux Bluetooth subsystem consist of several layers: | 21 | Linux Bluetooth subsystem consist of several layers: |
18 | Bluetooth Core (HCI device and connection manager, scheduler) | 22 | Bluetooth Core |
23 | HCI device and connection manager, scheduler | ||
24 | SCO audio links | ||
25 | L2CAP (Logical Link Control and Adaptation Protocol) | ||
26 | SMP (Security Manager Protocol) on LE (Low Energy) links | ||
19 | HCI Device drivers (Interface to the hardware) | 27 | HCI Device drivers (Interface to the hardware) |
20 | SCO Module (SCO audio links) | ||
21 | L2CAP Module (Logical Link Control and Adaptation Protocol) | ||
22 | RFCOMM Module (RFCOMM Protocol) | 28 | RFCOMM Module (RFCOMM Protocol) |
23 | BNEP Module (Bluetooth Network Encapsulation Protocol) | 29 | BNEP Module (Bluetooth Network Encapsulation Protocol) |
24 | CMTP Module (CAPI Message Transport Protocol) | 30 | CMTP Module (CAPI Message Transport Protocol) |
@@ -33,31 +39,6 @@ menuconfig BT | |||
33 | to Bluetooth kernel modules are provided in the BlueZ packages. For | 39 | to Bluetooth kernel modules are provided in the BlueZ packages. For |
34 | more information, see <http://www.bluez.org/>. | 40 | more information, see <http://www.bluez.org/>. |
35 | 41 | ||
36 | if BT != n | ||
37 | |||
38 | config BT_L2CAP | ||
39 | bool "L2CAP protocol support" | ||
40 | select CRC16 | ||
41 | select CRYPTO | ||
42 | select CRYPTO_BLKCIPHER | ||
43 | select CRYPTO_AES | ||
44 | select CRYPTO_ECB | ||
45 | help | ||
46 | L2CAP (Logical Link Control and Adaptation Protocol) provides | ||
47 | connection oriented and connection-less data transport. L2CAP | ||
48 | support is required for most Bluetooth applications. | ||
49 | |||
50 | Also included is support for SMP (Security Manager Protocol) which | ||
51 | is the security layer on top of LE (Low Energy) links. | ||
52 | |||
53 | config BT_SCO | ||
54 | bool "SCO links support" | ||
55 | help | ||
56 | SCO link provides voice transport over Bluetooth. SCO support is | ||
57 | required for voice applications like Headset and Audio. | ||
58 | |||
59 | endif | ||
60 | |||
61 | source "net/bluetooth/rfcomm/Kconfig" | 42 | source "net/bluetooth/rfcomm/Kconfig" |
62 | 43 | ||
63 | source "net/bluetooth/bnep/Kconfig" | 44 | source "net/bluetooth/bnep/Kconfig" |
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 9b67f3d08fa4..2dc5a5700f53 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile | |||
@@ -8,6 +8,5 @@ obj-$(CONFIG_BT_BNEP) += bnep/ | |||
8 | obj-$(CONFIG_BT_CMTP) += cmtp/ | 8 | obj-$(CONFIG_BT_CMTP) += cmtp/ |
9 | obj-$(CONFIG_BT_HIDP) += hidp/ | 9 | obj-$(CONFIG_BT_HIDP) += hidp/ |
10 | 10 | ||
11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o | 11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ |
12 | bluetooth-$(CONFIG_BT_L2CAP) += l2cap_core.o l2cap_sock.o smp.o | 12 | hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o |
13 | bluetooth-$(CONFIG_BT_SCO) += sco.o | ||
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 062124cd89cf..cdcfcabb34ab 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -199,15 +199,14 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
199 | 199 | ||
200 | BT_DBG("parent %p", parent); | 200 | BT_DBG("parent %p", parent); |
201 | 201 | ||
202 | local_bh_disable(); | ||
203 | list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { | 202 | list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { |
204 | sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); | 203 | sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); |
205 | 204 | ||
206 | bh_lock_sock(sk); | 205 | lock_sock(sk); |
207 | 206 | ||
208 | /* FIXME: Is this check still needed */ | 207 | /* FIXME: Is this check still needed */ |
209 | if (sk->sk_state == BT_CLOSED) { | 208 | if (sk->sk_state == BT_CLOSED) { |
210 | bh_unlock_sock(sk); | 209 | release_sock(sk); |
211 | bt_accept_unlink(sk); | 210 | bt_accept_unlink(sk); |
212 | continue; | 211 | continue; |
213 | } | 212 | } |
@@ -218,14 +217,12 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
218 | if (newsock) | 217 | if (newsock) |
219 | sock_graft(sk, newsock); | 218 | sock_graft(sk, newsock); |
220 | 219 | ||
221 | bh_unlock_sock(sk); | 220 | release_sock(sk); |
222 | local_bh_enable(); | ||
223 | return sk; | 221 | return sk; |
224 | } | 222 | } |
225 | 223 | ||
226 | bh_unlock_sock(sk); | 224 | release_sock(sk); |
227 | } | 225 | } |
228 | local_bh_enable(); | ||
229 | 226 | ||
230 | return NULL; | 227 | return NULL; |
231 | } | 228 | } |
diff --git a/net/bluetooth/bnep/Kconfig b/net/bluetooth/bnep/Kconfig index 35158b036d54..71791fc9f6b1 100644 --- a/net/bluetooth/bnep/Kconfig +++ b/net/bluetooth/bnep/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config BT_BNEP | 1 | config BT_BNEP |
2 | tristate "BNEP protocol support" | 2 | tristate "BNEP protocol support" |
3 | depends on BT && BT_L2CAP | 3 | depends on BT |
4 | select CRC32 | 4 | select CRC32 |
5 | help | 5 | help |
6 | BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet | 6 | BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet |
diff --git a/net/bluetooth/cmtp/Kconfig b/net/bluetooth/cmtp/Kconfig index d6b0382f6f3a..94cbf42ce155 100644 --- a/net/bluetooth/cmtp/Kconfig +++ b/net/bluetooth/cmtp/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config BT_CMTP | 1 | config BT_CMTP |
2 | tristate "CMTP protocol support" | 2 | tristate "CMTP protocol support" |
3 | depends on BT && BT_L2CAP && ISDN_CAPI | 3 | depends on BT && ISDN_CAPI |
4 | help | 4 | help |
5 | CMTP (CAPI Message Transport Protocol) is a transport layer | 5 | CMTP (CAPI Message Transport Protocol) is a transport layer |
6 | for CAPI messages. CMTP is required for the Bluetooth Common | 6 | for CAPI messages. CMTP is required for the Bluetooth Common |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 3fa08dda825e..3db432473ad5 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -275,9 +275,10 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) | |||
275 | } | 275 | } |
276 | } | 276 | } |
277 | 277 | ||
278 | static void hci_conn_timeout(unsigned long arg) | 278 | static void hci_conn_timeout(struct work_struct *work) |
279 | { | 279 | { |
280 | struct hci_conn *conn = (void *) arg; | 280 | struct hci_conn *conn = container_of(work, struct hci_conn, |
281 | disc_work.work); | ||
281 | struct hci_dev *hdev = conn->hdev; | 282 | struct hci_dev *hdev = conn->hdev; |
282 | __u8 reason; | 283 | __u8 reason; |
283 | 284 | ||
@@ -311,6 +312,42 @@ static void hci_conn_timeout(unsigned long arg) | |||
311 | hci_dev_unlock(hdev); | 312 | hci_dev_unlock(hdev); |
312 | } | 313 | } |
313 | 314 | ||
315 | /* Enter sniff mode */ | ||
316 | static void hci_conn_enter_sniff_mode(struct hci_conn *conn) | ||
317 | { | ||
318 | struct hci_dev *hdev = conn->hdev; | ||
319 | |||
320 | BT_DBG("conn %p mode %d", conn, conn->mode); | ||
321 | |||
322 | if (test_bit(HCI_RAW, &hdev->flags)) | ||
323 | return; | ||
324 | |||
325 | if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn)) | ||
326 | return; | ||
327 | |||
328 | if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF)) | ||
329 | return; | ||
330 | |||
331 | if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) { | ||
332 | struct hci_cp_sniff_subrate cp; | ||
333 | cp.handle = cpu_to_le16(conn->handle); | ||
334 | cp.max_latency = cpu_to_le16(0); | ||
335 | cp.min_remote_timeout = cpu_to_le16(0); | ||
336 | cp.min_local_timeout = cpu_to_le16(0); | ||
337 | hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp); | ||
338 | } | ||
339 | |||
340 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | ||
341 | struct hci_cp_sniff_mode cp; | ||
342 | cp.handle = cpu_to_le16(conn->handle); | ||
343 | cp.max_interval = cpu_to_le16(hdev->sniff_max_interval); | ||
344 | cp.min_interval = cpu_to_le16(hdev->sniff_min_interval); | ||
345 | cp.attempt = cpu_to_le16(4); | ||
346 | cp.timeout = cpu_to_le16(1); | ||
347 | hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp); | ||
348 | } | ||
349 | } | ||
350 | |||
314 | static void hci_conn_idle(unsigned long arg) | 351 | static void hci_conn_idle(unsigned long arg) |
315 | { | 352 | { |
316 | struct hci_conn *conn = (void *) arg; | 353 | struct hci_conn *conn = (void *) arg; |
@@ -325,12 +362,8 @@ static void hci_conn_auto_accept(unsigned long arg) | |||
325 | struct hci_conn *conn = (void *) arg; | 362 | struct hci_conn *conn = (void *) arg; |
326 | struct hci_dev *hdev = conn->hdev; | 363 | struct hci_dev *hdev = conn->hdev; |
327 | 364 | ||
328 | hci_dev_lock(hdev); | ||
329 | |||
330 | hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), | 365 | hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), |
331 | &conn->dst); | 366 | &conn->dst); |
332 | |||
333 | hci_dev_unlock(hdev); | ||
334 | } | 367 | } |
335 | 368 | ||
336 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | 369 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) |
@@ -374,9 +407,9 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
374 | 407 | ||
375 | skb_queue_head_init(&conn->data_q); | 408 | skb_queue_head_init(&conn->data_q); |
376 | 409 | ||
377 | hci_chan_hash_init(conn); | 410 | INIT_LIST_HEAD(&conn->chan_list);; |
378 | 411 | ||
379 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); | 412 | INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout); |
380 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); | 413 | setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); |
381 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, | 414 | setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, |
382 | (unsigned long) conn); | 415 | (unsigned long) conn); |
@@ -385,8 +418,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
385 | 418 | ||
386 | hci_dev_hold(hdev); | 419 | hci_dev_hold(hdev); |
387 | 420 | ||
388 | tasklet_disable(&hdev->tx_task); | ||
389 | |||
390 | hci_conn_hash_add(hdev, conn); | 421 | hci_conn_hash_add(hdev, conn); |
391 | if (hdev->notify) | 422 | if (hdev->notify) |
392 | hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); | 423 | hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); |
@@ -395,8 +426,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
395 | 426 | ||
396 | hci_conn_init_sysfs(conn); | 427 | hci_conn_init_sysfs(conn); |
397 | 428 | ||
398 | tasklet_enable(&hdev->tx_task); | ||
399 | |||
400 | return conn; | 429 | return conn; |
401 | } | 430 | } |
402 | 431 | ||
@@ -408,7 +437,7 @@ int hci_conn_del(struct hci_conn *conn) | |||
408 | 437 | ||
409 | del_timer(&conn->idle_timer); | 438 | del_timer(&conn->idle_timer); |
410 | 439 | ||
411 | del_timer(&conn->disc_timer); | 440 | cancel_delayed_work_sync(&conn->disc_work); |
412 | 441 | ||
413 | del_timer(&conn->auto_accept_timer); | 442 | del_timer(&conn->auto_accept_timer); |
414 | 443 | ||
@@ -432,16 +461,13 @@ int hci_conn_del(struct hci_conn *conn) | |||
432 | } | 461 | } |
433 | } | 462 | } |
434 | 463 | ||
435 | tasklet_disable(&hdev->tx_task); | ||
436 | 464 | ||
437 | hci_chan_hash_flush(conn); | 465 | hci_chan_list_flush(conn); |
438 | 466 | ||
439 | hci_conn_hash_del(hdev, conn); | 467 | hci_conn_hash_del(hdev, conn); |
440 | if (hdev->notify) | 468 | if (hdev->notify) |
441 | hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); | 469 | hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); |
442 | 470 | ||
443 | tasklet_enable(&hdev->tx_task); | ||
444 | |||
445 | skb_queue_purge(&conn->data_q); | 471 | skb_queue_purge(&conn->data_q); |
446 | 472 | ||
447 | hci_conn_put_device(conn); | 473 | hci_conn_put_device(conn); |
@@ -461,7 +487,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) | |||
461 | 487 | ||
462 | BT_DBG("%s -> %s", batostr(src), batostr(dst)); | 488 | BT_DBG("%s -> %s", batostr(src), batostr(dst)); |
463 | 489 | ||
464 | read_lock_bh(&hci_dev_list_lock); | 490 | read_lock(&hci_dev_list_lock); |
465 | 491 | ||
466 | list_for_each_entry(d, &hci_dev_list, list) { | 492 | list_for_each_entry(d, &hci_dev_list, list) { |
467 | if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags)) | 493 | if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags)) |
@@ -486,7 +512,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) | |||
486 | if (hdev) | 512 | if (hdev) |
487 | hdev = hci_dev_hold(hdev); | 513 | hdev = hci_dev_hold(hdev); |
488 | 514 | ||
489 | read_unlock_bh(&hci_dev_list_lock); | 515 | read_unlock(&hci_dev_list_lock); |
490 | return hdev; | 516 | return hdev; |
491 | } | 517 | } |
492 | EXPORT_SYMBOL(hci_get_route); | 518 | EXPORT_SYMBOL(hci_get_route); |
@@ -767,57 +793,15 @@ timer: | |||
767 | jiffies + msecs_to_jiffies(hdev->idle_timeout)); | 793 | jiffies + msecs_to_jiffies(hdev->idle_timeout)); |
768 | } | 794 | } |
769 | 795 | ||
770 | /* Enter sniff mode */ | ||
771 | void hci_conn_enter_sniff_mode(struct hci_conn *conn) | ||
772 | { | ||
773 | struct hci_dev *hdev = conn->hdev; | ||
774 | |||
775 | BT_DBG("conn %p mode %d", conn, conn->mode); | ||
776 | |||
777 | if (test_bit(HCI_RAW, &hdev->flags)) | ||
778 | return; | ||
779 | |||
780 | if (!lmp_sniff_capable(hdev) || !lmp_sniff_capable(conn)) | ||
781 | return; | ||
782 | |||
783 | if (conn->mode != HCI_CM_ACTIVE || !(conn->link_policy & HCI_LP_SNIFF)) | ||
784 | return; | ||
785 | |||
786 | if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) { | ||
787 | struct hci_cp_sniff_subrate cp; | ||
788 | cp.handle = cpu_to_le16(conn->handle); | ||
789 | cp.max_latency = cpu_to_le16(0); | ||
790 | cp.min_remote_timeout = cpu_to_le16(0); | ||
791 | cp.min_local_timeout = cpu_to_le16(0); | ||
792 | hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp); | ||
793 | } | ||
794 | |||
795 | if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { | ||
796 | struct hci_cp_sniff_mode cp; | ||
797 | cp.handle = cpu_to_le16(conn->handle); | ||
798 | cp.max_interval = cpu_to_le16(hdev->sniff_max_interval); | ||
799 | cp.min_interval = cpu_to_le16(hdev->sniff_min_interval); | ||
800 | cp.attempt = cpu_to_le16(4); | ||
801 | cp.timeout = cpu_to_le16(1); | ||
802 | hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp); | ||
803 | } | ||
804 | } | ||
805 | |||
806 | /* Drop all connection on the device */ | 796 | /* Drop all connection on the device */ |
807 | void hci_conn_hash_flush(struct hci_dev *hdev) | 797 | void hci_conn_hash_flush(struct hci_dev *hdev) |
808 | { | 798 | { |
809 | struct hci_conn_hash *h = &hdev->conn_hash; | 799 | struct hci_conn_hash *h = &hdev->conn_hash; |
810 | struct list_head *p; | 800 | struct hci_conn *c; |
811 | 801 | ||
812 | BT_DBG("hdev %s", hdev->name); | 802 | BT_DBG("hdev %s", hdev->name); |
813 | 803 | ||
814 | p = h->list.next; | 804 | list_for_each_entry_rcu(c, &h->list, list) { |
815 | while (p != &h->list) { | ||
816 | struct hci_conn *c; | ||
817 | |||
818 | c = list_entry(p, struct hci_conn, list); | ||
819 | p = p->next; | ||
820 | |||
821 | c->state = BT_CLOSED; | 805 | c->state = BT_CLOSED; |
822 | 806 | ||
823 | hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM); | 807 | hci_proto_disconn_cfm(c, HCI_ERROR_LOCAL_HOST_TERM); |
@@ -882,7 +866,7 @@ int hci_get_conn_list(void __user *arg) | |||
882 | 866 | ||
883 | ci = cl->conn_info; | 867 | ci = cl->conn_info; |
884 | 868 | ||
885 | hci_dev_lock_bh(hdev); | 869 | hci_dev_lock(hdev); |
886 | list_for_each_entry(c, &hdev->conn_hash.list, list) { | 870 | list_for_each_entry(c, &hdev->conn_hash.list, list) { |
887 | bacpy(&(ci + n)->bdaddr, &c->dst); | 871 | bacpy(&(ci + n)->bdaddr, &c->dst); |
888 | (ci + n)->handle = c->handle; | 872 | (ci + n)->handle = c->handle; |
@@ -893,7 +877,7 @@ int hci_get_conn_list(void __user *arg) | |||
893 | if (++n >= req.conn_num) | 877 | if (++n >= req.conn_num) |
894 | break; | 878 | break; |
895 | } | 879 | } |
896 | hci_dev_unlock_bh(hdev); | 880 | hci_dev_unlock(hdev); |
897 | 881 | ||
898 | cl->dev_id = hdev->id; | 882 | cl->dev_id = hdev->id; |
899 | cl->conn_num = n; | 883 | cl->conn_num = n; |
@@ -917,7 +901,7 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg) | |||
917 | if (copy_from_user(&req, arg, sizeof(req))) | 901 | if (copy_from_user(&req, arg, sizeof(req))) |
918 | return -EFAULT; | 902 | return -EFAULT; |
919 | 903 | ||
920 | hci_dev_lock_bh(hdev); | 904 | hci_dev_lock(hdev); |
921 | conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr); | 905 | conn = hci_conn_hash_lookup_ba(hdev, req.type, &req.bdaddr); |
922 | if (conn) { | 906 | if (conn) { |
923 | bacpy(&ci.bdaddr, &conn->dst); | 907 | bacpy(&ci.bdaddr, &conn->dst); |
@@ -927,7 +911,7 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg) | |||
927 | ci.state = conn->state; | 911 | ci.state = conn->state; |
928 | ci.link_mode = conn->link_mode; | 912 | ci.link_mode = conn->link_mode; |
929 | } | 913 | } |
930 | hci_dev_unlock_bh(hdev); | 914 | hci_dev_unlock(hdev); |
931 | 915 | ||
932 | if (!conn) | 916 | if (!conn) |
933 | return -ENOENT; | 917 | return -ENOENT; |
@@ -943,11 +927,11 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg) | |||
943 | if (copy_from_user(&req, arg, sizeof(req))) | 927 | if (copy_from_user(&req, arg, sizeof(req))) |
944 | return -EFAULT; | 928 | return -EFAULT; |
945 | 929 | ||
946 | hci_dev_lock_bh(hdev); | 930 | hci_dev_lock(hdev); |
947 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr); | 931 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr); |
948 | if (conn) | 932 | if (conn) |
949 | req.type = conn->auth_type; | 933 | req.type = conn->auth_type; |
950 | hci_dev_unlock_bh(hdev); | 934 | hci_dev_unlock(hdev); |
951 | 935 | ||
952 | if (!conn) | 936 | if (!conn) |
953 | return -ENOENT; | 937 | return -ENOENT; |
@@ -969,9 +953,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) | |||
969 | chan->conn = conn; | 953 | chan->conn = conn; |
970 | skb_queue_head_init(&chan->data_q); | 954 | skb_queue_head_init(&chan->data_q); |
971 | 955 | ||
972 | tasklet_disable(&hdev->tx_task); | 956 | list_add_rcu(&chan->list, &conn->chan_list); |
973 | hci_chan_hash_add(conn, chan); | ||
974 | tasklet_enable(&hdev->tx_task); | ||
975 | 957 | ||
976 | return chan; | 958 | return chan; |
977 | } | 959 | } |
@@ -983,9 +965,9 @@ int hci_chan_del(struct hci_chan *chan) | |||
983 | 965 | ||
984 | BT_DBG("%s conn %p chan %p", hdev->name, conn, chan); | 966 | BT_DBG("%s conn %p chan %p", hdev->name, conn, chan); |
985 | 967 | ||
986 | tasklet_disable(&hdev->tx_task); | 968 | list_del_rcu(&chan->list); |
987 | hci_chan_hash_del(conn, chan); | 969 | |
988 | tasklet_enable(&hdev->tx_task); | 970 | synchronize_rcu(); |
989 | 971 | ||
990 | skb_queue_purge(&chan->data_q); | 972 | skb_queue_purge(&chan->data_q); |
991 | kfree(chan); | 973 | kfree(chan); |
@@ -993,13 +975,12 @@ int hci_chan_del(struct hci_chan *chan) | |||
993 | return 0; | 975 | return 0; |
994 | } | 976 | } |
995 | 977 | ||
996 | void hci_chan_hash_flush(struct hci_conn *conn) | 978 | void hci_chan_list_flush(struct hci_conn *conn) |
997 | { | 979 | { |
998 | struct hci_chan_hash *h = &conn->chan_hash; | 980 | struct hci_chan *chan; |
999 | struct hci_chan *chan, *tmp; | ||
1000 | 981 | ||
1001 | BT_DBG("conn %p", conn); | 982 | BT_DBG("conn %p", conn); |
1002 | 983 | ||
1003 | list_for_each_entry_safe(chan, tmp, &h->list, list) | 984 | list_for_each_entry_rcu(chan, &conn->chan_list, list) |
1004 | hci_chan_del(chan); | 985 | hci_chan_del(chan); |
1005 | } | 986 | } |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ce3727ecc0c4..6d38d80195cb 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | BlueZ - Bluetooth protocol stack for Linux | 2 | BlueZ - Bluetooth protocol stack for Linux |
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | 3 | Copyright (C) 2000-2001 Qualcomm Incorporated |
4 | Copyright (C) 2011 ProFUSION Embedded Systems | ||
4 | 5 | ||
5 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | 6 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
6 | 7 | ||
@@ -56,11 +57,9 @@ | |||
56 | 57 | ||
57 | int enable_hs; | 58 | int enable_hs; |
58 | 59 | ||
59 | static void hci_cmd_task(unsigned long arg); | 60 | static void hci_rx_work(struct work_struct *work); |
60 | static void hci_rx_task(unsigned long arg); | 61 | static void hci_cmd_work(struct work_struct *work); |
61 | static void hci_tx_task(unsigned long arg); | 62 | static void hci_tx_work(struct work_struct *work); |
62 | |||
63 | static DEFINE_RWLOCK(hci_task_lock); | ||
64 | 63 | ||
65 | /* HCI device list */ | 64 | /* HCI device list */ |
66 | LIST_HEAD(hci_dev_list); | 65 | LIST_HEAD(hci_dev_list); |
@@ -70,10 +69,6 @@ DEFINE_RWLOCK(hci_dev_list_lock); | |||
70 | LIST_HEAD(hci_cb_list); | 69 | LIST_HEAD(hci_cb_list); |
71 | DEFINE_RWLOCK(hci_cb_list_lock); | 70 | DEFINE_RWLOCK(hci_cb_list_lock); |
72 | 71 | ||
73 | /* HCI protocols */ | ||
74 | #define HCI_MAX_PROTO 2 | ||
75 | struct hci_proto *hci_proto[HCI_MAX_PROTO]; | ||
76 | |||
77 | /* HCI notifiers list */ | 72 | /* HCI notifiers list */ |
78 | static ATOMIC_NOTIFIER_HEAD(hci_notifier); | 73 | static ATOMIC_NOTIFIER_HEAD(hci_notifier); |
79 | 74 | ||
@@ -192,33 +187,20 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) | |||
192 | hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); | 187 | hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); |
193 | } | 188 | } |
194 | 189 | ||
195 | static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | 190 | static void bredr_init(struct hci_dev *hdev) |
196 | { | 191 | { |
197 | struct hci_cp_delete_stored_link_key cp; | 192 | struct hci_cp_delete_stored_link_key cp; |
198 | struct sk_buff *skb; | ||
199 | __le16 param; | 193 | __le16 param; |
200 | __u8 flt_type; | 194 | __u8 flt_type; |
201 | 195 | ||
202 | BT_DBG("%s %ld", hdev->name, opt); | 196 | hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; |
203 | |||
204 | /* Driver initialization */ | ||
205 | |||
206 | /* Special commands */ | ||
207 | while ((skb = skb_dequeue(&hdev->driver_init))) { | ||
208 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; | ||
209 | skb->dev = (void *) hdev; | ||
210 | |||
211 | skb_queue_tail(&hdev->cmd_q, skb); | ||
212 | tasklet_schedule(&hdev->cmd_task); | ||
213 | } | ||
214 | skb_queue_purge(&hdev->driver_init); | ||
215 | 197 | ||
216 | /* Mandatory initialization */ | 198 | /* Mandatory initialization */ |
217 | 199 | ||
218 | /* Reset */ | 200 | /* Reset */ |
219 | if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { | 201 | if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { |
220 | set_bit(HCI_RESET, &hdev->flags); | 202 | set_bit(HCI_RESET, &hdev->flags); |
221 | hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); | 203 | hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); |
222 | } | 204 | } |
223 | 205 | ||
224 | /* Read Local Supported Features */ | 206 | /* Read Local Supported Features */ |
@@ -257,6 +239,51 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | |||
257 | hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); | 239 | hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); |
258 | } | 240 | } |
259 | 241 | ||
242 | static void amp_init(struct hci_dev *hdev) | ||
243 | { | ||
244 | hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; | ||
245 | |||
246 | /* Reset */ | ||
247 | hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); | ||
248 | |||
249 | /* Read Local Version */ | ||
250 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); | ||
251 | } | ||
252 | |||
253 | static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | ||
254 | { | ||
255 | struct sk_buff *skb; | ||
256 | |||
257 | BT_DBG("%s %ld", hdev->name, opt); | ||
258 | |||
259 | /* Driver initialization */ | ||
260 | |||
261 | /* Special commands */ | ||
262 | while ((skb = skb_dequeue(&hdev->driver_init))) { | ||
263 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; | ||
264 | skb->dev = (void *) hdev; | ||
265 | |||
266 | skb_queue_tail(&hdev->cmd_q, skb); | ||
267 | queue_work(hdev->workqueue, &hdev->cmd_work); | ||
268 | } | ||
269 | skb_queue_purge(&hdev->driver_init); | ||
270 | |||
271 | switch (hdev->dev_type) { | ||
272 | case HCI_BREDR: | ||
273 | bredr_init(hdev); | ||
274 | break; | ||
275 | |||
276 | case HCI_AMP: | ||
277 | amp_init(hdev); | ||
278 | break; | ||
279 | |||
280 | default: | ||
281 | BT_ERR("Unknown device type %d", hdev->dev_type); | ||
282 | break; | ||
283 | } | ||
284 | |||
285 | } | ||
286 | |||
260 | static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) | 287 | static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) |
261 | { | 288 | { |
262 | BT_DBG("%s", hdev->name); | 289 | BT_DBG("%s", hdev->name); |
@@ -433,14 +460,14 @@ int hci_inquiry(void __user *arg) | |||
433 | if (!hdev) | 460 | if (!hdev) |
434 | return -ENODEV; | 461 | return -ENODEV; |
435 | 462 | ||
436 | hci_dev_lock_bh(hdev); | 463 | hci_dev_lock(hdev); |
437 | if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || | 464 | if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || |
438 | inquiry_cache_empty(hdev) || | 465 | inquiry_cache_empty(hdev) || |
439 | ir.flags & IREQ_CACHE_FLUSH) { | 466 | ir.flags & IREQ_CACHE_FLUSH) { |
440 | inquiry_cache_flush(hdev); | 467 | inquiry_cache_flush(hdev); |
441 | do_inquiry = 1; | 468 | do_inquiry = 1; |
442 | } | 469 | } |
443 | hci_dev_unlock_bh(hdev); | 470 | hci_dev_unlock(hdev); |
444 | 471 | ||
445 | timeo = ir.length * msecs_to_jiffies(2000); | 472 | timeo = ir.length * msecs_to_jiffies(2000); |
446 | 473 | ||
@@ -462,9 +489,9 @@ int hci_inquiry(void __user *arg) | |||
462 | goto done; | 489 | goto done; |
463 | } | 490 | } |
464 | 491 | ||
465 | hci_dev_lock_bh(hdev); | 492 | hci_dev_lock(hdev); |
466 | ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); | 493 | ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf); |
467 | hci_dev_unlock_bh(hdev); | 494 | hci_dev_unlock(hdev); |
468 | 495 | ||
469 | BT_DBG("num_rsp %d", ir.num_rsp); | 496 | BT_DBG("num_rsp %d", ir.num_rsp); |
470 | 497 | ||
@@ -541,15 +568,15 @@ int hci_dev_open(__u16 dev) | |||
541 | set_bit(HCI_UP, &hdev->flags); | 568 | set_bit(HCI_UP, &hdev->flags); |
542 | hci_notify(hdev, HCI_DEV_UP); | 569 | hci_notify(hdev, HCI_DEV_UP); |
543 | if (!test_bit(HCI_SETUP, &hdev->flags)) { | 570 | if (!test_bit(HCI_SETUP, &hdev->flags)) { |
544 | hci_dev_lock_bh(hdev); | 571 | hci_dev_lock(hdev); |
545 | mgmt_powered(hdev, 1); | 572 | mgmt_powered(hdev, 1); |
546 | hci_dev_unlock_bh(hdev); | 573 | hci_dev_unlock(hdev); |
547 | } | 574 | } |
548 | } else { | 575 | } else { |
549 | /* Init failed, cleanup */ | 576 | /* Init failed, cleanup */ |
550 | tasklet_kill(&hdev->rx_task); | 577 | flush_work(&hdev->tx_work); |
551 | tasklet_kill(&hdev->tx_task); | 578 | flush_work(&hdev->cmd_work); |
552 | tasklet_kill(&hdev->cmd_task); | 579 | flush_work(&hdev->rx_work); |
553 | 580 | ||
554 | skb_queue_purge(&hdev->cmd_q); | 581 | skb_queue_purge(&hdev->cmd_q); |
555 | skb_queue_purge(&hdev->rx_q); | 582 | skb_queue_purge(&hdev->rx_q); |
@@ -585,9 +612,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
585 | return 0; | 612 | return 0; |
586 | } | 613 | } |
587 | 614 | ||
588 | /* Kill RX and TX tasks */ | 615 | /* Flush RX and TX works */ |
589 | tasklet_kill(&hdev->rx_task); | 616 | flush_work(&hdev->tx_work); |
590 | tasklet_kill(&hdev->tx_task); | 617 | flush_work(&hdev->rx_work); |
591 | 618 | ||
592 | if (hdev->discov_timeout > 0) { | 619 | if (hdev->discov_timeout > 0) { |
593 | cancel_delayed_work(&hdev->discov_off); | 620 | cancel_delayed_work(&hdev->discov_off); |
@@ -597,10 +624,13 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
597 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) | 624 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
598 | cancel_delayed_work(&hdev->power_off); | 625 | cancel_delayed_work(&hdev->power_off); |
599 | 626 | ||
600 | hci_dev_lock_bh(hdev); | 627 | if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->flags)) |
628 | cancel_delayed_work(&hdev->service_cache); | ||
629 | |||
630 | hci_dev_lock(hdev); | ||
601 | inquiry_cache_flush(hdev); | 631 | inquiry_cache_flush(hdev); |
602 | hci_conn_hash_flush(hdev); | 632 | hci_conn_hash_flush(hdev); |
603 | hci_dev_unlock_bh(hdev); | 633 | hci_dev_unlock(hdev); |
604 | 634 | ||
605 | hci_notify(hdev, HCI_DEV_DOWN); | 635 | hci_notify(hdev, HCI_DEV_DOWN); |
606 | 636 | ||
@@ -617,8 +647,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
617 | clear_bit(HCI_INIT, &hdev->flags); | 647 | clear_bit(HCI_INIT, &hdev->flags); |
618 | } | 648 | } |
619 | 649 | ||
620 | /* Kill cmd task */ | 650 | /* flush cmd work */ |
621 | tasklet_kill(&hdev->cmd_task); | 651 | flush_work(&hdev->cmd_work); |
622 | 652 | ||
623 | /* Drop queues */ | 653 | /* Drop queues */ |
624 | skb_queue_purge(&hdev->rx_q); | 654 | skb_queue_purge(&hdev->rx_q); |
@@ -636,9 +666,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
636 | * and no tasks are scheduled. */ | 666 | * and no tasks are scheduled. */ |
637 | hdev->close(hdev); | 667 | hdev->close(hdev); |
638 | 668 | ||
639 | hci_dev_lock_bh(hdev); | 669 | hci_dev_lock(hdev); |
640 | mgmt_powered(hdev, 0); | 670 | mgmt_powered(hdev, 0); |
641 | hci_dev_unlock_bh(hdev); | 671 | hci_dev_unlock(hdev); |
642 | 672 | ||
643 | /* Clear flags */ | 673 | /* Clear flags */ |
644 | hdev->flags = 0; | 674 | hdev->flags = 0; |
@@ -672,7 +702,6 @@ int hci_dev_reset(__u16 dev) | |||
672 | return -ENODEV; | 702 | return -ENODEV; |
673 | 703 | ||
674 | hci_req_lock(hdev); | 704 | hci_req_lock(hdev); |
675 | tasklet_disable(&hdev->tx_task); | ||
676 | 705 | ||
677 | if (!test_bit(HCI_UP, &hdev->flags)) | 706 | if (!test_bit(HCI_UP, &hdev->flags)) |
678 | goto done; | 707 | goto done; |
@@ -681,10 +710,10 @@ int hci_dev_reset(__u16 dev) | |||
681 | skb_queue_purge(&hdev->rx_q); | 710 | skb_queue_purge(&hdev->rx_q); |
682 | skb_queue_purge(&hdev->cmd_q); | 711 | skb_queue_purge(&hdev->cmd_q); |
683 | 712 | ||
684 | hci_dev_lock_bh(hdev); | 713 | hci_dev_lock(hdev); |
685 | inquiry_cache_flush(hdev); | 714 | inquiry_cache_flush(hdev); |
686 | hci_conn_hash_flush(hdev); | 715 | hci_conn_hash_flush(hdev); |
687 | hci_dev_unlock_bh(hdev); | 716 | hci_dev_unlock(hdev); |
688 | 717 | ||
689 | if (hdev->flush) | 718 | if (hdev->flush) |
690 | hdev->flush(hdev); | 719 | hdev->flush(hdev); |
@@ -697,7 +726,6 @@ int hci_dev_reset(__u16 dev) | |||
697 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 726 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); |
698 | 727 | ||
699 | done: | 728 | done: |
700 | tasklet_enable(&hdev->tx_task); | ||
701 | hci_req_unlock(hdev); | 729 | hci_req_unlock(hdev); |
702 | hci_dev_put(hdev); | 730 | hci_dev_put(hdev); |
703 | return ret; | 731 | return ret; |
@@ -816,7 +844,7 @@ int hci_get_dev_list(void __user *arg) | |||
816 | 844 | ||
817 | dr = dl->dev_req; | 845 | dr = dl->dev_req; |
818 | 846 | ||
819 | read_lock_bh(&hci_dev_list_lock); | 847 | read_lock(&hci_dev_list_lock); |
820 | list_for_each_entry(hdev, &hci_dev_list, list) { | 848 | list_for_each_entry(hdev, &hci_dev_list, list) { |
821 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) | 849 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
822 | cancel_delayed_work(&hdev->power_off); | 850 | cancel_delayed_work(&hdev->power_off); |
@@ -830,7 +858,7 @@ int hci_get_dev_list(void __user *arg) | |||
830 | if (++n >= dev_num) | 858 | if (++n >= dev_num) |
831 | break; | 859 | break; |
832 | } | 860 | } |
833 | read_unlock_bh(&hci_dev_list_lock); | 861 | read_unlock(&hci_dev_list_lock); |
834 | 862 | ||
835 | dl->dev_num = n; | 863 | dl->dev_num = n; |
836 | size = sizeof(*dl) + n * sizeof(*dr); | 864 | size = sizeof(*dl) + n * sizeof(*dr); |
@@ -939,7 +967,7 @@ static void hci_power_on(struct work_struct *work) | |||
939 | return; | 967 | return; |
940 | 968 | ||
941 | if (test_bit(HCI_AUTO_OFF, &hdev->flags)) | 969 | if (test_bit(HCI_AUTO_OFF, &hdev->flags)) |
942 | queue_delayed_work(hdev->workqueue, &hdev->power_off, | 970 | schedule_delayed_work(&hdev->power_off, |
943 | msecs_to_jiffies(AUTO_OFF_TIMEOUT)); | 971 | msecs_to_jiffies(AUTO_OFF_TIMEOUT)); |
944 | 972 | ||
945 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) | 973 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) |
@@ -967,13 +995,13 @@ static void hci_discov_off(struct work_struct *work) | |||
967 | 995 | ||
968 | BT_DBG("%s", hdev->name); | 996 | BT_DBG("%s", hdev->name); |
969 | 997 | ||
970 | hci_dev_lock_bh(hdev); | 998 | hci_dev_lock(hdev); |
971 | 999 | ||
972 | hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); | 1000 | hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, sizeof(scan), &scan); |
973 | 1001 | ||
974 | hdev->discov_timeout = 0; | 1002 | hdev->discov_timeout = 0; |
975 | 1003 | ||
976 | hci_dev_unlock_bh(hdev); | 1004 | hci_dev_unlock(hdev); |
977 | } | 1005 | } |
978 | 1006 | ||
979 | int hci_uuids_clear(struct hci_dev *hdev) | 1007 | int hci_uuids_clear(struct hci_dev *hdev) |
@@ -1207,7 +1235,7 @@ static void hci_cmd_timer(unsigned long arg) | |||
1207 | 1235 | ||
1208 | BT_ERR("%s command tx timeout", hdev->name); | 1236 | BT_ERR("%s command tx timeout", hdev->name); |
1209 | atomic_set(&hdev->cmd_cnt, 1); | 1237 | atomic_set(&hdev->cmd_cnt, 1); |
1210 | tasklet_schedule(&hdev->cmd_task); | 1238 | queue_work(hdev->workqueue, &hdev->cmd_work); |
1211 | } | 1239 | } |
1212 | 1240 | ||
1213 | struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, | 1241 | struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, |
@@ -1340,9 +1368,10 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1340 | return mgmt_device_unblocked(hdev, bdaddr); | 1368 | return mgmt_device_unblocked(hdev, bdaddr); |
1341 | } | 1369 | } |
1342 | 1370 | ||
1343 | static void hci_clear_adv_cache(unsigned long arg) | 1371 | static void hci_clear_adv_cache(struct work_struct *work) |
1344 | { | 1372 | { |
1345 | struct hci_dev *hdev = (void *) arg; | 1373 | struct hci_dev *hdev = container_of(work, struct hci_dev, |
1374 | adv_work.work); | ||
1346 | 1375 | ||
1347 | hci_dev_lock(hdev); | 1376 | hci_dev_lock(hdev); |
1348 | 1377 | ||
@@ -1429,7 +1458,7 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1429 | */ | 1458 | */ |
1430 | id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; | 1459 | id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; |
1431 | 1460 | ||
1432 | write_lock_bh(&hci_dev_list_lock); | 1461 | write_lock(&hci_dev_list_lock); |
1433 | 1462 | ||
1434 | /* Find first available device id */ | 1463 | /* Find first available device id */ |
1435 | list_for_each(p, &hci_dev_list) { | 1464 | list_for_each(p, &hci_dev_list) { |
@@ -1443,7 +1472,7 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1443 | list_add_tail(&hdev->list, head); | 1472 | list_add_tail(&hdev->list, head); |
1444 | 1473 | ||
1445 | atomic_set(&hdev->refcnt, 1); | 1474 | atomic_set(&hdev->refcnt, 1); |
1446 | spin_lock_init(&hdev->lock); | 1475 | mutex_init(&hdev->lock); |
1447 | 1476 | ||
1448 | hdev->flags = 0; | 1477 | hdev->flags = 0; |
1449 | hdev->dev_flags = 0; | 1478 | hdev->dev_flags = 0; |
@@ -1456,9 +1485,10 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1456 | hdev->sniff_max_interval = 800; | 1485 | hdev->sniff_max_interval = 800; |
1457 | hdev->sniff_min_interval = 80; | 1486 | hdev->sniff_min_interval = 80; |
1458 | 1487 | ||
1459 | tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev); | 1488 | INIT_WORK(&hdev->rx_work, hci_rx_work); |
1460 | tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev); | 1489 | INIT_WORK(&hdev->cmd_work, hci_cmd_work); |
1461 | tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev); | 1490 | INIT_WORK(&hdev->tx_work, hci_tx_work); |
1491 | |||
1462 | 1492 | ||
1463 | skb_queue_head_init(&hdev->rx_q); | 1493 | skb_queue_head_init(&hdev->rx_q); |
1464 | skb_queue_head_init(&hdev->cmd_q); | 1494 | skb_queue_head_init(&hdev->cmd_q); |
@@ -1487,9 +1517,8 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1487 | INIT_LIST_HEAD(&hdev->remote_oob_data); | 1517 | INIT_LIST_HEAD(&hdev->remote_oob_data); |
1488 | 1518 | ||
1489 | INIT_LIST_HEAD(&hdev->adv_entries); | 1519 | INIT_LIST_HEAD(&hdev->adv_entries); |
1490 | setup_timer(&hdev->adv_timer, hci_clear_adv_cache, | ||
1491 | (unsigned long) hdev); | ||
1492 | 1520 | ||
1521 | INIT_DELAYED_WORK(&hdev->adv_work, hci_clear_adv_cache); | ||
1493 | INIT_WORK(&hdev->power_on, hci_power_on); | 1522 | INIT_WORK(&hdev->power_on, hci_power_on); |
1494 | INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); | 1523 | INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); |
1495 | 1524 | ||
@@ -1499,9 +1528,10 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1499 | 1528 | ||
1500 | atomic_set(&hdev->promisc, 0); | 1529 | atomic_set(&hdev->promisc, 0); |
1501 | 1530 | ||
1502 | write_unlock_bh(&hci_dev_list_lock); | 1531 | write_unlock(&hci_dev_list_lock); |
1503 | 1532 | ||
1504 | hdev->workqueue = create_singlethread_workqueue(hdev->name); | 1533 | hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | |
1534 | WQ_MEM_RECLAIM, 1); | ||
1505 | if (!hdev->workqueue) { | 1535 | if (!hdev->workqueue) { |
1506 | error = -ENOMEM; | 1536 | error = -ENOMEM; |
1507 | goto err; | 1537 | goto err; |
@@ -1522,7 +1552,7 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1522 | 1552 | ||
1523 | set_bit(HCI_AUTO_OFF, &hdev->flags); | 1553 | set_bit(HCI_AUTO_OFF, &hdev->flags); |
1524 | set_bit(HCI_SETUP, &hdev->flags); | 1554 | set_bit(HCI_SETUP, &hdev->flags); |
1525 | queue_work(hdev->workqueue, &hdev->power_on); | 1555 | schedule_work(&hdev->power_on); |
1526 | 1556 | ||
1527 | hci_notify(hdev, HCI_DEV_REG); | 1557 | hci_notify(hdev, HCI_DEV_REG); |
1528 | 1558 | ||
@@ -1531,9 +1561,9 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1531 | err_wqueue: | 1561 | err_wqueue: |
1532 | destroy_workqueue(hdev->workqueue); | 1562 | destroy_workqueue(hdev->workqueue); |
1533 | err: | 1563 | err: |
1534 | write_lock_bh(&hci_dev_list_lock); | 1564 | write_lock(&hci_dev_list_lock); |
1535 | list_del(&hdev->list); | 1565 | list_del(&hdev->list); |
1536 | write_unlock_bh(&hci_dev_list_lock); | 1566 | write_unlock(&hci_dev_list_lock); |
1537 | 1567 | ||
1538 | return error; | 1568 | return error; |
1539 | } | 1569 | } |
@@ -1546,9 +1576,9 @@ void hci_unregister_dev(struct hci_dev *hdev) | |||
1546 | 1576 | ||
1547 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); | 1577 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
1548 | 1578 | ||
1549 | write_lock_bh(&hci_dev_list_lock); | 1579 | write_lock(&hci_dev_list_lock); |
1550 | list_del(&hdev->list); | 1580 | list_del(&hdev->list); |
1551 | write_unlock_bh(&hci_dev_list_lock); | 1581 | write_unlock(&hci_dev_list_lock); |
1552 | 1582 | ||
1553 | hci_dev_do_close(hdev); | 1583 | hci_dev_do_close(hdev); |
1554 | 1584 | ||
@@ -1557,9 +1587,9 @@ void hci_unregister_dev(struct hci_dev *hdev) | |||
1557 | 1587 | ||
1558 | if (!test_bit(HCI_INIT, &hdev->flags) && | 1588 | if (!test_bit(HCI_INIT, &hdev->flags) && |
1559 | !test_bit(HCI_SETUP, &hdev->flags)) { | 1589 | !test_bit(HCI_SETUP, &hdev->flags)) { |
1560 | hci_dev_lock_bh(hdev); | 1590 | hci_dev_lock(hdev); |
1561 | mgmt_index_removed(hdev); | 1591 | mgmt_index_removed(hdev); |
1562 | hci_dev_unlock_bh(hdev); | 1592 | hci_dev_unlock(hdev); |
1563 | } | 1593 | } |
1564 | 1594 | ||
1565 | /* mgmt_index_removed should take care of emptying the | 1595 | /* mgmt_index_removed should take care of emptying the |
@@ -1575,17 +1605,17 @@ void hci_unregister_dev(struct hci_dev *hdev) | |||
1575 | 1605 | ||
1576 | hci_del_sysfs(hdev); | 1606 | hci_del_sysfs(hdev); |
1577 | 1607 | ||
1578 | del_timer(&hdev->adv_timer); | 1608 | cancel_delayed_work_sync(&hdev->adv_work); |
1579 | 1609 | ||
1580 | destroy_workqueue(hdev->workqueue); | 1610 | destroy_workqueue(hdev->workqueue); |
1581 | 1611 | ||
1582 | hci_dev_lock_bh(hdev); | 1612 | hci_dev_lock(hdev); |
1583 | hci_blacklist_clear(hdev); | 1613 | hci_blacklist_clear(hdev); |
1584 | hci_uuids_clear(hdev); | 1614 | hci_uuids_clear(hdev); |
1585 | hci_link_keys_clear(hdev); | 1615 | hci_link_keys_clear(hdev); |
1586 | hci_remote_oob_data_clear(hdev); | 1616 | hci_remote_oob_data_clear(hdev); |
1587 | hci_adv_entries_clear(hdev); | 1617 | hci_adv_entries_clear(hdev); |
1588 | hci_dev_unlock_bh(hdev); | 1618 | hci_dev_unlock(hdev); |
1589 | 1619 | ||
1590 | __hci_dev_put(hdev); | 1620 | __hci_dev_put(hdev); |
1591 | } | 1621 | } |
@@ -1623,9 +1653,8 @@ int hci_recv_frame(struct sk_buff *skb) | |||
1623 | /* Time stamp */ | 1653 | /* Time stamp */ |
1624 | __net_timestamp(skb); | 1654 | __net_timestamp(skb); |
1625 | 1655 | ||
1626 | /* Queue frame for rx task */ | ||
1627 | skb_queue_tail(&hdev->rx_q, skb); | 1656 | skb_queue_tail(&hdev->rx_q, skb); |
1628 | tasklet_schedule(&hdev->rx_task); | 1657 | queue_work(hdev->workqueue, &hdev->rx_work); |
1629 | 1658 | ||
1630 | return 0; | 1659 | return 0; |
1631 | } | 1660 | } |
@@ -1797,59 +1826,13 @@ EXPORT_SYMBOL(hci_recv_stream_fragment); | |||
1797 | 1826 | ||
1798 | /* ---- Interface to upper protocols ---- */ | 1827 | /* ---- Interface to upper protocols ---- */ |
1799 | 1828 | ||
1800 | /* Register/Unregister protocols. | ||
1801 | * hci_task_lock is used to ensure that no tasks are running. */ | ||
1802 | int hci_register_proto(struct hci_proto *hp) | ||
1803 | { | ||
1804 | int err = 0; | ||
1805 | |||
1806 | BT_DBG("%p name %s id %d", hp, hp->name, hp->id); | ||
1807 | |||
1808 | if (hp->id >= HCI_MAX_PROTO) | ||
1809 | return -EINVAL; | ||
1810 | |||
1811 | write_lock_bh(&hci_task_lock); | ||
1812 | |||
1813 | if (!hci_proto[hp->id]) | ||
1814 | hci_proto[hp->id] = hp; | ||
1815 | else | ||
1816 | err = -EEXIST; | ||
1817 | |||
1818 | write_unlock_bh(&hci_task_lock); | ||
1819 | |||
1820 | return err; | ||
1821 | } | ||
1822 | EXPORT_SYMBOL(hci_register_proto); | ||
1823 | |||
1824 | int hci_unregister_proto(struct hci_proto *hp) | ||
1825 | { | ||
1826 | int err = 0; | ||
1827 | |||
1828 | BT_DBG("%p name %s id %d", hp, hp->name, hp->id); | ||
1829 | |||
1830 | if (hp->id >= HCI_MAX_PROTO) | ||
1831 | return -EINVAL; | ||
1832 | |||
1833 | write_lock_bh(&hci_task_lock); | ||
1834 | |||
1835 | if (hci_proto[hp->id]) | ||
1836 | hci_proto[hp->id] = NULL; | ||
1837 | else | ||
1838 | err = -ENOENT; | ||
1839 | |||
1840 | write_unlock_bh(&hci_task_lock); | ||
1841 | |||
1842 | return err; | ||
1843 | } | ||
1844 | EXPORT_SYMBOL(hci_unregister_proto); | ||
1845 | |||
1846 | int hci_register_cb(struct hci_cb *cb) | 1829 | int hci_register_cb(struct hci_cb *cb) |
1847 | { | 1830 | { |
1848 | BT_DBG("%p name %s", cb, cb->name); | 1831 | BT_DBG("%p name %s", cb, cb->name); |
1849 | 1832 | ||
1850 | write_lock_bh(&hci_cb_list_lock); | 1833 | write_lock(&hci_cb_list_lock); |
1851 | list_add(&cb->list, &hci_cb_list); | 1834 | list_add(&cb->list, &hci_cb_list); |
1852 | write_unlock_bh(&hci_cb_list_lock); | 1835 | write_unlock(&hci_cb_list_lock); |
1853 | 1836 | ||
1854 | return 0; | 1837 | return 0; |
1855 | } | 1838 | } |
@@ -1859,9 +1842,9 @@ int hci_unregister_cb(struct hci_cb *cb) | |||
1859 | { | 1842 | { |
1860 | BT_DBG("%p name %s", cb, cb->name); | 1843 | BT_DBG("%p name %s", cb, cb->name); |
1861 | 1844 | ||
1862 | write_lock_bh(&hci_cb_list_lock); | 1845 | write_lock(&hci_cb_list_lock); |
1863 | list_del(&cb->list); | 1846 | list_del(&cb->list); |
1864 | write_unlock_bh(&hci_cb_list_lock); | 1847 | write_unlock(&hci_cb_list_lock); |
1865 | 1848 | ||
1866 | return 0; | 1849 | return 0; |
1867 | } | 1850 | } |
@@ -1922,7 +1905,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) | |||
1922 | hdev->init_last_cmd = opcode; | 1905 | hdev->init_last_cmd = opcode; |
1923 | 1906 | ||
1924 | skb_queue_tail(&hdev->cmd_q, skb); | 1907 | skb_queue_tail(&hdev->cmd_q, skb); |
1925 | tasklet_schedule(&hdev->cmd_task); | 1908 | queue_work(hdev->workqueue, &hdev->cmd_work); |
1926 | 1909 | ||
1927 | return 0; | 1910 | return 0; |
1928 | } | 1911 | } |
@@ -1977,7 +1960,7 @@ static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, | |||
1977 | skb_shinfo(skb)->frag_list = NULL; | 1960 | skb_shinfo(skb)->frag_list = NULL; |
1978 | 1961 | ||
1979 | /* Queue all fragments atomically */ | 1962 | /* Queue all fragments atomically */ |
1980 | spin_lock_bh(&queue->lock); | 1963 | spin_lock(&queue->lock); |
1981 | 1964 | ||
1982 | __skb_queue_tail(queue, skb); | 1965 | __skb_queue_tail(queue, skb); |
1983 | 1966 | ||
@@ -1995,7 +1978,7 @@ static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, | |||
1995 | __skb_queue_tail(queue, skb); | 1978 | __skb_queue_tail(queue, skb); |
1996 | } while (list); | 1979 | } while (list); |
1997 | 1980 | ||
1998 | spin_unlock_bh(&queue->lock); | 1981 | spin_unlock(&queue->lock); |
1999 | } | 1982 | } |
2000 | } | 1983 | } |
2001 | 1984 | ||
@@ -2012,7 +1995,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) | |||
2012 | 1995 | ||
2013 | hci_queue_acl(conn, &chan->data_q, skb, flags); | 1996 | hci_queue_acl(conn, &chan->data_q, skb, flags); |
2014 | 1997 | ||
2015 | tasklet_schedule(&hdev->tx_task); | 1998 | queue_work(hdev->workqueue, &hdev->tx_work); |
2016 | } | 1999 | } |
2017 | EXPORT_SYMBOL(hci_send_acl); | 2000 | EXPORT_SYMBOL(hci_send_acl); |
2018 | 2001 | ||
@@ -2035,7 +2018,7 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) | |||
2035 | bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; | 2018 | bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; |
2036 | 2019 | ||
2037 | skb_queue_tail(&conn->data_q, skb); | 2020 | skb_queue_tail(&conn->data_q, skb); |
2038 | tasklet_schedule(&hdev->tx_task); | 2021 | queue_work(hdev->workqueue, &hdev->tx_work); |
2039 | } | 2022 | } |
2040 | EXPORT_SYMBOL(hci_send_sco); | 2023 | EXPORT_SYMBOL(hci_send_sco); |
2041 | 2024 | ||
@@ -2050,7 +2033,10 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int | |||
2050 | 2033 | ||
2051 | /* We don't have to lock device here. Connections are always | 2034 | /* We don't have to lock device here. Connections are always |
2052 | * added and removed with TX task disabled. */ | 2035 | * added and removed with TX task disabled. */ |
2053 | list_for_each_entry(c, &h->list, list) { | 2036 | |
2037 | rcu_read_lock(); | ||
2038 | |||
2039 | list_for_each_entry_rcu(c, &h->list, list) { | ||
2054 | if (c->type != type || skb_queue_empty(&c->data_q)) | 2040 | if (c->type != type || skb_queue_empty(&c->data_q)) |
2055 | continue; | 2041 | continue; |
2056 | 2042 | ||
@@ -2068,6 +2054,8 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int | |||
2068 | break; | 2054 | break; |
2069 | } | 2055 | } |
2070 | 2056 | ||
2057 | rcu_read_unlock(); | ||
2058 | |||
2071 | if (conn) { | 2059 | if (conn) { |
2072 | int cnt, q; | 2060 | int cnt, q; |
2073 | 2061 | ||
@@ -2103,14 +2091,18 @@ static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) | |||
2103 | 2091 | ||
2104 | BT_ERR("%s link tx timeout", hdev->name); | 2092 | BT_ERR("%s link tx timeout", hdev->name); |
2105 | 2093 | ||
2094 | rcu_read_lock(); | ||
2095 | |||
2106 | /* Kill stalled connections */ | 2096 | /* Kill stalled connections */ |
2107 | list_for_each_entry(c, &h->list, list) { | 2097 | list_for_each_entry_rcu(c, &h->list, list) { |
2108 | if (c->type == type && c->sent) { | 2098 | if (c->type == type && c->sent) { |
2109 | BT_ERR("%s killing stalled connection %s", | 2099 | BT_ERR("%s killing stalled connection %s", |
2110 | hdev->name, batostr(&c->dst)); | 2100 | hdev->name, batostr(&c->dst)); |
2111 | hci_acl_disconn(c, 0x13); | 2101 | hci_acl_disconn(c, 0x13); |
2112 | } | 2102 | } |
2113 | } | 2103 | } |
2104 | |||
2105 | rcu_read_unlock(); | ||
2114 | } | 2106 | } |
2115 | 2107 | ||
2116 | static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, | 2108 | static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, |
@@ -2124,8 +2116,9 @@ static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, | |||
2124 | 2116 | ||
2125 | BT_DBG("%s", hdev->name); | 2117 | BT_DBG("%s", hdev->name); |
2126 | 2118 | ||
2127 | list_for_each_entry(conn, &h->list, list) { | 2119 | rcu_read_lock(); |
2128 | struct hci_chan_hash *ch; | 2120 | |
2121 | list_for_each_entry_rcu(conn, &h->list, list) { | ||
2129 | struct hci_chan *tmp; | 2122 | struct hci_chan *tmp; |
2130 | 2123 | ||
2131 | if (conn->type != type) | 2124 | if (conn->type != type) |
@@ -2136,9 +2129,7 @@ static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, | |||
2136 | 2129 | ||
2137 | conn_num++; | 2130 | conn_num++; |
2138 | 2131 | ||
2139 | ch = &conn->chan_hash; | 2132 | list_for_each_entry_rcu(tmp, &conn->chan_list, list) { |
2140 | |||
2141 | list_for_each_entry(tmp, &ch->list, list) { | ||
2142 | struct sk_buff *skb; | 2133 | struct sk_buff *skb; |
2143 | 2134 | ||
2144 | if (skb_queue_empty(&tmp->data_q)) | 2135 | if (skb_queue_empty(&tmp->data_q)) |
@@ -2166,6 +2157,8 @@ static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, | |||
2166 | break; | 2157 | break; |
2167 | } | 2158 | } |
2168 | 2159 | ||
2160 | rcu_read_unlock(); | ||
2161 | |||
2169 | if (!chan) | 2162 | if (!chan) |
2170 | return NULL; | 2163 | return NULL; |
2171 | 2164 | ||
@@ -2199,8 +2192,9 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) | |||
2199 | 2192 | ||
2200 | BT_DBG("%s", hdev->name); | 2193 | BT_DBG("%s", hdev->name); |
2201 | 2194 | ||
2202 | list_for_each_entry(conn, &h->list, list) { | 2195 | rcu_read_lock(); |
2203 | struct hci_chan_hash *ch; | 2196 | |
2197 | list_for_each_entry_rcu(conn, &h->list, list) { | ||
2204 | struct hci_chan *chan; | 2198 | struct hci_chan *chan; |
2205 | 2199 | ||
2206 | if (conn->type != type) | 2200 | if (conn->type != type) |
@@ -2211,8 +2205,7 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) | |||
2211 | 2205 | ||
2212 | num++; | 2206 | num++; |
2213 | 2207 | ||
2214 | ch = &conn->chan_hash; | 2208 | list_for_each_entry_rcu(chan, &conn->chan_list, list) { |
2215 | list_for_each_entry(chan, &ch->list, list) { | ||
2216 | struct sk_buff *skb; | 2209 | struct sk_buff *skb; |
2217 | 2210 | ||
2218 | if (chan->sent) { | 2211 | if (chan->sent) { |
@@ -2236,6 +2229,9 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) | |||
2236 | if (hci_conn_num(hdev, type) == num) | 2229 | if (hci_conn_num(hdev, type) == num) |
2237 | break; | 2230 | break; |
2238 | } | 2231 | } |
2232 | |||
2233 | rcu_read_unlock(); | ||
2234 | |||
2239 | } | 2235 | } |
2240 | 2236 | ||
2241 | static inline void hci_sched_acl(struct hci_dev *hdev) | 2237 | static inline void hci_sched_acl(struct hci_dev *hdev) |
@@ -2386,13 +2382,11 @@ static inline void hci_sched_le(struct hci_dev *hdev) | |||
2386 | hci_prio_recalculate(hdev, LE_LINK); | 2382 | hci_prio_recalculate(hdev, LE_LINK); |
2387 | } | 2383 | } |
2388 | 2384 | ||
2389 | static void hci_tx_task(unsigned long arg) | 2385 | static void hci_tx_work(struct work_struct *work) |
2390 | { | 2386 | { |
2391 | struct hci_dev *hdev = (struct hci_dev *) arg; | 2387 | struct hci_dev *hdev = container_of(work, struct hci_dev, tx_work); |
2392 | struct sk_buff *skb; | 2388 | struct sk_buff *skb; |
2393 | 2389 | ||
2394 | read_lock(&hci_task_lock); | ||
2395 | |||
2396 | BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, | 2390 | BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, |
2397 | hdev->sco_cnt, hdev->le_cnt); | 2391 | hdev->sco_cnt, hdev->le_cnt); |
2398 | 2392 | ||
@@ -2409,8 +2403,6 @@ static void hci_tx_task(unsigned long arg) | |||
2409 | /* Send next queued raw (unknown type) packet */ | 2403 | /* Send next queued raw (unknown type) packet */ |
2410 | while ((skb = skb_dequeue(&hdev->raw_q))) | 2404 | while ((skb = skb_dequeue(&hdev->raw_q))) |
2411 | hci_send_frame(skb); | 2405 | hci_send_frame(skb); |
2412 | |||
2413 | read_unlock(&hci_task_lock); | ||
2414 | } | 2406 | } |
2415 | 2407 | ||
2416 | /* ----- HCI RX task (incoming data processing) ----- */ | 2408 | /* ----- HCI RX task (incoming data processing) ----- */ |
@@ -2437,16 +2429,11 @@ static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2437 | hci_dev_unlock(hdev); | 2429 | hci_dev_unlock(hdev); |
2438 | 2430 | ||
2439 | if (conn) { | 2431 | if (conn) { |
2440 | register struct hci_proto *hp; | 2432 | hci_conn_enter_active_mode(conn, BT_POWER_FORCE_ACTIVE_OFF); |
2441 | |||
2442 | hci_conn_enter_active_mode(conn, bt_cb(skb)->force_active); | ||
2443 | 2433 | ||
2444 | /* Send to upper protocol */ | 2434 | /* Send to upper protocol */ |
2445 | hp = hci_proto[HCI_PROTO_L2CAP]; | 2435 | l2cap_recv_acldata(conn, skb, flags); |
2446 | if (hp && hp->recv_acldata) { | 2436 | return; |
2447 | hp->recv_acldata(conn, skb, flags); | ||
2448 | return; | ||
2449 | } | ||
2450 | } else { | 2437 | } else { |
2451 | BT_ERR("%s ACL packet for unknown connection handle %d", | 2438 | BT_ERR("%s ACL packet for unknown connection handle %d", |
2452 | hdev->name, handle); | 2439 | hdev->name, handle); |
@@ -2475,14 +2462,9 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2475 | hci_dev_unlock(hdev); | 2462 | hci_dev_unlock(hdev); |
2476 | 2463 | ||
2477 | if (conn) { | 2464 | if (conn) { |
2478 | register struct hci_proto *hp; | ||
2479 | |||
2480 | /* Send to upper protocol */ | 2465 | /* Send to upper protocol */ |
2481 | hp = hci_proto[HCI_PROTO_SCO]; | 2466 | sco_recv_scodata(conn, skb); |
2482 | if (hp && hp->recv_scodata) { | 2467 | return; |
2483 | hp->recv_scodata(conn, skb); | ||
2484 | return; | ||
2485 | } | ||
2486 | } else { | 2468 | } else { |
2487 | BT_ERR("%s SCO packet for unknown connection handle %d", | 2469 | BT_ERR("%s SCO packet for unknown connection handle %d", |
2488 | hdev->name, handle); | 2470 | hdev->name, handle); |
@@ -2491,15 +2473,13 @@ static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2491 | kfree_skb(skb); | 2473 | kfree_skb(skb); |
2492 | } | 2474 | } |
2493 | 2475 | ||
2494 | static void hci_rx_task(unsigned long arg) | 2476 | static void hci_rx_work(struct work_struct *work) |
2495 | { | 2477 | { |
2496 | struct hci_dev *hdev = (struct hci_dev *) arg; | 2478 | struct hci_dev *hdev = container_of(work, struct hci_dev, rx_work); |
2497 | struct sk_buff *skb; | 2479 | struct sk_buff *skb; |
2498 | 2480 | ||
2499 | BT_DBG("%s", hdev->name); | 2481 | BT_DBG("%s", hdev->name); |
2500 | 2482 | ||
2501 | read_lock(&hci_task_lock); | ||
2502 | |||
2503 | while ((skb = skb_dequeue(&hdev->rx_q))) { | 2483 | while ((skb = skb_dequeue(&hdev->rx_q))) { |
2504 | if (atomic_read(&hdev->promisc)) { | 2484 | if (atomic_read(&hdev->promisc)) { |
2505 | /* Send copy to the sockets */ | 2485 | /* Send copy to the sockets */ |
@@ -2524,6 +2504,7 @@ static void hci_rx_task(unsigned long arg) | |||
2524 | /* Process frame */ | 2504 | /* Process frame */ |
2525 | switch (bt_cb(skb)->pkt_type) { | 2505 | switch (bt_cb(skb)->pkt_type) { |
2526 | case HCI_EVENT_PKT: | 2506 | case HCI_EVENT_PKT: |
2507 | BT_DBG("%s Event packet", hdev->name); | ||
2527 | hci_event_packet(hdev, skb); | 2508 | hci_event_packet(hdev, skb); |
2528 | break; | 2509 | break; |
2529 | 2510 | ||
@@ -2542,13 +2523,11 @@ static void hci_rx_task(unsigned long arg) | |||
2542 | break; | 2523 | break; |
2543 | } | 2524 | } |
2544 | } | 2525 | } |
2545 | |||
2546 | read_unlock(&hci_task_lock); | ||
2547 | } | 2526 | } |
2548 | 2527 | ||
2549 | static void hci_cmd_task(unsigned long arg) | 2528 | static void hci_cmd_work(struct work_struct *work) |
2550 | { | 2529 | { |
2551 | struct hci_dev *hdev = (struct hci_dev *) arg; | 2530 | struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); |
2552 | struct sk_buff *skb; | 2531 | struct sk_buff *skb; |
2553 | 2532 | ||
2554 | BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); | 2533 | BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); |
@@ -2572,7 +2551,7 @@ static void hci_cmd_task(unsigned long arg) | |||
2572 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); | 2551 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); |
2573 | } else { | 2552 | } else { |
2574 | skb_queue_head(&hdev->cmd_q, skb); | 2553 | skb_queue_head(&hdev->cmd_q, skb); |
2575 | tasklet_schedule(&hdev->cmd_task); | 2554 | queue_work(hdev->workqueue, &hdev->cmd_work); |
2576 | } | 2555 | } |
2577 | } | 2556 | } |
2578 | } | 2557 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 918dc09164ba..4221bd256bdd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -378,11 +378,8 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) | |||
378 | 378 | ||
379 | BT_DBG("%s voice setting 0x%04x", hdev->name, setting); | 379 | BT_DBG("%s voice setting 0x%04x", hdev->name, setting); |
380 | 380 | ||
381 | if (hdev->notify) { | 381 | if (hdev->notify) |
382 | tasklet_disable(&hdev->tx_task); | ||
383 | hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); | 382 | hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); |
384 | tasklet_enable(&hdev->tx_task); | ||
385 | } | ||
386 | } | 383 | } |
387 | 384 | ||
388 | static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) | 385 | static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -409,11 +406,8 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb | |||
409 | 406 | ||
410 | BT_DBG("%s voice setting 0x%04x", hdev->name, setting); | 407 | BT_DBG("%s voice setting 0x%04x", hdev->name, setting); |
411 | 408 | ||
412 | if (hdev->notify) { | 409 | if (hdev->notify) |
413 | tasklet_disable(&hdev->tx_task); | ||
414 | hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); | 410 | hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); |
415 | tasklet_enable(&hdev->tx_task); | ||
416 | } | ||
417 | } | 411 | } |
418 | 412 | ||
419 | static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) | 413 | static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -562,6 +556,9 @@ static void hci_set_le_support(struct hci_dev *hdev) | |||
562 | 556 | ||
563 | static void hci_setup(struct hci_dev *hdev) | 557 | static void hci_setup(struct hci_dev *hdev) |
564 | { | 558 | { |
559 | if (hdev->dev_type != HCI_BREDR) | ||
560 | return; | ||
561 | |||
565 | hci_setup_event_mask(hdev); | 562 | hci_setup_event_mask(hdev); |
566 | 563 | ||
567 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) | 564 | if (hdev->hci_ver > BLUETOOTH_VER_1_1) |
@@ -773,6 +770,28 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) | |||
773 | hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status); | 770 | hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status); |
774 | } | 771 | } |
775 | 772 | ||
773 | static void hci_cc_read_data_block_size(struct hci_dev *hdev, | ||
774 | struct sk_buff *skb) | ||
775 | { | ||
776 | struct hci_rp_read_data_block_size *rp = (void *) skb->data; | ||
777 | |||
778 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
779 | |||
780 | if (rp->status) | ||
781 | return; | ||
782 | |||
783 | hdev->block_mtu = __le16_to_cpu(rp->max_acl_len); | ||
784 | hdev->block_len = __le16_to_cpu(rp->block_len); | ||
785 | hdev->num_blocks = __le16_to_cpu(rp->num_blocks); | ||
786 | |||
787 | hdev->block_cnt = hdev->num_blocks; | ||
788 | |||
789 | BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, | ||
790 | hdev->block_cnt, hdev->block_len); | ||
791 | |||
792 | hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status); | ||
793 | } | ||
794 | |||
776 | static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) | 795 | static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) |
777 | { | 796 | { |
778 | __u8 status = *((__u8 *) skb->data); | 797 | __u8 status = *((__u8 *) skb->data); |
@@ -1014,18 +1033,28 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
1014 | if (!cp) | 1033 | if (!cp) |
1015 | return; | 1034 | return; |
1016 | 1035 | ||
1017 | if (cp->enable == 0x01) { | 1036 | switch (cp->enable) { |
1037 | case LE_SCANNING_ENABLED: | ||
1018 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); | 1038 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); |
1019 | 1039 | ||
1020 | del_timer(&hdev->adv_timer); | 1040 | cancel_delayed_work_sync(&hdev->adv_work); |
1021 | 1041 | ||
1022 | hci_dev_lock(hdev); | 1042 | hci_dev_lock(hdev); |
1023 | hci_adv_entries_clear(hdev); | 1043 | hci_adv_entries_clear(hdev); |
1024 | hci_dev_unlock(hdev); | 1044 | hci_dev_unlock(hdev); |
1025 | } else if (cp->enable == 0x00) { | 1045 | break; |
1046 | |||
1047 | case LE_SCANNING_DISABLED: | ||
1026 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); | 1048 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); |
1027 | 1049 | ||
1028 | mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT); | 1050 | cancel_delayed_work_sync(&hdev->adv_work); |
1051 | queue_delayed_work(hdev->workqueue, &hdev->adv_work, | ||
1052 | jiffies + ADV_CLEAR_TIMEOUT); | ||
1053 | break; | ||
1054 | |||
1055 | default: | ||
1056 | BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable); | ||
1057 | break; | ||
1029 | } | 1058 | } |
1030 | } | 1059 | } |
1031 | 1060 | ||
@@ -2022,6 +2051,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
2022 | hci_cc_read_bd_addr(hdev, skb); | 2051 | hci_cc_read_bd_addr(hdev, skb); |
2023 | break; | 2052 | break; |
2024 | 2053 | ||
2054 | case HCI_OP_READ_DATA_BLOCK_SIZE: | ||
2055 | hci_cc_read_data_block_size(hdev, skb); | ||
2056 | break; | ||
2057 | |||
2025 | case HCI_OP_WRITE_CA_TIMEOUT: | 2058 | case HCI_OP_WRITE_CA_TIMEOUT: |
2026 | hci_cc_write_ca_timeout(hdev, skb); | 2059 | hci_cc_write_ca_timeout(hdev, skb); |
2027 | break; | 2060 | break; |
@@ -2116,7 +2149,7 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
2116 | if (ev->ncmd) { | 2149 | if (ev->ncmd) { |
2117 | atomic_set(&hdev->cmd_cnt, 1); | 2150 | atomic_set(&hdev->cmd_cnt, 1); |
2118 | if (!skb_queue_empty(&hdev->cmd_q)) | 2151 | if (!skb_queue_empty(&hdev->cmd_q)) |
2119 | tasklet_schedule(&hdev->cmd_task); | 2152 | queue_work(hdev->workqueue, &hdev->cmd_work); |
2120 | } | 2153 | } |
2121 | } | 2154 | } |
2122 | 2155 | ||
@@ -2198,7 +2231,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2198 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { | 2231 | if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { |
2199 | atomic_set(&hdev->cmd_cnt, 1); | 2232 | atomic_set(&hdev->cmd_cnt, 1); |
2200 | if (!skb_queue_empty(&hdev->cmd_q)) | 2233 | if (!skb_queue_empty(&hdev->cmd_q)) |
2201 | tasklet_schedule(&hdev->cmd_task); | 2234 | queue_work(hdev->workqueue, &hdev->cmd_work); |
2202 | } | 2235 | } |
2203 | } | 2236 | } |
2204 | 2237 | ||
@@ -2231,56 +2264,68 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb | |||
2231 | static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2264 | static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) |
2232 | { | 2265 | { |
2233 | struct hci_ev_num_comp_pkts *ev = (void *) skb->data; | 2266 | struct hci_ev_num_comp_pkts *ev = (void *) skb->data; |
2234 | __le16 *ptr; | ||
2235 | int i; | 2267 | int i; |
2236 | 2268 | ||
2237 | skb_pull(skb, sizeof(*ev)); | 2269 | skb_pull(skb, sizeof(*ev)); |
2238 | 2270 | ||
2239 | BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); | 2271 | BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl); |
2240 | 2272 | ||
2273 | if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) { | ||
2274 | BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode); | ||
2275 | return; | ||
2276 | } | ||
2277 | |||
2241 | if (skb->len < ev->num_hndl * 4) { | 2278 | if (skb->len < ev->num_hndl * 4) { |
2242 | BT_DBG("%s bad parameters", hdev->name); | 2279 | BT_DBG("%s bad parameters", hdev->name); |
2243 | return; | 2280 | return; |
2244 | } | 2281 | } |
2245 | 2282 | ||
2246 | tasklet_disable(&hdev->tx_task); | 2283 | for (i = 0; i < ev->num_hndl; i++) { |
2247 | 2284 | struct hci_comp_pkts_info *info = &ev->handles[i]; | |
2248 | for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) { | ||
2249 | struct hci_conn *conn; | 2285 | struct hci_conn *conn; |
2250 | __u16 handle, count; | 2286 | __u16 handle, count; |
2251 | 2287 | ||
2252 | handle = get_unaligned_le16(ptr++); | 2288 | handle = __le16_to_cpu(info->handle); |
2253 | count = get_unaligned_le16(ptr++); | 2289 | count = __le16_to_cpu(info->count); |
2254 | 2290 | ||
2255 | conn = hci_conn_hash_lookup_handle(hdev, handle); | 2291 | conn = hci_conn_hash_lookup_handle(hdev, handle); |
2256 | if (conn) { | 2292 | if (!conn) |
2257 | conn->sent -= count; | 2293 | continue; |
2258 | 2294 | ||
2259 | if (conn->type == ACL_LINK) { | 2295 | conn->sent -= count; |
2296 | |||
2297 | switch (conn->type) { | ||
2298 | case ACL_LINK: | ||
2299 | hdev->acl_cnt += count; | ||
2300 | if (hdev->acl_cnt > hdev->acl_pkts) | ||
2301 | hdev->acl_cnt = hdev->acl_pkts; | ||
2302 | break; | ||
2303 | |||
2304 | case LE_LINK: | ||
2305 | if (hdev->le_pkts) { | ||
2306 | hdev->le_cnt += count; | ||
2307 | if (hdev->le_cnt > hdev->le_pkts) | ||
2308 | hdev->le_cnt = hdev->le_pkts; | ||
2309 | } else { | ||
2260 | hdev->acl_cnt += count; | 2310 | hdev->acl_cnt += count; |
2261 | if (hdev->acl_cnt > hdev->acl_pkts) | 2311 | if (hdev->acl_cnt > hdev->acl_pkts) |
2262 | hdev->acl_cnt = hdev->acl_pkts; | 2312 | hdev->acl_cnt = hdev->acl_pkts; |
2263 | } else if (conn->type == LE_LINK) { | ||
2264 | if (hdev->le_pkts) { | ||
2265 | hdev->le_cnt += count; | ||
2266 | if (hdev->le_cnt > hdev->le_pkts) | ||
2267 | hdev->le_cnt = hdev->le_pkts; | ||
2268 | } else { | ||
2269 | hdev->acl_cnt += count; | ||
2270 | if (hdev->acl_cnt > hdev->acl_pkts) | ||
2271 | hdev->acl_cnt = hdev->acl_pkts; | ||
2272 | } | ||
2273 | } else { | ||
2274 | hdev->sco_cnt += count; | ||
2275 | if (hdev->sco_cnt > hdev->sco_pkts) | ||
2276 | hdev->sco_cnt = hdev->sco_pkts; | ||
2277 | } | 2313 | } |
2314 | break; | ||
2315 | |||
2316 | case SCO_LINK: | ||
2317 | hdev->sco_cnt += count; | ||
2318 | if (hdev->sco_cnt > hdev->sco_pkts) | ||
2319 | hdev->sco_cnt = hdev->sco_pkts; | ||
2320 | break; | ||
2321 | |||
2322 | default: | ||
2323 | BT_ERR("Unknown type %d conn %p", conn->type, conn); | ||
2324 | break; | ||
2278 | } | 2325 | } |
2279 | } | 2326 | } |
2280 | 2327 | ||
2281 | tasklet_schedule(&hdev->tx_task); | 2328 | queue_work(hdev->workqueue, &hdev->tx_work); |
2282 | |||
2283 | tasklet_enable(&hdev->tx_task); | ||
2284 | } | 2329 | } |
2285 | 2330 | ||
2286 | static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2331 | static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 78746cfa1659..6d94616af312 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -188,11 +188,11 @@ static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg) | |||
188 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) | 188 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) |
189 | return -EFAULT; | 189 | return -EFAULT; |
190 | 190 | ||
191 | hci_dev_lock_bh(hdev); | 191 | hci_dev_lock(hdev); |
192 | 192 | ||
193 | err = hci_blacklist_add(hdev, &bdaddr); | 193 | err = hci_blacklist_add(hdev, &bdaddr); |
194 | 194 | ||
195 | hci_dev_unlock_bh(hdev); | 195 | hci_dev_unlock(hdev); |
196 | 196 | ||
197 | return err; | 197 | return err; |
198 | } | 198 | } |
@@ -205,11 +205,11 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) | |||
205 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) | 205 | if (copy_from_user(&bdaddr, arg, sizeof(bdaddr))) |
206 | return -EFAULT; | 206 | return -EFAULT; |
207 | 207 | ||
208 | hci_dev_lock_bh(hdev); | 208 | hci_dev_lock(hdev); |
209 | 209 | ||
210 | err = hci_blacklist_del(hdev, &bdaddr); | 210 | err = hci_blacklist_del(hdev, &bdaddr); |
211 | 211 | ||
212 | hci_dev_unlock_bh(hdev); | 212 | hci_dev_unlock(hdev); |
213 | 213 | ||
214 | return err; | 214 | return err; |
215 | } | 215 | } |
@@ -343,8 +343,11 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le | |||
343 | if (haddr.hci_channel > HCI_CHANNEL_CONTROL) | 343 | if (haddr.hci_channel > HCI_CHANNEL_CONTROL) |
344 | return -EINVAL; | 344 | return -EINVAL; |
345 | 345 | ||
346 | if (haddr.hci_channel == HCI_CHANNEL_CONTROL && !enable_mgmt) | 346 | if (haddr.hci_channel == HCI_CHANNEL_CONTROL) { |
347 | return -EINVAL; | 347 | if (!enable_mgmt) |
348 | return -EINVAL; | ||
349 | set_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags); | ||
350 | } | ||
348 | 351 | ||
349 | lock_sock(sk); | 352 | lock_sock(sk); |
350 | 353 | ||
@@ -535,10 +538,10 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
535 | 538 | ||
536 | if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) { | 539 | if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) { |
537 | skb_queue_tail(&hdev->raw_q, skb); | 540 | skb_queue_tail(&hdev->raw_q, skb); |
538 | tasklet_schedule(&hdev->tx_task); | 541 | queue_work(hdev->workqueue, &hdev->tx_work); |
539 | } else { | 542 | } else { |
540 | skb_queue_tail(&hdev->cmd_q, skb); | 543 | skb_queue_tail(&hdev->cmd_q, skb); |
541 | tasklet_schedule(&hdev->cmd_task); | 544 | queue_work(hdev->workqueue, &hdev->cmd_work); |
542 | } | 545 | } |
543 | } else { | 546 | } else { |
544 | if (!capable(CAP_NET_RAW)) { | 547 | if (!capable(CAP_NET_RAW)) { |
@@ -547,7 +550,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
547 | } | 550 | } |
548 | 551 | ||
549 | skb_queue_tail(&hdev->raw_q, skb); | 552 | skb_queue_tail(&hdev->raw_q, skb); |
550 | tasklet_schedule(&hdev->tx_task); | 553 | queue_work(hdev->workqueue, &hdev->tx_work); |
551 | } | 554 | } |
552 | 555 | ||
553 | err = len; | 556 | err = len; |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index c62d254a1379..521095614235 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -89,11 +89,35 @@ static struct device_type bt_link = { | |||
89 | .release = bt_link_release, | 89 | .release = bt_link_release, |
90 | }; | 90 | }; |
91 | 91 | ||
92 | static void add_conn(struct work_struct *work) | 92 | /* |
93 | * The rfcomm tty device will possibly retain even when conn | ||
94 | * is down, and sysfs doesn't support move zombie device, | ||
95 | * so we should move the device before conn device is destroyed. | ||
96 | */ | ||
97 | static int __match_tty(struct device *dev, void *data) | ||
98 | { | ||
99 | return !strncmp(dev_name(dev), "rfcomm", 6); | ||
100 | } | ||
101 | |||
102 | void hci_conn_init_sysfs(struct hci_conn *conn) | ||
103 | { | ||
104 | struct hci_dev *hdev = conn->hdev; | ||
105 | |||
106 | BT_DBG("conn %p", conn); | ||
107 | |||
108 | conn->dev.type = &bt_link; | ||
109 | conn->dev.class = bt_class; | ||
110 | conn->dev.parent = &hdev->dev; | ||
111 | |||
112 | device_initialize(&conn->dev); | ||
113 | } | ||
114 | |||
115 | void hci_conn_add_sysfs(struct hci_conn *conn) | ||
93 | { | 116 | { |
94 | struct hci_conn *conn = container_of(work, struct hci_conn, work_add); | ||
95 | struct hci_dev *hdev = conn->hdev; | 117 | struct hci_dev *hdev = conn->hdev; |
96 | 118 | ||
119 | BT_DBG("conn %p", conn); | ||
120 | |||
97 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); | 121 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); |
98 | 122 | ||
99 | dev_set_drvdata(&conn->dev, conn); | 123 | dev_set_drvdata(&conn->dev, conn); |
@@ -106,19 +130,8 @@ static void add_conn(struct work_struct *work) | |||
106 | hci_dev_hold(hdev); | 130 | hci_dev_hold(hdev); |
107 | } | 131 | } |
108 | 132 | ||
109 | /* | 133 | void hci_conn_del_sysfs(struct hci_conn *conn) |
110 | * The rfcomm tty device will possibly retain even when conn | ||
111 | * is down, and sysfs doesn't support move zombie device, | ||
112 | * so we should move the device before conn device is destroyed. | ||
113 | */ | ||
114 | static int __match_tty(struct device *dev, void *data) | ||
115 | { | ||
116 | return !strncmp(dev_name(dev), "rfcomm", 6); | ||
117 | } | ||
118 | |||
119 | static void del_conn(struct work_struct *work) | ||
120 | { | 134 | { |
121 | struct hci_conn *conn = container_of(work, struct hci_conn, work_del); | ||
122 | struct hci_dev *hdev = conn->hdev; | 135 | struct hci_dev *hdev = conn->hdev; |
123 | 136 | ||
124 | if (!device_is_registered(&conn->dev)) | 137 | if (!device_is_registered(&conn->dev)) |
@@ -140,36 +153,6 @@ static void del_conn(struct work_struct *work) | |||
140 | hci_dev_put(hdev); | 153 | hci_dev_put(hdev); |
141 | } | 154 | } |
142 | 155 | ||
143 | void hci_conn_init_sysfs(struct hci_conn *conn) | ||
144 | { | ||
145 | struct hci_dev *hdev = conn->hdev; | ||
146 | |||
147 | BT_DBG("conn %p", conn); | ||
148 | |||
149 | conn->dev.type = &bt_link; | ||
150 | conn->dev.class = bt_class; | ||
151 | conn->dev.parent = &hdev->dev; | ||
152 | |||
153 | device_initialize(&conn->dev); | ||
154 | |||
155 | INIT_WORK(&conn->work_add, add_conn); | ||
156 | INIT_WORK(&conn->work_del, del_conn); | ||
157 | } | ||
158 | |||
159 | void hci_conn_add_sysfs(struct hci_conn *conn) | ||
160 | { | ||
161 | BT_DBG("conn %p", conn); | ||
162 | |||
163 | queue_work(conn->hdev->workqueue, &conn->work_add); | ||
164 | } | ||
165 | |||
166 | void hci_conn_del_sysfs(struct hci_conn *conn) | ||
167 | { | ||
168 | BT_DBG("conn %p", conn); | ||
169 | |||
170 | queue_work(conn->hdev->workqueue, &conn->work_del); | ||
171 | } | ||
172 | |||
173 | static inline char *host_bustostr(int bus) | 156 | static inline char *host_bustostr(int bus) |
174 | { | 157 | { |
175 | switch (bus) { | 158 | switch (bus) { |
@@ -403,7 +386,7 @@ static int inquiry_cache_show(struct seq_file *f, void *p) | |||
403 | struct inquiry_cache *cache = &hdev->inq_cache; | 386 | struct inquiry_cache *cache = &hdev->inq_cache; |
404 | struct inquiry_entry *e; | 387 | struct inquiry_entry *e; |
405 | 388 | ||
406 | hci_dev_lock_bh(hdev); | 389 | hci_dev_lock(hdev); |
407 | 390 | ||
408 | for (e = cache->list; e; e = e->next) { | 391 | for (e = cache->list; e; e = e->next) { |
409 | struct inquiry_data *data = &e->data; | 392 | struct inquiry_data *data = &e->data; |
@@ -416,7 +399,7 @@ static int inquiry_cache_show(struct seq_file *f, void *p) | |||
416 | data->rssi, data->ssp_mode, e->timestamp); | 399 | data->rssi, data->ssp_mode, e->timestamp); |
417 | } | 400 | } |
418 | 401 | ||
419 | hci_dev_unlock_bh(hdev); | 402 | hci_dev_unlock(hdev); |
420 | 403 | ||
421 | return 0; | 404 | return 0; |
422 | } | 405 | } |
@@ -438,12 +421,12 @@ static int blacklist_show(struct seq_file *f, void *p) | |||
438 | struct hci_dev *hdev = f->private; | 421 | struct hci_dev *hdev = f->private; |
439 | struct bdaddr_list *b; | 422 | struct bdaddr_list *b; |
440 | 423 | ||
441 | hci_dev_lock_bh(hdev); | 424 | hci_dev_lock(hdev); |
442 | 425 | ||
443 | list_for_each_entry(b, &hdev->blacklist, list) | 426 | list_for_each_entry(b, &hdev->blacklist, list) |
444 | seq_printf(f, "%s\n", batostr(&b->bdaddr)); | 427 | seq_printf(f, "%s\n", batostr(&b->bdaddr)); |
445 | 428 | ||
446 | hci_dev_unlock_bh(hdev); | 429 | hci_dev_unlock(hdev); |
447 | 430 | ||
448 | return 0; | 431 | return 0; |
449 | } | 432 | } |
@@ -482,12 +465,12 @@ static int uuids_show(struct seq_file *f, void *p) | |||
482 | struct hci_dev *hdev = f->private; | 465 | struct hci_dev *hdev = f->private; |
483 | struct bt_uuid *uuid; | 466 | struct bt_uuid *uuid; |
484 | 467 | ||
485 | hci_dev_lock_bh(hdev); | 468 | hci_dev_lock(hdev); |
486 | 469 | ||
487 | list_for_each_entry(uuid, &hdev->uuids, list) | 470 | list_for_each_entry(uuid, &hdev->uuids, list) |
488 | print_bt_uuid(f, uuid->uuid); | 471 | print_bt_uuid(f, uuid->uuid); |
489 | 472 | ||
490 | hci_dev_unlock_bh(hdev); | 473 | hci_dev_unlock(hdev); |
491 | 474 | ||
492 | return 0; | 475 | return 0; |
493 | } | 476 | } |
@@ -508,11 +491,11 @@ static int auto_accept_delay_set(void *data, u64 val) | |||
508 | { | 491 | { |
509 | struct hci_dev *hdev = data; | 492 | struct hci_dev *hdev = data; |
510 | 493 | ||
511 | hci_dev_lock_bh(hdev); | 494 | hci_dev_lock(hdev); |
512 | 495 | ||
513 | hdev->auto_accept_delay = val; | 496 | hdev->auto_accept_delay = val; |
514 | 497 | ||
515 | hci_dev_unlock_bh(hdev); | 498 | hci_dev_unlock(hdev); |
516 | 499 | ||
517 | return 0; | 500 | return 0; |
518 | } | 501 | } |
@@ -521,11 +504,11 @@ static int auto_accept_delay_get(void *data, u64 *val) | |||
521 | { | 504 | { |
522 | struct hci_dev *hdev = data; | 505 | struct hci_dev *hdev = data; |
523 | 506 | ||
524 | hci_dev_lock_bh(hdev); | 507 | hci_dev_lock(hdev); |
525 | 508 | ||
526 | *val = hdev->auto_accept_delay; | 509 | *val = hdev->auto_accept_delay; |
527 | 510 | ||
528 | hci_dev_unlock_bh(hdev); | 511 | hci_dev_unlock(hdev); |
529 | 512 | ||
530 | return 0; | 513 | return 0; |
531 | } | 514 | } |
diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig index 86a91543172a..4deaca78e91e 100644 --- a/net/bluetooth/hidp/Kconfig +++ b/net/bluetooth/hidp/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config BT_HIDP | 1 | config BT_HIDP |
2 | tristate "HIDP protocol support" | 2 | tristate "HIDP protocol support" |
3 | depends on BT && BT_L2CAP && INPUT && HID_SUPPORT | 3 | depends on BT && INPUT && HID_SUPPORT |
4 | select HID | 4 | select HID |
5 | help | 5 | help |
6 | HIDP (Human Interface Device Protocol) is a transport layer | 6 | HIDP (Human Interface Device Protocol) is a transport layer |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 3c2d888925d7..d478be11d562 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -795,11 +795,11 @@ static struct hci_conn *hidp_get_connection(struct hidp_session *session) | |||
795 | if (!hdev) | 795 | if (!hdev) |
796 | return NULL; | 796 | return NULL; |
797 | 797 | ||
798 | hci_dev_lock_bh(hdev); | 798 | hci_dev_lock(hdev); |
799 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 799 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
800 | if (conn) | 800 | if (conn) |
801 | hci_conn_hold_device(conn); | 801 | hci_conn_hold_device(conn); |
802 | hci_dev_unlock_bh(hdev); | 802 | hci_dev_unlock(hdev); |
803 | 803 | ||
804 | hci_dev_put(hdev); | 804 | hci_dev_put(hdev); |
805 | 805 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9bc22e4c4c61..aa78d8c4b93b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -3,6 +3,7 @@ | |||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | 3 | Copyright (C) 2000-2001 Qualcomm Incorporated |
4 | Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> | 4 | Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> |
5 | Copyright (C) 2010 Google Inc. | 5 | Copyright (C) 2010 Google Inc. |
6 | Copyright (C) 2011 ProFUSION Embedded Systems | ||
6 | 7 | ||
7 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | 8 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
8 | 9 | ||
@@ -76,37 +77,38 @@ static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); | |||
76 | 77 | ||
77 | /* ---- L2CAP channels ---- */ | 78 | /* ---- L2CAP channels ---- */ |
78 | 79 | ||
79 | static inline void chan_hold(struct l2cap_chan *c) | ||
80 | { | ||
81 | atomic_inc(&c->refcnt); | ||
82 | } | ||
83 | |||
84 | static inline void chan_put(struct l2cap_chan *c) | ||
85 | { | ||
86 | if (atomic_dec_and_test(&c->refcnt)) | ||
87 | kfree(c); | ||
88 | } | ||
89 | |||
90 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) | 80 | static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) |
91 | { | 81 | { |
92 | struct l2cap_chan *c; | 82 | struct l2cap_chan *c, *r = NULL; |
93 | 83 | ||
94 | list_for_each_entry(c, &conn->chan_l, list) { | 84 | rcu_read_lock(); |
95 | if (c->dcid == cid) | 85 | |
96 | return c; | 86 | list_for_each_entry_rcu(c, &conn->chan_l, list) { |
87 | if (c->dcid == cid) { | ||
88 | r = c; | ||
89 | break; | ||
90 | } | ||
97 | } | 91 | } |
98 | return NULL; | 92 | |
93 | rcu_read_unlock(); | ||
94 | return r; | ||
99 | } | 95 | } |
100 | 96 | ||
101 | static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) | 97 | static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) |
102 | { | 98 | { |
103 | struct l2cap_chan *c; | 99 | struct l2cap_chan *c, *r = NULL; |
104 | 100 | ||
105 | list_for_each_entry(c, &conn->chan_l, list) { | 101 | rcu_read_lock(); |
106 | if (c->scid == cid) | 102 | |
107 | return c; | 103 | list_for_each_entry_rcu(c, &conn->chan_l, list) { |
104 | if (c->scid == cid) { | ||
105 | r = c; | ||
106 | break; | ||
107 | } | ||
108 | } | 108 | } |
109 | return NULL; | 109 | |
110 | rcu_read_unlock(); | ||
111 | return r; | ||
110 | } | 112 | } |
111 | 113 | ||
112 | /* Find channel with given SCID. | 114 | /* Find channel with given SCID. |
@@ -115,34 +117,36 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 ci | |||
115 | { | 117 | { |
116 | struct l2cap_chan *c; | 118 | struct l2cap_chan *c; |
117 | 119 | ||
118 | read_lock(&conn->chan_lock); | ||
119 | c = __l2cap_get_chan_by_scid(conn, cid); | 120 | c = __l2cap_get_chan_by_scid(conn, cid); |
120 | if (c) | 121 | if (c) |
121 | bh_lock_sock(c->sk); | 122 | lock_sock(c->sk); |
122 | read_unlock(&conn->chan_lock); | ||
123 | return c; | 123 | return c; |
124 | } | 124 | } |
125 | 125 | ||
126 | static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) | 126 | static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) |
127 | { | 127 | { |
128 | struct l2cap_chan *c; | 128 | struct l2cap_chan *c, *r = NULL; |
129 | 129 | ||
130 | list_for_each_entry(c, &conn->chan_l, list) { | 130 | rcu_read_lock(); |
131 | if (c->ident == ident) | 131 | |
132 | return c; | 132 | list_for_each_entry_rcu(c, &conn->chan_l, list) { |
133 | if (c->ident == ident) { | ||
134 | r = c; | ||
135 | break; | ||
136 | } | ||
133 | } | 137 | } |
134 | return NULL; | 138 | |
139 | rcu_read_unlock(); | ||
140 | return r; | ||
135 | } | 141 | } |
136 | 142 | ||
137 | static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) | 143 | static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) |
138 | { | 144 | { |
139 | struct l2cap_chan *c; | 145 | struct l2cap_chan *c; |
140 | 146 | ||
141 | read_lock(&conn->chan_lock); | ||
142 | c = __l2cap_get_chan_by_ident(conn, ident); | 147 | c = __l2cap_get_chan_by_ident(conn, ident); |
143 | if (c) | 148 | if (c) |
144 | bh_lock_sock(c->sk); | 149 | lock_sock(c->sk); |
145 | read_unlock(&conn->chan_lock); | ||
146 | return c; | 150 | return c; |
147 | } | 151 | } |
148 | 152 | ||
@@ -213,22 +217,6 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
213 | return 0; | 217 | return 0; |
214 | } | 218 | } |
215 | 219 | ||
216 | static void l2cap_set_timer(struct l2cap_chan *chan, struct timer_list *timer, long timeout) | ||
217 | { | ||
218 | BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout); | ||
219 | |||
220 | if (!mod_timer(timer, jiffies + msecs_to_jiffies(timeout))) | ||
221 | chan_hold(chan); | ||
222 | } | ||
223 | |||
224 | static void l2cap_clear_timer(struct l2cap_chan *chan, struct timer_list *timer) | ||
225 | { | ||
226 | BT_DBG("chan %p state %d", chan, chan->state); | ||
227 | |||
228 | if (timer_pending(timer) && del_timer(timer)) | ||
229 | chan_put(chan); | ||
230 | } | ||
231 | |||
232 | static char *state_to_string(int state) | 220 | static char *state_to_string(int state) |
233 | { | 221 | { |
234 | switch(state) { | 222 | switch(state) { |
@@ -264,23 +252,16 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state) | |||
264 | chan->ops->state_change(chan->data, state); | 252 | chan->ops->state_change(chan->data, state); |
265 | } | 253 | } |
266 | 254 | ||
267 | static void l2cap_chan_timeout(unsigned long arg) | 255 | static void l2cap_chan_timeout(struct work_struct *work) |
268 | { | 256 | { |
269 | struct l2cap_chan *chan = (struct l2cap_chan *) arg; | 257 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, |
258 | chan_timer.work); | ||
270 | struct sock *sk = chan->sk; | 259 | struct sock *sk = chan->sk; |
271 | int reason; | 260 | int reason; |
272 | 261 | ||
273 | BT_DBG("chan %p state %d", chan, chan->state); | 262 | BT_DBG("chan %p state %d", chan, chan->state); |
274 | 263 | ||
275 | bh_lock_sock(sk); | 264 | lock_sock(sk); |
276 | |||
277 | if (sock_owned_by_user(sk)) { | ||
278 | /* sk is owned by user. Try again later */ | ||
279 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); | ||
280 | bh_unlock_sock(sk); | ||
281 | chan_put(chan); | ||
282 | return; | ||
283 | } | ||
284 | 265 | ||
285 | if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG) | 266 | if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG) |
286 | reason = ECONNREFUSED; | 267 | reason = ECONNREFUSED; |
@@ -292,10 +273,10 @@ static void l2cap_chan_timeout(unsigned long arg) | |||
292 | 273 | ||
293 | l2cap_chan_close(chan, reason); | 274 | l2cap_chan_close(chan, reason); |
294 | 275 | ||
295 | bh_unlock_sock(sk); | 276 | release_sock(sk); |
296 | 277 | ||
297 | chan->ops->close(chan->data); | 278 | chan->ops->close(chan->data); |
298 | chan_put(chan); | 279 | l2cap_chan_put(chan); |
299 | } | 280 | } |
300 | 281 | ||
301 | struct l2cap_chan *l2cap_chan_create(struct sock *sk) | 282 | struct l2cap_chan *l2cap_chan_create(struct sock *sk) |
@@ -312,7 +293,7 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk) | |||
312 | list_add(&chan->global_l, &chan_list); | 293 | list_add(&chan->global_l, &chan_list); |
313 | write_unlock_bh(&chan_list_lock); | 294 | write_unlock_bh(&chan_list_lock); |
314 | 295 | ||
315 | setup_timer(&chan->chan_timer, l2cap_chan_timeout, (unsigned long) chan); | 296 | INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout); |
316 | 297 | ||
317 | chan->state = BT_OPEN; | 298 | chan->state = BT_OPEN; |
318 | 299 | ||
@@ -329,10 +310,10 @@ void l2cap_chan_destroy(struct l2cap_chan *chan) | |||
329 | list_del(&chan->global_l); | 310 | list_del(&chan->global_l); |
330 | write_unlock_bh(&chan_list_lock); | 311 | write_unlock_bh(&chan_list_lock); |
331 | 312 | ||
332 | chan_put(chan); | 313 | l2cap_chan_put(chan); |
333 | } | 314 | } |
334 | 315 | ||
335 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | 316 | static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) |
336 | { | 317 | { |
337 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, | 318 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, |
338 | chan->psm, chan->dcid); | 319 | chan->psm, chan->dcid); |
@@ -371,9 +352,9 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
371 | chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; | 352 | chan->local_acc_lat = L2CAP_DEFAULT_ACC_LAT; |
372 | chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO; | 353 | chan->local_flush_to = L2CAP_DEFAULT_FLUSH_TO; |
373 | 354 | ||
374 | chan_hold(chan); | 355 | l2cap_chan_hold(chan); |
375 | 356 | ||
376 | list_add(&chan->list, &conn->chan_l); | 357 | list_add_rcu(&chan->list, &conn->chan_l); |
377 | } | 358 | } |
378 | 359 | ||
379 | /* Delete channel. | 360 | /* Delete channel. |
@@ -390,10 +371,10 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
390 | 371 | ||
391 | if (conn) { | 372 | if (conn) { |
392 | /* Delete from channel list */ | 373 | /* Delete from channel list */ |
393 | write_lock_bh(&conn->chan_lock); | 374 | list_del_rcu(&chan->list); |
394 | list_del(&chan->list); | 375 | synchronize_rcu(); |
395 | write_unlock_bh(&conn->chan_lock); | 376 | |
396 | chan_put(chan); | 377 | l2cap_chan_put(chan); |
397 | 378 | ||
398 | chan->conn = NULL; | 379 | chan->conn = NULL; |
399 | hci_conn_put(conn->hcon); | 380 | hci_conn_put(conn->hcon); |
@@ -707,7 +688,7 @@ static void l2cap_do_start(struct l2cap_chan *chan) | |||
707 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; | 688 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; |
708 | conn->info_ident = l2cap_get_ident(conn); | 689 | conn->info_ident = l2cap_get_ident(conn); |
709 | 690 | ||
710 | mod_timer(&conn->info_timer, jiffies + | 691 | schedule_delayed_work(&conn->info_timer, |
711 | msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); | 692 | msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); |
712 | 693 | ||
713 | l2cap_send_cmd(conn, conn->info_ident, | 694 | l2cap_send_cmd(conn, conn->info_ident, |
@@ -759,13 +740,13 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c | |||
759 | /* ---- L2CAP connections ---- */ | 740 | /* ---- L2CAP connections ---- */ |
760 | static void l2cap_conn_start(struct l2cap_conn *conn) | 741 | static void l2cap_conn_start(struct l2cap_conn *conn) |
761 | { | 742 | { |
762 | struct l2cap_chan *chan, *tmp; | 743 | struct l2cap_chan *chan; |
763 | 744 | ||
764 | BT_DBG("conn %p", conn); | 745 | BT_DBG("conn %p", conn); |
765 | 746 | ||
766 | read_lock(&conn->chan_lock); | 747 | rcu_read_lock(); |
767 | 748 | ||
768 | list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) { | 749 | list_for_each_entry_rcu(chan, &conn->chan_l, list) { |
769 | struct sock *sk = chan->sk; | 750 | struct sock *sk = chan->sk; |
770 | 751 | ||
771 | bh_lock_sock(sk); | 752 | bh_lock_sock(sk); |
@@ -789,9 +770,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
789 | &chan->conf_state)) { | 770 | &chan->conf_state)) { |
790 | /* l2cap_chan_close() calls list_del(chan) | 771 | /* l2cap_chan_close() calls list_del(chan) |
791 | * so release the lock */ | 772 | * so release the lock */ |
792 | read_unlock(&conn->chan_lock); | ||
793 | l2cap_chan_close(chan, ECONNRESET); | 773 | l2cap_chan_close(chan, ECONNRESET); |
794 | read_lock(&conn->chan_lock); | ||
795 | bh_unlock_sock(sk); | 774 | bh_unlock_sock(sk); |
796 | continue; | 775 | continue; |
797 | } | 776 | } |
@@ -847,7 +826,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
847 | bh_unlock_sock(sk); | 826 | bh_unlock_sock(sk); |
848 | } | 827 | } |
849 | 828 | ||
850 | read_unlock(&conn->chan_lock); | 829 | rcu_read_unlock(); |
851 | } | 830 | } |
852 | 831 | ||
853 | /* Find socket with cid and source bdaddr. | 832 | /* Find socket with cid and source bdaddr. |
@@ -898,7 +877,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
898 | 877 | ||
899 | parent = pchan->sk; | 878 | parent = pchan->sk; |
900 | 879 | ||
901 | bh_lock_sock(parent); | 880 | lock_sock(parent); |
902 | 881 | ||
903 | /* Check for backlog size */ | 882 | /* Check for backlog size */ |
904 | if (sk_acceptq_is_full(parent)) { | 883 | if (sk_acceptq_is_full(parent)) { |
@@ -912,8 +891,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
912 | 891 | ||
913 | sk = chan->sk; | 892 | sk = chan->sk; |
914 | 893 | ||
915 | write_lock_bh(&conn->chan_lock); | ||
916 | |||
917 | hci_conn_hold(conn->hcon); | 894 | hci_conn_hold(conn->hcon); |
918 | 895 | ||
919 | bacpy(&bt_sk(sk)->src, conn->src); | 896 | bacpy(&bt_sk(sk)->src, conn->src); |
@@ -921,17 +898,15 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
921 | 898 | ||
922 | bt_accept_enqueue(parent, sk); | 899 | bt_accept_enqueue(parent, sk); |
923 | 900 | ||
924 | __l2cap_chan_add(conn, chan); | 901 | l2cap_chan_add(conn, chan); |
925 | 902 | ||
926 | __set_chan_timer(chan, sk->sk_sndtimeo); | 903 | __set_chan_timer(chan, sk->sk_sndtimeo); |
927 | 904 | ||
928 | l2cap_state_change(chan, BT_CONNECTED); | 905 | l2cap_state_change(chan, BT_CONNECTED); |
929 | parent->sk_data_ready(parent, 0); | 906 | parent->sk_data_ready(parent, 0); |
930 | 907 | ||
931 | write_unlock_bh(&conn->chan_lock); | ||
932 | |||
933 | clean: | 908 | clean: |
934 | bh_unlock_sock(parent); | 909 | release_sock(parent); |
935 | } | 910 | } |
936 | 911 | ||
937 | static void l2cap_chan_ready(struct sock *sk) | 912 | static void l2cap_chan_ready(struct sock *sk) |
@@ -963,9 +938,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
963 | if (conn->hcon->out && conn->hcon->type == LE_LINK) | 938 | if (conn->hcon->out && conn->hcon->type == LE_LINK) |
964 | smp_conn_security(conn, conn->hcon->pending_sec_level); | 939 | smp_conn_security(conn, conn->hcon->pending_sec_level); |
965 | 940 | ||
966 | read_lock(&conn->chan_lock); | 941 | rcu_read_lock(); |
967 | 942 | ||
968 | list_for_each_entry(chan, &conn->chan_l, list) { | 943 | list_for_each_entry_rcu(chan, &conn->chan_l, list) { |
969 | struct sock *sk = chan->sk; | 944 | struct sock *sk = chan->sk; |
970 | 945 | ||
971 | bh_lock_sock(sk); | 946 | bh_lock_sock(sk); |
@@ -985,7 +960,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
985 | bh_unlock_sock(sk); | 960 | bh_unlock_sock(sk); |
986 | } | 961 | } |
987 | 962 | ||
988 | read_unlock(&conn->chan_lock); | 963 | rcu_read_unlock(); |
989 | } | 964 | } |
990 | 965 | ||
991 | /* Notify sockets that we cannot guaranty reliability anymore */ | 966 | /* Notify sockets that we cannot guaranty reliability anymore */ |
@@ -995,21 +970,22 @@ static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err) | |||
995 | 970 | ||
996 | BT_DBG("conn %p", conn); | 971 | BT_DBG("conn %p", conn); |
997 | 972 | ||
998 | read_lock(&conn->chan_lock); | 973 | rcu_read_lock(); |
999 | 974 | ||
1000 | list_for_each_entry(chan, &conn->chan_l, list) { | 975 | list_for_each_entry_rcu(chan, &conn->chan_l, list) { |
1001 | struct sock *sk = chan->sk; | 976 | struct sock *sk = chan->sk; |
1002 | 977 | ||
1003 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) | 978 | if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags)) |
1004 | sk->sk_err = err; | 979 | sk->sk_err = err; |
1005 | } | 980 | } |
1006 | 981 | ||
1007 | read_unlock(&conn->chan_lock); | 982 | rcu_read_unlock(); |
1008 | } | 983 | } |
1009 | 984 | ||
1010 | static void l2cap_info_timeout(unsigned long arg) | 985 | static void l2cap_info_timeout(struct work_struct *work) |
1011 | { | 986 | { |
1012 | struct l2cap_conn *conn = (void *) arg; | 987 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, |
988 | info_timer.work); | ||
1013 | 989 | ||
1014 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 990 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
1015 | conn->info_ident = 0; | 991 | conn->info_ident = 0; |
@@ -1033,19 +1009,19 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
1033 | /* Kill channels */ | 1009 | /* Kill channels */ |
1034 | list_for_each_entry_safe(chan, l, &conn->chan_l, list) { | 1010 | list_for_each_entry_safe(chan, l, &conn->chan_l, list) { |
1035 | sk = chan->sk; | 1011 | sk = chan->sk; |
1036 | bh_lock_sock(sk); | 1012 | lock_sock(sk); |
1037 | l2cap_chan_del(chan, err); | 1013 | l2cap_chan_del(chan, err); |
1038 | bh_unlock_sock(sk); | 1014 | release_sock(sk); |
1039 | chan->ops->close(chan->data); | 1015 | chan->ops->close(chan->data); |
1040 | } | 1016 | } |
1041 | 1017 | ||
1042 | hci_chan_del(conn->hchan); | 1018 | hci_chan_del(conn->hchan); |
1043 | 1019 | ||
1044 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | 1020 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) |
1045 | del_timer_sync(&conn->info_timer); | 1021 | __cancel_delayed_work(&conn->info_timer); |
1046 | 1022 | ||
1047 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) { | 1023 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) { |
1048 | del_timer(&conn->security_timer); | 1024 | __cancel_delayed_work(&conn->security_timer); |
1049 | smp_chan_destroy(conn); | 1025 | smp_chan_destroy(conn); |
1050 | } | 1026 | } |
1051 | 1027 | ||
@@ -1053,9 +1029,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
1053 | kfree(conn); | 1029 | kfree(conn); |
1054 | } | 1030 | } |
1055 | 1031 | ||
1056 | static void security_timeout(unsigned long arg) | 1032 | static void security_timeout(struct work_struct *work) |
1057 | { | 1033 | { |
1058 | struct l2cap_conn *conn = (void *) arg; | 1034 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, |
1035 | security_timer.work); | ||
1059 | 1036 | ||
1060 | l2cap_conn_del(conn->hcon, ETIMEDOUT); | 1037 | l2cap_conn_del(conn->hcon, ETIMEDOUT); |
1061 | } | 1038 | } |
@@ -1095,29 +1072,19 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
1095 | conn->feat_mask = 0; | 1072 | conn->feat_mask = 0; |
1096 | 1073 | ||
1097 | spin_lock_init(&conn->lock); | 1074 | spin_lock_init(&conn->lock); |
1098 | rwlock_init(&conn->chan_lock); | ||
1099 | 1075 | ||
1100 | INIT_LIST_HEAD(&conn->chan_l); | 1076 | INIT_LIST_HEAD(&conn->chan_l); |
1101 | 1077 | ||
1102 | if (hcon->type == LE_LINK) | 1078 | if (hcon->type == LE_LINK) |
1103 | setup_timer(&conn->security_timer, security_timeout, | 1079 | INIT_DELAYED_WORK(&conn->security_timer, security_timeout); |
1104 | (unsigned long) conn); | ||
1105 | else | 1080 | else |
1106 | setup_timer(&conn->info_timer, l2cap_info_timeout, | 1081 | INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); |
1107 | (unsigned long) conn); | ||
1108 | 1082 | ||
1109 | conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; | 1083 | conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; |
1110 | 1084 | ||
1111 | return conn; | 1085 | return conn; |
1112 | } | 1086 | } |
1113 | 1087 | ||
1114 | static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | ||
1115 | { | ||
1116 | write_lock_bh(&conn->chan_lock); | ||
1117 | __l2cap_chan_add(conn, chan); | ||
1118 | write_unlock_bh(&conn->chan_lock); | ||
1119 | } | ||
1120 | |||
1121 | /* ---- Socket interface ---- */ | 1088 | /* ---- Socket interface ---- */ |
1122 | 1089 | ||
1123 | /* Find socket with psm and source bdaddr. | 1090 | /* Find socket with psm and source bdaddr. |
@@ -1153,11 +1120,10 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr | |||
1153 | return c1; | 1120 | return c1; |
1154 | } | 1121 | } |
1155 | 1122 | ||
1156 | int l2cap_chan_connect(struct l2cap_chan *chan) | 1123 | inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst) |
1157 | { | 1124 | { |
1158 | struct sock *sk = chan->sk; | 1125 | struct sock *sk = chan->sk; |
1159 | bdaddr_t *src = &bt_sk(sk)->src; | 1126 | bdaddr_t *src = &bt_sk(sk)->src; |
1160 | bdaddr_t *dst = &bt_sk(sk)->dst; | ||
1161 | struct l2cap_conn *conn; | 1127 | struct l2cap_conn *conn; |
1162 | struct hci_conn *hcon; | 1128 | struct hci_conn *hcon; |
1163 | struct hci_dev *hdev; | 1129 | struct hci_dev *hdev; |
@@ -1171,7 +1137,62 @@ int l2cap_chan_connect(struct l2cap_chan *chan) | |||
1171 | if (!hdev) | 1137 | if (!hdev) |
1172 | return -EHOSTUNREACH; | 1138 | return -EHOSTUNREACH; |
1173 | 1139 | ||
1174 | hci_dev_lock_bh(hdev); | 1140 | hci_dev_lock(hdev); |
1141 | |||
1142 | lock_sock(sk); | ||
1143 | |||
1144 | /* PSM must be odd and lsb of upper byte must be 0 */ | ||
1145 | if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid && | ||
1146 | chan->chan_type != L2CAP_CHAN_RAW) { | ||
1147 | err = -EINVAL; | ||
1148 | goto done; | ||
1149 | } | ||
1150 | |||
1151 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !(psm || cid)) { | ||
1152 | err = -EINVAL; | ||
1153 | goto done; | ||
1154 | } | ||
1155 | |||
1156 | switch (chan->mode) { | ||
1157 | case L2CAP_MODE_BASIC: | ||
1158 | break; | ||
1159 | case L2CAP_MODE_ERTM: | ||
1160 | case L2CAP_MODE_STREAMING: | ||
1161 | if (!disable_ertm) | ||
1162 | break; | ||
1163 | /* fall through */ | ||
1164 | default: | ||
1165 | err = -ENOTSUPP; | ||
1166 | goto done; | ||
1167 | } | ||
1168 | |||
1169 | switch (sk->sk_state) { | ||
1170 | case BT_CONNECT: | ||
1171 | case BT_CONNECT2: | ||
1172 | case BT_CONFIG: | ||
1173 | /* Already connecting */ | ||
1174 | err = 0; | ||
1175 | goto done; | ||
1176 | |||
1177 | case BT_CONNECTED: | ||
1178 | /* Already connected */ | ||
1179 | err = -EISCONN; | ||
1180 | goto done; | ||
1181 | |||
1182 | case BT_OPEN: | ||
1183 | case BT_BOUND: | ||
1184 | /* Can connect */ | ||
1185 | break; | ||
1186 | |||
1187 | default: | ||
1188 | err = -EBADFD; | ||
1189 | goto done; | ||
1190 | } | ||
1191 | |||
1192 | /* Set destination address and psm */ | ||
1193 | bacpy(&bt_sk(sk)->dst, src); | ||
1194 | chan->psm = psm; | ||
1195 | chan->dcid = cid; | ||
1175 | 1196 | ||
1176 | auth_type = l2cap_get_auth_type(chan); | 1197 | auth_type = l2cap_get_auth_type(chan); |
1177 | 1198 | ||
@@ -1214,7 +1235,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan) | |||
1214 | err = 0; | 1235 | err = 0; |
1215 | 1236 | ||
1216 | done: | 1237 | done: |
1217 | hci_dev_unlock_bh(hdev); | 1238 | hci_dev_unlock(hdev); |
1218 | hci_dev_put(hdev); | 1239 | hci_dev_put(hdev); |
1219 | return err; | 1240 | return err; |
1220 | } | 1241 | } |
@@ -1251,17 +1272,18 @@ int __l2cap_wait_ack(struct sock *sk) | |||
1251 | return err; | 1272 | return err; |
1252 | } | 1273 | } |
1253 | 1274 | ||
1254 | static void l2cap_monitor_timeout(unsigned long arg) | 1275 | static void l2cap_monitor_timeout(struct work_struct *work) |
1255 | { | 1276 | { |
1256 | struct l2cap_chan *chan = (void *) arg; | 1277 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, |
1278 | monitor_timer.work); | ||
1257 | struct sock *sk = chan->sk; | 1279 | struct sock *sk = chan->sk; |
1258 | 1280 | ||
1259 | BT_DBG("chan %p", chan); | 1281 | BT_DBG("chan %p", chan); |
1260 | 1282 | ||
1261 | bh_lock_sock(sk); | 1283 | lock_sock(sk); |
1262 | if (chan->retry_count >= chan->remote_max_tx) { | 1284 | if (chan->retry_count >= chan->remote_max_tx) { |
1263 | l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); | 1285 | l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); |
1264 | bh_unlock_sock(sk); | 1286 | release_sock(sk); |
1265 | return; | 1287 | return; |
1266 | } | 1288 | } |
1267 | 1289 | ||
@@ -1269,24 +1291,25 @@ static void l2cap_monitor_timeout(unsigned long arg) | |||
1269 | __set_monitor_timer(chan); | 1291 | __set_monitor_timer(chan); |
1270 | 1292 | ||
1271 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); | 1293 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); |
1272 | bh_unlock_sock(sk); | 1294 | release_sock(sk); |
1273 | } | 1295 | } |
1274 | 1296 | ||
1275 | static void l2cap_retrans_timeout(unsigned long arg) | 1297 | static void l2cap_retrans_timeout(struct work_struct *work) |
1276 | { | 1298 | { |
1277 | struct l2cap_chan *chan = (void *) arg; | 1299 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, |
1300 | retrans_timer.work); | ||
1278 | struct sock *sk = chan->sk; | 1301 | struct sock *sk = chan->sk; |
1279 | 1302 | ||
1280 | BT_DBG("chan %p", chan); | 1303 | BT_DBG("chan %p", chan); |
1281 | 1304 | ||
1282 | bh_lock_sock(sk); | 1305 | lock_sock(sk); |
1283 | chan->retry_count = 1; | 1306 | chan->retry_count = 1; |
1284 | __set_monitor_timer(chan); | 1307 | __set_monitor_timer(chan); |
1285 | 1308 | ||
1286 | set_bit(CONN_WAIT_F, &chan->conn_state); | 1309 | set_bit(CONN_WAIT_F, &chan->conn_state); |
1287 | 1310 | ||
1288 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); | 1311 | l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); |
1289 | bh_unlock_sock(sk); | 1312 | release_sock(sk); |
1290 | } | 1313 | } |
1291 | 1314 | ||
1292 | static void l2cap_drop_acked_frames(struct l2cap_chan *chan) | 1315 | static void l2cap_drop_acked_frames(struct l2cap_chan *chan) |
@@ -1778,8 +1801,9 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1778 | 1801 | ||
1779 | BT_DBG("conn %p", conn); | 1802 | BT_DBG("conn %p", conn); |
1780 | 1803 | ||
1781 | read_lock(&conn->chan_lock); | 1804 | rcu_read_lock(); |
1782 | list_for_each_entry(chan, &conn->chan_l, list) { | 1805 | |
1806 | list_for_each_entry_rcu(chan, &conn->chan_l, list) { | ||
1783 | struct sock *sk = chan->sk; | 1807 | struct sock *sk = chan->sk; |
1784 | if (chan->chan_type != L2CAP_CHAN_RAW) | 1808 | if (chan->chan_type != L2CAP_CHAN_RAW) |
1785 | continue; | 1809 | continue; |
@@ -1794,7 +1818,8 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1794 | if (chan->ops->recv(chan->data, nskb)) | 1818 | if (chan->ops->recv(chan->data, nskb)) |
1795 | kfree_skb(nskb); | 1819 | kfree_skb(nskb); |
1796 | } | 1820 | } |
1797 | read_unlock(&conn->chan_lock); | 1821 | |
1822 | rcu_read_unlock(); | ||
1798 | } | 1823 | } |
1799 | 1824 | ||
1800 | /* ---- L2CAP signalling commands ---- */ | 1825 | /* ---- L2CAP signalling commands ---- */ |
@@ -1955,37 +1980,33 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) | |||
1955 | (unsigned long) &efs); | 1980 | (unsigned long) &efs); |
1956 | } | 1981 | } |
1957 | 1982 | ||
1958 | static void l2cap_ack_timeout(unsigned long arg) | 1983 | static void l2cap_ack_timeout(struct work_struct *work) |
1959 | { | 1984 | { |
1960 | struct l2cap_chan *chan = (void *) arg; | 1985 | struct l2cap_chan *chan = container_of(work, struct l2cap_chan, |
1986 | ack_timer.work); | ||
1961 | 1987 | ||
1962 | bh_lock_sock(chan->sk); | 1988 | BT_DBG("chan %p", chan); |
1989 | |||
1990 | lock_sock(chan->sk); | ||
1963 | l2cap_send_ack(chan); | 1991 | l2cap_send_ack(chan); |
1964 | bh_unlock_sock(chan->sk); | 1992 | release_sock(chan->sk); |
1965 | } | 1993 | } |
1966 | 1994 | ||
1967 | static inline void l2cap_ertm_init(struct l2cap_chan *chan) | 1995 | static inline void l2cap_ertm_init(struct l2cap_chan *chan) |
1968 | { | 1996 | { |
1969 | struct sock *sk = chan->sk; | ||
1970 | |||
1971 | chan->expected_ack_seq = 0; | 1997 | chan->expected_ack_seq = 0; |
1972 | chan->unacked_frames = 0; | 1998 | chan->unacked_frames = 0; |
1973 | chan->buffer_seq = 0; | 1999 | chan->buffer_seq = 0; |
1974 | chan->num_acked = 0; | 2000 | chan->num_acked = 0; |
1975 | chan->frames_sent = 0; | 2001 | chan->frames_sent = 0; |
1976 | 2002 | ||
1977 | setup_timer(&chan->retrans_timer, l2cap_retrans_timeout, | 2003 | INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout); |
1978 | (unsigned long) chan); | 2004 | INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout); |
1979 | setup_timer(&chan->monitor_timer, l2cap_monitor_timeout, | 2005 | INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout); |
1980 | (unsigned long) chan); | ||
1981 | setup_timer(&chan->ack_timer, l2cap_ack_timeout, (unsigned long) chan); | ||
1982 | 2006 | ||
1983 | skb_queue_head_init(&chan->srej_q); | 2007 | skb_queue_head_init(&chan->srej_q); |
1984 | 2008 | ||
1985 | INIT_LIST_HEAD(&chan->srej_l); | 2009 | INIT_LIST_HEAD(&chan->srej_l); |
1986 | |||
1987 | |||
1988 | sk->sk_backlog_rcv = l2cap_ertm_data_rcv; | ||
1989 | } | 2010 | } |
1990 | 2011 | ||
1991 | static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) | 2012 | static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) |
@@ -2553,7 +2574,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2553 | 2574 | ||
2554 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && | 2575 | if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) && |
2555 | cmd->ident == conn->info_ident) { | 2576 | cmd->ident == conn->info_ident) { |
2556 | del_timer(&conn->info_timer); | 2577 | __cancel_delayed_work(&conn->info_timer); |
2557 | 2578 | ||
2558 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 2579 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
2559 | conn->info_ident = 0; | 2580 | conn->info_ident = 0; |
@@ -2586,7 +2607,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2586 | 2607 | ||
2587 | parent = pchan->sk; | 2608 | parent = pchan->sk; |
2588 | 2609 | ||
2589 | bh_lock_sock(parent); | 2610 | lock_sock(parent); |
2590 | 2611 | ||
2591 | /* Check if the ACL is secure enough (if not SDP) */ | 2612 | /* Check if the ACL is secure enough (if not SDP) */ |
2592 | if (psm != cpu_to_le16(0x0001) && | 2613 | if (psm != cpu_to_le16(0x0001) && |
@@ -2610,11 +2631,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2610 | 2631 | ||
2611 | sk = chan->sk; | 2632 | sk = chan->sk; |
2612 | 2633 | ||
2613 | write_lock_bh(&conn->chan_lock); | ||
2614 | |||
2615 | /* Check if we already have channel with that dcid */ | 2634 | /* Check if we already have channel with that dcid */ |
2616 | if (__l2cap_get_chan_by_dcid(conn, scid)) { | 2635 | if (__l2cap_get_chan_by_dcid(conn, scid)) { |
2617 | write_unlock_bh(&conn->chan_lock); | ||
2618 | sock_set_flag(sk, SOCK_ZAPPED); | 2636 | sock_set_flag(sk, SOCK_ZAPPED); |
2619 | chan->ops->close(chan->data); | 2637 | chan->ops->close(chan->data); |
2620 | goto response; | 2638 | goto response; |
@@ -2629,7 +2647,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2629 | 2647 | ||
2630 | bt_accept_enqueue(parent, sk); | 2648 | bt_accept_enqueue(parent, sk); |
2631 | 2649 | ||
2632 | __l2cap_chan_add(conn, chan); | 2650 | l2cap_chan_add(conn, chan); |
2633 | 2651 | ||
2634 | dcid = chan->scid; | 2652 | dcid = chan->scid; |
2635 | 2653 | ||
@@ -2660,10 +2678,8 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2660 | status = L2CAP_CS_NO_INFO; | 2678 | status = L2CAP_CS_NO_INFO; |
2661 | } | 2679 | } |
2662 | 2680 | ||
2663 | write_unlock_bh(&conn->chan_lock); | ||
2664 | |||
2665 | response: | 2681 | response: |
2666 | bh_unlock_sock(parent); | 2682 | release_sock(parent); |
2667 | 2683 | ||
2668 | sendresp: | 2684 | sendresp: |
2669 | rsp.scid = cpu_to_le16(scid); | 2685 | rsp.scid = cpu_to_le16(scid); |
@@ -2679,7 +2695,7 @@ sendresp: | |||
2679 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; | 2695 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; |
2680 | conn->info_ident = l2cap_get_ident(conn); | 2696 | conn->info_ident = l2cap_get_ident(conn); |
2681 | 2697 | ||
2682 | mod_timer(&conn->info_timer, jiffies + | 2698 | schedule_delayed_work(&conn->info_timer, |
2683 | msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); | 2699 | msecs_to_jiffies(L2CAP_INFO_TIMEOUT)); |
2684 | 2700 | ||
2685 | l2cap_send_cmd(conn, conn->info_ident, | 2701 | l2cap_send_cmd(conn, conn->info_ident, |
@@ -2745,19 +2761,11 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2745 | break; | 2761 | break; |
2746 | 2762 | ||
2747 | default: | 2763 | default: |
2748 | /* don't delete l2cap channel if sk is owned by user */ | ||
2749 | if (sock_owned_by_user(sk)) { | ||
2750 | l2cap_state_change(chan, BT_DISCONN); | ||
2751 | __clear_chan_timer(chan); | ||
2752 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); | ||
2753 | break; | ||
2754 | } | ||
2755 | |||
2756 | l2cap_chan_del(chan, ECONNREFUSED); | 2764 | l2cap_chan_del(chan, ECONNREFUSED); |
2757 | break; | 2765 | break; |
2758 | } | 2766 | } |
2759 | 2767 | ||
2760 | bh_unlock_sock(sk); | 2768 | release_sock(sk); |
2761 | return 0; | 2769 | return 0; |
2762 | } | 2770 | } |
2763 | 2771 | ||
@@ -2879,7 +2887,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2879 | } | 2887 | } |
2880 | 2888 | ||
2881 | unlock: | 2889 | unlock: |
2882 | bh_unlock_sock(sk); | 2890 | release_sock(sk); |
2883 | return 0; | 2891 | return 0; |
2884 | } | 2892 | } |
2885 | 2893 | ||
@@ -2986,7 +2994,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2986 | } | 2994 | } |
2987 | 2995 | ||
2988 | done: | 2996 | done: |
2989 | bh_unlock_sock(sk); | 2997 | release_sock(sk); |
2990 | return 0; | 2998 | return 0; |
2991 | } | 2999 | } |
2992 | 3000 | ||
@@ -3015,17 +3023,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
3015 | 3023 | ||
3016 | sk->sk_shutdown = SHUTDOWN_MASK; | 3024 | sk->sk_shutdown = SHUTDOWN_MASK; |
3017 | 3025 | ||
3018 | /* don't delete l2cap channel if sk is owned by user */ | ||
3019 | if (sock_owned_by_user(sk)) { | ||
3020 | l2cap_state_change(chan, BT_DISCONN); | ||
3021 | __clear_chan_timer(chan); | ||
3022 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); | ||
3023 | bh_unlock_sock(sk); | ||
3024 | return 0; | ||
3025 | } | ||
3026 | |||
3027 | l2cap_chan_del(chan, ECONNRESET); | 3026 | l2cap_chan_del(chan, ECONNRESET); |
3028 | bh_unlock_sock(sk); | 3027 | release_sock(sk); |
3029 | 3028 | ||
3030 | chan->ops->close(chan->data); | 3029 | chan->ops->close(chan->data); |
3031 | return 0; | 3030 | return 0; |
@@ -3049,17 +3048,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
3049 | 3048 | ||
3050 | sk = chan->sk; | 3049 | sk = chan->sk; |
3051 | 3050 | ||
3052 | /* don't delete l2cap channel if sk is owned by user */ | ||
3053 | if (sock_owned_by_user(sk)) { | ||
3054 | l2cap_state_change(chan, BT_DISCONN); | ||
3055 | __clear_chan_timer(chan); | ||
3056 | __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); | ||
3057 | bh_unlock_sock(sk); | ||
3058 | return 0; | ||
3059 | } | ||
3060 | |||
3061 | l2cap_chan_del(chan, 0); | 3051 | l2cap_chan_del(chan, 0); |
3062 | bh_unlock_sock(sk); | 3052 | release_sock(sk); |
3063 | 3053 | ||
3064 | chan->ops->close(chan->data); | 3054 | chan->ops->close(chan->data); |
3065 | return 0; | 3055 | return 0; |
@@ -3130,7 +3120,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm | |||
3130 | conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) | 3120 | conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) |
3131 | return 0; | 3121 | return 0; |
3132 | 3122 | ||
3133 | del_timer(&conn->info_timer); | 3123 | __cancel_delayed_work(&conn->info_timer); |
3134 | 3124 | ||
3135 | if (result != L2CAP_IR_SUCCESS) { | 3125 | if (result != L2CAP_IR_SUCCESS) { |
3136 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | 3126 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; |
@@ -4247,12 +4237,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
4247 | break; | 4237 | break; |
4248 | 4238 | ||
4249 | case L2CAP_MODE_ERTM: | 4239 | case L2CAP_MODE_ERTM: |
4250 | if (!sock_owned_by_user(sk)) { | 4240 | l2cap_ertm_data_rcv(sk, skb); |
4251 | l2cap_ertm_data_rcv(sk, skb); | ||
4252 | } else { | ||
4253 | if (sk_add_backlog(sk, skb)) | ||
4254 | goto drop; | ||
4255 | } | ||
4256 | 4241 | ||
4257 | goto done; | 4242 | goto done; |
4258 | 4243 | ||
@@ -4302,7 +4287,7 @@ drop: | |||
4302 | 4287 | ||
4303 | done: | 4288 | done: |
4304 | if (sk) | 4289 | if (sk) |
4305 | bh_unlock_sock(sk); | 4290 | release_sock(sk); |
4306 | 4291 | ||
4307 | return 0; | 4292 | return 0; |
4308 | } | 4293 | } |
@@ -4318,7 +4303,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str | |||
4318 | 4303 | ||
4319 | sk = chan->sk; | 4304 | sk = chan->sk; |
4320 | 4305 | ||
4321 | bh_lock_sock(sk); | 4306 | lock_sock(sk); |
4322 | 4307 | ||
4323 | BT_DBG("sk %p, len %d", sk, skb->len); | 4308 | BT_DBG("sk %p, len %d", sk, skb->len); |
4324 | 4309 | ||
@@ -4336,7 +4321,7 @@ drop: | |||
4336 | 4321 | ||
4337 | done: | 4322 | done: |
4338 | if (sk) | 4323 | if (sk) |
4339 | bh_unlock_sock(sk); | 4324 | release_sock(sk); |
4340 | return 0; | 4325 | return 0; |
4341 | } | 4326 | } |
4342 | 4327 | ||
@@ -4351,7 +4336,7 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct | |||
4351 | 4336 | ||
4352 | sk = chan->sk; | 4337 | sk = chan->sk; |
4353 | 4338 | ||
4354 | bh_lock_sock(sk); | 4339 | lock_sock(sk); |
4355 | 4340 | ||
4356 | BT_DBG("sk %p, len %d", sk, skb->len); | 4341 | BT_DBG("sk %p, len %d", sk, skb->len); |
4357 | 4342 | ||
@@ -4369,7 +4354,7 @@ drop: | |||
4369 | 4354 | ||
4370 | done: | 4355 | done: |
4371 | if (sk) | 4356 | if (sk) |
4372 | bh_unlock_sock(sk); | 4357 | release_sock(sk); |
4373 | return 0; | 4358 | return 0; |
4374 | } | 4359 | } |
4375 | 4360 | ||
@@ -4419,14 +4404,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
4419 | 4404 | ||
4420 | /* ---- L2CAP interface with lower layer (HCI) ---- */ | 4405 | /* ---- L2CAP interface with lower layer (HCI) ---- */ |
4421 | 4406 | ||
4422 | static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | 4407 | int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) |
4423 | { | 4408 | { |
4424 | int exact = 0, lm1 = 0, lm2 = 0; | 4409 | int exact = 0, lm1 = 0, lm2 = 0; |
4425 | struct l2cap_chan *c; | 4410 | struct l2cap_chan *c; |
4426 | 4411 | ||
4427 | if (type != ACL_LINK) | ||
4428 | return -EINVAL; | ||
4429 | |||
4430 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 4412 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
4431 | 4413 | ||
4432 | /* Find listening sockets and check their link_mode */ | 4414 | /* Find listening sockets and check their link_mode */ |
@@ -4453,15 +4435,12 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
4453 | return exact ? lm1 : lm2; | 4435 | return exact ? lm1 : lm2; |
4454 | } | 4436 | } |
4455 | 4437 | ||
4456 | static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | 4438 | int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) |
4457 | { | 4439 | { |
4458 | struct l2cap_conn *conn; | 4440 | struct l2cap_conn *conn; |
4459 | 4441 | ||
4460 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 4442 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
4461 | 4443 | ||
4462 | if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK)) | ||
4463 | return -EINVAL; | ||
4464 | |||
4465 | if (!status) { | 4444 | if (!status) { |
4466 | conn = l2cap_conn_add(hcon, status); | 4445 | conn = l2cap_conn_add(hcon, status); |
4467 | if (conn) | 4446 | if (conn) |
@@ -4472,27 +4451,22 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | |||
4472 | return 0; | 4451 | return 0; |
4473 | } | 4452 | } |
4474 | 4453 | ||
4475 | static int l2cap_disconn_ind(struct hci_conn *hcon) | 4454 | int l2cap_disconn_ind(struct hci_conn *hcon) |
4476 | { | 4455 | { |
4477 | struct l2cap_conn *conn = hcon->l2cap_data; | 4456 | struct l2cap_conn *conn = hcon->l2cap_data; |
4478 | 4457 | ||
4479 | BT_DBG("hcon %p", hcon); | 4458 | BT_DBG("hcon %p", hcon); |
4480 | 4459 | ||
4481 | if ((hcon->type != ACL_LINK && hcon->type != LE_LINK) || !conn) | 4460 | if (!conn) |
4482 | return HCI_ERROR_REMOTE_USER_TERM; | 4461 | return HCI_ERROR_REMOTE_USER_TERM; |
4483 | |||
4484 | return conn->disc_reason; | 4462 | return conn->disc_reason; |
4485 | } | 4463 | } |
4486 | 4464 | ||
4487 | static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) | 4465 | int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) |
4488 | { | 4466 | { |
4489 | BT_DBG("hcon %p reason %d", hcon, reason); | 4467 | BT_DBG("hcon %p reason %d", hcon, reason); |
4490 | 4468 | ||
4491 | if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK)) | ||
4492 | return -EINVAL; | ||
4493 | |||
4494 | l2cap_conn_del(hcon, bt_to_errno(reason)); | 4469 | l2cap_conn_del(hcon, bt_to_errno(reason)); |
4495 | |||
4496 | return 0; | 4470 | return 0; |
4497 | } | 4471 | } |
4498 | 4472 | ||
@@ -4513,7 +4487,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) | |||
4513 | } | 4487 | } |
4514 | } | 4488 | } |
4515 | 4489 | ||
4516 | static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | 4490 | int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) |
4517 | { | 4491 | { |
4518 | struct l2cap_conn *conn = hcon->l2cap_data; | 4492 | struct l2cap_conn *conn = hcon->l2cap_data; |
4519 | struct l2cap_chan *chan; | 4493 | struct l2cap_chan *chan; |
@@ -4525,12 +4499,12 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4525 | 4499 | ||
4526 | if (hcon->type == LE_LINK) { | 4500 | if (hcon->type == LE_LINK) { |
4527 | smp_distribute_keys(conn, 0); | 4501 | smp_distribute_keys(conn, 0); |
4528 | del_timer(&conn->security_timer); | 4502 | __cancel_delayed_work(&conn->security_timer); |
4529 | } | 4503 | } |
4530 | 4504 | ||
4531 | read_lock(&conn->chan_lock); | 4505 | rcu_read_lock(); |
4532 | 4506 | ||
4533 | list_for_each_entry(chan, &conn->chan_l, list) { | 4507 | list_for_each_entry_rcu(chan, &conn->chan_l, list) { |
4534 | struct sock *sk = chan->sk; | 4508 | struct sock *sk = chan->sk; |
4535 | 4509 | ||
4536 | bh_lock_sock(sk); | 4510 | bh_lock_sock(sk); |
@@ -4608,12 +4582,12 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4608 | bh_unlock_sock(sk); | 4582 | bh_unlock_sock(sk); |
4609 | } | 4583 | } |
4610 | 4584 | ||
4611 | read_unlock(&conn->chan_lock); | 4585 | rcu_read_unlock(); |
4612 | 4586 | ||
4613 | return 0; | 4587 | return 0; |
4614 | } | 4588 | } |
4615 | 4589 | ||
4616 | static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) | 4590 | int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) |
4617 | { | 4591 | { |
4618 | struct l2cap_conn *conn = hcon->l2cap_data; | 4592 | struct l2cap_conn *conn = hcon->l2cap_data; |
4619 | 4593 | ||
@@ -4674,11 +4648,11 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
4674 | BT_ERR("Frame exceeding recv MTU (len %d, " | 4648 | BT_ERR("Frame exceeding recv MTU (len %d, " |
4675 | "MTU %d)", len, | 4649 | "MTU %d)", len, |
4676 | chan->imtu); | 4650 | chan->imtu); |
4677 | bh_unlock_sock(sk); | 4651 | release_sock(sk); |
4678 | l2cap_conn_unreliable(conn, ECOMM); | 4652 | l2cap_conn_unreliable(conn, ECOMM); |
4679 | goto drop; | 4653 | goto drop; |
4680 | } | 4654 | } |
4681 | bh_unlock_sock(sk); | 4655 | release_sock(sk); |
4682 | } | 4656 | } |
4683 | 4657 | ||
4684 | /* Allocate skb for the complete frame (with header) */ | 4658 | /* Allocate skb for the complete frame (with header) */ |
@@ -4760,17 +4734,6 @@ static const struct file_operations l2cap_debugfs_fops = { | |||
4760 | 4734 | ||
4761 | static struct dentry *l2cap_debugfs; | 4735 | static struct dentry *l2cap_debugfs; |
4762 | 4736 | ||
4763 | static struct hci_proto l2cap_hci_proto = { | ||
4764 | .name = "L2CAP", | ||
4765 | .id = HCI_PROTO_L2CAP, | ||
4766 | .connect_ind = l2cap_connect_ind, | ||
4767 | .connect_cfm = l2cap_connect_cfm, | ||
4768 | .disconn_ind = l2cap_disconn_ind, | ||
4769 | .disconn_cfm = l2cap_disconn_cfm, | ||
4770 | .security_cfm = l2cap_security_cfm, | ||
4771 | .recv_acldata = l2cap_recv_acldata | ||
4772 | }; | ||
4773 | |||
4774 | int __init l2cap_init(void) | 4737 | int __init l2cap_init(void) |
4775 | { | 4738 | { |
4776 | int err; | 4739 | int err; |
@@ -4779,13 +4742,6 @@ int __init l2cap_init(void) | |||
4779 | if (err < 0) | 4742 | if (err < 0) |
4780 | return err; | 4743 | return err; |
4781 | 4744 | ||
4782 | err = hci_register_proto(&l2cap_hci_proto); | ||
4783 | if (err < 0) { | ||
4784 | BT_ERR("L2CAP protocol registration failed"); | ||
4785 | bt_sock_unregister(BTPROTO_L2CAP); | ||
4786 | goto error; | ||
4787 | } | ||
4788 | |||
4789 | if (bt_debugfs) { | 4745 | if (bt_debugfs) { |
4790 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, | 4746 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, |
4791 | bt_debugfs, NULL, &l2cap_debugfs_fops); | 4747 | bt_debugfs, NULL, &l2cap_debugfs_fops); |
@@ -4794,19 +4750,11 @@ int __init l2cap_init(void) | |||
4794 | } | 4750 | } |
4795 | 4751 | ||
4796 | return 0; | 4752 | return 0; |
4797 | |||
4798 | error: | ||
4799 | l2cap_cleanup_sockets(); | ||
4800 | return err; | ||
4801 | } | 4753 | } |
4802 | 4754 | ||
4803 | void l2cap_exit(void) | 4755 | void l2cap_exit(void) |
4804 | { | 4756 | { |
4805 | debugfs_remove(l2cap_debugfs); | 4757 | debugfs_remove(l2cap_debugfs); |
4806 | |||
4807 | if (hci_unregister_proto(&l2cap_hci_proto) < 0) | ||
4808 | BT_ERR("L2CAP protocol unregistration failed"); | ||
4809 | |||
4810 | l2cap_cleanup_sockets(); | 4758 | l2cap_cleanup_sockets(); |
4811 | } | 4759 | } |
4812 | 4760 | ||
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index f73704321a77..9ca5616166f7 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -3,6 +3,7 @@ | |||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | 3 | Copyright (C) 2000-2001 Qualcomm Incorporated |
4 | Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> | 4 | Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> |
5 | Copyright (C) 2010 Google Inc. | 5 | Copyright (C) 2010 Google Inc. |
6 | Copyright (C) 2011 ProFUSION Embedded Systems | ||
6 | 7 | ||
7 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | 8 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> |
8 | 9 | ||
@@ -122,70 +123,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
122 | if (la.l2_cid && la.l2_psm) | 123 | if (la.l2_cid && la.l2_psm) |
123 | return -EINVAL; | 124 | return -EINVAL; |
124 | 125 | ||
125 | lock_sock(sk); | 126 | err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr); |
126 | |||
127 | if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED | ||
128 | && !(la.l2_psm || la.l2_cid)) { | ||
129 | err = -EINVAL; | ||
130 | goto done; | ||
131 | } | ||
132 | |||
133 | switch (chan->mode) { | ||
134 | case L2CAP_MODE_BASIC: | ||
135 | break; | ||
136 | case L2CAP_MODE_ERTM: | ||
137 | case L2CAP_MODE_STREAMING: | ||
138 | if (!disable_ertm) | ||
139 | break; | ||
140 | /* fall through */ | ||
141 | default: | ||
142 | err = -ENOTSUPP; | ||
143 | goto done; | ||
144 | } | ||
145 | |||
146 | switch (sk->sk_state) { | ||
147 | case BT_CONNECT: | ||
148 | case BT_CONNECT2: | ||
149 | case BT_CONFIG: | ||
150 | /* Already connecting */ | ||
151 | goto wait; | ||
152 | |||
153 | case BT_CONNECTED: | ||
154 | /* Already connected */ | ||
155 | err = -EISCONN; | ||
156 | goto done; | ||
157 | |||
158 | case BT_OPEN: | ||
159 | case BT_BOUND: | ||
160 | /* Can connect */ | ||
161 | break; | ||
162 | |||
163 | default: | ||
164 | err = -EBADFD; | ||
165 | goto done; | ||
166 | } | ||
167 | |||
168 | /* PSM must be odd and lsb of upper byte must be 0 */ | ||
169 | if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && !la.l2_cid && | ||
170 | chan->chan_type != L2CAP_CHAN_RAW) { | ||
171 | err = -EINVAL; | ||
172 | goto done; | ||
173 | } | ||
174 | |||
175 | /* Set destination address and psm */ | ||
176 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); | ||
177 | chan->psm = la.l2_psm; | ||
178 | chan->dcid = la.l2_cid; | ||
179 | |||
180 | err = l2cap_chan_connect(l2cap_pi(sk)->chan); | ||
181 | if (err) | 127 | if (err) |
182 | goto done; | 128 | goto done; |
183 | 129 | ||
184 | wait: | ||
185 | err = bt_sock_wait_state(sk, BT_CONNECTED, | 130 | err = bt_sock_wait_state(sk, BT_CONNECTED, |
186 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | 131 | sock_sndtimeo(sk, flags & O_NONBLOCK)); |
187 | done: | 132 | done: |
188 | release_sock(sk); | 133 | if (sock_owned_by_user(sk)) |
134 | release_sock(sk); | ||
189 | return err; | 135 | return err; |
190 | } | 136 | } |
191 | 137 | ||
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 1ce549bae241..2540944d871f 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -30,12 +30,15 @@ | |||
30 | #include <net/bluetooth/bluetooth.h> | 30 | #include <net/bluetooth/bluetooth.h> |
31 | #include <net/bluetooth/hci_core.h> | 31 | #include <net/bluetooth/hci_core.h> |
32 | #include <net/bluetooth/mgmt.h> | 32 | #include <net/bluetooth/mgmt.h> |
33 | #include <net/bluetooth/smp.h> | ||
33 | 34 | ||
34 | #define MGMT_VERSION 0 | 35 | #define MGMT_VERSION 0 |
35 | #define MGMT_REVISION 1 | 36 | #define MGMT_REVISION 1 |
36 | 37 | ||
37 | #define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */ | 38 | #define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */ |
38 | 39 | ||
40 | #define SERVICE_CACHE_TIMEOUT (5 * 1000) | ||
41 | |||
39 | struct pending_cmd { | 42 | struct pending_cmd { |
40 | struct list_head list; | 43 | struct list_head list; |
41 | u16 opcode; | 44 | u16 opcode; |
@@ -243,6 +246,262 @@ static int read_index_list(struct sock *sk) | |||
243 | return err; | 246 | return err; |
244 | } | 247 | } |
245 | 248 | ||
249 | static u32 get_supported_settings(struct hci_dev *hdev) | ||
250 | { | ||
251 | u32 settings = 0; | ||
252 | |||
253 | settings |= MGMT_SETTING_POWERED; | ||
254 | settings |= MGMT_SETTING_CONNECTABLE; | ||
255 | settings |= MGMT_SETTING_FAST_CONNECTABLE; | ||
256 | settings |= MGMT_SETTING_DISCOVERABLE; | ||
257 | settings |= MGMT_SETTING_PAIRABLE; | ||
258 | |||
259 | if (hdev->features[6] & LMP_SIMPLE_PAIR) | ||
260 | settings |= MGMT_SETTING_SSP; | ||
261 | |||
262 | if (!(hdev->features[4] & LMP_NO_BREDR)) { | ||
263 | settings |= MGMT_SETTING_BREDR; | ||
264 | settings |= MGMT_SETTING_LINK_SECURITY; | ||
265 | } | ||
266 | |||
267 | if (hdev->features[4] & LMP_LE) | ||
268 | settings |= MGMT_SETTING_LE; | ||
269 | |||
270 | return settings; | ||
271 | } | ||
272 | |||
273 | static u32 get_current_settings(struct hci_dev *hdev) | ||
274 | { | ||
275 | u32 settings = 0; | ||
276 | |||
277 | if (test_bit(HCI_UP, &hdev->flags)) | ||
278 | settings |= MGMT_SETTING_POWERED; | ||
279 | else | ||
280 | return settings; | ||
281 | |||
282 | if (test_bit(HCI_PSCAN, &hdev->flags)) | ||
283 | settings |= MGMT_SETTING_CONNECTABLE; | ||
284 | |||
285 | if (test_bit(HCI_ISCAN, &hdev->flags)) | ||
286 | settings |= MGMT_SETTING_DISCOVERABLE; | ||
287 | |||
288 | if (test_bit(HCI_PAIRABLE, &hdev->flags)) | ||
289 | settings |= MGMT_SETTING_PAIRABLE; | ||
290 | |||
291 | if (!(hdev->features[4] & LMP_NO_BREDR)) | ||
292 | settings |= MGMT_SETTING_BREDR; | ||
293 | |||
294 | if (hdev->extfeatures[0] & LMP_HOST_LE) | ||
295 | settings |= MGMT_SETTING_LE; | ||
296 | |||
297 | if (test_bit(HCI_AUTH, &hdev->flags)) | ||
298 | settings |= MGMT_SETTING_LINK_SECURITY; | ||
299 | |||
300 | if (hdev->ssp_mode > 0) | ||
301 | settings |= MGMT_SETTING_SSP; | ||
302 | |||
303 | return settings; | ||
304 | } | ||
305 | |||
306 | #define EIR_FLAGS 0x01 /* flags */ | ||
307 | #define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ | ||
308 | #define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ | ||
309 | #define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ | ||
310 | #define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ | ||
311 | #define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ | ||
312 | #define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ | ||
313 | #define EIR_NAME_SHORT 0x08 /* shortened local name */ | ||
314 | #define EIR_NAME_COMPLETE 0x09 /* complete local name */ | ||
315 | #define EIR_TX_POWER 0x0A /* transmit power level */ | ||
316 | #define EIR_DEVICE_ID 0x10 /* device ID */ | ||
317 | |||
318 | #define PNP_INFO_SVCLASS_ID 0x1200 | ||
319 | |||
320 | static u8 bluetooth_base_uuid[] = { | ||
321 | 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, | ||
322 | 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
323 | }; | ||
324 | |||
325 | static u16 get_uuid16(u8 *uuid128) | ||
326 | { | ||
327 | u32 val; | ||
328 | int i; | ||
329 | |||
330 | for (i = 0; i < 12; i++) { | ||
331 | if (bluetooth_base_uuid[i] != uuid128[i]) | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | memcpy(&val, &uuid128[12], 4); | ||
336 | |||
337 | val = le32_to_cpu(val); | ||
338 | if (val > 0xffff) | ||
339 | return 0; | ||
340 | |||
341 | return (u16) val; | ||
342 | } | ||
343 | |||
344 | static void create_eir(struct hci_dev *hdev, u8 *data) | ||
345 | { | ||
346 | u8 *ptr = data; | ||
347 | u16 eir_len = 0; | ||
348 | u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; | ||
349 | int i, truncated = 0; | ||
350 | struct bt_uuid *uuid; | ||
351 | size_t name_len; | ||
352 | |||
353 | name_len = strlen(hdev->dev_name); | ||
354 | |||
355 | if (name_len > 0) { | ||
356 | /* EIR Data type */ | ||
357 | if (name_len > 48) { | ||
358 | name_len = 48; | ||
359 | ptr[1] = EIR_NAME_SHORT; | ||
360 | } else | ||
361 | ptr[1] = EIR_NAME_COMPLETE; | ||
362 | |||
363 | /* EIR Data length */ | ||
364 | ptr[0] = name_len + 1; | ||
365 | |||
366 | memcpy(ptr + 2, hdev->dev_name, name_len); | ||
367 | |||
368 | eir_len += (name_len + 2); | ||
369 | ptr += (name_len + 2); | ||
370 | } | ||
371 | |||
372 | memset(uuid16_list, 0, sizeof(uuid16_list)); | ||
373 | |||
374 | /* Group all UUID16 types */ | ||
375 | list_for_each_entry(uuid, &hdev->uuids, list) { | ||
376 | u16 uuid16; | ||
377 | |||
378 | uuid16 = get_uuid16(uuid->uuid); | ||
379 | if (uuid16 == 0) | ||
380 | return; | ||
381 | |||
382 | if (uuid16 < 0x1100) | ||
383 | continue; | ||
384 | |||
385 | if (uuid16 == PNP_INFO_SVCLASS_ID) | ||
386 | continue; | ||
387 | |||
388 | /* Stop if not enough space to put next UUID */ | ||
389 | if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) { | ||
390 | truncated = 1; | ||
391 | break; | ||
392 | } | ||
393 | |||
394 | /* Check for duplicates */ | ||
395 | for (i = 0; uuid16_list[i] != 0; i++) | ||
396 | if (uuid16_list[i] == uuid16) | ||
397 | break; | ||
398 | |||
399 | if (uuid16_list[i] == 0) { | ||
400 | uuid16_list[i] = uuid16; | ||
401 | eir_len += sizeof(u16); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | if (uuid16_list[0] != 0) { | ||
406 | u8 *length = ptr; | ||
407 | |||
408 | /* EIR Data type */ | ||
409 | ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; | ||
410 | |||
411 | ptr += 2; | ||
412 | eir_len += 2; | ||
413 | |||
414 | for (i = 0; uuid16_list[i] != 0; i++) { | ||
415 | *ptr++ = (uuid16_list[i] & 0x00ff); | ||
416 | *ptr++ = (uuid16_list[i] & 0xff00) >> 8; | ||
417 | } | ||
418 | |||
419 | /* EIR Data length */ | ||
420 | *length = (i * sizeof(u16)) + 1; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | static int update_eir(struct hci_dev *hdev) | ||
425 | { | ||
426 | struct hci_cp_write_eir cp; | ||
427 | |||
428 | if (!(hdev->features[6] & LMP_EXT_INQ)) | ||
429 | return 0; | ||
430 | |||
431 | if (hdev->ssp_mode == 0) | ||
432 | return 0; | ||
433 | |||
434 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
435 | return 0; | ||
436 | |||
437 | memset(&cp, 0, sizeof(cp)); | ||
438 | |||
439 | create_eir(hdev, cp.data); | ||
440 | |||
441 | if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0) | ||
442 | return 0; | ||
443 | |||
444 | memcpy(hdev->eir, cp.data, sizeof(cp.data)); | ||
445 | |||
446 | return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); | ||
447 | } | ||
448 | |||
449 | static u8 get_service_classes(struct hci_dev *hdev) | ||
450 | { | ||
451 | struct bt_uuid *uuid; | ||
452 | u8 val = 0; | ||
453 | |||
454 | list_for_each_entry(uuid, &hdev->uuids, list) | ||
455 | val |= uuid->svc_hint; | ||
456 | |||
457 | return val; | ||
458 | } | ||
459 | |||
460 | static int update_class(struct hci_dev *hdev) | ||
461 | { | ||
462 | u8 cod[3]; | ||
463 | |||
464 | BT_DBG("%s", hdev->name); | ||
465 | |||
466 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
467 | return 0; | ||
468 | |||
469 | cod[0] = hdev->minor_class; | ||
470 | cod[1] = hdev->major_class; | ||
471 | cod[2] = get_service_classes(hdev); | ||
472 | |||
473 | if (memcmp(cod, hdev->dev_class, 3) == 0) | ||
474 | return 0; | ||
475 | |||
476 | return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | ||
477 | } | ||
478 | |||
479 | static void service_cache_off(struct work_struct *work) | ||
480 | { | ||
481 | struct hci_dev *hdev = container_of(work, struct hci_dev, | ||
482 | service_cache.work); | ||
483 | |||
484 | if (!test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
485 | return; | ||
486 | |||
487 | hci_dev_lock(hdev); | ||
488 | |||
489 | update_eir(hdev); | ||
490 | update_class(hdev); | ||
491 | |||
492 | hci_dev_unlock(hdev); | ||
493 | } | ||
494 | |||
495 | static void mgmt_init_hdev(struct hci_dev *hdev) | ||
496 | { | ||
497 | if (!test_and_set_bit(HCI_MGMT, &hdev->flags)) | ||
498 | INIT_DELAYED_WORK(&hdev->service_cache, service_cache_off); | ||
499 | |||
500 | if (!test_and_set_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
501 | schedule_delayed_work(&hdev->service_cache, | ||
502 | msecs_to_jiffies(SERVICE_CACHE_TIMEOUT)); | ||
503 | } | ||
504 | |||
246 | static int read_controller_info(struct sock *sk, u16 index) | 505 | static int read_controller_info(struct sock *sk, u16 index) |
247 | { | 506 | { |
248 | struct mgmt_rp_read_info rp; | 507 | struct mgmt_rp_read_info rp; |
@@ -258,36 +517,27 @@ static int read_controller_info(struct sock *sk, u16 index) | |||
258 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) | 517 | if (test_and_clear_bit(HCI_AUTO_OFF, &hdev->flags)) |
259 | cancel_delayed_work_sync(&hdev->power_off); | 518 | cancel_delayed_work_sync(&hdev->power_off); |
260 | 519 | ||
261 | hci_dev_lock_bh(hdev); | 520 | hci_dev_lock(hdev); |
262 | 521 | ||
263 | set_bit(HCI_MGMT, &hdev->flags); | 522 | if (test_and_clear_bit(HCI_PI_MGMT_INIT, &hci_pi(sk)->flags)) |
523 | mgmt_init_hdev(hdev); | ||
264 | 524 | ||
265 | memset(&rp, 0, sizeof(rp)); | 525 | memset(&rp, 0, sizeof(rp)); |
266 | 526 | ||
267 | rp.type = hdev->dev_type; | 527 | bacpy(&rp.bdaddr, &hdev->bdaddr); |
268 | 528 | ||
269 | rp.powered = test_bit(HCI_UP, &hdev->flags); | 529 | rp.version = hdev->hci_ver; |
270 | rp.connectable = test_bit(HCI_PSCAN, &hdev->flags); | ||
271 | rp.discoverable = test_bit(HCI_ISCAN, &hdev->flags); | ||
272 | rp.pairable = test_bit(HCI_PSCAN, &hdev->flags); | ||
273 | 530 | ||
274 | if (test_bit(HCI_AUTH, &hdev->flags)) | 531 | put_unaligned_le16(hdev->manufacturer, &rp.manufacturer); |
275 | rp.sec_mode = 3; | 532 | |
276 | else if (hdev->ssp_mode > 0) | 533 | rp.supported_settings = cpu_to_le32(get_supported_settings(hdev)); |
277 | rp.sec_mode = 4; | 534 | rp.current_settings = cpu_to_le32(get_current_settings(hdev)); |
278 | else | ||
279 | rp.sec_mode = 2; | ||
280 | 535 | ||
281 | bacpy(&rp.bdaddr, &hdev->bdaddr); | ||
282 | memcpy(rp.features, hdev->features, 8); | ||
283 | memcpy(rp.dev_class, hdev->dev_class, 3); | 536 | memcpy(rp.dev_class, hdev->dev_class, 3); |
284 | put_unaligned_le16(hdev->manufacturer, &rp.manufacturer); | ||
285 | rp.hci_ver = hdev->hci_ver; | ||
286 | put_unaligned_le16(hdev->hci_rev, &rp.hci_rev); | ||
287 | 537 | ||
288 | memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name)); | 538 | memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name)); |
289 | 539 | ||
290 | hci_dev_unlock_bh(hdev); | 540 | hci_dev_unlock(hdev); |
291 | hci_dev_put(hdev); | 541 | hci_dev_put(hdev); |
292 | 542 | ||
293 | return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp)); | 543 | return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp)); |
@@ -366,13 +616,11 @@ static void mgmt_pending_remove(struct pending_cmd *cmd) | |||
366 | mgmt_pending_free(cmd); | 616 | mgmt_pending_free(cmd); |
367 | } | 617 | } |
368 | 618 | ||
369 | static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val) | 619 | static int send_settings_rsp(struct sock *sk, u16 opcode, struct hci_dev *hdev) |
370 | { | 620 | { |
371 | struct mgmt_mode rp; | 621 | __le32 settings = cpu_to_le32(get_current_settings(hdev)); |
372 | 622 | ||
373 | rp.val = val; | 623 | return cmd_complete(sk, hdev->id, opcode, &settings, sizeof(settings)); |
374 | |||
375 | return cmd_complete(sk, index, opcode, &rp, sizeof(rp)); | ||
376 | } | 624 | } |
377 | 625 | ||
378 | static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | 626 | static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) |
@@ -395,11 +643,11 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
395 | return cmd_status(sk, index, MGMT_OP_SET_POWERED, | 643 | return cmd_status(sk, index, MGMT_OP_SET_POWERED, |
396 | MGMT_STATUS_INVALID_PARAMS); | 644 | MGMT_STATUS_INVALID_PARAMS); |
397 | 645 | ||
398 | hci_dev_lock_bh(hdev); | 646 | hci_dev_lock(hdev); |
399 | 647 | ||
400 | up = test_bit(HCI_UP, &hdev->flags); | 648 | up = test_bit(HCI_UP, &hdev->flags); |
401 | if ((cp->val && up) || (!cp->val && !up)) { | 649 | if ((cp->val && up) || (!cp->val && !up)) { |
402 | err = send_mode_rsp(sk, index, MGMT_OP_SET_POWERED, cp->val); | 650 | err = send_settings_rsp(sk, MGMT_OP_SET_POWERED, hdev); |
403 | goto failed; | 651 | goto failed; |
404 | } | 652 | } |
405 | 653 | ||
@@ -416,14 +664,14 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
416 | } | 664 | } |
417 | 665 | ||
418 | if (cp->val) | 666 | if (cp->val) |
419 | queue_work(hdev->workqueue, &hdev->power_on); | 667 | schedule_work(&hdev->power_on); |
420 | else | 668 | else |
421 | queue_work(hdev->workqueue, &hdev->power_off.work); | 669 | schedule_work(&hdev->power_off.work); |
422 | 670 | ||
423 | err = 0; | 671 | err = 0; |
424 | 672 | ||
425 | failed: | 673 | failed: |
426 | hci_dev_unlock_bh(hdev); | 674 | hci_dev_unlock(hdev); |
427 | hci_dev_put(hdev); | 675 | hci_dev_put(hdev); |
428 | return err; | 676 | return err; |
429 | } | 677 | } |
@@ -450,7 +698,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
450 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, | 698 | return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, |
451 | MGMT_STATUS_INVALID_PARAMS); | 699 | MGMT_STATUS_INVALID_PARAMS); |
452 | 700 | ||
453 | hci_dev_lock_bh(hdev); | 701 | hci_dev_lock(hdev); |
454 | 702 | ||
455 | if (!test_bit(HCI_UP, &hdev->flags)) { | 703 | if (!test_bit(HCI_UP, &hdev->flags)) { |
456 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, | 704 | err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, |
@@ -467,8 +715,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
467 | 715 | ||
468 | if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) && | 716 | if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) && |
469 | test_bit(HCI_PSCAN, &hdev->flags)) { | 717 | test_bit(HCI_PSCAN, &hdev->flags)) { |
470 | err = send_mode_rsp(sk, index, MGMT_OP_SET_DISCOVERABLE, | 718 | err = send_settings_rsp(sk, MGMT_OP_SET_DISCOVERABLE, hdev); |
471 | cp->val); | ||
472 | goto failed; | 719 | goto failed; |
473 | } | 720 | } |
474 | 721 | ||
@@ -493,7 +740,7 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data, | |||
493 | hdev->discov_timeout = get_unaligned_le16(&cp->timeout); | 740 | hdev->discov_timeout = get_unaligned_le16(&cp->timeout); |
494 | 741 | ||
495 | failed: | 742 | failed: |
496 | hci_dev_unlock_bh(hdev); | 743 | hci_dev_unlock(hdev); |
497 | hci_dev_put(hdev); | 744 | hci_dev_put(hdev); |
498 | 745 | ||
499 | return err; | 746 | return err; |
@@ -521,7 +768,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
521 | return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, | 768 | return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, |
522 | MGMT_STATUS_INVALID_PARAMS); | 769 | MGMT_STATUS_INVALID_PARAMS); |
523 | 770 | ||
524 | hci_dev_lock_bh(hdev); | 771 | hci_dev_lock(hdev); |
525 | 772 | ||
526 | if (!test_bit(HCI_UP, &hdev->flags)) { | 773 | if (!test_bit(HCI_UP, &hdev->flags)) { |
527 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, | 774 | err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, |
@@ -537,8 +784,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
537 | } | 784 | } |
538 | 785 | ||
539 | if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) { | 786 | if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) { |
540 | err = send_mode_rsp(sk, index, MGMT_OP_SET_CONNECTABLE, | 787 | err = send_settings_rsp(sk, MGMT_OP_SET_CONNECTABLE, hdev); |
541 | cp->val); | ||
542 | goto failed; | 788 | goto failed; |
543 | } | 789 | } |
544 | 790 | ||
@@ -558,7 +804,7 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data, | |||
558 | mgmt_pending_remove(cmd); | 804 | mgmt_pending_remove(cmd); |
559 | 805 | ||
560 | failed: | 806 | failed: |
561 | hci_dev_unlock_bh(hdev); | 807 | hci_dev_unlock(hdev); |
562 | hci_dev_put(hdev); | 808 | hci_dev_put(hdev); |
563 | 809 | ||
564 | return err; | 810 | return err; |
@@ -596,8 +842,9 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, | |||
596 | static int set_pairable(struct sock *sk, u16 index, unsigned char *data, | 842 | static int set_pairable(struct sock *sk, u16 index, unsigned char *data, |
597 | u16 len) | 843 | u16 len) |
598 | { | 844 | { |
599 | struct mgmt_mode *cp, ev; | 845 | struct mgmt_mode *cp; |
600 | struct hci_dev *hdev; | 846 | struct hci_dev *hdev; |
847 | __le32 ev; | ||
601 | int err; | 848 | int err; |
602 | 849 | ||
603 | cp = (void *) data; | 850 | cp = (void *) data; |
@@ -613,201 +860,28 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data, | |||
613 | return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, | 860 | return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, |
614 | MGMT_STATUS_INVALID_PARAMS); | 861 | MGMT_STATUS_INVALID_PARAMS); |
615 | 862 | ||
616 | hci_dev_lock_bh(hdev); | 863 | hci_dev_lock(hdev); |
617 | 864 | ||
618 | if (cp->val) | 865 | if (cp->val) |
619 | set_bit(HCI_PAIRABLE, &hdev->flags); | 866 | set_bit(HCI_PAIRABLE, &hdev->flags); |
620 | else | 867 | else |
621 | clear_bit(HCI_PAIRABLE, &hdev->flags); | 868 | clear_bit(HCI_PAIRABLE, &hdev->flags); |
622 | 869 | ||
623 | err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, index, cp->val); | 870 | err = send_settings_rsp(sk, MGMT_OP_SET_PAIRABLE, hdev); |
624 | if (err < 0) | 871 | if (err < 0) |
625 | goto failed; | 872 | goto failed; |
626 | 873 | ||
627 | ev.val = cp->val; | 874 | ev = cpu_to_le32(get_current_settings(hdev)); |
628 | 875 | ||
629 | err = mgmt_event(MGMT_EV_PAIRABLE, hdev, &ev, sizeof(ev), sk); | 876 | err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), sk); |
630 | 877 | ||
631 | failed: | 878 | failed: |
632 | hci_dev_unlock_bh(hdev); | 879 | hci_dev_unlock(hdev); |
633 | hci_dev_put(hdev); | 880 | hci_dev_put(hdev); |
634 | 881 | ||
635 | return err; | 882 | return err; |
636 | } | 883 | } |
637 | 884 | ||
638 | #define EIR_FLAGS 0x01 /* flags */ | ||
639 | #define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ | ||
640 | #define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ | ||
641 | #define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ | ||
642 | #define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ | ||
643 | #define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ | ||
644 | #define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ | ||
645 | #define EIR_NAME_SHORT 0x08 /* shortened local name */ | ||
646 | #define EIR_NAME_COMPLETE 0x09 /* complete local name */ | ||
647 | #define EIR_TX_POWER 0x0A /* transmit power level */ | ||
648 | #define EIR_DEVICE_ID 0x10 /* device ID */ | ||
649 | |||
650 | #define PNP_INFO_SVCLASS_ID 0x1200 | ||
651 | |||
652 | static u8 bluetooth_base_uuid[] = { | ||
653 | 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, | ||
654 | 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
655 | }; | ||
656 | |||
657 | static u16 get_uuid16(u8 *uuid128) | ||
658 | { | ||
659 | u32 val; | ||
660 | int i; | ||
661 | |||
662 | for (i = 0; i < 12; i++) { | ||
663 | if (bluetooth_base_uuid[i] != uuid128[i]) | ||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | memcpy(&val, &uuid128[12], 4); | ||
668 | |||
669 | val = le32_to_cpu(val); | ||
670 | if (val > 0xffff) | ||
671 | return 0; | ||
672 | |||
673 | return (u16) val; | ||
674 | } | ||
675 | |||
676 | static void create_eir(struct hci_dev *hdev, u8 *data) | ||
677 | { | ||
678 | u8 *ptr = data; | ||
679 | u16 eir_len = 0; | ||
680 | u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; | ||
681 | int i, truncated = 0; | ||
682 | struct bt_uuid *uuid; | ||
683 | size_t name_len; | ||
684 | |||
685 | name_len = strlen(hdev->dev_name); | ||
686 | |||
687 | if (name_len > 0) { | ||
688 | /* EIR Data type */ | ||
689 | if (name_len > 48) { | ||
690 | name_len = 48; | ||
691 | ptr[1] = EIR_NAME_SHORT; | ||
692 | } else | ||
693 | ptr[1] = EIR_NAME_COMPLETE; | ||
694 | |||
695 | /* EIR Data length */ | ||
696 | ptr[0] = name_len + 1; | ||
697 | |||
698 | memcpy(ptr + 2, hdev->dev_name, name_len); | ||
699 | |||
700 | eir_len += (name_len + 2); | ||
701 | ptr += (name_len + 2); | ||
702 | } | ||
703 | |||
704 | memset(uuid16_list, 0, sizeof(uuid16_list)); | ||
705 | |||
706 | /* Group all UUID16 types */ | ||
707 | list_for_each_entry(uuid, &hdev->uuids, list) { | ||
708 | u16 uuid16; | ||
709 | |||
710 | uuid16 = get_uuid16(uuid->uuid); | ||
711 | if (uuid16 == 0) | ||
712 | return; | ||
713 | |||
714 | if (uuid16 < 0x1100) | ||
715 | continue; | ||
716 | |||
717 | if (uuid16 == PNP_INFO_SVCLASS_ID) | ||
718 | continue; | ||
719 | |||
720 | /* Stop if not enough space to put next UUID */ | ||
721 | if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) { | ||
722 | truncated = 1; | ||
723 | break; | ||
724 | } | ||
725 | |||
726 | /* Check for duplicates */ | ||
727 | for (i = 0; uuid16_list[i] != 0; i++) | ||
728 | if (uuid16_list[i] == uuid16) | ||
729 | break; | ||
730 | |||
731 | if (uuid16_list[i] == 0) { | ||
732 | uuid16_list[i] = uuid16; | ||
733 | eir_len += sizeof(u16); | ||
734 | } | ||
735 | } | ||
736 | |||
737 | if (uuid16_list[0] != 0) { | ||
738 | u8 *length = ptr; | ||
739 | |||
740 | /* EIR Data type */ | ||
741 | ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; | ||
742 | |||
743 | ptr += 2; | ||
744 | eir_len += 2; | ||
745 | |||
746 | for (i = 0; uuid16_list[i] != 0; i++) { | ||
747 | *ptr++ = (uuid16_list[i] & 0x00ff); | ||
748 | *ptr++ = (uuid16_list[i] & 0xff00) >> 8; | ||
749 | } | ||
750 | |||
751 | /* EIR Data length */ | ||
752 | *length = (i * sizeof(u16)) + 1; | ||
753 | } | ||
754 | } | ||
755 | |||
756 | static int update_eir(struct hci_dev *hdev) | ||
757 | { | ||
758 | struct hci_cp_write_eir cp; | ||
759 | |||
760 | if (!(hdev->features[6] & LMP_EXT_INQ)) | ||
761 | return 0; | ||
762 | |||
763 | if (hdev->ssp_mode == 0) | ||
764 | return 0; | ||
765 | |||
766 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
767 | return 0; | ||
768 | |||
769 | memset(&cp, 0, sizeof(cp)); | ||
770 | |||
771 | create_eir(hdev, cp.data); | ||
772 | |||
773 | if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0) | ||
774 | return 0; | ||
775 | |||
776 | memcpy(hdev->eir, cp.data, sizeof(cp.data)); | ||
777 | |||
778 | return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); | ||
779 | } | ||
780 | |||
781 | static u8 get_service_classes(struct hci_dev *hdev) | ||
782 | { | ||
783 | struct bt_uuid *uuid; | ||
784 | u8 val = 0; | ||
785 | |||
786 | list_for_each_entry(uuid, &hdev->uuids, list) | ||
787 | val |= uuid->svc_hint; | ||
788 | |||
789 | return val; | ||
790 | } | ||
791 | |||
792 | static int update_class(struct hci_dev *hdev) | ||
793 | { | ||
794 | u8 cod[3]; | ||
795 | |||
796 | BT_DBG("%s", hdev->name); | ||
797 | |||
798 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
799 | return 0; | ||
800 | |||
801 | cod[0] = hdev->minor_class; | ||
802 | cod[1] = hdev->major_class; | ||
803 | cod[2] = get_service_classes(hdev); | ||
804 | |||
805 | if (memcmp(cod, hdev->dev_class, 3) == 0) | ||
806 | return 0; | ||
807 | |||
808 | return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | ||
809 | } | ||
810 | |||
811 | static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | 885 | static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) |
812 | { | 886 | { |
813 | struct mgmt_cp_add_uuid *cp; | 887 | struct mgmt_cp_add_uuid *cp; |
@@ -828,7 +902,7 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
828 | return cmd_status(sk, index, MGMT_OP_ADD_UUID, | 902 | return cmd_status(sk, index, MGMT_OP_ADD_UUID, |
829 | MGMT_STATUS_INVALID_PARAMS); | 903 | MGMT_STATUS_INVALID_PARAMS); |
830 | 904 | ||
831 | hci_dev_lock_bh(hdev); | 905 | hci_dev_lock(hdev); |
832 | 906 | ||
833 | uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); | 907 | uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); |
834 | if (!uuid) { | 908 | if (!uuid) { |
@@ -852,7 +926,7 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
852 | err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0); | 926 | err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0); |
853 | 927 | ||
854 | failed: | 928 | failed: |
855 | hci_dev_unlock_bh(hdev); | 929 | hci_dev_unlock(hdev); |
856 | hci_dev_put(hdev); | 930 | hci_dev_put(hdev); |
857 | 931 | ||
858 | return err; | 932 | return err; |
@@ -879,7 +953,7 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
879 | return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, | 953 | return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, |
880 | MGMT_STATUS_INVALID_PARAMS); | 954 | MGMT_STATUS_INVALID_PARAMS); |
881 | 955 | ||
882 | hci_dev_lock_bh(hdev); | 956 | hci_dev_lock(hdev); |
883 | 957 | ||
884 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { | 958 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { |
885 | err = hci_uuids_clear(hdev); | 959 | err = hci_uuids_clear(hdev); |
@@ -915,7 +989,7 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
915 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0); | 989 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0); |
916 | 990 | ||
917 | unlock: | 991 | unlock: |
918 | hci_dev_unlock_bh(hdev); | 992 | hci_dev_unlock(hdev); |
919 | hci_dev_put(hdev); | 993 | hci_dev_put(hdev); |
920 | 994 | ||
921 | return err; | 995 | return err; |
@@ -941,62 +1015,24 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data, | |||
941 | return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, | 1015 | return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, |
942 | MGMT_STATUS_INVALID_PARAMS); | 1016 | MGMT_STATUS_INVALID_PARAMS); |
943 | 1017 | ||
944 | hci_dev_lock_bh(hdev); | 1018 | hci_dev_lock(hdev); |
945 | 1019 | ||
946 | hdev->major_class = cp->major; | 1020 | hdev->major_class = cp->major; |
947 | hdev->minor_class = cp->minor; | 1021 | hdev->minor_class = cp->minor; |
948 | 1022 | ||
1023 | if (test_and_clear_bit(HCI_SERVICE_CACHE, &hdev->flags)) { | ||
1024 | hci_dev_unlock(hdev); | ||
1025 | cancel_delayed_work_sync(&hdev->service_cache); | ||
1026 | hci_dev_lock(hdev); | ||
1027 | update_eir(hdev); | ||
1028 | } | ||
1029 | |||
949 | err = update_class(hdev); | 1030 | err = update_class(hdev); |
950 | 1031 | ||
951 | if (err == 0) | 1032 | if (err == 0) |
952 | err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0); | 1033 | err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0); |
953 | 1034 | ||
954 | hci_dev_unlock_bh(hdev); | 1035 | hci_dev_unlock(hdev); |
955 | hci_dev_put(hdev); | ||
956 | |||
957 | return err; | ||
958 | } | ||
959 | |||
960 | static int set_service_cache(struct sock *sk, u16 index, unsigned char *data, | ||
961 | u16 len) | ||
962 | { | ||
963 | struct hci_dev *hdev; | ||
964 | struct mgmt_cp_set_service_cache *cp; | ||
965 | int err; | ||
966 | |||
967 | cp = (void *) data; | ||
968 | |||
969 | if (len != sizeof(*cp)) | ||
970 | return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, | ||
971 | MGMT_STATUS_INVALID_PARAMS); | ||
972 | |||
973 | hdev = hci_dev_get(index); | ||
974 | if (!hdev) | ||
975 | return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, | ||
976 | MGMT_STATUS_INVALID_PARAMS); | ||
977 | |||
978 | hci_dev_lock_bh(hdev); | ||
979 | |||
980 | BT_DBG("hci%u enable %d", index, cp->enable); | ||
981 | |||
982 | if (cp->enable) { | ||
983 | set_bit(HCI_SERVICE_CACHE, &hdev->flags); | ||
984 | err = 0; | ||
985 | } else { | ||
986 | clear_bit(HCI_SERVICE_CACHE, &hdev->flags); | ||
987 | err = update_class(hdev); | ||
988 | if (err == 0) | ||
989 | err = update_eir(hdev); | ||
990 | } | ||
991 | |||
992 | if (err == 0) | ||
993 | err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL, | ||
994 | 0); | ||
995 | else | ||
996 | cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, -err); | ||
997 | |||
998 | |||
999 | hci_dev_unlock_bh(hdev); | ||
1000 | hci_dev_put(hdev); | 1036 | hci_dev_put(hdev); |
1001 | 1037 | ||
1002 | return err; | 1038 | return err; |
@@ -1035,7 +1071,7 @@ static int load_link_keys(struct sock *sk, u16 index, unsigned char *data, | |||
1035 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, | 1071 | BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys, |
1036 | key_count); | 1072 | key_count); |
1037 | 1073 | ||
1038 | hci_dev_lock_bh(hdev); | 1074 | hci_dev_lock(hdev); |
1039 | 1075 | ||
1040 | hci_link_keys_clear(hdev); | 1076 | hci_link_keys_clear(hdev); |
1041 | 1077 | ||
@@ -1055,7 +1091,7 @@ static int load_link_keys(struct sock *sk, u16 index, unsigned char *data, | |||
1055 | 1091 | ||
1056 | cmd_complete(sk, index, MGMT_OP_LOAD_LINK_KEYS, NULL, 0); | 1092 | cmd_complete(sk, index, MGMT_OP_LOAD_LINK_KEYS, NULL, 0); |
1057 | 1093 | ||
1058 | hci_dev_unlock_bh(hdev); | 1094 | hci_dev_unlock(hdev); |
1059 | hci_dev_put(hdev); | 1095 | hci_dev_put(hdev); |
1060 | 1096 | ||
1061 | return 0; | 1097 | return 0; |
@@ -1083,7 +1119,7 @@ static int remove_keys(struct sock *sk, u16 index, unsigned char *data, | |||
1083 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, | 1119 | return cmd_status(sk, index, MGMT_OP_REMOVE_KEYS, |
1084 | MGMT_STATUS_INVALID_PARAMS); | 1120 | MGMT_STATUS_INVALID_PARAMS); |
1085 | 1121 | ||
1086 | hci_dev_lock_bh(hdev); | 1122 | hci_dev_lock(hdev); |
1087 | 1123 | ||
1088 | memset(&rp, 0, sizeof(rp)); | 1124 | memset(&rp, 0, sizeof(rp)); |
1089 | bacpy(&rp.bdaddr, &cp->bdaddr); | 1125 | bacpy(&rp.bdaddr, &cp->bdaddr); |
@@ -1124,7 +1160,7 @@ unlock: | |||
1124 | if (err < 0) | 1160 | if (err < 0) |
1125 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_KEYS, &rp, | 1161 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_KEYS, &rp, |
1126 | sizeof(rp)); | 1162 | sizeof(rp)); |
1127 | hci_dev_unlock_bh(hdev); | 1163 | hci_dev_unlock(hdev); |
1128 | hci_dev_put(hdev); | 1164 | hci_dev_put(hdev); |
1129 | 1165 | ||
1130 | return err; | 1166 | return err; |
@@ -1152,7 +1188,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1152 | return cmd_status(sk, index, MGMT_OP_DISCONNECT, | 1188 | return cmd_status(sk, index, MGMT_OP_DISCONNECT, |
1153 | MGMT_STATUS_INVALID_PARAMS); | 1189 | MGMT_STATUS_INVALID_PARAMS); |
1154 | 1190 | ||
1155 | hci_dev_lock_bh(hdev); | 1191 | hci_dev_lock(hdev); |
1156 | 1192 | ||
1157 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1193 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1158 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, | 1194 | err = cmd_status(sk, index, MGMT_OP_DISCONNECT, |
@@ -1190,7 +1226,7 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1190 | mgmt_pending_remove(cmd); | 1226 | mgmt_pending_remove(cmd); |
1191 | 1227 | ||
1192 | failed: | 1228 | failed: |
1193 | hci_dev_unlock_bh(hdev); | 1229 | hci_dev_unlock(hdev); |
1194 | hci_dev_put(hdev); | 1230 | hci_dev_put(hdev); |
1195 | 1231 | ||
1196 | return err; | 1232 | return err; |
@@ -1232,7 +1268,7 @@ static int get_connections(struct sock *sk, u16 index) | |||
1232 | return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, | 1268 | return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, |
1233 | MGMT_STATUS_INVALID_PARAMS); | 1269 | MGMT_STATUS_INVALID_PARAMS); |
1234 | 1270 | ||
1235 | hci_dev_lock_bh(hdev); | 1271 | hci_dev_lock(hdev); |
1236 | 1272 | ||
1237 | count = 0; | 1273 | count = 0; |
1238 | list_for_each(p, &hdev->conn_hash.list) { | 1274 | list_for_each(p, &hdev->conn_hash.list) { |
@@ -1264,7 +1300,7 @@ static int get_connections(struct sock *sk, u16 index) | |||
1264 | 1300 | ||
1265 | unlock: | 1301 | unlock: |
1266 | kfree(rp); | 1302 | kfree(rp); |
1267 | hci_dev_unlock_bh(hdev); | 1303 | hci_dev_unlock(hdev); |
1268 | hci_dev_put(hdev); | 1304 | hci_dev_put(hdev); |
1269 | return err; | 1305 | return err; |
1270 | } | 1306 | } |
@@ -1312,7 +1348,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1312 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | 1348 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, |
1313 | MGMT_STATUS_INVALID_PARAMS); | 1349 | MGMT_STATUS_INVALID_PARAMS); |
1314 | 1350 | ||
1315 | hci_dev_lock_bh(hdev); | 1351 | hci_dev_lock(hdev); |
1316 | 1352 | ||
1317 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1353 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1318 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, | 1354 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, |
@@ -1355,7 +1391,7 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1355 | mgmt_pending_remove(cmd); | 1391 | mgmt_pending_remove(cmd); |
1356 | 1392 | ||
1357 | failed: | 1393 | failed: |
1358 | hci_dev_unlock_bh(hdev); | 1394 | hci_dev_unlock(hdev); |
1359 | hci_dev_put(hdev); | 1395 | hci_dev_put(hdev); |
1360 | 1396 | ||
1361 | return err; | 1397 | return err; |
@@ -1381,7 +1417,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1381 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, | 1417 | return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, |
1382 | MGMT_STATUS_INVALID_PARAMS); | 1418 | MGMT_STATUS_INVALID_PARAMS); |
1383 | 1419 | ||
1384 | hci_dev_lock_bh(hdev); | 1420 | hci_dev_lock(hdev); |
1385 | 1421 | ||
1386 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1422 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1387 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, | 1423 | err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, |
@@ -1392,7 +1428,7 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data, | |||
1392 | err = send_pin_code_neg_reply(sk, index, hdev, cp); | 1428 | err = send_pin_code_neg_reply(sk, index, hdev, cp); |
1393 | 1429 | ||
1394 | failed: | 1430 | failed: |
1395 | hci_dev_unlock_bh(hdev); | 1431 | hci_dev_unlock(hdev); |
1396 | hci_dev_put(hdev); | 1432 | hci_dev_put(hdev); |
1397 | 1433 | ||
1398 | return err; | 1434 | return err; |
@@ -1417,14 +1453,14 @@ static int set_io_capability(struct sock *sk, u16 index, unsigned char *data, | |||
1417 | return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, | 1453 | return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, |
1418 | MGMT_STATUS_INVALID_PARAMS); | 1454 | MGMT_STATUS_INVALID_PARAMS); |
1419 | 1455 | ||
1420 | hci_dev_lock_bh(hdev); | 1456 | hci_dev_lock(hdev); |
1421 | 1457 | ||
1422 | hdev->io_capability = cp->io_capability; | 1458 | hdev->io_capability = cp->io_capability; |
1423 | 1459 | ||
1424 | BT_DBG("%s IO capability set to 0x%02x", hdev->name, | 1460 | BT_DBG("%s IO capability set to 0x%02x", hdev->name, |
1425 | hdev->io_capability); | 1461 | hdev->io_capability); |
1426 | 1462 | ||
1427 | hci_dev_unlock_bh(hdev); | 1463 | hci_dev_unlock(hdev); |
1428 | hci_dev_put(hdev); | 1464 | hci_dev_put(hdev); |
1429 | 1465 | ||
1430 | return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0); | 1466 | return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0); |
@@ -1505,7 +1541,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1505 | return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, | 1541 | return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, |
1506 | MGMT_STATUS_INVALID_PARAMS); | 1542 | MGMT_STATUS_INVALID_PARAMS); |
1507 | 1543 | ||
1508 | hci_dev_lock_bh(hdev); | 1544 | hci_dev_lock(hdev); |
1509 | 1545 | ||
1510 | sec_level = BT_SECURITY_MEDIUM; | 1546 | sec_level = BT_SECURITY_MEDIUM; |
1511 | if (cp->io_cap == 0x03) | 1547 | if (cp->io_cap == 0x03) |
@@ -1562,7 +1598,7 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len) | |||
1562 | err = 0; | 1598 | err = 0; |
1563 | 1599 | ||
1564 | unlock: | 1600 | unlock: |
1565 | hci_dev_unlock_bh(hdev); | 1601 | hci_dev_unlock(hdev); |
1566 | hci_dev_put(hdev); | 1602 | hci_dev_put(hdev); |
1567 | 1603 | ||
1568 | return err; | 1604 | return err; |
@@ -1581,7 +1617,7 @@ static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr, | |||
1581 | return cmd_status(sk, index, mgmt_op, | 1617 | return cmd_status(sk, index, mgmt_op, |
1582 | MGMT_STATUS_INVALID_PARAMS); | 1618 | MGMT_STATUS_INVALID_PARAMS); |
1583 | 1619 | ||
1584 | hci_dev_lock_bh(hdev); | 1620 | hci_dev_lock(hdev); |
1585 | 1621 | ||
1586 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1622 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1587 | err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_NOT_POWERED); | 1623 | err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_NOT_POWERED); |
@@ -1607,8 +1643,15 @@ static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr, | |||
1607 | } | 1643 | } |
1608 | 1644 | ||
1609 | /* Continue with pairing via SMP */ | 1645 | /* Continue with pairing via SMP */ |
1646 | err = smp_user_confirm_reply(conn, mgmt_op, passkey); | ||
1647 | |||
1648 | if (!err) | ||
1649 | err = cmd_status(sk, index, mgmt_op, | ||
1650 | MGMT_STATUS_SUCCESS); | ||
1651 | else | ||
1652 | err = cmd_status(sk, index, mgmt_op, | ||
1653 | MGMT_STATUS_FAILED); | ||
1610 | 1654 | ||
1611 | err = cmd_status(sk, index, mgmt_op, MGMT_STATUS_SUCCESS); | ||
1612 | goto done; | 1655 | goto done; |
1613 | } | 1656 | } |
1614 | 1657 | ||
@@ -1632,7 +1675,7 @@ static int user_pairing_resp(struct sock *sk, u16 index, bdaddr_t *bdaddr, | |||
1632 | mgmt_pending_remove(cmd); | 1675 | mgmt_pending_remove(cmd); |
1633 | 1676 | ||
1634 | done: | 1677 | done: |
1635 | hci_dev_unlock_bh(hdev); | 1678 | hci_dev_unlock(hdev); |
1636 | hci_dev_put(hdev); | 1679 | hci_dev_put(hdev); |
1637 | 1680 | ||
1638 | return err; | 1681 | return err; |
@@ -1656,7 +1699,7 @@ static int user_confirm_reply(struct sock *sk, u16 index, void *data, u16 len) | |||
1656 | static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data, | 1699 | static int user_confirm_neg_reply(struct sock *sk, u16 index, void *data, |
1657 | u16 len) | 1700 | u16 len) |
1658 | { | 1701 | { |
1659 | struct mgmt_cp_user_confirm_reply *cp = (void *) data; | 1702 | struct mgmt_cp_user_confirm_neg_reply *cp = data; |
1660 | 1703 | ||
1661 | BT_DBG(""); | 1704 | BT_DBG(""); |
1662 | 1705 | ||
@@ -1720,7 +1763,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, | |||
1720 | return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, | 1763 | return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, |
1721 | MGMT_STATUS_INVALID_PARAMS); | 1764 | MGMT_STATUS_INVALID_PARAMS); |
1722 | 1765 | ||
1723 | hci_dev_lock_bh(hdev); | 1766 | hci_dev_lock(hdev); |
1724 | 1767 | ||
1725 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len); | 1768 | cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, hdev, data, len); |
1726 | if (!cmd) { | 1769 | if (!cmd) { |
@@ -1735,7 +1778,7 @@ static int set_local_name(struct sock *sk, u16 index, unsigned char *data, | |||
1735 | mgmt_pending_remove(cmd); | 1778 | mgmt_pending_remove(cmd); |
1736 | 1779 | ||
1737 | failed: | 1780 | failed: |
1738 | hci_dev_unlock_bh(hdev); | 1781 | hci_dev_unlock(hdev); |
1739 | hci_dev_put(hdev); | 1782 | hci_dev_put(hdev); |
1740 | 1783 | ||
1741 | return err; | 1784 | return err; |
@@ -1754,7 +1797,7 @@ static int read_local_oob_data(struct sock *sk, u16 index) | |||
1754 | return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 1797 | return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, |
1755 | MGMT_STATUS_INVALID_PARAMS); | 1798 | MGMT_STATUS_INVALID_PARAMS); |
1756 | 1799 | ||
1757 | hci_dev_lock_bh(hdev); | 1800 | hci_dev_lock(hdev); |
1758 | 1801 | ||
1759 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1802 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1760 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, | 1803 | err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, |
@@ -1785,7 +1828,7 @@ static int read_local_oob_data(struct sock *sk, u16 index) | |||
1785 | mgmt_pending_remove(cmd); | 1828 | mgmt_pending_remove(cmd); |
1786 | 1829 | ||
1787 | unlock: | 1830 | unlock: |
1788 | hci_dev_unlock_bh(hdev); | 1831 | hci_dev_unlock(hdev); |
1789 | hci_dev_put(hdev); | 1832 | hci_dev_put(hdev); |
1790 | 1833 | ||
1791 | return err; | 1834 | return err; |
@@ -1809,7 +1852,7 @@ static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data, | |||
1809 | return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, | 1852 | return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, |
1810 | MGMT_STATUS_INVALID_PARAMS); | 1853 | MGMT_STATUS_INVALID_PARAMS); |
1811 | 1854 | ||
1812 | hci_dev_lock_bh(hdev); | 1855 | hci_dev_lock(hdev); |
1813 | 1856 | ||
1814 | err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash, | 1857 | err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash, |
1815 | cp->randomizer); | 1858 | cp->randomizer); |
@@ -1820,7 +1863,7 @@ static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data, | |||
1820 | err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL, | 1863 | err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL, |
1821 | 0); | 1864 | 0); |
1822 | 1865 | ||
1823 | hci_dev_unlock_bh(hdev); | 1866 | hci_dev_unlock(hdev); |
1824 | hci_dev_put(hdev); | 1867 | hci_dev_put(hdev); |
1825 | 1868 | ||
1826 | return err; | 1869 | return err; |
@@ -1844,7 +1887,7 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, | |||
1844 | return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, | 1887 | return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, |
1845 | MGMT_STATUS_INVALID_PARAMS); | 1888 | MGMT_STATUS_INVALID_PARAMS); |
1846 | 1889 | ||
1847 | hci_dev_lock_bh(hdev); | 1890 | hci_dev_lock(hdev); |
1848 | 1891 | ||
1849 | err = hci_remove_remote_oob_data(hdev, &cp->bdaddr); | 1892 | err = hci_remove_remote_oob_data(hdev, &cp->bdaddr); |
1850 | if (err < 0) | 1893 | if (err < 0) |
@@ -1854,7 +1897,7 @@ static int remove_remote_oob_data(struct sock *sk, u16 index, | |||
1854 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, | 1897 | err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA, |
1855 | NULL, 0); | 1898 | NULL, 0); |
1856 | 1899 | ||
1857 | hci_dev_unlock_bh(hdev); | 1900 | hci_dev_unlock(hdev); |
1858 | hci_dev_put(hdev); | 1901 | hci_dev_put(hdev); |
1859 | 1902 | ||
1860 | return err; | 1903 | return err; |
@@ -1879,7 +1922,7 @@ static int start_discovery(struct sock *sk, u16 index, | |||
1879 | return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, | 1922 | return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, |
1880 | MGMT_STATUS_INVALID_PARAMS); | 1923 | MGMT_STATUS_INVALID_PARAMS); |
1881 | 1924 | ||
1882 | hci_dev_lock_bh(hdev); | 1925 | hci_dev_lock(hdev); |
1883 | 1926 | ||
1884 | if (!test_bit(HCI_UP, &hdev->flags)) { | 1927 | if (!test_bit(HCI_UP, &hdev->flags)) { |
1885 | err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY, | 1928 | err = cmd_status(sk, index, MGMT_OP_START_DISCOVERY, |
@@ -1898,7 +1941,7 @@ static int start_discovery(struct sock *sk, u16 index, | |||
1898 | mgmt_pending_remove(cmd); | 1941 | mgmt_pending_remove(cmd); |
1899 | 1942 | ||
1900 | failed: | 1943 | failed: |
1901 | hci_dev_unlock_bh(hdev); | 1944 | hci_dev_unlock(hdev); |
1902 | hci_dev_put(hdev); | 1945 | hci_dev_put(hdev); |
1903 | 1946 | ||
1904 | return err; | 1947 | return err; |
@@ -1917,7 +1960,7 @@ static int stop_discovery(struct sock *sk, u16 index) | |||
1917 | return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, | 1960 | return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, |
1918 | MGMT_STATUS_INVALID_PARAMS); | 1961 | MGMT_STATUS_INVALID_PARAMS); |
1919 | 1962 | ||
1920 | hci_dev_lock_bh(hdev); | 1963 | hci_dev_lock(hdev); |
1921 | 1964 | ||
1922 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0); | 1965 | cmd = mgmt_pending_add(sk, MGMT_OP_STOP_DISCOVERY, hdev, NULL, 0); |
1923 | if (!cmd) { | 1966 | if (!cmd) { |
@@ -1930,7 +1973,7 @@ static int stop_discovery(struct sock *sk, u16 index) | |||
1930 | mgmt_pending_remove(cmd); | 1973 | mgmt_pending_remove(cmd); |
1931 | 1974 | ||
1932 | failed: | 1975 | failed: |
1933 | hci_dev_unlock_bh(hdev); | 1976 | hci_dev_unlock(hdev); |
1934 | hci_dev_put(hdev); | 1977 | hci_dev_put(hdev); |
1935 | 1978 | ||
1936 | return err; | 1979 | return err; |
@@ -1954,7 +1997,7 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data, | |||
1954 | return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, | 1997 | return cmd_status(sk, index, MGMT_OP_BLOCK_DEVICE, |
1955 | MGMT_STATUS_INVALID_PARAMS); | 1998 | MGMT_STATUS_INVALID_PARAMS); |
1956 | 1999 | ||
1957 | hci_dev_lock_bh(hdev); | 2000 | hci_dev_lock(hdev); |
1958 | 2001 | ||
1959 | err = hci_blacklist_add(hdev, &cp->bdaddr); | 2002 | err = hci_blacklist_add(hdev, &cp->bdaddr); |
1960 | if (err < 0) | 2003 | if (err < 0) |
@@ -1964,7 +2007,7 @@ static int block_device(struct sock *sk, u16 index, unsigned char *data, | |||
1964 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, | 2007 | err = cmd_complete(sk, index, MGMT_OP_BLOCK_DEVICE, |
1965 | NULL, 0); | 2008 | NULL, 0); |
1966 | 2009 | ||
1967 | hci_dev_unlock_bh(hdev); | 2010 | hci_dev_unlock(hdev); |
1968 | hci_dev_put(hdev); | 2011 | hci_dev_put(hdev); |
1969 | 2012 | ||
1970 | return err; | 2013 | return err; |
@@ -1988,7 +2031,7 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1988 | return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, | 2031 | return cmd_status(sk, index, MGMT_OP_UNBLOCK_DEVICE, |
1989 | MGMT_STATUS_INVALID_PARAMS); | 2032 | MGMT_STATUS_INVALID_PARAMS); |
1990 | 2033 | ||
1991 | hci_dev_lock_bh(hdev); | 2034 | hci_dev_lock(hdev); |
1992 | 2035 | ||
1993 | err = hci_blacklist_del(hdev, &cp->bdaddr); | 2036 | err = hci_blacklist_del(hdev, &cp->bdaddr); |
1994 | 2037 | ||
@@ -1999,7 +2042,7 @@ static int unblock_device(struct sock *sk, u16 index, unsigned char *data, | |||
1999 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, | 2042 | err = cmd_complete(sk, index, MGMT_OP_UNBLOCK_DEVICE, |
2000 | NULL, 0); | 2043 | NULL, 0); |
2001 | 2044 | ||
2002 | hci_dev_unlock_bh(hdev); | 2045 | hci_dev_unlock(hdev); |
2003 | hci_dev_put(hdev); | 2046 | hci_dev_put(hdev); |
2004 | 2047 | ||
2005 | return err; | 2048 | return err; |
@@ -2009,7 +2052,7 @@ static int set_fast_connectable(struct sock *sk, u16 index, | |||
2009 | unsigned char *data, u16 len) | 2052 | unsigned char *data, u16 len) |
2010 | { | 2053 | { |
2011 | struct hci_dev *hdev; | 2054 | struct hci_dev *hdev; |
2012 | struct mgmt_cp_set_fast_connectable *cp = (void *) data; | 2055 | struct mgmt_mode *cp = (void *) data; |
2013 | struct hci_cp_write_page_scan_activity acp; | 2056 | struct hci_cp_write_page_scan_activity acp; |
2014 | u8 type; | 2057 | u8 type; |
2015 | int err; | 2058 | int err; |
@@ -2027,7 +2070,7 @@ static int set_fast_connectable(struct sock *sk, u16 index, | |||
2027 | 2070 | ||
2028 | hci_dev_lock(hdev); | 2071 | hci_dev_lock(hdev); |
2029 | 2072 | ||
2030 | if (cp->enable) { | 2073 | if (cp->val) { |
2031 | type = PAGE_SCAN_TYPE_INTERLACED; | 2074 | type = PAGE_SCAN_TYPE_INTERLACED; |
2032 | acp.interval = 0x0024; /* 22.5 msec page scan interval */ | 2075 | acp.interval = 0x0024; /* 22.5 msec page scan interval */ |
2033 | } else { | 2076 | } else { |
@@ -2111,6 +2154,10 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
2111 | case MGMT_OP_SET_CONNECTABLE: | 2154 | case MGMT_OP_SET_CONNECTABLE: |
2112 | err = set_connectable(sk, index, buf + sizeof(*hdr), len); | 2155 | err = set_connectable(sk, index, buf + sizeof(*hdr), len); |
2113 | break; | 2156 | break; |
2157 | case MGMT_OP_SET_FAST_CONNECTABLE: | ||
2158 | err = set_fast_connectable(sk, index, buf + sizeof(*hdr), | ||
2159 | len); | ||
2160 | break; | ||
2114 | case MGMT_OP_SET_PAIRABLE: | 2161 | case MGMT_OP_SET_PAIRABLE: |
2115 | err = set_pairable(sk, index, buf + sizeof(*hdr), len); | 2162 | err = set_pairable(sk, index, buf + sizeof(*hdr), len); |
2116 | break; | 2163 | break; |
@@ -2123,9 +2170,6 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
2123 | case MGMT_OP_SET_DEV_CLASS: | 2170 | case MGMT_OP_SET_DEV_CLASS: |
2124 | err = set_dev_class(sk, index, buf + sizeof(*hdr), len); | 2171 | err = set_dev_class(sk, index, buf + sizeof(*hdr), len); |
2125 | break; | 2172 | break; |
2126 | case MGMT_OP_SET_SERVICE_CACHE: | ||
2127 | err = set_service_cache(sk, index, buf + sizeof(*hdr), len); | ||
2128 | break; | ||
2129 | case MGMT_OP_LOAD_LINK_KEYS: | 2173 | case MGMT_OP_LOAD_LINK_KEYS: |
2130 | err = load_link_keys(sk, index, buf + sizeof(*hdr), len); | 2174 | err = load_link_keys(sk, index, buf + sizeof(*hdr), len); |
2131 | break; | 2175 | break; |
@@ -2189,10 +2233,6 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
2189 | case MGMT_OP_UNBLOCK_DEVICE: | 2233 | case MGMT_OP_UNBLOCK_DEVICE: |
2190 | err = unblock_device(sk, index, buf + sizeof(*hdr), len); | 2234 | err = unblock_device(sk, index, buf + sizeof(*hdr), len); |
2191 | break; | 2235 | break; |
2192 | case MGMT_OP_SET_FAST_CONNECTABLE: | ||
2193 | err = set_fast_connectable(sk, index, buf + sizeof(*hdr), | ||
2194 | len); | ||
2195 | break; | ||
2196 | default: | 2236 | default: |
2197 | BT_DBG("Unknown op %u", opcode); | 2237 | BT_DBG("Unknown op %u", opcode); |
2198 | err = cmd_status(sk, index, opcode, | 2238 | err = cmd_status(sk, index, opcode, |
@@ -2235,17 +2275,14 @@ int mgmt_index_removed(struct hci_dev *hdev) | |||
2235 | struct cmd_lookup { | 2275 | struct cmd_lookup { |
2236 | u8 val; | 2276 | u8 val; |
2237 | struct sock *sk; | 2277 | struct sock *sk; |
2278 | struct hci_dev *hdev; | ||
2238 | }; | 2279 | }; |
2239 | 2280 | ||
2240 | static void mode_rsp(struct pending_cmd *cmd, void *data) | 2281 | static void settings_rsp(struct pending_cmd *cmd, void *data) |
2241 | { | 2282 | { |
2242 | struct mgmt_mode *cp = cmd->param; | ||
2243 | struct cmd_lookup *match = data; | 2283 | struct cmd_lookup *match = data; |
2244 | 2284 | ||
2245 | if (cp->val != match->val) | 2285 | send_settings_rsp(cmd->sk, cmd->opcode, match->hdev); |
2246 | return; | ||
2247 | |||
2248 | send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val); | ||
2249 | 2286 | ||
2250 | list_del(&cmd->list); | 2287 | list_del(&cmd->list); |
2251 | 2288 | ||
@@ -2259,20 +2296,21 @@ static void mode_rsp(struct pending_cmd *cmd, void *data) | |||
2259 | 2296 | ||
2260 | int mgmt_powered(struct hci_dev *hdev, u8 powered) | 2297 | int mgmt_powered(struct hci_dev *hdev, u8 powered) |
2261 | { | 2298 | { |
2262 | struct mgmt_mode ev; | 2299 | struct cmd_lookup match = { powered, NULL, hdev }; |
2263 | struct cmd_lookup match = { powered, NULL }; | 2300 | __le32 ev; |
2264 | int ret; | 2301 | int ret; |
2265 | 2302 | ||
2266 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, mode_rsp, &match); | 2303 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); |
2267 | 2304 | ||
2268 | if (!powered) { | 2305 | if (!powered) { |
2269 | u8 status = ENETDOWN; | 2306 | u8 status = ENETDOWN; |
2270 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); | 2307 | mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); |
2271 | } | 2308 | } |
2272 | 2309 | ||
2273 | ev.val = powered; | 2310 | ev = cpu_to_le32(get_current_settings(hdev)); |
2274 | 2311 | ||
2275 | ret = mgmt_event(MGMT_EV_POWERED, hdev, &ev, sizeof(ev), match.sk); | 2312 | ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), |
2313 | match.sk); | ||
2276 | 2314 | ||
2277 | if (match.sk) | 2315 | if (match.sk) |
2278 | sock_put(match.sk); | 2316 | sock_put(match.sk); |
@@ -2282,17 +2320,16 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) | |||
2282 | 2320 | ||
2283 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) | 2321 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) |
2284 | { | 2322 | { |
2285 | struct mgmt_mode ev; | 2323 | struct cmd_lookup match = { discoverable, NULL, hdev }; |
2286 | struct cmd_lookup match = { discoverable, NULL }; | 2324 | __le32 ev; |
2287 | int ret; | 2325 | int ret; |
2288 | 2326 | ||
2289 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, mode_rsp, &match); | 2327 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, hdev, settings_rsp, &match); |
2290 | 2328 | ||
2291 | ev.val = discoverable; | 2329 | ev = cpu_to_le32(get_current_settings(hdev)); |
2292 | 2330 | ||
2293 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, hdev, &ev, sizeof(ev), | 2331 | ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), |
2294 | match.sk); | 2332 | match.sk); |
2295 | |||
2296 | if (match.sk) | 2333 | if (match.sk) |
2297 | sock_put(match.sk); | 2334 | sock_put(match.sk); |
2298 | 2335 | ||
@@ -2301,15 +2338,16 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) | |||
2301 | 2338 | ||
2302 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable) | 2339 | int mgmt_connectable(struct hci_dev *hdev, u8 connectable) |
2303 | { | 2340 | { |
2304 | struct mgmt_mode ev; | 2341 | __le32 ev; |
2305 | struct cmd_lookup match = { connectable, NULL }; | 2342 | struct cmd_lookup match = { connectable, NULL, hdev }; |
2306 | int ret; | 2343 | int ret; |
2307 | 2344 | ||
2308 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, mode_rsp, &match); | 2345 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, hdev, settings_rsp, |
2346 | &match); | ||
2309 | 2347 | ||
2310 | ev.val = connectable; | 2348 | ev = cpu_to_le32(get_current_settings(hdev)); |
2311 | 2349 | ||
2312 | ret = mgmt_event(MGMT_EV_CONNECTABLE, hdev, &ev, sizeof(ev), match.sk); | 2350 | ret = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk); |
2313 | 2351 | ||
2314 | if (match.sk) | 2352 | if (match.sk) |
2315 | sock_put(match.sk); | 2353 | sock_put(match.sk); |
diff --git a/net/bluetooth/rfcomm/Kconfig b/net/bluetooth/rfcomm/Kconfig index 405a0e61e7dc..22e718b554e4 100644 --- a/net/bluetooth/rfcomm/Kconfig +++ b/net/bluetooth/rfcomm/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config BT_RFCOMM | 1 | config BT_RFCOMM |
2 | tristate "RFCOMM protocol support" | 2 | tristate "RFCOMM protocol support" |
3 | depends on BT && BT_L2CAP | 3 | depends on BT |
4 | help | 4 | help |
5 | RFCOMM provides connection oriented stream transport. RFCOMM | 5 | RFCOMM provides connection oriented stream transport. RFCOMM |
6 | support is required for Dialup Networking, OBEX and other Bluetooth | 6 | support is required for Dialup Networking, OBEX and other Bluetooth |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index eac849b935a1..501649bf5596 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -65,8 +65,7 @@ static DEFINE_MUTEX(rfcomm_mutex); | |||
65 | 65 | ||
66 | static LIST_HEAD(session_list); | 66 | static LIST_HEAD(session_list); |
67 | 67 | ||
68 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len, | 68 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len); |
69 | u32 priority); | ||
70 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci); | 69 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci); |
71 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci); | 70 | static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci); |
72 | static int rfcomm_queue_disc(struct rfcomm_dlc *d); | 71 | static int rfcomm_queue_disc(struct rfcomm_dlc *d); |
@@ -748,32 +747,23 @@ void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *d | |||
748 | } | 747 | } |
749 | 748 | ||
750 | /* ---- RFCOMM frame sending ---- */ | 749 | /* ---- RFCOMM frame sending ---- */ |
751 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len, | 750 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len) |
752 | u32 priority) | ||
753 | { | 751 | { |
754 | struct socket *sock = s->sock; | ||
755 | struct sock *sk = sock->sk; | ||
756 | struct kvec iv = { data, len }; | 752 | struct kvec iv = { data, len }; |
757 | struct msghdr msg; | 753 | struct msghdr msg; |
758 | 754 | ||
759 | BT_DBG("session %p len %d priority %u", s, len, priority); | 755 | BT_DBG("session %p len %d", s, len); |
760 | |||
761 | if (sk->sk_priority != priority) { | ||
762 | lock_sock(sk); | ||
763 | sk->sk_priority = priority; | ||
764 | release_sock(sk); | ||
765 | } | ||
766 | 756 | ||
767 | memset(&msg, 0, sizeof(msg)); | 757 | memset(&msg, 0, sizeof(msg)); |
768 | 758 | ||
769 | return kernel_sendmsg(sock, &msg, &iv, 1, len); | 759 | return kernel_sendmsg(s->sock, &msg, &iv, 1, len); |
770 | } | 760 | } |
771 | 761 | ||
772 | static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd) | 762 | static int rfcomm_send_cmd(struct rfcomm_session *s, struct rfcomm_cmd *cmd) |
773 | { | 763 | { |
774 | BT_DBG("%p cmd %u", s, cmd->ctrl); | 764 | BT_DBG("%p cmd %u", s, cmd->ctrl); |
775 | 765 | ||
776 | return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd), HCI_PRIO_MAX); | 766 | return rfcomm_send_frame(s, (void *) cmd, sizeof(*cmd)); |
777 | } | 767 | } |
778 | 768 | ||
779 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) | 769 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci) |
@@ -829,8 +819,6 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) | |||
829 | if (!skb) | 819 | if (!skb) |
830 | return -ENOMEM; | 820 | return -ENOMEM; |
831 | 821 | ||
832 | skb->priority = HCI_PRIO_MAX; | ||
833 | |||
834 | cmd = (void *) __skb_put(skb, sizeof(*cmd)); | 822 | cmd = (void *) __skb_put(skb, sizeof(*cmd)); |
835 | cmd->addr = d->addr; | 823 | cmd->addr = d->addr; |
836 | cmd->ctrl = __ctrl(RFCOMM_DISC, 1); | 824 | cmd->ctrl = __ctrl(RFCOMM_DISC, 1); |
@@ -878,7 +866,7 @@ static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type) | |||
878 | 866 | ||
879 | *ptr = __fcs(buf); ptr++; | 867 | *ptr = __fcs(buf); ptr++; |
880 | 868 | ||
881 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); | 869 | return rfcomm_send_frame(s, buf, ptr - buf); |
882 | } | 870 | } |
883 | 871 | ||
884 | static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d) | 872 | static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d) |
@@ -920,7 +908,7 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d | |||
920 | 908 | ||
921 | *ptr = __fcs(buf); ptr++; | 909 | *ptr = __fcs(buf); ptr++; |
922 | 910 | ||
923 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); | 911 | return rfcomm_send_frame(s, buf, ptr - buf); |
924 | } | 912 | } |
925 | 913 | ||
926 | int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, | 914 | int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, |
@@ -958,7 +946,7 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, | |||
958 | 946 | ||
959 | *ptr = __fcs(buf); ptr++; | 947 | *ptr = __fcs(buf); ptr++; |
960 | 948 | ||
961 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); | 949 | return rfcomm_send_frame(s, buf, ptr - buf); |
962 | } | 950 | } |
963 | 951 | ||
964 | static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) | 952 | static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) |
@@ -985,7 +973,7 @@ static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status) | |||
985 | 973 | ||
986 | *ptr = __fcs(buf); ptr++; | 974 | *ptr = __fcs(buf); ptr++; |
987 | 975 | ||
988 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); | 976 | return rfcomm_send_frame(s, buf, ptr - buf); |
989 | } | 977 | } |
990 | 978 | ||
991 | static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig) | 979 | static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig) |
@@ -1012,7 +1000,7 @@ static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig | |||
1012 | 1000 | ||
1013 | *ptr = __fcs(buf); ptr++; | 1001 | *ptr = __fcs(buf); ptr++; |
1014 | 1002 | ||
1015 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); | 1003 | return rfcomm_send_frame(s, buf, ptr - buf); |
1016 | } | 1004 | } |
1017 | 1005 | ||
1018 | static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) | 1006 | static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) |
@@ -1034,7 +1022,7 @@ static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr) | |||
1034 | 1022 | ||
1035 | *ptr = __fcs(buf); ptr++; | 1023 | *ptr = __fcs(buf); ptr++; |
1036 | 1024 | ||
1037 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); | 1025 | return rfcomm_send_frame(s, buf, ptr - buf); |
1038 | } | 1026 | } |
1039 | 1027 | ||
1040 | static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) | 1028 | static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) |
@@ -1056,7 +1044,7 @@ static int rfcomm_send_fcon(struct rfcomm_session *s, int cr) | |||
1056 | 1044 | ||
1057 | *ptr = __fcs(buf); ptr++; | 1045 | *ptr = __fcs(buf); ptr++; |
1058 | 1046 | ||
1059 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); | 1047 | return rfcomm_send_frame(s, buf, ptr - buf); |
1060 | } | 1048 | } |
1061 | 1049 | ||
1062 | static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len) | 1050 | static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len) |
@@ -1107,7 +1095,7 @@ static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits) | |||
1107 | 1095 | ||
1108 | *ptr = __fcs(buf); ptr++; | 1096 | *ptr = __fcs(buf); ptr++; |
1109 | 1097 | ||
1110 | return rfcomm_send_frame(s, buf, ptr - buf, HCI_PRIO_MAX); | 1098 | return rfcomm_send_frame(s, buf, ptr - buf); |
1111 | } | 1099 | } |
1112 | 1100 | ||
1113 | static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) | 1101 | static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) |
@@ -1786,8 +1774,7 @@ static inline int rfcomm_process_tx(struct rfcomm_dlc *d) | |||
1786 | return skb_queue_len(&d->tx_queue); | 1774 | return skb_queue_len(&d->tx_queue); |
1787 | 1775 | ||
1788 | while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) { | 1776 | while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) { |
1789 | err = rfcomm_send_frame(d->session, skb->data, skb->len, | 1777 | err = rfcomm_send_frame(d->session, skb->data, skb->len); |
1790 | skb->priority); | ||
1791 | if (err < 0) { | 1778 | if (err < 0) { |
1792 | skb_queue_head(&d->tx_queue, skb); | 1779 | skb_queue_head(&d->tx_queue, skb); |
1793 | break; | 1780 | break; |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index a0d11b873831..5dc2f2126fac 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -189,7 +189,7 @@ static int sco_connect(struct sock *sk) | |||
189 | if (!hdev) | 189 | if (!hdev) |
190 | return -EHOSTUNREACH; | 190 | return -EHOSTUNREACH; |
191 | 191 | ||
192 | hci_dev_lock_bh(hdev); | 192 | hci_dev_lock(hdev); |
193 | 193 | ||
194 | if (lmp_esco_capable(hdev) && !disable_esco) | 194 | if (lmp_esco_capable(hdev) && !disable_esco) |
195 | type = ESCO_LINK; | 195 | type = ESCO_LINK; |
@@ -225,7 +225,7 @@ static int sco_connect(struct sock *sk) | |||
225 | } | 225 | } |
226 | 226 | ||
227 | done: | 227 | done: |
228 | hci_dev_unlock_bh(hdev); | 228 | hci_dev_unlock(hdev); |
229 | hci_dev_put(hdev); | 229 | hci_dev_put(hdev); |
230 | return err; | 230 | return err; |
231 | } | 231 | } |
@@ -893,15 +893,12 @@ done: | |||
893 | } | 893 | } |
894 | 894 | ||
895 | /* ----- SCO interface with lower layer (HCI) ----- */ | 895 | /* ----- SCO interface with lower layer (HCI) ----- */ |
896 | static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | 896 | int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) |
897 | { | 897 | { |
898 | register struct sock *sk; | 898 | register struct sock *sk; |
899 | struct hlist_node *node; | 899 | struct hlist_node *node; |
900 | int lm = 0; | 900 | int lm = 0; |
901 | 901 | ||
902 | if (type != SCO_LINK && type != ESCO_LINK) | ||
903 | return -EINVAL; | ||
904 | |||
905 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 902 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
906 | 903 | ||
907 | /* Find listening sockets */ | 904 | /* Find listening sockets */ |
@@ -921,13 +918,9 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | |||
921 | return lm; | 918 | return lm; |
922 | } | 919 | } |
923 | 920 | ||
924 | static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) | 921 | int sco_connect_cfm(struct hci_conn *hcon, __u8 status) |
925 | { | 922 | { |
926 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 923 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
927 | |||
928 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | ||
929 | return -EINVAL; | ||
930 | |||
931 | if (!status) { | 924 | if (!status) { |
932 | struct sco_conn *conn; | 925 | struct sco_conn *conn; |
933 | 926 | ||
@@ -940,19 +933,15 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) | |||
940 | return 0; | 933 | return 0; |
941 | } | 934 | } |
942 | 935 | ||
943 | static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) | 936 | int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) |
944 | { | 937 | { |
945 | BT_DBG("hcon %p reason %d", hcon, reason); | 938 | BT_DBG("hcon %p reason %d", hcon, reason); |
946 | 939 | ||
947 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | ||
948 | return -EINVAL; | ||
949 | |||
950 | sco_conn_del(hcon, bt_to_errno(reason)); | 940 | sco_conn_del(hcon, bt_to_errno(reason)); |
951 | |||
952 | return 0; | 941 | return 0; |
953 | } | 942 | } |
954 | 943 | ||
955 | static int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) | 944 | int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) |
956 | { | 945 | { |
957 | struct sco_conn *conn = hcon->sco_data; | 946 | struct sco_conn *conn = hcon->sco_data; |
958 | 947 | ||
@@ -1028,15 +1017,6 @@ static const struct net_proto_family sco_sock_family_ops = { | |||
1028 | .create = sco_sock_create, | 1017 | .create = sco_sock_create, |
1029 | }; | 1018 | }; |
1030 | 1019 | ||
1031 | static struct hci_proto sco_hci_proto = { | ||
1032 | .name = "SCO", | ||
1033 | .id = HCI_PROTO_SCO, | ||
1034 | .connect_ind = sco_connect_ind, | ||
1035 | .connect_cfm = sco_connect_cfm, | ||
1036 | .disconn_cfm = sco_disconn_cfm, | ||
1037 | .recv_scodata = sco_recv_scodata | ||
1038 | }; | ||
1039 | |||
1040 | int __init sco_init(void) | 1020 | int __init sco_init(void) |
1041 | { | 1021 | { |
1042 | int err; | 1022 | int err; |
@@ -1051,13 +1031,6 @@ int __init sco_init(void) | |||
1051 | goto error; | 1031 | goto error; |
1052 | } | 1032 | } |
1053 | 1033 | ||
1054 | err = hci_register_proto(&sco_hci_proto); | ||
1055 | if (err < 0) { | ||
1056 | BT_ERR("SCO protocol registration failed"); | ||
1057 | bt_sock_unregister(BTPROTO_SCO); | ||
1058 | goto error; | ||
1059 | } | ||
1060 | |||
1061 | if (bt_debugfs) { | 1034 | if (bt_debugfs) { |
1062 | sco_debugfs = debugfs_create_file("sco", 0444, | 1035 | sco_debugfs = debugfs_create_file("sco", 0444, |
1063 | bt_debugfs, NULL, &sco_debugfs_fops); | 1036 | bt_debugfs, NULL, &sco_debugfs_fops); |
@@ -1081,9 +1054,6 @@ void __exit sco_exit(void) | |||
1081 | if (bt_sock_unregister(BTPROTO_SCO) < 0) | 1054 | if (bt_sock_unregister(BTPROTO_SCO) < 0) |
1082 | BT_ERR("SCO socket unregistration failed"); | 1055 | BT_ERR("SCO socket unregistration failed"); |
1083 | 1056 | ||
1084 | if (hci_unregister_proto(&sco_hci_proto) < 0) | ||
1085 | BT_ERR("SCO protocol unregistration failed"); | ||
1086 | |||
1087 | proto_unregister(&sco_proto); | 1057 | proto_unregister(&sco_proto); |
1088 | } | 1058 | } |
1089 | 1059 | ||
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 0b96737d0ad3..32c47de30344 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <net/bluetooth/bluetooth.h> | 23 | #include <net/bluetooth/bluetooth.h> |
24 | #include <net/bluetooth/hci_core.h> | 24 | #include <net/bluetooth/hci_core.h> |
25 | #include <net/bluetooth/l2cap.h> | 25 | #include <net/bluetooth/l2cap.h> |
26 | #include <net/bluetooth/mgmt.h> | ||
26 | #include <net/bluetooth/smp.h> | 27 | #include <net/bluetooth/smp.h> |
27 | #include <linux/crypto.h> | 28 | #include <linux/crypto.h> |
28 | #include <linux/scatterlist.h> | 29 | #include <linux/scatterlist.h> |
@@ -184,28 +185,50 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | |||
184 | skb->priority = HCI_PRIO_MAX; | 185 | skb->priority = HCI_PRIO_MAX; |
185 | hci_send_acl(conn->hchan, skb, 0); | 186 | hci_send_acl(conn->hchan, skb, 0); |
186 | 187 | ||
187 | mod_timer(&conn->security_timer, jiffies + | 188 | cancel_delayed_work_sync(&conn->security_timer); |
189 | schedule_delayed_work(&conn->security_timer, | ||
188 | msecs_to_jiffies(SMP_TIMEOUT)); | 190 | msecs_to_jiffies(SMP_TIMEOUT)); |
189 | } | 191 | } |
190 | 192 | ||
193 | static __u8 authreq_to_seclevel(__u8 authreq) | ||
194 | { | ||
195 | if (authreq & SMP_AUTH_MITM) | ||
196 | return BT_SECURITY_HIGH; | ||
197 | else | ||
198 | return BT_SECURITY_MEDIUM; | ||
199 | } | ||
200 | |||
201 | static __u8 seclevel_to_authreq(__u8 sec_level) | ||
202 | { | ||
203 | switch (sec_level) { | ||
204 | case BT_SECURITY_HIGH: | ||
205 | return SMP_AUTH_MITM | SMP_AUTH_BONDING; | ||
206 | case BT_SECURITY_MEDIUM: | ||
207 | return SMP_AUTH_BONDING; | ||
208 | default: | ||
209 | return SMP_AUTH_NONE; | ||
210 | } | ||
211 | } | ||
212 | |||
191 | static void build_pairing_cmd(struct l2cap_conn *conn, | 213 | static void build_pairing_cmd(struct l2cap_conn *conn, |
192 | struct smp_cmd_pairing *req, | 214 | struct smp_cmd_pairing *req, |
193 | struct smp_cmd_pairing *rsp, | 215 | struct smp_cmd_pairing *rsp, |
194 | __u8 authreq) | 216 | __u8 authreq) |
195 | { | 217 | { |
196 | u8 dist_keys; | 218 | u8 dist_keys = 0; |
197 | 219 | ||
198 | dist_keys = 0; | ||
199 | if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) { | 220 | if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->flags)) { |
200 | dist_keys = SMP_DIST_ENC_KEY; | 221 | dist_keys = SMP_DIST_ENC_KEY; |
201 | authreq |= SMP_AUTH_BONDING; | 222 | authreq |= SMP_AUTH_BONDING; |
223 | } else { | ||
224 | authreq &= ~SMP_AUTH_BONDING; | ||
202 | } | 225 | } |
203 | 226 | ||
204 | if (rsp == NULL) { | 227 | if (rsp == NULL) { |
205 | req->io_capability = conn->hcon->io_capability; | 228 | req->io_capability = conn->hcon->io_capability; |
206 | req->oob_flag = SMP_OOB_NOT_PRESENT; | 229 | req->oob_flag = SMP_OOB_NOT_PRESENT; |
207 | req->max_key_size = SMP_MAX_ENC_KEY_SIZE; | 230 | req->max_key_size = SMP_MAX_ENC_KEY_SIZE; |
208 | req->init_key_dist = dist_keys; | 231 | req->init_key_dist = 0; |
209 | req->resp_key_dist = dist_keys; | 232 | req->resp_key_dist = dist_keys; |
210 | req->auth_req = authreq; | 233 | req->auth_req = authreq; |
211 | return; | 234 | return; |
@@ -214,7 +237,7 @@ static void build_pairing_cmd(struct l2cap_conn *conn, | |||
214 | rsp->io_capability = conn->hcon->io_capability; | 237 | rsp->io_capability = conn->hcon->io_capability; |
215 | rsp->oob_flag = SMP_OOB_NOT_PRESENT; | 238 | rsp->oob_flag = SMP_OOB_NOT_PRESENT; |
216 | rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; | 239 | rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE; |
217 | rsp->init_key_dist = req->init_key_dist & dist_keys; | 240 | rsp->init_key_dist = 0; |
218 | rsp->resp_key_dist = req->resp_key_dist & dist_keys; | 241 | rsp->resp_key_dist = req->resp_key_dist & dist_keys; |
219 | rsp->auth_req = authreq; | 242 | rsp->auth_req = authreq; |
220 | } | 243 | } |
@@ -240,10 +263,99 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) | |||
240 | 263 | ||
241 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->pend); | 264 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->pend); |
242 | mgmt_auth_failed(conn->hcon->hdev, conn->dst, reason); | 265 | mgmt_auth_failed(conn->hcon->hdev, conn->dst, reason); |
243 | del_timer(&conn->security_timer); | 266 | cancel_delayed_work_sync(&conn->security_timer); |
244 | smp_chan_destroy(conn); | 267 | smp_chan_destroy(conn); |
245 | } | 268 | } |
246 | 269 | ||
270 | #define JUST_WORKS 0x00 | ||
271 | #define JUST_CFM 0x01 | ||
272 | #define REQ_PASSKEY 0x02 | ||
273 | #define CFM_PASSKEY 0x03 | ||
274 | #define REQ_OOB 0x04 | ||
275 | #define OVERLAP 0xFF | ||
276 | |||
277 | static const u8 gen_method[5][5] = { | ||
278 | { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, | ||
279 | { JUST_WORKS, JUST_CFM, REQ_PASSKEY, JUST_WORKS, REQ_PASSKEY }, | ||
280 | { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, CFM_PASSKEY }, | ||
281 | { JUST_WORKS, JUST_CFM, JUST_WORKS, JUST_WORKS, JUST_CFM }, | ||
282 | { CFM_PASSKEY, CFM_PASSKEY, REQ_PASSKEY, JUST_WORKS, OVERLAP }, | ||
283 | }; | ||
284 | |||
285 | static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, | ||
286 | u8 local_io, u8 remote_io) | ||
287 | { | ||
288 | struct hci_conn *hcon = conn->hcon; | ||
289 | struct smp_chan *smp = conn->smp_chan; | ||
290 | u8 method; | ||
291 | u32 passkey = 0; | ||
292 | int ret = 0; | ||
293 | |||
294 | /* Initialize key for JUST WORKS */ | ||
295 | memset(smp->tk, 0, sizeof(smp->tk)); | ||
296 | clear_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | ||
297 | |||
298 | BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io); | ||
299 | |||
300 | /* If neither side wants MITM, use JUST WORKS */ | ||
301 | /* If either side has unknown io_caps, use JUST WORKS */ | ||
302 | /* Otherwise, look up method from the table */ | ||
303 | if (!(auth & SMP_AUTH_MITM) || | ||
304 | local_io > SMP_IO_KEYBOARD_DISPLAY || | ||
305 | remote_io > SMP_IO_KEYBOARD_DISPLAY) | ||
306 | method = JUST_WORKS; | ||
307 | else | ||
308 | method = gen_method[local_io][remote_io]; | ||
309 | |||
310 | /* If not bonding, don't ask user to confirm a Zero TK */ | ||
311 | if (!(auth & SMP_AUTH_BONDING) && method == JUST_CFM) | ||
312 | method = JUST_WORKS; | ||
313 | |||
314 | /* If Just Works, Continue with Zero TK */ | ||
315 | if (method == JUST_WORKS) { | ||
316 | set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | /* Not Just Works/Confirm results in MITM Authentication */ | ||
321 | if (method != JUST_CFM) | ||
322 | set_bit(SMP_FLAG_MITM_AUTH, &smp->smp_flags); | ||
323 | |||
324 | /* If both devices have Keyoard-Display I/O, the master | ||
325 | * Confirms and the slave Enters the passkey. | ||
326 | */ | ||
327 | if (method == OVERLAP) { | ||
328 | if (hcon->link_mode & HCI_LM_MASTER) | ||
329 | method = CFM_PASSKEY; | ||
330 | else | ||
331 | method = REQ_PASSKEY; | ||
332 | } | ||
333 | |||
334 | /* Generate random passkey. Not valid until confirmed. */ | ||
335 | if (method == CFM_PASSKEY) { | ||
336 | u8 key[16]; | ||
337 | |||
338 | memset(key, 0, sizeof(key)); | ||
339 | get_random_bytes(&passkey, sizeof(passkey)); | ||
340 | passkey %= 1000000; | ||
341 | put_unaligned_le32(passkey, key); | ||
342 | swap128(key, smp->tk); | ||
343 | BT_DBG("PassKey: %d", passkey); | ||
344 | } | ||
345 | |||
346 | hci_dev_lock(hcon->hdev); | ||
347 | |||
348 | if (method == REQ_PASSKEY) | ||
349 | ret = mgmt_user_passkey_request(hcon->hdev, conn->dst); | ||
350 | else | ||
351 | ret = mgmt_user_confirm_request(hcon->hdev, conn->dst, | ||
352 | cpu_to_le32(passkey), 0); | ||
353 | |||
354 | hci_dev_unlock(hcon->hdev); | ||
355 | |||
356 | return ret; | ||
357 | } | ||
358 | |||
247 | static void confirm_work(struct work_struct *work) | 359 | static void confirm_work(struct work_struct *work) |
248 | { | 360 | { |
249 | struct smp_chan *smp = container_of(work, struct smp_chan, confirm); | 361 | struct smp_chan *smp = container_of(work, struct smp_chan, confirm); |
@@ -276,6 +388,8 @@ static void confirm_work(struct work_struct *work) | |||
276 | goto error; | 388 | goto error; |
277 | } | 389 | } |
278 | 390 | ||
391 | clear_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); | ||
392 | |||
279 | swap128(res, cp.confirm_val); | 393 | swap128(res, cp.confirm_val); |
280 | smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); | 394 | smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); |
281 | 395 | ||
@@ -381,6 +495,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | |||
381 | 495 | ||
382 | smp->conn = conn; | 496 | smp->conn = conn; |
383 | conn->smp_chan = smp; | 497 | conn->smp_chan = smp; |
498 | conn->hcon->smp_conn = conn; | ||
384 | 499 | ||
385 | hci_conn_hold(conn->hcon); | 500 | hci_conn_hold(conn->hcon); |
386 | 501 | ||
@@ -398,18 +513,64 @@ void smp_chan_destroy(struct l2cap_conn *conn) | |||
398 | 513 | ||
399 | kfree(smp); | 514 | kfree(smp); |
400 | conn->smp_chan = NULL; | 515 | conn->smp_chan = NULL; |
516 | conn->hcon->smp_conn = NULL; | ||
401 | hci_conn_put(conn->hcon); | 517 | hci_conn_put(conn->hcon); |
402 | } | 518 | } |
403 | 519 | ||
520 | int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | ||
521 | { | ||
522 | struct l2cap_conn *conn = hcon->smp_conn; | ||
523 | struct smp_chan *smp; | ||
524 | u32 value; | ||
525 | u8 key[16]; | ||
526 | |||
527 | BT_DBG(""); | ||
528 | |||
529 | if (!conn) | ||
530 | return -ENOTCONN; | ||
531 | |||
532 | smp = conn->smp_chan; | ||
533 | |||
534 | switch (mgmt_op) { | ||
535 | case MGMT_OP_USER_PASSKEY_REPLY: | ||
536 | value = le32_to_cpu(passkey); | ||
537 | memset(key, 0, sizeof(key)); | ||
538 | BT_DBG("PassKey: %d", value); | ||
539 | put_unaligned_le32(value, key); | ||
540 | swap128(key, smp->tk); | ||
541 | /* Fall Through */ | ||
542 | case MGMT_OP_USER_CONFIRM_REPLY: | ||
543 | set_bit(SMP_FLAG_TK_VALID, &smp->smp_flags); | ||
544 | break; | ||
545 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: | ||
546 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: | ||
547 | smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1); | ||
548 | return 0; | ||
549 | default: | ||
550 | smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1); | ||
551 | return -EOPNOTSUPP; | ||
552 | } | ||
553 | |||
554 | /* If it is our turn to send Pairing Confirm, do so now */ | ||
555 | if (test_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags)) | ||
556 | queue_work(hcon->hdev->workqueue, &smp->confirm); | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
404 | static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | 561 | static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) |
405 | { | 562 | { |
406 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; | 563 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; |
407 | struct smp_chan *smp; | 564 | struct smp_chan *smp; |
408 | u8 key_size; | 565 | u8 key_size; |
566 | u8 auth = SMP_AUTH_NONE; | ||
409 | int ret; | 567 | int ret; |
410 | 568 | ||
411 | BT_DBG("conn %p", conn); | 569 | BT_DBG("conn %p", conn); |
412 | 570 | ||
571 | if (conn->hcon->link_mode & HCI_LM_MASTER) | ||
572 | return SMP_CMD_NOTSUPP; | ||
573 | |||
413 | if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend)) | 574 | if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend)) |
414 | smp = smp_chan_create(conn); | 575 | smp = smp_chan_create(conn); |
415 | 576 | ||
@@ -419,19 +580,16 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
419 | memcpy(&smp->preq[1], req, sizeof(*req)); | 580 | memcpy(&smp->preq[1], req, sizeof(*req)); |
420 | skb_pull(skb, sizeof(*req)); | 581 | skb_pull(skb, sizeof(*req)); |
421 | 582 | ||
422 | if (req->oob_flag) | 583 | /* We didn't start the pairing, so match remote */ |
423 | return SMP_OOB_NOT_AVAIL; | 584 | if (req->auth_req & SMP_AUTH_BONDING) |
585 | auth = req->auth_req; | ||
424 | 586 | ||
425 | /* We didn't start the pairing, so no requirements */ | 587 | build_pairing_cmd(conn, req, &rsp, auth); |
426 | build_pairing_cmd(conn, req, &rsp, SMP_AUTH_NONE); | ||
427 | 588 | ||
428 | key_size = min(req->max_key_size, rsp.max_key_size); | 589 | key_size = min(req->max_key_size, rsp.max_key_size); |
429 | if (check_enc_key_size(conn, key_size)) | 590 | if (check_enc_key_size(conn, key_size)) |
430 | return SMP_ENC_KEY_SIZE; | 591 | return SMP_ENC_KEY_SIZE; |
431 | 592 | ||
432 | /* Just works */ | ||
433 | memset(smp->tk, 0, sizeof(smp->tk)); | ||
434 | |||
435 | ret = smp_rand(smp->prnd); | 593 | ret = smp_rand(smp->prnd); |
436 | if (ret) | 594 | if (ret) |
437 | return SMP_UNSPECIFIED; | 595 | return SMP_UNSPECIFIED; |
@@ -441,6 +599,11 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
441 | 599 | ||
442 | smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); | 600 | smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); |
443 | 601 | ||
602 | /* Request setup of TK */ | ||
603 | ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); | ||
604 | if (ret) | ||
605 | return SMP_UNSPECIFIED; | ||
606 | |||
444 | return 0; | 607 | return 0; |
445 | } | 608 | } |
446 | 609 | ||
@@ -449,11 +612,14 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
449 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; | 612 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; |
450 | struct smp_chan *smp = conn->smp_chan; | 613 | struct smp_chan *smp = conn->smp_chan; |
451 | struct hci_dev *hdev = conn->hcon->hdev; | 614 | struct hci_dev *hdev = conn->hcon->hdev; |
452 | u8 key_size; | 615 | u8 key_size, auth = SMP_AUTH_NONE; |
453 | int ret; | 616 | int ret; |
454 | 617 | ||
455 | BT_DBG("conn %p", conn); | 618 | BT_DBG("conn %p", conn); |
456 | 619 | ||
620 | if (!(conn->hcon->link_mode & HCI_LM_MASTER)) | ||
621 | return SMP_CMD_NOTSUPP; | ||
622 | |||
457 | skb_pull(skb, sizeof(*rsp)); | 623 | skb_pull(skb, sizeof(*rsp)); |
458 | 624 | ||
459 | req = (void *) &smp->preq[1]; | 625 | req = (void *) &smp->preq[1]; |
@@ -462,12 +628,6 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
462 | if (check_enc_key_size(conn, key_size)) | 628 | if (check_enc_key_size(conn, key_size)) |
463 | return SMP_ENC_KEY_SIZE; | 629 | return SMP_ENC_KEY_SIZE; |
464 | 630 | ||
465 | if (rsp->oob_flag) | ||
466 | return SMP_OOB_NOT_AVAIL; | ||
467 | |||
468 | /* Just works */ | ||
469 | memset(smp->tk, 0, sizeof(smp->tk)); | ||
470 | |||
471 | ret = smp_rand(smp->prnd); | 631 | ret = smp_rand(smp->prnd); |
472 | if (ret) | 632 | if (ret) |
473 | return SMP_UNSPECIFIED; | 633 | return SMP_UNSPECIFIED; |
@@ -475,6 +635,22 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
475 | smp->prsp[0] = SMP_CMD_PAIRING_RSP; | 635 | smp->prsp[0] = SMP_CMD_PAIRING_RSP; |
476 | memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); | 636 | memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); |
477 | 637 | ||
638 | if ((req->auth_req & SMP_AUTH_BONDING) && | ||
639 | (rsp->auth_req & SMP_AUTH_BONDING)) | ||
640 | auth = SMP_AUTH_BONDING; | ||
641 | |||
642 | auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; | ||
643 | |||
644 | ret = tk_request(conn, 0, auth, rsp->io_capability, req->io_capability); | ||
645 | if (ret) | ||
646 | return SMP_UNSPECIFIED; | ||
647 | |||
648 | set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); | ||
649 | |||
650 | /* Can't compose response until we have been confirmed */ | ||
651 | if (!test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) | ||
652 | return 0; | ||
653 | |||
478 | queue_work(hdev->workqueue, &smp->confirm); | 654 | queue_work(hdev->workqueue, &smp->confirm); |
479 | 655 | ||
480 | return 0; | 656 | return 0; |
@@ -496,8 +672,10 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | |||
496 | swap128(smp->prnd, random); | 672 | swap128(smp->prnd, random); |
497 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random), | 673 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(random), |
498 | random); | 674 | random); |
499 | } else { | 675 | } else if (test_bit(SMP_FLAG_TK_VALID, &smp->smp_flags)) { |
500 | queue_work(hdev->workqueue, &smp->confirm); | 676 | queue_work(hdev->workqueue, &smp->confirm); |
677 | } else { | ||
678 | set_bit(SMP_FLAG_CFM_PENDING, &smp->smp_flags); | ||
501 | } | 679 | } |
502 | 680 | ||
503 | return 0; | 681 | return 0; |
@@ -550,7 +728,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
550 | 728 | ||
551 | BT_DBG("conn %p", conn); | 729 | BT_DBG("conn %p", conn); |
552 | 730 | ||
553 | hcon->pending_sec_level = BT_SECURITY_MEDIUM; | 731 | hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); |
554 | 732 | ||
555 | if (smp_ltk_encrypt(conn)) | 733 | if (smp_ltk_encrypt(conn)) |
556 | return 0; | 734 | return 0; |
@@ -577,6 +755,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | |||
577 | { | 755 | { |
578 | struct hci_conn *hcon = conn->hcon; | 756 | struct hci_conn *hcon = conn->hcon; |
579 | struct smp_chan *smp = conn->smp_chan; | 757 | struct smp_chan *smp = conn->smp_chan; |
758 | __u8 authreq; | ||
580 | 759 | ||
581 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); | 760 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); |
582 | 761 | ||
@@ -597,18 +776,22 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) | |||
597 | return 0; | 776 | return 0; |
598 | 777 | ||
599 | smp = smp_chan_create(conn); | 778 | smp = smp_chan_create(conn); |
779 | if (!smp) | ||
780 | return 1; | ||
781 | |||
782 | authreq = seclevel_to_authreq(sec_level); | ||
600 | 783 | ||
601 | if (hcon->link_mode & HCI_LM_MASTER) { | 784 | if (hcon->link_mode & HCI_LM_MASTER) { |
602 | struct smp_cmd_pairing cp; | 785 | struct smp_cmd_pairing cp; |
603 | 786 | ||
604 | build_pairing_cmd(conn, &cp, NULL, SMP_AUTH_NONE); | 787 | build_pairing_cmd(conn, &cp, NULL, authreq); |
605 | smp->preq[0] = SMP_CMD_PAIRING_REQ; | 788 | smp->preq[0] = SMP_CMD_PAIRING_REQ; |
606 | memcpy(&smp->preq[1], &cp, sizeof(cp)); | 789 | memcpy(&smp->preq[1], &cp, sizeof(cp)); |
607 | 790 | ||
608 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); | 791 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); |
609 | } else { | 792 | } else { |
610 | struct smp_cmd_security_req cp; | 793 | struct smp_cmd_security_req cp; |
611 | cp.auth_req = SMP_AUTH_NONE; | 794 | cp.auth_req = authreq; |
612 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); | 795 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); |
613 | } | 796 | } |
614 | 797 | ||
@@ -637,7 +820,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | |||
637 | 820 | ||
638 | skb_pull(skb, sizeof(*rp)); | 821 | skb_pull(skb, sizeof(*rp)); |
639 | 822 | ||
640 | hci_add_ltk(conn->hcon->hdev, 1, conn->src, smp->smp_key_size, | 823 | hci_add_ltk(conn->hcon->hdev, 1, conn->dst, smp->smp_key_size, |
641 | rp->ediv, rp->rand, smp->tk); | 824 | rp->ediv, rp->rand, smp->tk); |
642 | 825 | ||
643 | smp_distribute_keys(conn, 1); | 826 | smp_distribute_keys(conn, 1); |
@@ -800,7 +983,7 @@ int smp_distribute_keys(struct l2cap_conn *conn, __u8 force) | |||
800 | 983 | ||
801 | if (conn->hcon->out || force) { | 984 | if (conn->hcon->out || force) { |
802 | clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend); | 985 | clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->pend); |
803 | del_timer(&conn->security_timer); | 986 | cancel_delayed_work_sync(&conn->security_timer); |
804 | smp_chan_destroy(conn); | 987 | smp_chan_destroy(conn); |
805 | } | 988 | } |
806 | 989 | ||
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index e92f98d32746..76be61744198 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -392,6 +392,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | |||
392 | #endif | 392 | #endif |
393 | 393 | ||
394 | spin_lock_bh(&sta->lock); | 394 | spin_lock_bh(&sta->lock); |
395 | sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; | ||
395 | sta->ampdu_mlme.addba_req_num[tid]++; | 396 | sta->ampdu_mlme.addba_req_num[tid]++; |
396 | spin_unlock_bh(&sta->lock); | 397 | spin_unlock_bh(&sta->lock); |
397 | 398 | ||
@@ -492,6 +493,24 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
492 | goto err_unlock_sta; | 493 | goto err_unlock_sta; |
493 | } | 494 | } |
494 | 495 | ||
496 | /* | ||
497 | * if we have tried more than HT_AGG_BURST_RETRIES times we | ||
498 | * will spread our requests in time to avoid stalling connection | ||
499 | * for too long | ||
500 | */ | ||
501 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && | ||
502 | time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + | ||
503 | HT_AGG_RETRIES_PERIOD)) { | ||
504 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
505 | printk(KERN_DEBUG "BA request denied - " | ||
506 | "waiting a grace period after %d failed requests " | ||
507 | "on tid %u\n", | ||
508 | sta->ampdu_mlme.addba_req_num[tid], tid); | ||
509 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
510 | ret = -EBUSY; | ||
511 | goto err_unlock_sta; | ||
512 | } | ||
513 | |||
495 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 514 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
496 | /* check if the TID is not in aggregation flow already */ | 515 | /* check if the TID is not in aggregation flow already */ |
497 | if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { | 516 | if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 66ad9d9af87f..850bb96bd680 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -355,7 +355,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
355 | STATION_INFO_RX_DROP_MISC | | 355 | STATION_INFO_RX_DROP_MISC | |
356 | STATION_INFO_BSS_PARAM | | 356 | STATION_INFO_BSS_PARAM | |
357 | STATION_INFO_CONNECTED_TIME | | 357 | STATION_INFO_CONNECTED_TIME | |
358 | STATION_INFO_STA_FLAGS; | 358 | STATION_INFO_STA_FLAGS | |
359 | STATION_INFO_BEACON_LOSS_COUNT; | ||
359 | 360 | ||
360 | do_posix_clock_monotonic_gettime(&uptime); | 361 | do_posix_clock_monotonic_gettime(&uptime); |
361 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; | 362 | sinfo->connected_time = uptime.tv_sec - sta->last_connected; |
@@ -368,6 +369,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
368 | sinfo->tx_retries = sta->tx_retry_count; | 369 | sinfo->tx_retries = sta->tx_retry_count; |
369 | sinfo->tx_failed = sta->tx_retry_failed; | 370 | sinfo->tx_failed = sta->tx_retry_failed; |
370 | sinfo->rx_dropped_misc = sta->rx_dropped; | 371 | sinfo->rx_dropped_misc = sta->rx_dropped; |
372 | sinfo->beacon_loss_count = sta->beacon_loss_count; | ||
371 | 373 | ||
372 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || | 374 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || |
373 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { | 375 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a984f1f60ddb..57989a046fca 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1381,6 +1381,14 @@ void ieee80211_beacon_connection_loss_work(struct work_struct *work) | |||
1381 | struct ieee80211_sub_if_data *sdata = | 1381 | struct ieee80211_sub_if_data *sdata = |
1382 | container_of(work, struct ieee80211_sub_if_data, | 1382 | container_of(work, struct ieee80211_sub_if_data, |
1383 | u.mgd.beacon_connection_loss_work); | 1383 | u.mgd.beacon_connection_loss_work); |
1384 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
1385 | struct sta_info *sta; | ||
1386 | |||
1387 | if (ifmgd->associated) { | ||
1388 | sta = sta_info_get(sdata, ifmgd->bssid); | ||
1389 | if (sta) | ||
1390 | sta->beacon_loss_count++; | ||
1391 | } | ||
1384 | 1392 | ||
1385 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | 1393 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) |
1386 | __ieee80211_connection_loss(sdata); | 1394 | __ieee80211_connection_loss(sdata); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 2be5b7d69ad7..59f124c58333 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "wpa.h" | 28 | #include "wpa.h" |
29 | #include "tkip.h" | 29 | #include "tkip.h" |
30 | #include "wme.h" | 30 | #include "wme.h" |
31 | #include "rate.h" | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * monitor mode reception | 34 | * monitor mode reception |
@@ -1826,7 +1827,12 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1826 | } | 1827 | } |
1827 | 1828 | ||
1828 | if (xmit_skb) { | 1829 | if (xmit_skb) { |
1829 | /* send to wireless media */ | 1830 | /* |
1831 | * Send to wireless media and increase priority by 256 to | ||
1832 | * keep the received priority instead of reclassifying | ||
1833 | * the frame (see cfg80211_classify8021d). | ||
1834 | */ | ||
1835 | xmit_skb->priority += 256; | ||
1830 | xmit_skb->protocol = htons(ETH_P_802_3); | 1836 | xmit_skb->protocol = htons(ETH_P_802_3); |
1831 | skb_reset_network_header(xmit_skb); | 1837 | skb_reset_network_header(xmit_skb); |
1832 | skb_reset_mac_header(xmit_skb); | 1838 | skb_reset_mac_header(xmit_skb); |
@@ -2233,6 +2239,63 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2233 | return RX_DROP_UNUSABLE; | 2239 | return RX_DROP_UNUSABLE; |
2234 | 2240 | ||
2235 | switch (mgmt->u.action.category) { | 2241 | switch (mgmt->u.action.category) { |
2242 | case WLAN_CATEGORY_HT: | ||
2243 | /* reject HT action frames from stations not supporting HT */ | ||
2244 | if (!rx->sta->sta.ht_cap.ht_supported) | ||
2245 | goto invalid; | ||
2246 | |||
2247 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | ||
2248 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | ||
2249 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | ||
2250 | sdata->vif.type != NL80211_IFTYPE_AP && | ||
2251 | sdata->vif.type != NL80211_IFTYPE_ADHOC) | ||
2252 | break; | ||
2253 | |||
2254 | /* verify action & smps_control are present */ | ||
2255 | if (len < IEEE80211_MIN_ACTION_SIZE + 2) | ||
2256 | goto invalid; | ||
2257 | |||
2258 | switch (mgmt->u.action.u.ht_smps.action) { | ||
2259 | case WLAN_HT_ACTION_SMPS: { | ||
2260 | struct ieee80211_supported_band *sband; | ||
2261 | u8 smps; | ||
2262 | |||
2263 | /* convert to HT capability */ | ||
2264 | switch (mgmt->u.action.u.ht_smps.smps_control) { | ||
2265 | case WLAN_HT_SMPS_CONTROL_DISABLED: | ||
2266 | smps = WLAN_HT_CAP_SM_PS_DISABLED; | ||
2267 | break; | ||
2268 | case WLAN_HT_SMPS_CONTROL_STATIC: | ||
2269 | smps = WLAN_HT_CAP_SM_PS_STATIC; | ||
2270 | break; | ||
2271 | case WLAN_HT_SMPS_CONTROL_DYNAMIC: | ||
2272 | smps = WLAN_HT_CAP_SM_PS_DYNAMIC; | ||
2273 | break; | ||
2274 | default: | ||
2275 | goto invalid; | ||
2276 | } | ||
2277 | smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT; | ||
2278 | |||
2279 | /* if no change do nothing */ | ||
2280 | if ((rx->sta->sta.ht_cap.cap & | ||
2281 | IEEE80211_HT_CAP_SM_PS) == smps) | ||
2282 | goto handled; | ||
2283 | |||
2284 | rx->sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SM_PS; | ||
2285 | rx->sta->sta.ht_cap.cap |= smps; | ||
2286 | |||
2287 | sband = rx->local->hw.wiphy->bands[status->band]; | ||
2288 | |||
2289 | rate_control_rate_update(local, sband, rx->sta, | ||
2290 | IEEE80211_RC_SMPS_CHANGED, | ||
2291 | local->_oper_channel_type); | ||
2292 | goto handled; | ||
2293 | } | ||
2294 | default: | ||
2295 | goto invalid; | ||
2296 | } | ||
2297 | |||
2298 | break; | ||
2236 | case WLAN_CATEGORY_BACK: | 2299 | case WLAN_CATEGORY_BACK: |
2237 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 2300 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
2238 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | 2301 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 2db01e9541e7..f0d3b483dabd 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -822,10 +822,13 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
822 | * until the aggregation stop completes. Refer | 822 | * until the aggregation stop completes. Refer |
823 | * http://thread.gmane.org/gmane.linux.kernel.wireless.general/81936 | 823 | * http://thread.gmane.org/gmane.linux.kernel.wireless.general/81936 |
824 | */ | 824 | */ |
825 | |||
826 | mutex_lock(&sta->ampdu_mlme.mtx); | ||
827 | |||
825 | for (i = 0; i < STA_TID_NUM; i++) { | 828 | for (i = 0; i < STA_TID_NUM; i++) { |
826 | if (!sta->ampdu_mlme.tid_tx[i]) | 829 | tid_tx = rcu_dereference_protected_tid_tx(sta, i); |
830 | if (!tid_tx) | ||
827 | continue; | 831 | continue; |
828 | tid_tx = sta->ampdu_mlme.tid_tx[i]; | ||
829 | if (skb_queue_len(&tid_tx->pending)) { | 832 | if (skb_queue_len(&tid_tx->pending)) { |
830 | #ifdef CONFIG_MAC80211_HT_DEBUG | 833 | #ifdef CONFIG_MAC80211_HT_DEBUG |
831 | wiphy_debug(local->hw.wiphy, "TX A-MPDU purging %d " | 834 | wiphy_debug(local->hw.wiphy, "TX A-MPDU purging %d " |
@@ -837,6 +840,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
837 | kfree_rcu(tid_tx, rcu_head); | 840 | kfree_rcu(tid_tx, rcu_head); |
838 | } | 841 | } |
839 | 842 | ||
843 | mutex_unlock(&sta->ampdu_mlme.mtx); | ||
844 | |||
840 | sta_info_free(local, sta); | 845 | sta_info_free(local, sta); |
841 | 846 | ||
842 | return 0; | 847 | return 0; |
@@ -941,6 +946,9 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
941 | 946 | ||
942 | mutex_lock(&local->sta_mtx); | 947 | mutex_lock(&local->sta_mtx); |
943 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) | 948 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) |
949 | if (sdata != sta->sdata) | ||
950 | continue; | ||
951 | |||
944 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 952 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
945 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 953 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
946 | printk(KERN_DEBUG "%s: expiring inactive STA %pM\n", | 954 | printk(KERN_DEBUG "%s: expiring inactive STA %pM\n", |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 15b3bb7d8629..6f77f12dc3fc 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -83,7 +83,9 @@ enum ieee80211_sta_state { | |||
83 | 83 | ||
84 | #define STA_TID_NUM 16 | 84 | #define STA_TID_NUM 16 |
85 | #define ADDBA_RESP_INTERVAL HZ | 85 | #define ADDBA_RESP_INTERVAL HZ |
86 | #define HT_AGG_MAX_RETRIES 0x3 | 86 | #define HT_AGG_MAX_RETRIES 15 |
87 | #define HT_AGG_BURST_RETRIES 3 | ||
88 | #define HT_AGG_RETRIES_PERIOD (15 * HZ) | ||
87 | 89 | ||
88 | #define HT_AGG_STATE_DRV_READY 0 | 90 | #define HT_AGG_STATE_DRV_READY 0 |
89 | #define HT_AGG_STATE_RESPONSE_RECEIVED 1 | 91 | #define HT_AGG_STATE_RESPONSE_RECEIVED 1 |
@@ -179,6 +181,7 @@ struct tid_ampdu_rx { | |||
179 | * @tid_tx: aggregation info for Tx per TID | 181 | * @tid_tx: aggregation info for Tx per TID |
180 | * @tid_start_tx: sessions where start was requested | 182 | * @tid_start_tx: sessions where start was requested |
181 | * @addba_req_num: number of times addBA request has been sent. | 183 | * @addba_req_num: number of times addBA request has been sent. |
184 | * @last_addba_req_time: timestamp of the last addBA request. | ||
182 | * @dialog_token_allocator: dialog token enumerator for each new session; | 185 | * @dialog_token_allocator: dialog token enumerator for each new session; |
183 | * @work: work struct for starting/stopping aggregation | 186 | * @work: work struct for starting/stopping aggregation |
184 | * @tid_rx_timer_expired: bitmap indicating on which TIDs the | 187 | * @tid_rx_timer_expired: bitmap indicating on which TIDs the |
@@ -198,6 +201,7 @@ struct sta_ampdu_mlme { | |||
198 | struct work_struct work; | 201 | struct work_struct work; |
199 | struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM]; | 202 | struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM]; |
200 | struct tid_ampdu_tx *tid_start_tx[STA_TID_NUM]; | 203 | struct tid_ampdu_tx *tid_start_tx[STA_TID_NUM]; |
204 | unsigned long last_addba_req_time[STA_TID_NUM]; | ||
201 | u8 addba_req_num[STA_TID_NUM]; | 205 | u8 addba_req_num[STA_TID_NUM]; |
202 | u8 dialog_token_allocator; | 206 | u8 dialog_token_allocator; |
203 | }; | 207 | }; |
@@ -271,6 +275,7 @@ struct sta_ampdu_mlme { | |||
271 | * EAP frames before association | 275 | * EAP frames before association |
272 | * @sta: station information we share with the driver | 276 | * @sta: station information we share with the driver |
273 | * @sta_state: duplicates information about station state (for debug) | 277 | * @sta_state: duplicates information about station state (for debug) |
278 | * @beacon_loss_count: number of times beacon loss has triggered | ||
274 | */ | 279 | */ |
275 | struct sta_info { | 280 | struct sta_info { |
276 | /* General information, mostly static */ | 281 | /* General information, mostly static */ |
@@ -363,6 +368,7 @@ struct sta_info { | |||
363 | #endif | 368 | #endif |
364 | 369 | ||
365 | unsigned int lost_packets; | 370 | unsigned int lost_packets; |
371 | unsigned int beacon_loss_count; | ||
366 | 372 | ||
367 | /* should be right in front of sta to be in the same cache line */ | 373 | /* should be right in front of sta to be in the same cache line */ |
368 | bool dummy; | 374 | bool dummy; |
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 67756b23eac5..1d32680807d6 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
@@ -554,11 +554,9 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, | |||
554 | goto enqueue; | 554 | goto enqueue; |
555 | } | 555 | } |
556 | } | 556 | } |
557 | 557 | mutex_unlock(&local->socket_lock); | |
558 | } | 558 | } |
559 | 559 | ||
560 | mutex_unlock(&local->socket_lock); | ||
561 | |||
562 | reason = LLCP_DM_NOBOUND; | 560 | reason = LLCP_DM_NOBOUND; |
563 | goto fail; | 561 | goto fail; |
564 | 562 | ||
@@ -956,7 +954,7 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev) | |||
956 | skb_queue_purge(&local->tx_queue); | 954 | skb_queue_purge(&local->tx_queue); |
957 | destroy_workqueue(local->tx_wq); | 955 | destroy_workqueue(local->tx_wq); |
958 | destroy_workqueue(local->rx_wq); | 956 | destroy_workqueue(local->rx_wq); |
959 | kfree(local->rx_pending); | 957 | kfree_skb(local->rx_pending); |
960 | kfree(local); | 958 | kfree(local); |
961 | } | 959 | } |
962 | 960 | ||
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 2c2c4015c68b..6d28d75995b0 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h | |||
@@ -60,11 +60,11 @@ void nfc_llcp_exit(void); | |||
60 | 60 | ||
61 | #else | 61 | #else |
62 | 62 | ||
63 | void nfc_llcp_mac_is_down(struct nfc_dev *dev) | 63 | static inline void nfc_llcp_mac_is_down(struct nfc_dev *dev) |
64 | { | 64 | { |
65 | } | 65 | } |
66 | 66 | ||
67 | void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, | 67 | static inline void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, |
68 | u8 comm_mode, u8 rf_mode) | 68 | u8 comm_mode, u8 rf_mode) |
69 | { | 69 | { |
70 | } | 70 | } |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b07c4fc4ae22..b3d3cf8931cb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2390,6 +2390,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, | |||
2390 | if (sinfo->filled & STATION_INFO_TX_FAILED) | 2390 | if (sinfo->filled & STATION_INFO_TX_FAILED) |
2391 | NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED, | 2391 | NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED, |
2392 | sinfo->tx_failed); | 2392 | sinfo->tx_failed); |
2393 | if (sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) | ||
2394 | NLA_PUT_U32(msg, NL80211_STA_INFO_BEACON_LOSS, | ||
2395 | sinfo->beacon_loss_count); | ||
2393 | if (sinfo->filled & STATION_INFO_BSS_PARAM) { | 2396 | if (sinfo->filled & STATION_INFO_BSS_PARAM) { |
2394 | bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); | 2397 | bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); |
2395 | if (!bss_param) | 2398 | if (!bss_param) |