aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-06-19 17:37:15 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-19 17:37:15 -0400
commita77f4b4acf5b77f038bc11d3ca9b3af6f0124015 (patch)
tree167fc01ea7be7474b7e59173f638a9b25845fbf2 /drivers
parent364f5b3a151942ad24521155355cc7d1d252fd55 (diff)
parentb3c911eeb47d08aada986f769b6a060794dfe9d0 (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John Linville says: ==================== This is a sizeable batch of updates intended for 3.6... The bulk of the changes here are Bluetooth. Gustavo says: Here goes the first Bluetooth pull request for 3.6, we have queued quite a lot of work. Andrei Emeltchenko added the AMP Manager code, a lot of work is needed, but the first bit are already there. This code is disabled by default. Mat Martineau changed the whole L2CAP ERTM state machine code, replacing the old one with a new implementation. Besides that we had lot of coding style fixes (to follow net rules), more l2cap core separation from socket and many clean ups and fixed all over the tree. Along with the above, there is a healthy dose of ath9k, iwlwifi, and other driver updates. There is also another pull from the wireless tree to resolve some merge issues. I also fixed-up some merge discrepencies between net-next and wireless-next. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bluetooth/bluecard_cs.c10
-rw-r--r--drivers/bluetooth/bpa10x.c2
-rw-r--r--drivers/bluetooth/bt3c_cs.c4
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c3
-rw-r--r--drivers/bluetooth/btuart_cs.c4
-rw-r--r--drivers/bluetooth/btusb.c14
-rw-r--r--drivers/bluetooth/dtl1_cs.c4
-rw-r--r--drivers/bluetooth/hci_bcsp.c2
-rw-r--r--drivers/bluetooth/hci_h4.c2
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/bluetooth/hci_ll.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c330
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.h32
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c162
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c126
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h59
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c169
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c14
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile10
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h17
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h26
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c24
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/testmode.c778
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c38
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.c856
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.h161
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h (renamed from drivers/net/wireless/iwlwifi/dvm/testmode.h)0
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/6000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h9
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c71
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c95
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c11
-rw-r--r--drivers/net/wireless/rndis_wlan.c2
53 files changed, 1890 insertions, 1303 deletions
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 1fcd92380356..585c88e01893 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -231,12 +231,12 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
231 } 231 }
232 232
233 do { 233 do {
234 register unsigned int iobase = info->p_dev->resource[0]->start; 234 unsigned int iobase = info->p_dev->resource[0]->start;
235 register unsigned int offset; 235 unsigned int offset;
236 register unsigned char command; 236 unsigned char command;
237 register unsigned long ready_bit; 237 unsigned long ready_bit;
238 register struct sk_buff *skb; 238 register struct sk_buff *skb;
239 register int len; 239 int len;
240 240
241 clear_bit(XMIT_WAKEUP, &(info->tx_state)); 241 clear_bit(XMIT_WAKEUP, &(info->tx_state));
242 242
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 609861a53c28..29caaed2d715 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -470,7 +470,7 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
470 hdev->flush = bpa10x_flush; 470 hdev->flush = bpa10x_flush;
471 hdev->send = bpa10x_send_frame; 471 hdev->send = bpa10x_send_frame;
472 472
473 set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); 473 set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
474 474
475 err = hci_register_dev(hdev); 475 err = hci_register_dev(hdev);
476 if (err < 0) { 476 if (err < 0) {
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 308c8599ab55..b2b0fbbb43b5 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -186,9 +186,9 @@ static void bt3c_write_wakeup(bt3c_info_t *info)
186 return; 186 return;
187 187
188 do { 188 do {
189 register unsigned int iobase = info->p_dev->resource[0]->start; 189 unsigned int iobase = info->p_dev->resource[0]->start;
190 register struct sk_buff *skb; 190 register struct sk_buff *skb;
191 register int len; 191 int len;
192 192
193 if (!pcmcia_dev_present(info->p_dev)) 193 if (!pcmcia_dev_present(info->p_dev))
194 break; 194 break;
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index a853244e7fd7..2867499f7256 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -110,6 +110,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = {
110 /* Marvell SD8787 Bluetooth device */ 110 /* Marvell SD8787 Bluetooth device */
111 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), 111 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A),
112 .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, 112 .driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
113 /* Marvell SD8787 Bluetooth AMP device */
114 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911B),
115 .driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
113 /* Marvell SD8797 Bluetooth device */ 116 /* Marvell SD8797 Bluetooth device */
114 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), 117 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
115 .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, 118 .driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index c4fc2f3fc32c..65b8d996840c 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -140,9 +140,9 @@ static void btuart_write_wakeup(btuart_info_t *info)
140 } 140 }
141 141
142 do { 142 do {
143 register unsigned int iobase = info->p_dev->resource[0]->start; 143 unsigned int iobase = info->p_dev->resource[0]->start;
144 register struct sk_buff *skb; 144 register struct sk_buff *skb;
145 register int len; 145 int len;
146 146
147 clear_bit(XMIT_WAKEUP, &(info->tx_state)); 147 clear_bit(XMIT_WAKEUP, &(info->tx_state));
148 148
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c9463af8e564..a45e717f5f84 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -21,15 +21,7 @@
21 * 21 *
22 */ 22 */
23 23
24#include <linux/kernel.h>
25#include <linux/module.h> 24#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/slab.h>
28#include <linux/types.h>
29#include <linux/sched.h>
30#include <linux/errno.h>
31#include <linux/skbuff.h>
32
33#include <linux/usb.h> 25#include <linux/usb.h>
34 26
35#include <net/bluetooth/bluetooth.h> 27#include <net/bluetooth/bluetooth.h>
@@ -1026,7 +1018,7 @@ static int btusb_probe(struct usb_interface *intf,
1026 data->isoc = usb_ifnum_to_if(data->udev, 1); 1018 data->isoc = usb_ifnum_to_if(data->udev, 1);
1027 1019
1028 if (!reset) 1020 if (!reset)
1029 set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); 1021 set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
1030 1022
1031 if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) { 1023 if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
1032 if (!disable_scofix) 1024 if (!disable_scofix)
@@ -1038,7 +1030,7 @@ static int btusb_probe(struct usb_interface *intf,
1038 1030
1039 if (id->driver_info & BTUSB_DIGIANSWER) { 1031 if (id->driver_info & BTUSB_DIGIANSWER) {
1040 data->cmdreq_type = USB_TYPE_VENDOR; 1032 data->cmdreq_type = USB_TYPE_VENDOR;
1041 set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); 1033 set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
1042 } 1034 }
1043 1035
1044 if (id->driver_info & BTUSB_CSR) { 1036 if (id->driver_info & BTUSB_CSR) {
@@ -1046,7 +1038,7 @@ static int btusb_probe(struct usb_interface *intf,
1046 1038
1047 /* Old firmware would otherwise execute USB reset */ 1039 /* Old firmware would otherwise execute USB reset */
1048 if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117) 1040 if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
1049 set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); 1041 set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
1050 } 1042 }
1051 1043
1052 if (id->driver_info & BTUSB_SNIFFER) { 1044 if (id->driver_info & BTUSB_SNIFFER) {
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 6e8d96189684..b1b37ccd3cd4 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -144,9 +144,9 @@ static void dtl1_write_wakeup(dtl1_info_t *info)
144 } 144 }
145 145
146 do { 146 do {
147 register unsigned int iobase = info->p_dev->resource[0]->start; 147 unsigned int iobase = info->p_dev->resource[0]->start;
148 register struct sk_buff *skb; 148 register struct sk_buff *skb;
149 register int len; 149 int len;
150 150
151 clear_bit(XMIT_WAKEUP, &(info->tx_state)); 151 clear_bit(XMIT_WAKEUP, &(info->tx_state));
152 152
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 661a8dc4d2f8..57e502e06080 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -552,7 +552,7 @@ static u16 bscp_get_crc(struct bcsp_struct *bcsp)
552static int bcsp_recv(struct hci_uart *hu, void *data, int count) 552static int bcsp_recv(struct hci_uart *hu, void *data, int count)
553{ 553{
554 struct bcsp_struct *bcsp = hu->priv; 554 struct bcsp_struct *bcsp = hu->priv;
555 register unsigned char *ptr; 555 unsigned char *ptr;
556 556
557 BT_DBG("hu %p count %d rx_state %d rx_count %ld", 557 BT_DBG("hu %p count %d rx_state %d rx_count %ld",
558 hu, count, bcsp->rx_state, bcsp->rx_count); 558 hu, count, bcsp->rx_state, bcsp->rx_count);
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 748329468d26..c60623f206d4 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -126,7 +126,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
126 126
127static inline int h4_check_data_len(struct h4_struct *h4, int len) 127static inline int h4_check_data_len(struct h4_struct *h4, int len)
128{ 128{
129 register int room = skb_tailroom(h4->rx_skb); 129 int room = skb_tailroom(h4->rx_skb);
130 130
131 BT_DBG("len %d room %d", len, room); 131 BT_DBG("len %d room %d", len, room);
132 132
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index e564579a6115..2f9b796e106e 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -394,7 +394,7 @@ static int hci_uart_register_dev(struct hci_uart *hu)
394 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); 394 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
395 395
396 if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags)) 396 if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
397 set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); 397 set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
398 398
399 if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags)) 399 if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
400 hdev->dev_type = HCI_AMP; 400 hdev->dev_type = HCI_AMP;
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index b874c0efde24..ff6d589c34a5 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -348,7 +348,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
348 348
349static inline int ll_check_data_len(struct ll_struct *ll, int len) 349static inline int ll_check_data_len(struct ll_struct *ll, int len)
350{ 350{
351 register int room = skb_tailroom(ll->rx_skb); 351 int room = skb_tailroom(ll->rx_skb);
352 352
353 BT_DBG("len %d room %d", len, room); 353 BT_DBG("len %d room %d", len, room);
354 354
@@ -374,11 +374,11 @@ static inline int ll_check_data_len(struct ll_struct *ll, int len)
374static int ll_recv(struct hci_uart *hu, void *data, int count) 374static int ll_recv(struct hci_uart *hu, void *data, int count)
375{ 375{
376 struct ll_struct *ll = hu->priv; 376 struct ll_struct *ll = hu->priv;
377 register char *ptr; 377 char *ptr;
378 struct hci_event_hdr *eh; 378 struct hci_event_hdr *eh;
379 struct hci_acl_hdr *ah; 379 struct hci_acl_hdr *ah;
380 struct hci_sco_hdr *sh; 380 struct hci_sco_hdr *sh;
381 register int len, type, dlen; 381 int len, type, dlen;
382 382
383 BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count); 383 BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count);
384 384
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index d9e0824af093..78816b8b2173 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -181,11 +181,14 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
181 u32 mask2 = 0; 181 u32 mask2 = 0;
182 struct ath9k_hw_capabilities *pCap = &ah->caps; 182 struct ath9k_hw_capabilities *pCap = &ah->caps;
183 struct ath_common *common = ath9k_hw_common(ah); 183 struct ath_common *common = ath9k_hw_common(ah);
184 u32 sync_cause = 0, async_cause; 184 u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ;
185
186 if (ath9k_hw_mci_is_enabled(ah))
187 async_mask |= AR_INTR_ASYNC_MASK_MCI;
185 188
186 async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE); 189 async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
187 190
188 if (async_cause & (AR_INTR_MAC_IRQ | AR_INTR_ASYNC_MASK_MCI)) { 191 if (async_cause & async_mask) {
189 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) 192 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
190 == AR_RTC_STATUS_ON) 193 == AR_RTC_STATUS_ON)
191 isr = REG_READ(ah, AR_ISR); 194 isr = REG_READ(ah, AR_ISR);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index b1ced2a76da3..cc2853ade8f8 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -321,7 +321,7 @@ void ar9003_mci_set_full_sleep(struct ath_hw *ah)
321{ 321{
322 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 322 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
323 323
324 if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) && 324 if (ar9003_mci_state(ah, MCI_STATE_ENABLE) &&
325 (mci->bt_state != MCI_BT_SLEEP) && 325 (mci->bt_state != MCI_BT_SLEEP) &&
326 !mci->halted_bt_gpm) { 326 !mci->halted_bt_gpm) {
327 ar9003_mci_send_coex_halt_bt_gpm(ah, true, true); 327 ar9003_mci_send_coex_halt_bt_gpm(ah, true, true);
@@ -484,7 +484,7 @@ static void ar9003_mci_sync_bt_state(struct ath_hw *ah)
484 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 484 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
485 u32 cur_bt_state; 485 u32 cur_bt_state;
486 486
487 cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); 487 cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP);
488 488
489 if (mci->bt_state != cur_bt_state) 489 if (mci->bt_state != cur_bt_state)
490 mci->bt_state = cur_bt_state; 490 mci->bt_state = cur_bt_state;
@@ -593,8 +593,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
593 if (!time_out) 593 if (!time_out)
594 break; 594 break;
595 595
596 offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, 596 offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data);
597 &more_data);
598 597
599 if (offset == MCI_GPM_INVALID) 598 if (offset == MCI_GPM_INVALID)
600 continue; 599 continue;
@@ -658,8 +657,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
658 time_out = 0; 657 time_out = 0;
659 658
660 while (more_data == MCI_GPM_MORE) { 659 while (more_data == MCI_GPM_MORE) {
661 offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, 660 offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data);
662 &more_data);
663 if (offset == MCI_GPM_INVALID) 661 if (offset == MCI_GPM_INVALID)
664 break; 662 break;
665 663
@@ -893,13 +891,16 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
893 udelay(100); 891 udelay(100);
894 } 892 }
895 893
894 /* Check pending GPM msg before MCI Reset Rx */
895 ar9003_mci_check_gpm_offset(ah);
896
896 regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); 897 regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
897 REG_WRITE(ah, AR_MCI_COMMAND2, regval); 898 REG_WRITE(ah, AR_MCI_COMMAND2, regval);
898 udelay(1); 899 udelay(1);
899 regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX); 900 regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
900 REG_WRITE(ah, AR_MCI_COMMAND2, regval); 901 REG_WRITE(ah, AR_MCI_COMMAND2, regval);
901 902
902 ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); 903 ar9003_mci_get_next_gpm_offset(ah, true, NULL);
903 904
904 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 905 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
905 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | 906 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
@@ -1010,38 +1011,32 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header,
1010 } 1011 }
1011} 1012}
1012 1013
1013void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) 1014void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force)
1014{ 1015{
1015 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 1016 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1016 1017
1017 if (!mci->update_2g5g) 1018 if (!mci->update_2g5g && !force)
1018 return; 1019 return;
1019 1020
1020 if (mci->is_2g) { 1021 if (mci->is_2g) {
1021 ar9003_mci_send_2g5g_status(ah, true); 1022 ar9003_mci_send_2g5g_status(ah, true);
1022 ar9003_mci_send_lna_transfer(ah, true);
1023 udelay(5);
1024 1023
1025 REG_CLR_BIT(ah, AR_MCI_TX_CTRL, 1024 REG_SET_BIT(ah, AR_MCI_TX_CTRL,
1026 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 1025 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
1027 REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, 1026 REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL,
1028 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); 1027 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
1029 1028
1030 if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) 1029 if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
1031 REG_SET_BIT(ah, AR_BTCOEX_CTRL, 1030 ar9003_mci_osla_setup(ah, true);
1032 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
1033 } else { 1031 } else {
1034 ar9003_mci_send_lna_take(ah, true);
1035 udelay(5);
1036
1037 REG_SET_BIT(ah, AR_MCI_TX_CTRL, 1032 REG_SET_BIT(ah, AR_MCI_TX_CTRL,
1038 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 1033 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
1039 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, 1034 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
1040 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); 1035 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
1041 REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
1042 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
1043 1036
1044 ar9003_mci_send_2g5g_status(ah, true); 1037 ar9003_mci_osla_setup(ah, false);
1038 if (!force)
1039 ar9003_mci_send_2g5g_status(ah, true);
1045 } 1040 }
1046} 1041}
1047 1042
@@ -1169,11 +1164,10 @@ void ar9003_mci_cleanup(struct ath_hw *ah)
1169} 1164}
1170EXPORT_SYMBOL(ar9003_mci_cleanup); 1165EXPORT_SYMBOL(ar9003_mci_cleanup);
1171 1166
1172u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) 1167u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type)
1173{ 1168{
1174 struct ath_common *common = ath9k_hw_common(ah);
1175 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 1169 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1176 u32 value = 0, more_gpm = 0, gpm_ptr; 1170 u32 value = 0;
1177 u8 query_type; 1171 u8 query_type;
1178 1172
1179 switch (state_type) { 1173 switch (state_type) {
@@ -1186,81 +1180,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
1186 } 1180 }
1187 value &= AR_BTCOEX_CTRL_MCI_MODE_EN; 1181 value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
1188 break; 1182 break;
1189 case MCI_STATE_INIT_GPM_OFFSET:
1190 value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1191 mci->gpm_idx = value;
1192 break;
1193 case MCI_STATE_NEXT_GPM_OFFSET:
1194 case MCI_STATE_LAST_GPM_OFFSET:
1195 /*
1196 * This could be useful to avoid new GPM message interrupt which
1197 * may lead to spurious interrupt after power sleep, or multiple
1198 * entry of ath_mci_intr().
1199 * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
1200 * alleviate this effect, but clearing GPM RX interrupt bit is
1201 * safe, because whether this is called from hw or driver code
1202 * there must be an interrupt bit set/triggered initially
1203 */
1204 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
1205 AR_MCI_INTERRUPT_RX_MSG_GPM);
1206
1207 gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1208 value = gpm_ptr;
1209
1210 if (value == 0)
1211 value = mci->gpm_len - 1;
1212 else if (value >= mci->gpm_len) {
1213 if (value != 0xFFFF)
1214 value = 0;
1215 } else {
1216 value--;
1217 }
1218
1219 if (value == 0xFFFF) {
1220 value = MCI_GPM_INVALID;
1221 more_gpm = MCI_GPM_NOMORE;
1222 } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) {
1223 if (gpm_ptr == mci->gpm_idx) {
1224 value = MCI_GPM_INVALID;
1225 more_gpm = MCI_GPM_NOMORE;
1226 } else {
1227 for (;;) {
1228 u32 temp_index;
1229
1230 /* skip reserved GPM if any */
1231
1232 if (value != mci->gpm_idx)
1233 more_gpm = MCI_GPM_MORE;
1234 else
1235 more_gpm = MCI_GPM_NOMORE;
1236
1237 temp_index = mci->gpm_idx;
1238 mci->gpm_idx++;
1239
1240 if (mci->gpm_idx >=
1241 mci->gpm_len)
1242 mci->gpm_idx = 0;
1243
1244 if (ar9003_mci_is_gpm_valid(ah,
1245 temp_index)) {
1246 value = temp_index;
1247 break;
1248 }
1249
1250 if (more_gpm == MCI_GPM_NOMORE) {
1251 value = MCI_GPM_INVALID;
1252 break;
1253 }
1254 }
1255 }
1256 if (p_data)
1257 *p_data = more_gpm;
1258 }
1259
1260 if (value != MCI_GPM_INVALID)
1261 value <<= 4;
1262
1263 break;
1264 case MCI_STATE_LAST_SCHD_MSG_OFFSET: 1183 case MCI_STATE_LAST_SCHD_MSG_OFFSET:
1265 value = MS(REG_READ(ah, AR_MCI_RX_STATUS), 1184 value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
1266 AR_MCI_RX_LAST_SCHD_MSG_INDEX); 1185 AR_MCI_RX_LAST_SCHD_MSG_INDEX);
@@ -1272,21 +1191,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
1272 AR_MCI_RX_REMOTE_SLEEP) ? 1191 AR_MCI_RX_REMOTE_SLEEP) ?
1273 MCI_BT_SLEEP : MCI_BT_AWAKE; 1192 MCI_BT_SLEEP : MCI_BT_AWAKE;
1274 break; 1193 break;
1275 case MCI_STATE_CONT_RSSI_POWER:
1276 value = MS(mci->cont_status, AR_MCI_CONT_RSSI_POWER);
1277 break;
1278 case MCI_STATE_CONT_PRIORITY:
1279 value = MS(mci->cont_status, AR_MCI_CONT_RRIORITY);
1280 break;
1281 case MCI_STATE_CONT_TXRX:
1282 value = MS(mci->cont_status, AR_MCI_CONT_TXRX);
1283 break;
1284 case MCI_STATE_BT:
1285 value = mci->bt_state;
1286 break;
1287 case MCI_STATE_SET_BT_SLEEP:
1288 mci->bt_state = MCI_BT_SLEEP;
1289 break;
1290 case MCI_STATE_SET_BT_AWAKE: 1194 case MCI_STATE_SET_BT_AWAKE:
1291 mci->bt_state = MCI_BT_AWAKE; 1195 mci->bt_state = MCI_BT_AWAKE;
1292 ar9003_mci_send_coex_version_query(ah, true); 1196 ar9003_mci_send_coex_version_query(ah, true);
@@ -1295,7 +1199,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
1295 if (mci->unhalt_bt_gpm) 1199 if (mci->unhalt_bt_gpm)
1296 ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); 1200 ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
1297 1201
1298 ar9003_mci_2g5g_switch(ah, true); 1202 ar9003_mci_2g5g_switch(ah, false);
1299 break; 1203 break;
1300 case MCI_STATE_SET_BT_CAL_START: 1204 case MCI_STATE_SET_BT_CAL_START:
1301 mci->bt_state = MCI_BT_CAL_START; 1205 mci->bt_state = MCI_BT_CAL_START;
@@ -1319,34 +1223,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
1319 case MCI_STATE_SEND_WLAN_COEX_VERSION: 1223 case MCI_STATE_SEND_WLAN_COEX_VERSION:
1320 ar9003_mci_send_coex_version_response(ah, true); 1224 ar9003_mci_send_coex_version_response(ah, true);
1321 break; 1225 break;
1322 case MCI_STATE_SET_BT_COEX_VERSION:
1323 if (!p_data)
1324 ath_dbg(common, MCI,
1325 "MCI Set BT Coex version with NULL data!!\n");
1326 else {
1327 mci->bt_ver_major = (*p_data >> 8) & 0xff;
1328 mci->bt_ver_minor = (*p_data) & 0xff;
1329 mci->bt_version_known = true;
1330 ath_dbg(common, MCI, "MCI BT version set: %d.%d\n",
1331 mci->bt_ver_major, mci->bt_ver_minor);
1332 }
1333 break;
1334 case MCI_STATE_SEND_WLAN_CHANNELS:
1335 if (p_data) {
1336 if (((mci->wlan_channels[1] & 0xffff0000) ==
1337 (*(p_data + 1) & 0xffff0000)) &&
1338 (mci->wlan_channels[2] == *(p_data + 2)) &&
1339 (mci->wlan_channels[3] == *(p_data + 3)))
1340 break;
1341
1342 mci->wlan_channels[0] = *p_data++;
1343 mci->wlan_channels[1] = *p_data++;
1344 mci->wlan_channels[2] = *p_data++;
1345 mci->wlan_channels[3] = *p_data++;
1346 }
1347 mci->wlan_channels_update = true;
1348 ar9003_mci_send_coex_wlan_channels(ah, true);
1349 break;
1350 case MCI_STATE_SEND_VERSION_QUERY: 1226 case MCI_STATE_SEND_VERSION_QUERY:
1351 ar9003_mci_send_coex_version_query(ah, true); 1227 ar9003_mci_send_coex_version_query(ah, true);
1352 break; 1228 break;
@@ -1354,29 +1230,12 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data)
1354 query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY; 1230 query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY;
1355 ar9003_mci_send_coex_bt_status_query(ah, true, query_type); 1231 ar9003_mci_send_coex_bt_status_query(ah, true, query_type);
1356 break; 1232 break;
1357 case MCI_STATE_NEED_FLUSH_BT_INFO:
1358 /*
1359 * btcoex_hw.mci.unhalt_bt_gpm means whether it's
1360 * needed to send UNHALT message. It's set whenever
1361 * there's a request to send HALT message.
1362 * mci_halted_bt_gpm means whether HALT message is sent
1363 * out successfully.
1364 *
1365 * Checking (mci_unhalt_bt_gpm == false) instead of
1366 * checking (ah->mci_halted_bt_gpm == false) will make
1367 * sure currently is in UNHALT-ed mode and BT can
1368 * respond to status query.
1369 */
1370 value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0;
1371 if (p_data)
1372 mci->need_flush_btinfo = (*p_data != 0) ? true : false;
1373 break;
1374 case MCI_STATE_RECOVER_RX: 1233 case MCI_STATE_RECOVER_RX:
1375 ar9003_mci_prep_interface(ah); 1234 ar9003_mci_prep_interface(ah);
1376 mci->query_bt = true; 1235 mci->query_bt = true;
1377 mci->need_flush_btinfo = true; 1236 mci->need_flush_btinfo = true;
1378 ar9003_mci_send_coex_wlan_channels(ah, true); 1237 ar9003_mci_send_coex_wlan_channels(ah, true);
1379 ar9003_mci_2g5g_switch(ah, true); 1238 ar9003_mci_2g5g_switch(ah, false);
1380 break; 1239 break;
1381 case MCI_STATE_NEED_FTP_STOMP: 1240 case MCI_STATE_NEED_FTP_STOMP:
1382 value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); 1241 value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP);
@@ -1404,3 +1263,154 @@ void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah)
1404 /* Force another 2g5g update at next scanning */ 1263 /* Force another 2g5g update at next scanning */
1405 mci->update_2g5g = true; 1264 mci->update_2g5g = true;
1406} 1265}
1266
1267void ar9003_mci_set_power_awake(struct ath_hw *ah)
1268{
1269 u32 btcoex_ctrl2, diag_sw;
1270 int i;
1271 u8 lna_ctrl, bt_sleep;
1272
1273 for (i = 0; i < AH_WAIT_TIMEOUT; i++) {
1274 btcoex_ctrl2 = REG_READ(ah, AR_BTCOEX_CTRL2);
1275 if (btcoex_ctrl2 != 0xdeadbeef)
1276 break;
1277 udelay(AH_TIME_QUANTUM);
1278 }
1279 REG_WRITE(ah, AR_BTCOEX_CTRL2, (btcoex_ctrl2 | BIT(23)));
1280
1281 for (i = 0; i < AH_WAIT_TIMEOUT; i++) {
1282 diag_sw = REG_READ(ah, AR_DIAG_SW);
1283 if (diag_sw != 0xdeadbeef)
1284 break;
1285 udelay(AH_TIME_QUANTUM);
1286 }
1287 REG_WRITE(ah, AR_DIAG_SW, (diag_sw | BIT(27) | BIT(19) | BIT(18)));
1288 lna_ctrl = REG_READ(ah, AR_OBS_BUS_CTRL) & 0x3;
1289 bt_sleep = REG_READ(ah, AR_MCI_RX_STATUS) & AR_MCI_RX_REMOTE_SLEEP;
1290
1291 REG_WRITE(ah, AR_BTCOEX_CTRL2, btcoex_ctrl2);
1292 REG_WRITE(ah, AR_DIAG_SW, diag_sw);
1293
1294 if (bt_sleep && (lna_ctrl == 2)) {
1295 REG_SET_BIT(ah, AR_BTCOEX_RC, 0x1);
1296 REG_CLR_BIT(ah, AR_BTCOEX_RC, 0x1);
1297 udelay(50);
1298 }
1299}
1300
1301void ar9003_mci_check_gpm_offset(struct ath_hw *ah)
1302{
1303 struct ath_common *common = ath9k_hw_common(ah);
1304 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1305 u32 offset;
1306
1307 /*
1308 * This should only be called before "MAC Warm Reset" or "MCI Reset Rx".
1309 */
1310 offset = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1311 if (mci->gpm_idx == offset)
1312 return;
1313 ath_dbg(common, MCI, "GPM cached write pointer mismatch %d %d\n",
1314 mci->gpm_idx, offset);
1315 mci->query_bt = true;
1316 mci->need_flush_btinfo = true;
1317 mci->gpm_idx = 0;
1318}
1319
1320u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more)
1321{
1322 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1323 u32 offset, more_gpm = 0, gpm_ptr;
1324
1325 if (first) {
1326 gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1327 mci->gpm_idx = gpm_ptr;
1328 return gpm_ptr;
1329 }
1330
1331 /*
1332 * This could be useful to avoid new GPM message interrupt which
1333 * may lead to spurious interrupt after power sleep, or multiple
1334 * entry of ath_mci_intr().
1335 * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
1336 * alleviate this effect, but clearing GPM RX interrupt bit is
1337 * safe, because whether this is called from hw or driver code
1338 * there must be an interrupt bit set/triggered initially
1339 */
1340 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
1341 AR_MCI_INTERRUPT_RX_MSG_GPM);
1342
1343 gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1344 offset = gpm_ptr;
1345
1346 if (!offset)
1347 offset = mci->gpm_len - 1;
1348 else if (offset >= mci->gpm_len) {
1349 if (offset != 0xFFFF)
1350 offset = 0;
1351 } else {
1352 offset--;
1353 }
1354
1355 if ((offset == 0xFFFF) || (gpm_ptr == mci->gpm_idx)) {
1356 offset = MCI_GPM_INVALID;
1357 more_gpm = MCI_GPM_NOMORE;
1358 goto out;
1359 }
1360 for (;;) {
1361 u32 temp_index;
1362
1363 /* skip reserved GPM if any */
1364
1365 if (offset != mci->gpm_idx)
1366 more_gpm = MCI_GPM_MORE;
1367 else
1368 more_gpm = MCI_GPM_NOMORE;
1369
1370 temp_index = mci->gpm_idx;
1371 mci->gpm_idx++;
1372
1373 if (mci->gpm_idx >= mci->gpm_len)
1374 mci->gpm_idx = 0;
1375
1376 if (ar9003_mci_is_gpm_valid(ah, temp_index)) {
1377 offset = temp_index;
1378 break;
1379 }
1380
1381 if (more_gpm == MCI_GPM_NOMORE) {
1382 offset = MCI_GPM_INVALID;
1383 break;
1384 }
1385 }
1386
1387 if (offset != MCI_GPM_INVALID)
1388 offset <<= 4;
1389out:
1390 if (more)
1391 *more = more_gpm;
1392
1393 return offset;
1394}
1395EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset);
1396
1397void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor)
1398{
1399 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1400
1401 mci->bt_ver_major = major;
1402 mci->bt_ver_minor = minor;
1403 mci->bt_version_known = true;
1404 ath_dbg(ath9k_hw_common(ah), MCI, "MCI BT version set: %d.%d\n",
1405 mci->bt_ver_major, mci->bt_ver_minor);
1406}
1407EXPORT_SYMBOL(ar9003_mci_set_bt_version);
1408
1409void ar9003_mci_send_wlan_channels(struct ath_hw *ah)
1410{
1411 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1412
1413 mci->wlan_channels_update = true;
1414 ar9003_mci_send_coex_wlan_channels(ah, true);
1415}
1416EXPORT_SYMBOL(ar9003_mci_send_wlan_channels);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
index 10282e2bcdc9..d33b8e128855 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
@@ -189,26 +189,15 @@ enum mci_bt_state {
189/* Type of state query */ 189/* Type of state query */
190enum mci_state_type { 190enum mci_state_type {
191 MCI_STATE_ENABLE, 191 MCI_STATE_ENABLE,
192 MCI_STATE_INIT_GPM_OFFSET,
193 MCI_STATE_NEXT_GPM_OFFSET,
194 MCI_STATE_LAST_GPM_OFFSET,
195 MCI_STATE_BT,
196 MCI_STATE_SET_BT_SLEEP,
197 MCI_STATE_SET_BT_AWAKE, 192 MCI_STATE_SET_BT_AWAKE,
198 MCI_STATE_SET_BT_CAL_START, 193 MCI_STATE_SET_BT_CAL_START,
199 MCI_STATE_SET_BT_CAL, 194 MCI_STATE_SET_BT_CAL,
200 MCI_STATE_LAST_SCHD_MSG_OFFSET, 195 MCI_STATE_LAST_SCHD_MSG_OFFSET,
201 MCI_STATE_REMOTE_SLEEP, 196 MCI_STATE_REMOTE_SLEEP,
202 MCI_STATE_CONT_RSSI_POWER,
203 MCI_STATE_CONT_PRIORITY,
204 MCI_STATE_CONT_TXRX,
205 MCI_STATE_RESET_REQ_WAKE, 197 MCI_STATE_RESET_REQ_WAKE,
206 MCI_STATE_SEND_WLAN_COEX_VERSION, 198 MCI_STATE_SEND_WLAN_COEX_VERSION,
207 MCI_STATE_SET_BT_COEX_VERSION,
208 MCI_STATE_SEND_WLAN_CHANNELS,
209 MCI_STATE_SEND_VERSION_QUERY, 199 MCI_STATE_SEND_VERSION_QUERY,
210 MCI_STATE_SEND_STATUS_QUERY, 200 MCI_STATE_SEND_STATUS_QUERY,
211 MCI_STATE_NEED_FLUSH_BT_INFO,
212 MCI_STATE_SET_CONCUR_TX_PRI, 201 MCI_STATE_SET_CONCUR_TX_PRI,
213 MCI_STATE_RECOVER_RX, 202 MCI_STATE_RECOVER_RX,
214 MCI_STATE_NEED_FTP_STOMP, 203 MCI_STATE_NEED_FTP_STOMP,
@@ -259,14 +248,15 @@ enum mci_gpm_coex_opcode {
259bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, 248bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
260 u32 *payload, u8 len, bool wait_done, 249 u32 *payload, u8 len, bool wait_done,
261 bool check_bt); 250 bool check_bt);
262u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data); 251u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type);
263void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, 252void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
264 u16 len, u32 sched_addr); 253 u16 len, u32 sched_addr);
265void ar9003_mci_cleanup(struct ath_hw *ah); 254void ar9003_mci_cleanup(struct ath_hw *ah);
266void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, 255void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
267 u32 *rx_msg_intr); 256 u32 *rx_msg_intr);
268void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); 257u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more);
269 258void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor);
259void ar9003_mci_send_wlan_channels(struct ath_hw *ah);
270/* 260/*
271 * These functions are used by ath9k_hw. 261 * These functions are used by ath9k_hw.
272 */ 262 */
@@ -277,7 +267,7 @@ void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep);
277void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); 267void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable);
278void ar9003_mci_init_cal_done(struct ath_hw *ah); 268void ar9003_mci_init_cal_done(struct ath_hw *ah);
279void ar9003_mci_set_full_sleep(struct ath_hw *ah); 269void ar9003_mci_set_full_sleep(struct ath_hw *ah);
280void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done); 270void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force);
281void ar9003_mci_check_bt(struct ath_hw *ah); 271void ar9003_mci_check_bt(struct ath_hw *ah);
282bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); 272bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan);
283int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, 273int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
@@ -285,6 +275,9 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
285void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, 275void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
286 bool is_full_sleep); 276 bool is_full_sleep);
287void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); 277void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked);
278void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah);
279void ar9003_mci_set_power_awake(struct ath_hw *ah);
280void ar9003_mci_check_gpm_offset(struct ath_hw *ah);
288 281
289#else 282#else
290 283
@@ -322,6 +315,15 @@ static inline void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
322static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked) 315static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
323{ 316{
324} 317}
318static inline void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah)
319{
320}
321static inline void ar9003_mci_set_power_awake(struct ath_hw *ah)
322{
323}
324static inline void ar9003_mci_check_gpm_offset(struct ath_hw *ah)
325{
326}
325#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ 327#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
326 328
327#endif 329#endif
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index 4a93e1534c1d..8f406ff2c95e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -52,7 +52,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
52 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, 52 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
53 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, 53 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8},
54 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, 54 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e},
55 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x33795d5e}, 55 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x32395d5e},
56 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 56 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
57 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, 57 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
58 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, 58 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 02fc1c1e5eeb..a8c050085648 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -698,6 +698,7 @@ struct ath_softc {
698#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 698#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
699 struct ath_btcoex btcoex; 699 struct ath_btcoex btcoex;
700 struct ath_mci_coex mci_coex; 700 struct ath_mci_coex mci_coex;
701 struct work_struct mci_work;
701#endif 702#endif
702 703
703 struct ath_descdma txsdma; 704 struct ath_descdma txsdma;
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index af6d27350291..26032cb59b8a 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -202,7 +202,7 @@ static void ath_btcoex_period_timer(unsigned long data)
202 202
203 btcoex->bt_wait_time += btcoex->btcoex_period; 203 btcoex->bt_wait_time += btcoex->btcoex_period;
204 if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { 204 if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) {
205 if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP, NULL) && 205 if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) &&
206 (mci->num_pan || mci->num_other_acl)) 206 (mci->num_pan || mci->num_other_acl))
207 ah->btcoex_hw.mci.stomp_ftp = 207 ah->btcoex_hw.mci.stomp_ftp =
208 (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); 208 (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH);
@@ -232,7 +232,7 @@ static void ath_btcoex_period_timer(unsigned long data)
232 } 232 }
233 233
234 ath9k_ps_restore(sc); 234 ath9k_ps_restore(sc);
235 timer_period = btcoex->btcoex_period / 1000; 235 timer_period = btcoex->btcoex_period;
236 mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); 236 mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period));
237} 237}
238 238
@@ -267,10 +267,10 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)
267{ 267{
268 struct ath_btcoex *btcoex = &sc->btcoex; 268 struct ath_btcoex *btcoex = &sc->btcoex;
269 269
270 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; 270 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
271 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 271 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 *
272 btcoex->btcoex_period / 100; 272 btcoex->btcoex_period / 100;
273 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 273 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 *
274 btcoex->btcoex_period / 100; 274 btcoex->btcoex_period / 100;
275 275
276 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, 276 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 45e670087e1c..784baee5db84 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1348,6 +1348,9 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1348 } 1348 }
1349 } 1349 }
1350 1350
1351 if (ath9k_hw_mci_is_enabled(ah))
1352 ar9003_mci_check_gpm_offset(ah);
1353
1351 REG_WRITE(ah, AR_RTC_RC, rst_flags); 1354 REG_WRITE(ah, AR_RTC_RC, rst_flags);
1352 1355
1353 REGWRITE_BUFFER_FLUSH(ah); 1356 REGWRITE_BUFFER_FLUSH(ah);
@@ -1708,7 +1711,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
1708 ath9k_hw_start_nfcal(ah, true); 1711 ath9k_hw_start_nfcal(ah, true);
1709 1712
1710 if (ath9k_hw_mci_is_enabled(ah)) 1713 if (ath9k_hw_mci_is_enabled(ah))
1711 ar9003_mci_2g5g_switch(ah, true); 1714 ar9003_mci_2g5g_switch(ah, false);
1712 1715
1713 if (AR_SREV_9271(ah)) 1716 if (AR_SREV_9271(ah))
1714 ar9002_hw_load_ani_reg(ah, chan); 1717 ar9002_hw_load_ani_reg(ah, chan);
@@ -1912,7 +1915,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1912 1915
1913 ath9k_hw_set_dma(ah); 1916 ath9k_hw_set_dma(ah);
1914 1917
1915 REG_WRITE(ah, AR_OBS, 8); 1918 if (!ath9k_hw_mci_is_enabled(ah))
1919 REG_WRITE(ah, AR_OBS, 8);
1916 1920
1917 if (ah->config.rx_intr_mitigation) { 1921 if (ah->config.rx_intr_mitigation) {
1918 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 1922 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
@@ -2111,6 +2115,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah)
2111 AR_RTC_FORCE_WAKE_EN); 2115 AR_RTC_FORCE_WAKE_EN);
2112 udelay(50); 2116 udelay(50);
2113 2117
2118 if (ath9k_hw_mci_is_enabled(ah))
2119 ar9003_mci_set_power_awake(ah);
2120
2114 for (i = POWER_UP_TIME / 50; i > 0; i--) { 2121 for (i = POWER_UP_TIME / 50; i > 0; i--) {
2115 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; 2122 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
2116 if (val == AR_RTC_STATUS_ON) 2123 if (val == AR_RTC_STATUS_ON)
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 0cc4c70f7f0c..a105c9426251 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -136,6 +136,14 @@ void ath_hw_pll_work(struct work_struct *work)
136 u32 pll_sqsum; 136 u32 pll_sqsum;
137 struct ath_softc *sc = container_of(work, struct ath_softc, 137 struct ath_softc *sc = container_of(work, struct ath_softc,
138 hw_pll_work.work); 138 hw_pll_work.work);
139 /*
140 * ensure that the PLL WAR is executed only
141 * after the STA is associated (or) if the
142 * beaconing had started in interfaces that
143 * uses beacons.
144 */
145 if (!test_bit(SC_OP_BEACONS, &sc->sc_flags))
146 return;
139 147
140 ath9k_ps_wakeup(sc); 148 ath9k_ps_wakeup(sc);
141 pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); 149 pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c0f478b0a9a2..52561b341d68 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -150,6 +150,9 @@ static void __ath_cancel_work(struct ath_softc *sc)
150 cancel_work_sync(&sc->hw_check_work); 150 cancel_work_sync(&sc->hw_check_work);
151 cancel_delayed_work_sync(&sc->tx_complete_work); 151 cancel_delayed_work_sync(&sc->tx_complete_work);
152 cancel_delayed_work_sync(&sc->hw_pll_work); 152 cancel_delayed_work_sync(&sc->hw_pll_work);
153#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
154 cancel_work_sync(&sc->mci_work);
155#endif
153} 156}
154 157
155static void ath_cancel_work(struct ath_softc *sc) 158static void ath_cancel_work(struct ath_softc *sc)
@@ -1033,15 +1036,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1033 } 1036 }
1034 } 1037 }
1035 1038
1036 if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
1037 ((vif->type == NL80211_IFTYPE_ADHOC) &&
1038 sc->nvifs > 0)) {
1039 ath_err(common, "Cannot create ADHOC interface when other"
1040 " interfaces already exist.\n");
1041 ret = -EINVAL;
1042 goto out;
1043 }
1044
1045 ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); 1039 ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
1046 1040
1047 sc->nvifs++; 1041 sc->nvifs++;
@@ -1066,15 +1060,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1066 mutex_lock(&sc->mutex); 1060 mutex_lock(&sc->mutex);
1067 ath9k_ps_wakeup(sc); 1061 ath9k_ps_wakeup(sc);
1068 1062
1069 /* See if new interface type is valid. */
1070 if ((new_type == NL80211_IFTYPE_ADHOC) &&
1071 (sc->nvifs > 1)) {
1072 ath_err(common, "When using ADHOC, it must be the only"
1073 " interface.\n");
1074 ret = -EINVAL;
1075 goto out;
1076 }
1077
1078 if (ath9k_uses_beacons(new_type) && 1063 if (ath9k_uses_beacons(new_type) &&
1079 !ath9k_uses_beacons(vif->type)) { 1064 !ath9k_uses_beacons(vif->type)) {
1080 if (sc->nbcnvifs >= ATH_BCBUF) { 1065 if (sc->nbcnvifs >= ATH_BCBUF) {
@@ -1258,6 +1243,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1258 if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { 1243 if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
1259 ath_err(common, "Unable to set channel\n"); 1244 ath_err(common, "Unable to set channel\n");
1260 mutex_unlock(&sc->mutex); 1245 mutex_unlock(&sc->mutex);
1246 ath9k_ps_restore(sc);
1261 return -EINVAL; 1247 return -EINVAL;
1262 } 1248 }
1263 1249
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 49137f477b05..7d34a504d617 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -20,7 +20,7 @@
20#include "ath9k.h" 20#include "ath9k.h"
21#include "mci.h" 21#include "mci.h"
22 22
23static const u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; 23static const u8 ath_mci_duty_cycle[] = { 55, 50, 60, 70, 80, 85, 90, 95, 98 };
24 24
25static struct ath_mci_profile_info* 25static struct ath_mci_profile_info*
26ath_mci_find_profile(struct ath_mci_profile *mci, 26ath_mci_find_profile(struct ath_mci_profile *mci,
@@ -28,11 +28,14 @@ ath_mci_find_profile(struct ath_mci_profile *mci,
28{ 28{
29 struct ath_mci_profile_info *entry; 29 struct ath_mci_profile_info *entry;
30 30
31 if (list_empty(&mci->info))
32 return NULL;
33
31 list_for_each_entry(entry, &mci->info, list) { 34 list_for_each_entry(entry, &mci->info, list) {
32 if (entry->conn_handle == info->conn_handle) 35 if (entry->conn_handle == info->conn_handle)
33 break; 36 return entry;
34 } 37 }
35 return entry; 38 return NULL;
36} 39}
37 40
38static bool ath_mci_add_profile(struct ath_common *common, 41static bool ath_mci_add_profile(struct ath_common *common,
@@ -49,31 +52,21 @@ static bool ath_mci_add_profile(struct ath_common *common,
49 (info->type != MCI_GPM_COEX_PROFILE_VOICE)) 52 (info->type != MCI_GPM_COEX_PROFILE_VOICE))
50 return false; 53 return false;
51 54
52 entry = ath_mci_find_profile(mci, info); 55 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
53 56 if (!entry)
54 if (entry) { 57 return false;
55 memcpy(entry, info, 10);
56 } else {
57 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
58 if (!entry)
59 return false;
60 58
61 memcpy(entry, info, 10); 59 memcpy(entry, info, 10);
62 INC_PROF(mci, info); 60 INC_PROF(mci, info);
63 list_add_tail(&info->list, &mci->info); 61 list_add_tail(&entry->list, &mci->info);
64 }
65 62
66 return true; 63 return true;
67} 64}
68 65
69static void ath_mci_del_profile(struct ath_common *common, 66static void ath_mci_del_profile(struct ath_common *common,
70 struct ath_mci_profile *mci, 67 struct ath_mci_profile *mci,
71 struct ath_mci_profile_info *info) 68 struct ath_mci_profile_info *entry)
72{ 69{
73 struct ath_mci_profile_info *entry;
74
75 entry = ath_mci_find_profile(mci, info);
76
77 if (!entry) 70 if (!entry)
78 return; 71 return;
79 72
@@ -86,12 +79,16 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci)
86{ 79{
87 struct ath_mci_profile_info *info, *tinfo; 80 struct ath_mci_profile_info *info, *tinfo;
88 81
82 mci->aggr_limit = 0;
83
84 if (list_empty(&mci->info))
85 return;
86
89 list_for_each_entry_safe(info, tinfo, &mci->info, list) { 87 list_for_each_entry_safe(info, tinfo, &mci->info, list) {
90 list_del(&info->list); 88 list_del(&info->list);
91 DEC_PROF(mci, info); 89 DEC_PROF(mci, info);
92 kfree(info); 90 kfree(info);
93 } 91 }
94 mci->aggr_limit = 0;
95} 92}
96 93
97static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex) 94static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex)
@@ -123,6 +120,8 @@ static void ath_mci_update_scheme(struct ath_softc *sc)
123 if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_TUNING) 120 if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_TUNING)
124 goto skip_tuning; 121 goto skip_tuning;
125 122
123 btcoex->duty_cycle = ath_mci_duty_cycle[num_profile];
124
126 if (num_profile == 1) { 125 if (num_profile == 1) {
127 info = list_first_entry(&mci->info, 126 info = list_first_entry(&mci->info,
128 struct ath_mci_profile_info, 127 struct ath_mci_profile_info,
@@ -181,12 +180,11 @@ skip_tuning:
181 if (IS_CHAN_5GHZ(sc->sc_ah->curchan)) 180 if (IS_CHAN_5GHZ(sc->sc_ah->curchan))
182 return; 181 return;
183 182
184 btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0); 183 btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_BDR_DUTY_CYCLE : 0);
185 if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) 184 if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE)
186 btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; 185 btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE;
187 186
188 btcoex->btcoex_period *= 1000; 187 btcoex->btcoex_no_stomp = btcoex->btcoex_period * 1000 *
189 btcoex->btcoex_no_stomp = btcoex->btcoex_period *
190 (100 - btcoex->duty_cycle) / 100; 188 (100 - btcoex->duty_cycle) / 100;
191 189
192 ath9k_hw_btcoex_enable(sc->sc_ah); 190 ath9k_hw_btcoex_enable(sc->sc_ah);
@@ -197,20 +195,16 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
197{ 195{
198 struct ath_hw *ah = sc->sc_ah; 196 struct ath_hw *ah = sc->sc_ah;
199 struct ath_common *common = ath9k_hw_common(ah); 197 struct ath_common *common = ath9k_hw_common(ah);
198 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
200 u32 payload[4] = {0, 0, 0, 0}; 199 u32 payload[4] = {0, 0, 0, 0};
201 200
202 switch (opcode) { 201 switch (opcode) {
203 case MCI_GPM_BT_CAL_REQ: 202 case MCI_GPM_BT_CAL_REQ:
204 if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { 203 if (mci_hw->bt_state == MCI_BT_AWAKE) {
205 ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL); 204 ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START);
206 ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 205 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
207 } else {
208 ath_dbg(common, MCI, "MCI State mismatch: %d\n",
209 ar9003_mci_state(ah, MCI_STATE_BT, NULL));
210 } 206 }
211 break; 207 ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state);
212 case MCI_GPM_BT_CAL_DONE:
213 ar9003_mci_state(ah, MCI_STATE_BT, NULL);
214 break; 208 break;
215 case MCI_GPM_BT_CAL_GRANT: 209 case MCI_GPM_BT_CAL_GRANT:
216 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); 210 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
@@ -223,32 +217,42 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
223 } 217 }
224} 218}
225 219
220static void ath9k_mci_work(struct work_struct *work)
221{
222 struct ath_softc *sc = container_of(work, struct ath_softc, mci_work);
223
224 ath_mci_update_scheme(sc);
225}
226
226static void ath_mci_process_profile(struct ath_softc *sc, 227static void ath_mci_process_profile(struct ath_softc *sc,
227 struct ath_mci_profile_info *info) 228 struct ath_mci_profile_info *info)
228{ 229{
229 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 230 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
230 struct ath_btcoex *btcoex = &sc->btcoex; 231 struct ath_btcoex *btcoex = &sc->btcoex;
231 struct ath_mci_profile *mci = &btcoex->mci; 232 struct ath_mci_profile *mci = &btcoex->mci;
233 struct ath_mci_profile_info *entry = NULL;
234
235 entry = ath_mci_find_profile(mci, info);
236 if (entry)
237 memcpy(entry, info, 10);
232 238
233 if (info->start) { 239 if (info->start) {
234 if (!ath_mci_add_profile(common, mci, info)) 240 if (!entry && !ath_mci_add_profile(common, mci, info))
235 return; 241 return;
236 } else 242 } else
237 ath_mci_del_profile(common, mci, info); 243 ath_mci_del_profile(common, mci, entry);
238 244
239 btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; 245 btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD;
240 mci->aggr_limit = mci->num_sco ? 6 : 0; 246 mci->aggr_limit = mci->num_sco ? 6 : 0;
241 247
242 if (NUM_PROF(mci)) { 248 btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)];
249 if (NUM_PROF(mci))
243 btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; 250 btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
244 btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; 251 else
245 } else {
246 btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : 252 btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL :
247 ATH_BTCOEX_STOMP_LOW; 253 ATH_BTCOEX_STOMP_LOW;
248 btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
249 }
250 254
251 ath_mci_update_scheme(sc); 255 ieee80211_queue_work(sc->hw, &sc->mci_work);
252} 256}
253 257
254static void ath_mci_process_status(struct ath_softc *sc, 258static void ath_mci_process_status(struct ath_softc *sc,
@@ -263,8 +267,6 @@ static void ath_mci_process_status(struct ath_softc *sc,
263 if (status->is_link) 267 if (status->is_link)
264 return; 268 return;
265 269
266 memset(&info, 0, sizeof(struct ath_mci_profile_info));
267
268 info.conn_handle = status->conn_handle; 270 info.conn_handle = status->conn_handle;
269 if (ath_mci_find_profile(mci, &info)) 271 if (ath_mci_find_profile(mci, &info))
270 return; 272 return;
@@ -284,7 +286,7 @@ static void ath_mci_process_status(struct ath_softc *sc,
284 } while (++i < ATH_MCI_MAX_PROFILE); 286 } while (++i < ATH_MCI_MAX_PROFILE);
285 287
286 if (old_num_mgmt != mci->num_mgmt) 288 if (old_num_mgmt != mci->num_mgmt)
287 ath_mci_update_scheme(sc); 289 ieee80211_queue_work(sc->hw, &sc->mci_work);
288} 290}
289 291
290static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) 292static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
@@ -293,25 +295,20 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
293 struct ath_mci_profile_info profile_info; 295 struct ath_mci_profile_info profile_info;
294 struct ath_mci_profile_status profile_status; 296 struct ath_mci_profile_status profile_status;
295 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 297 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
296 u32 version; 298 u8 major, minor;
297 u8 major;
298 u8 minor;
299 u32 seq_num; 299 u32 seq_num;
300 300
301 switch (opcode) { 301 switch (opcode) {
302 case MCI_GPM_COEX_VERSION_QUERY: 302 case MCI_GPM_COEX_VERSION_QUERY:
303 version = ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION, 303 ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION);
304 NULL);
305 break; 304 break;
306 case MCI_GPM_COEX_VERSION_RESPONSE: 305 case MCI_GPM_COEX_VERSION_RESPONSE:
307 major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); 306 major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION);
308 minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); 307 minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION);
309 version = (major << 8) + minor; 308 ar9003_mci_set_bt_version(ah, major, minor);
310 version = ar9003_mci_state(ah, MCI_STATE_SET_BT_COEX_VERSION,
311 &version);
312 break; 309 break;
313 case MCI_GPM_COEX_STATUS_QUERY: 310 case MCI_GPM_COEX_STATUS_QUERY:
314 ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL); 311 ar9003_mci_send_wlan_channels(ah);
315 break; 312 break;
316 case MCI_GPM_COEX_BT_PROFILE_INFO: 313 case MCI_GPM_COEX_BT_PROFILE_INFO:
317 memcpy(&profile_info, 314 memcpy(&profile_info,
@@ -378,6 +375,7 @@ int ath_mci_setup(struct ath_softc *sc)
378 mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), 375 mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4),
379 mci->sched_buf.bf_paddr); 376 mci->sched_buf.bf_paddr);
380 377
378 INIT_WORK(&sc->mci_work, ath9k_mci_work);
381 ath_dbg(common, MCI, "MCI Initialized\n"); 379 ath_dbg(common, MCI, "MCI Initialized\n");
382 380
383 return 0; 381 return 0;
@@ -405,6 +403,7 @@ void ath_mci_intr(struct ath_softc *sc)
405 struct ath_mci_coex *mci = &sc->mci_coex; 403 struct ath_mci_coex *mci = &sc->mci_coex;
406 struct ath_hw *ah = sc->sc_ah; 404 struct ath_hw *ah = sc->sc_ah;
407 struct ath_common *common = ath9k_hw_common(ah); 405 struct ath_common *common = ath9k_hw_common(ah);
406 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
408 u32 mci_int, mci_int_rxmsg; 407 u32 mci_int, mci_int_rxmsg;
409 u32 offset, subtype, opcode; 408 u32 offset, subtype, opcode;
410 u32 *pgpm; 409 u32 *pgpm;
@@ -413,8 +412,8 @@ void ath_mci_intr(struct ath_softc *sc)
413 412
414 ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); 413 ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg);
415 414
416 if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { 415 if (ar9003_mci_state(ah, MCI_STATE_ENABLE) == 0) {
417 ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); 416 ar9003_mci_get_next_gpm_offset(ah, true, NULL);
418 return; 417 return;
419 } 418 }
420 419
@@ -433,46 +432,41 @@ void ath_mci_intr(struct ath_softc *sc)
433 NULL, 0, true, false); 432 NULL, 0, true, false);
434 433
435 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE; 434 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE;
436 ar9003_mci_state(ah, MCI_STATE_RESET_REQ_WAKE, NULL); 435 ar9003_mci_state(ah, MCI_STATE_RESET_REQ_WAKE);
437 436
438 /* 437 /*
439 * always do this for recovery and 2G/5G toggling and LNA_TRANS 438 * always do this for recovery and 2G/5G toggling and LNA_TRANS
440 */ 439 */
441 ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL); 440 ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE);
442 } 441 }
443 442
444 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) { 443 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) {
445 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING; 444 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING;
446 445
447 if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_SLEEP) { 446 if ((mci_hw->bt_state == MCI_BT_SLEEP) &&
448 if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != 447 (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) !=
449 MCI_BT_SLEEP) 448 MCI_BT_SLEEP))
450 ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, 449 ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE);
451 NULL);
452 }
453 } 450 }
454 451
455 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { 452 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) {
456 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING; 453 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING;
457 454
458 if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { 455 if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
459 if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != 456 (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) !=
460 MCI_BT_AWAKE) 457 MCI_BT_AWAKE))
461 ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP, 458 mci_hw->bt_state = MCI_BT_SLEEP;
462 NULL);
463 }
464 } 459 }
465 460
466 if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || 461 if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) ||
467 (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { 462 (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) {
468 ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL); 463 ar9003_mci_state(ah, MCI_STATE_RECOVER_RX);
469 skip_gpm = true; 464 skip_gpm = true;
470 } 465 }
471 466
472 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) { 467 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) {
473 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO; 468 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO;
474 offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET, 469 offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET);
475 NULL);
476 } 470 }
477 471
478 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) { 472 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) {
@@ -481,8 +475,8 @@ void ath_mci_intr(struct ath_softc *sc)
481 while (more_data == MCI_GPM_MORE) { 475 while (more_data == MCI_GPM_MORE) {
482 476
483 pgpm = mci->gpm_buf.bf_addr; 477 pgpm = mci->gpm_buf.bf_addr;
484 offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, 478 offset = ar9003_mci_get_next_gpm_offset(ah, false,
485 &more_data); 479 &more_data);
486 480
487 if (offset == MCI_GPM_INVALID) 481 if (offset == MCI_GPM_INVALID)
488 break; 482 break;
@@ -523,23 +517,17 @@ void ath_mci_intr(struct ath_softc *sc)
523 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; 517 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO;
524 518
525 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { 519 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) {
526 int value_dbm = ar9003_mci_state(ah, 520 int value_dbm = MS(mci_hw->cont_status,
527 MCI_STATE_CONT_RSSI_POWER, NULL); 521 AR_MCI_CONT_RSSI_POWER);
528 522
529 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; 523 mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO;
530 524
531 if (ar9003_mci_state(ah, MCI_STATE_CONT_TXRX, NULL)) 525 ath_dbg(common, MCI,
532 ath_dbg(common, MCI, 526 "MCI CONT_INFO: (%s) pri = %d pwr = %d dBm\n",
533 "MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n", 527 MS(mci_hw->cont_status, AR_MCI_CONT_TXRX) ?
534 ar9003_mci_state(ah, 528 "tx" : "rx",
535 MCI_STATE_CONT_PRIORITY, NULL), 529 MS(mci_hw->cont_status, AR_MCI_CONT_PRIORITY),
536 value_dbm); 530 value_dbm);
537 else
538 ath_dbg(common, MCI,
539 "MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n",
540 ar9003_mci_state(ah,
541 MCI_STATE_CONT_PRIORITY, NULL),
542 value_dbm);
543 } 531 }
544 532
545 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) 533 if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK)
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 92a6c0a87f89..e034add9cd5a 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -770,7 +770,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
770 struct ieee80211_tx_rate *rates = tx_info->control.rates; 770 struct ieee80211_tx_rate *rates = tx_info->control.rates;
771 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 771 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
772 __le16 fc = hdr->frame_control; 772 __le16 fc = hdr->frame_control;
773 u8 try_per_rate, i = 0, rix, high_rix; 773 u8 try_per_rate, i = 0, rix;
774 int is_probe = 0; 774 int is_probe = 0;
775 775
776 if (rate_control_send_low(sta, priv_sta, txrc)) 776 if (rate_control_send_low(sta, priv_sta, txrc))
@@ -791,7 +791,6 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
791 rate_table = ath_rc_priv->rate_table; 791 rate_table = ath_rc_priv->rate_table;
792 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, 792 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table,
793 &is_probe, false); 793 &is_probe, false);
794 high_rix = rix;
795 794
796 /* 795 /*
797 * If we're in HT mode and both us and our peer supports LDPC. 796 * If we're in HT mode and both us and our peer supports LDPC.
@@ -839,16 +838,16 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
839 try_per_rate = 8; 838 try_per_rate = 8;
840 839
841 /* 840 /*
842 * Use a legacy rate as last retry to ensure that the frame 841 * If the last rate in the rate series is MCS and has
843 * is tried in both MCS and legacy rates. 842 * more than 80% of per thresh, then use a legacy rate
843 * as last retry to ensure that the frame is tried in both
844 * MCS and legacy rate.
844 */ 845 */
845 if ((rates[2].flags & IEEE80211_TX_RC_MCS) && 846 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
846 (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) || 847 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy) &&
847 (ath_rc_priv->per[high_rix] > 45))) 848 (ath_rc_priv->per[rix] > 45))
848 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, 849 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table,
849 &is_probe, true); 850 &is_probe, true);
850 else
851 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
852 851
853 /* All other rates in the series have RTS enabled */ 852 /* All other rates in the series have RTS enabled */
854 ath_rc_rate_set_series(rate_table, &rates[i], txrc, 853 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 560d6effac7a..75acefbd4937 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -2098,8 +2098,8 @@ enum {
2098#define AR_MCI_CONT_STATUS 0x1848 2098#define AR_MCI_CONT_STATUS 0x1848
2099#define AR_MCI_CONT_RSSI_POWER 0x000000FF 2099#define AR_MCI_CONT_RSSI_POWER 0x000000FF
2100#define AR_MCI_CONT_RSSI_POWER_S 0 2100#define AR_MCI_CONT_RSSI_POWER_S 0
2101#define AR_MCI_CONT_RRIORITY 0x0000FF00 2101#define AR_MCI_CONT_PRIORITY 0x0000FF00
2102#define AR_MCI_CONT_RRIORITY_S 8 2102#define AR_MCI_CONT_PRIORITY_S 8
2103#define AR_MCI_CONT_TXRX 0x00010000 2103#define AR_MCI_CONT_TXRX 0x00010000
2104#define AR_MCI_CONT_TXRX_S 16 2104#define AR_MCI_CONT_TXRX_S 16
2105 2105
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index abb48032753b..9d5170b6df50 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -34,3 +34,5 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
34 sdio_chip.o 34 sdio_chip.o
35brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ 35brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
36 usb.o 36 usb.o
37brcmfmac-$(CONFIG_BRCMDBG) += \
38 dhd_dbg.o \ No newline at end of file
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 9f637014486e..a11fe54f5950 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -613,6 +613,9 @@ struct brcmf_pub {
613 struct work_struct multicast_work; 613 struct work_struct multicast_work;
614 u8 macvalue[ETH_ALEN]; 614 u8 macvalue[ETH_ALEN];
615 atomic_t pend_8021x_cnt; 615 atomic_t pend_8021x_cnt;
616#ifdef DEBUG
617 struct dentry *dbgfs_dir;
618#endif
616}; 619};
617 620
618struct brcmf_if_event { 621struct brcmf_if_event {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
new file mode 100644
index 000000000000..7f89540b56da
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -0,0 +1,126 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
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 ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/debugfs.h>
17#include <linux/if_ether.h>
18#include <linux/if.h>
19#include <linux/ieee80211.h>
20#include <linux/module.h>
21
22#include <defs.h>
23#include <brcmu_wifi.h>
24#include <brcmu_utils.h>
25#include "dhd.h"
26#include "dhd_bus.h"
27#include "dhd_dbg.h"
28
29static struct dentry *root_folder;
30
31void brcmf_debugfs_init(void)
32{
33 root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
34 if (IS_ERR(root_folder))
35 root_folder = NULL;
36}
37
38void brcmf_debugfs_exit(void)
39{
40 if (!root_folder)
41 return;
42
43 debugfs_remove_recursive(root_folder);
44 root_folder = NULL;
45}
46
47int brcmf_debugfs_attach(struct brcmf_pub *drvr)
48{
49 if (!root_folder)
50 return -ENODEV;
51
52 drvr->dbgfs_dir = debugfs_create_dir(dev_name(drvr->dev), root_folder);
53 return PTR_RET(drvr->dbgfs_dir);
54}
55
56void brcmf_debugfs_detach(struct brcmf_pub *drvr)
57{
58 if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
59 debugfs_remove_recursive(drvr->dbgfs_dir);
60}
61
62struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
63{
64 return drvr->dbgfs_dir;
65}
66
67static
68ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data,
69 size_t count, loff_t *ppos)
70{
71 struct brcmf_sdio_count *sdcnt = f->private_data;
72 char buf[750];
73 int res;
74
75 /* only allow read from start */
76 if (*ppos > 0)
77 return 0;
78
79 res = scnprintf(buf, sizeof(buf),
80 "intrcount: %u\nlastintrs: %u\n"
81 "pollcnt: %u\nregfails: %u\n"
82 "tx_sderrs: %u\nfcqueued: %u\n"
83 "rxrtx: %u\nrx_toolong: %u\n"
84 "rxc_errors: %u\nrx_hdrfail: %u\n"
85 "rx_badhdr: %u\nrx_badseq: %u\n"
86 "fc_rcvd: %u\nfc_xoff: %u\n"
87 "fc_xon: %u\nrxglomfail: %u\n"
88 "rxglomframes: %u\nrxglompkts: %u\n"
89 "f2rxhdrs: %u\nf2rxdata: %u\n"
90 "f2txdata: %u\nf1regdata: %u\n"
91 "tickcnt: %u\ntx_ctlerrs: %lu\n"
92 "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
93 "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
94 sdcnt->intrcount, sdcnt->lastintrs,
95 sdcnt->pollcnt, sdcnt->regfails,
96 sdcnt->tx_sderrs, sdcnt->fcqueued,
97 sdcnt->rxrtx, sdcnt->rx_toolong,
98 sdcnt->rxc_errors, sdcnt->rx_hdrfail,
99 sdcnt->rx_badhdr, sdcnt->rx_badseq,
100 sdcnt->fc_rcvd, sdcnt->fc_xoff,
101 sdcnt->fc_xon, sdcnt->rxglomfail,
102 sdcnt->rxglomframes, sdcnt->rxglompkts,
103 sdcnt->f2rxhdrs, sdcnt->f2rxdata,
104 sdcnt->f2txdata, sdcnt->f1regdata,
105 sdcnt->tickcnt, sdcnt->tx_ctlerrs,
106 sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
107 sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
108
109 return simple_read_from_buffer(data, count, ppos, buf, res);
110}
111
112static const struct file_operations brcmf_debugfs_sdio_counter_ops = {
113 .owner = THIS_MODULE,
114 .open = simple_open,
115 .read = brcmf_debugfs_sdio_counter_read
116};
117
118void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
119 struct brcmf_sdio_count *sdcnt)
120{
121 struct dentry *dentry = drvr->dbgfs_dir;
122
123 if (!IS_ERR_OR_NULL(dentry))
124 debugfs_create_file("counters", S_IRUGO, dentry,
125 sdcnt, &brcmf_debugfs_sdio_counter_ops);
126}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index a2c4576cf9ff..b784920532d3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -76,4 +76,63 @@ do { \
76 76
77extern int brcmf_msg_level; 77extern int brcmf_msg_level;
78 78
79/*
80 * hold counter variables used in brcmfmac sdio driver.
81 */
82struct brcmf_sdio_count {
83 uint intrcount; /* Count of device interrupt callbacks */
84 uint lastintrs; /* Count as of last watchdog timer */
85 uint pollcnt; /* Count of active polls */
86 uint regfails; /* Count of R_REG failures */
87 uint tx_sderrs; /* Count of tx attempts with sd errors */
88 uint fcqueued; /* Tx packets that got queued */
89 uint rxrtx; /* Count of rtx requests (NAK to dongle) */
90 uint rx_toolong; /* Receive frames too long to receive */
91 uint rxc_errors; /* SDIO errors when reading control frames */
92 uint rx_hdrfail; /* SDIO errors on header reads */
93 uint rx_badhdr; /* Bad received headers (roosync?) */
94 uint rx_badseq; /* Mismatched rx sequence number */
95 uint fc_rcvd; /* Number of flow-control events received */
96 uint fc_xoff; /* Number which turned on flow-control */
97 uint fc_xon; /* Number which turned off flow-control */
98 uint rxglomfail; /* Failed deglom attempts */
99 uint rxglomframes; /* Number of glom frames (superframes) */
100 uint rxglompkts; /* Number of packets from glom frames */
101 uint f2rxhdrs; /* Number of header reads */
102 uint f2rxdata; /* Number of frame data reads */
103 uint f2txdata; /* Number of f2 frame writes */
104 uint f1regdata; /* Number of f1 register accesses */
105 uint tickcnt; /* Number of watchdog been schedule */
106 ulong tx_ctlerrs; /* Err of sending ctrl frames */
107 ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
108 ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
109 ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
110 ulong rx_readahead_cnt; /* packets where header read-ahead was used */
111};
112
113struct brcmf_pub;
114#ifdef DEBUG
115void brcmf_debugfs_init(void);
116void brcmf_debugfs_exit(void);
117int brcmf_debugfs_attach(struct brcmf_pub *drvr);
118void brcmf_debugfs_detach(struct brcmf_pub *drvr);
119struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
120void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
121 struct brcmf_sdio_count *sdcnt);
122#else
123static inline void brcmf_debugfs_init(void)
124{
125}
126static inline void brcmf_debugfs_exit(void)
127{
128}
129static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
130{
131 return 0;
132}
133static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
134{
135}
136#endif
137
79#endif /* _BRCMF_DBG_H_ */ 138#endif /* _BRCMF_DBG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 8933f9b31a9a..01cf6c03390b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -1007,6 +1007,9 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
1007 drvr->bus_if->drvr = drvr; 1007 drvr->bus_if->drvr = drvr;
1008 drvr->dev = dev; 1008 drvr->dev = dev;
1009 1009
1010 /* create device debugfs folder */
1011 brcmf_debugfs_attach(drvr);
1012
1010 /* Attach and link in the protocol */ 1013 /* Attach and link in the protocol */
1011 ret = brcmf_proto_attach(drvr); 1014 ret = brcmf_proto_attach(drvr);
1012 if (ret != 0) { 1015 if (ret != 0) {
@@ -1123,6 +1126,7 @@ void brcmf_detach(struct device *dev)
1123 brcmf_proto_detach(drvr); 1126 brcmf_proto_detach(drvr);
1124 } 1127 }
1125 1128
1129 brcmf_debugfs_detach(drvr);
1126 bus_if->drvr = NULL; 1130 bus_if->drvr = NULL;
1127 kfree(drvr); 1131 kfree(drvr);
1128} 1132}
@@ -1192,6 +1196,8 @@ exit:
1192 1196
1193static void brcmf_driver_init(struct work_struct *work) 1197static void brcmf_driver_init(struct work_struct *work)
1194{ 1198{
1199 brcmf_debugfs_init();
1200
1195#ifdef CONFIG_BRCMFMAC_SDIO 1201#ifdef CONFIG_BRCMFMAC_SDIO
1196 brcmf_sdio_init(); 1202 brcmf_sdio_init();
1197#endif 1203#endif
@@ -1219,6 +1225,7 @@ static void __exit brcmfmac_module_exit(void)
1219#ifdef CONFIG_BRCMFMAC_USB 1225#ifdef CONFIG_BRCMFMAC_USB
1220 brcmf_usb_exit(); 1226 brcmf_usb_exit();
1221#endif 1227#endif
1228 brcmf_debugfs_exit();
1222} 1229}
1223 1230
1224module_init(brcmfmac_module_init); 1231module_init(brcmfmac_module_init);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 4deae28fc211..b023766954a6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -502,12 +502,9 @@ struct brcmf_sdio {
502 bool intr; /* Use interrupts */ 502 bool intr; /* Use interrupts */
503 bool poll; /* Use polling */ 503 bool poll; /* Use polling */
504 bool ipend; /* Device interrupt is pending */ 504 bool ipend; /* Device interrupt is pending */
505 uint intrcount; /* Count of device interrupt callbacks */
506 uint lastintrs; /* Count as of last watchdog timer */
507 uint spurious; /* Count of spurious interrupts */ 505 uint spurious; /* Count of spurious interrupts */
508 uint pollrate; /* Ticks between device polls */ 506 uint pollrate; /* Ticks between device polls */
509 uint polltick; /* Tick counter */ 507 uint polltick; /* Tick counter */
510 uint pollcnt; /* Count of active polls */
511 508
512#ifdef DEBUG 509#ifdef DEBUG
513 uint console_interval; 510 uint console_interval;
@@ -515,8 +512,6 @@ struct brcmf_sdio {
515 uint console_addr; /* Console address from shared struct */ 512 uint console_addr; /* Console address from shared struct */
516#endif /* DEBUG */ 513#endif /* DEBUG */
517 514
518 uint regfails; /* Count of R_REG failures */
519
520 uint clkstate; /* State of sd and backplane clock(s) */ 515 uint clkstate; /* State of sd and backplane clock(s) */
521 bool activity; /* Activity flag for clock down */ 516 bool activity; /* Activity flag for clock down */
522 s32 idletime; /* Control for activity timeout */ 517 s32 idletime; /* Control for activity timeout */
@@ -531,33 +526,6 @@ struct brcmf_sdio {
531/* Field to decide if rx of control frames happen in rxbuf or lb-pool */ 526/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
532 bool usebufpool; 527 bool usebufpool;
533 528
534 /* Some additional counters */
535 uint tx_sderrs; /* Count of tx attempts with sd errors */
536 uint fcqueued; /* Tx packets that got queued */
537 uint rxrtx; /* Count of rtx requests (NAK to dongle) */
538 uint rx_toolong; /* Receive frames too long to receive */
539 uint rxc_errors; /* SDIO errors when reading control frames */
540 uint rx_hdrfail; /* SDIO errors on header reads */
541 uint rx_badhdr; /* Bad received headers (roosync?) */
542 uint rx_badseq; /* Mismatched rx sequence number */
543 uint fc_rcvd; /* Number of flow-control events received */
544 uint fc_xoff; /* Number which turned on flow-control */
545 uint fc_xon; /* Number which turned off flow-control */
546 uint rxglomfail; /* Failed deglom attempts */
547 uint rxglomframes; /* Number of glom frames (superframes) */
548 uint rxglompkts; /* Number of packets from glom frames */
549 uint f2rxhdrs; /* Number of header reads */
550 uint f2rxdata; /* Number of frame data reads */
551 uint f2txdata; /* Number of f2 frame writes */
552 uint f1regdata; /* Number of f1 register accesses */
553 uint tickcnt; /* Number of watchdog been schedule */
554 unsigned long tx_ctlerrs; /* Err of sending ctrl frames */
555 unsigned long tx_ctlpkts; /* Ctrl frames sent to dongle */
556 unsigned long rx_ctlerrs; /* Err of processing rx ctrl frames */
557 unsigned long rx_ctlpkts; /* Ctrl frames processed from dongle */
558 unsigned long rx_readahead_cnt; /* Number of packets where header
559 * read-ahead was used. */
560
561 u8 *ctrl_frame_buf; 529 u8 *ctrl_frame_buf;
562 u32 ctrl_frame_len; 530 u32 ctrl_frame_len;
563 bool ctrl_frame_stat; 531 bool ctrl_frame_stat;
@@ -583,6 +551,7 @@ struct brcmf_sdio {
583 u32 fw_ptr; 551 u32 fw_ptr;
584 552
585 bool txoff; /* Transmit flow-controlled */ 553 bool txoff; /* Transmit flow-controlled */
554 struct brcmf_sdio_count sdcnt;
586}; 555};
587 556
588/* clkstate */ 557/* clkstate */
@@ -945,7 +914,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
945 if (ret == 0) 914 if (ret == 0)
946 w_sdreg32(bus, SMB_INT_ACK, 915 w_sdreg32(bus, SMB_INT_ACK,
947 offsetof(struct sdpcmd_regs, tosbmailbox)); 916 offsetof(struct sdpcmd_regs, tosbmailbox));
948 bus->f1regdata += 2; 917 bus->sdcnt.f1regdata += 2;
949 918
950 /* Dongle recomposed rx frames, accept them again */ 919 /* Dongle recomposed rx frames, accept them again */
951 if (hmb_data & HMB_DATA_NAKHANDLED) { 920 if (hmb_data & HMB_DATA_NAKHANDLED) {
@@ -984,12 +953,12 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
984 HMB_DATA_FCDATA_SHIFT; 953 HMB_DATA_FCDATA_SHIFT;
985 954
986 if (fcbits & ~bus->flowcontrol) 955 if (fcbits & ~bus->flowcontrol)
987 bus->fc_xoff++; 956 bus->sdcnt.fc_xoff++;
988 957
989 if (bus->flowcontrol & ~fcbits) 958 if (bus->flowcontrol & ~fcbits)
990 bus->fc_xon++; 959 bus->sdcnt.fc_xon++;
991 960
992 bus->fc_rcvd++; 961 bus->sdcnt.fc_rcvd++;
993 bus->flowcontrol = fcbits; 962 bus->flowcontrol = fcbits;
994 } 963 }
995 964
@@ -1021,7 +990,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1021 990
1022 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, 991 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
1023 SFC_RF_TERM, &err); 992 SFC_RF_TERM, &err);
1024 bus->f1regdata++; 993 bus->sdcnt.f1regdata++;
1025 994
1026 /* Wait until the packet has been flushed (device/FIFO stable) */ 995 /* Wait until the packet has been flushed (device/FIFO stable) */
1027 for (lastrbc = retries = 0xffff; retries > 0; retries--) { 996 for (lastrbc = retries = 0xffff; retries > 0; retries--) {
@@ -1029,7 +998,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1029 SBSDIO_FUNC1_RFRAMEBCHI, &err); 998 SBSDIO_FUNC1_RFRAMEBCHI, &err);
1030 lo = brcmf_sdio_regrb(bus->sdiodev, 999 lo = brcmf_sdio_regrb(bus->sdiodev,
1031 SBSDIO_FUNC1_RFRAMEBCLO, &err); 1000 SBSDIO_FUNC1_RFRAMEBCLO, &err);
1032 bus->f1regdata += 2; 1001 bus->sdcnt.f1regdata += 2;
1033 1002
1034 if ((hi == 0) && (lo == 0)) 1003 if ((hi == 0) && (lo == 0))
1035 break; 1004 break;
@@ -1047,11 +1016,11 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1047 brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries); 1016 brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries);
1048 1017
1049 if (rtx) { 1018 if (rtx) {
1050 bus->rxrtx++; 1019 bus->sdcnt.rxrtx++;
1051 err = w_sdreg32(bus, SMB_NAK, 1020 err = w_sdreg32(bus, SMB_NAK,
1052 offsetof(struct sdpcmd_regs, tosbmailbox)); 1021 offsetof(struct sdpcmd_regs, tosbmailbox));
1053 1022
1054 bus->f1regdata++; 1023 bus->sdcnt.f1regdata++;
1055 if (err == 0) 1024 if (err == 0)
1056 bus->rxskip = true; 1025 bus->rxskip = true;
1057 } 1026 }
@@ -1243,7 +1212,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1243 dlen); 1212 dlen);
1244 errcode = -1; 1213 errcode = -1;
1245 } 1214 }
1246 bus->f2rxdata++; 1215 bus->sdcnt.f2rxdata++;
1247 1216
1248 /* On failure, kill the superframe, allow a couple retries */ 1217 /* On failure, kill the superframe, allow a couple retries */
1249 if (errcode < 0) { 1218 if (errcode < 0) {
@@ -1256,7 +1225,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1256 } else { 1225 } else {
1257 bus->glomerr = 0; 1226 bus->glomerr = 0;
1258 brcmf_sdbrcm_rxfail(bus, true, false); 1227 brcmf_sdbrcm_rxfail(bus, true, false);
1259 bus->rxglomfail++; 1228 bus->sdcnt.rxglomfail++;
1260 brcmf_sdbrcm_free_glom(bus); 1229 brcmf_sdbrcm_free_glom(bus);
1261 } 1230 }
1262 return 0; 1231 return 0;
@@ -1312,7 +1281,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1312 if (rxseq != seq) { 1281 if (rxseq != seq) {
1313 brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n", 1282 brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n",
1314 seq, rxseq); 1283 seq, rxseq);
1315 bus->rx_badseq++; 1284 bus->sdcnt.rx_badseq++;
1316 rxseq = seq; 1285 rxseq = seq;
1317 } 1286 }
1318 1287
@@ -1376,7 +1345,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1376 } else { 1345 } else {
1377 bus->glomerr = 0; 1346 bus->glomerr = 0;
1378 brcmf_sdbrcm_rxfail(bus, true, false); 1347 brcmf_sdbrcm_rxfail(bus, true, false);
1379 bus->rxglomfail++; 1348 bus->sdcnt.rxglomfail++;
1380 brcmf_sdbrcm_free_glom(bus); 1349 brcmf_sdbrcm_free_glom(bus);
1381 } 1350 }
1382 bus->nextlen = 0; 1351 bus->nextlen = 0;
@@ -1402,7 +1371,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1402 if (rxseq != seq) { 1371 if (rxseq != seq) {
1403 brcmf_dbg(GLOM, "rx_seq %d, expected %d\n", 1372 brcmf_dbg(GLOM, "rx_seq %d, expected %d\n",
1404 seq, rxseq); 1373 seq, rxseq);
1405 bus->rx_badseq++; 1374 bus->sdcnt.rx_badseq++;
1406 rxseq = seq; 1375 rxseq = seq;
1407 } 1376 }
1408 rxseq++; 1377 rxseq++;
@@ -1441,8 +1410,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1441 down(&bus->sdsem); 1410 down(&bus->sdsem);
1442 } 1411 }
1443 1412
1444 bus->rxglomframes++; 1413 bus->sdcnt.rxglomframes++;
1445 bus->rxglompkts += bus->glom.qlen; 1414 bus->sdcnt.rxglompkts += bus->glom.qlen;
1446 } 1415 }
1447 return num; 1416 return num;
1448} 1417}
@@ -1526,7 +1495,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1526 brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", 1495 brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
1527 len, len - doff, bus->sdiodev->bus_if->maxctl); 1496 len, len - doff, bus->sdiodev->bus_if->maxctl);
1528 bus->sdiodev->bus_if->dstats.rx_errors++; 1497 bus->sdiodev->bus_if->dstats.rx_errors++;
1529 bus->rx_toolong++; 1498 bus->sdcnt.rx_toolong++;
1530 brcmf_sdbrcm_rxfail(bus, false, false); 1499 brcmf_sdbrcm_rxfail(bus, false, false);
1531 goto done; 1500 goto done;
1532 } 1501 }
@@ -1536,13 +1505,13 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1536 bus->sdiodev->sbwad, 1505 bus->sdiodev->sbwad,
1537 SDIO_FUNC_2, 1506 SDIO_FUNC_2,
1538 F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen); 1507 F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen);
1539 bus->f2rxdata++; 1508 bus->sdcnt.f2rxdata++;
1540 1509
1541 /* Control frame failures need retransmission */ 1510 /* Control frame failures need retransmission */
1542 if (sdret < 0) { 1511 if (sdret < 0) {
1543 brcmf_dbg(ERROR, "read %d control bytes failed: %d\n", 1512 brcmf_dbg(ERROR, "read %d control bytes failed: %d\n",
1544 rdlen, sdret); 1513 rdlen, sdret);
1545 bus->rxc_errors++; 1514 bus->sdcnt.rxc_errors++;
1546 brcmf_sdbrcm_rxfail(bus, true, true); 1515 brcmf_sdbrcm_rxfail(bus, true, true);
1547 goto done; 1516 goto done;
1548 } 1517 }
@@ -1589,7 +1558,7 @@ brcmf_alloc_pkt_and_read(struct brcmf_sdio *bus, u16 rdlen,
1589 /* Read the entire frame */ 1558 /* Read the entire frame */
1590 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1559 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1591 SDIO_FUNC_2, F2SYNC, *pkt); 1560 SDIO_FUNC_2, F2SYNC, *pkt);
1592 bus->f2rxdata++; 1561 bus->sdcnt.f2rxdata++;
1593 1562
1594 if (sdret < 0) { 1563 if (sdret < 0) {
1595 brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n", 1564 brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n",
@@ -1630,7 +1599,7 @@ brcmf_check_rxbuf(struct brcmf_sdio *bus, struct sk_buff *pkt, u8 *rxbuf,
1630 if ((u16)~(*len ^ check)) { 1599 if ((u16)~(*len ^ check)) {
1631 brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n", 1600 brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n",
1632 nextlen, *len, check); 1601 nextlen, *len, check);
1633 bus->rx_badhdr++; 1602 bus->sdcnt.rx_badhdr++;
1634 brcmf_sdbrcm_rxfail(bus, false, false); 1603 brcmf_sdbrcm_rxfail(bus, false, false);
1635 goto fail; 1604 goto fail;
1636 } 1605 }
@@ -1746,7 +1715,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1746 bus->nextlen = 0; 1715 bus->nextlen = 0;
1747 } 1716 }
1748 1717
1749 bus->rx_readahead_cnt++; 1718 bus->sdcnt.rx_readahead_cnt++;
1750 1719
1751 /* Handle Flow Control */ 1720 /* Handle Flow Control */
1752 fcbits = SDPCM_FCMASK_VALUE( 1721 fcbits = SDPCM_FCMASK_VALUE(
@@ -1754,12 +1723,12 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1754 1723
1755 if (bus->flowcontrol != fcbits) { 1724 if (bus->flowcontrol != fcbits) {
1756 if (~bus->flowcontrol & fcbits) 1725 if (~bus->flowcontrol & fcbits)
1757 bus->fc_xoff++; 1726 bus->sdcnt.fc_xoff++;
1758 1727
1759 if (bus->flowcontrol & ~fcbits) 1728 if (bus->flowcontrol & ~fcbits)
1760 bus->fc_xon++; 1729 bus->sdcnt.fc_xon++;
1761 1730
1762 bus->fc_rcvd++; 1731 bus->sdcnt.fc_rcvd++;
1763 bus->flowcontrol = fcbits; 1732 bus->flowcontrol = fcbits;
1764 } 1733 }
1765 1734
@@ -1767,7 +1736,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1767 if (rxseq != seq) { 1736 if (rxseq != seq) {
1768 brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n", 1737 brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n",
1769 seq, rxseq); 1738 seq, rxseq);
1770 bus->rx_badseq++; 1739 bus->sdcnt.rx_badseq++;
1771 rxseq = seq; 1740 rxseq = seq;
1772 } 1741 }
1773 1742
@@ -1814,11 +1783,11 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1814 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, 1783 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
1815 SDIO_FUNC_2, F2SYNC, bus->rxhdr, 1784 SDIO_FUNC_2, F2SYNC, bus->rxhdr,
1816 BRCMF_FIRSTREAD); 1785 BRCMF_FIRSTREAD);
1817 bus->f2rxhdrs++; 1786 bus->sdcnt.f2rxhdrs++;
1818 1787
1819 if (sdret < 0) { 1788 if (sdret < 0) {
1820 brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret); 1789 brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret);
1821 bus->rx_hdrfail++; 1790 bus->sdcnt.rx_hdrfail++;
1822 brcmf_sdbrcm_rxfail(bus, true, true); 1791 brcmf_sdbrcm_rxfail(bus, true, true);
1823 continue; 1792 continue;
1824 } 1793 }
@@ -1840,7 +1809,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1840 if ((u16) ~(len ^ check)) { 1809 if ((u16) ~(len ^ check)) {
1841 brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n", 1810 brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n",
1842 len, check); 1811 len, check);
1843 bus->rx_badhdr++; 1812 bus->sdcnt.rx_badhdr++;
1844 brcmf_sdbrcm_rxfail(bus, false, false); 1813 brcmf_sdbrcm_rxfail(bus, false, false);
1845 continue; 1814 continue;
1846 } 1815 }
@@ -1861,7 +1830,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1861 if ((doff < SDPCM_HDRLEN) || (doff > len)) { 1830 if ((doff < SDPCM_HDRLEN) || (doff > len)) {
1862 brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n", 1831 brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n",
1863 doff, len, SDPCM_HDRLEN, seq); 1832 doff, len, SDPCM_HDRLEN, seq);
1864 bus->rx_badhdr++; 1833 bus->sdcnt.rx_badhdr++;
1865 brcmf_sdbrcm_rxfail(bus, false, false); 1834 brcmf_sdbrcm_rxfail(bus, false, false);
1866 continue; 1835 continue;
1867 } 1836 }
@@ -1880,19 +1849,19 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1880 1849
1881 if (bus->flowcontrol != fcbits) { 1850 if (bus->flowcontrol != fcbits) {
1882 if (~bus->flowcontrol & fcbits) 1851 if (~bus->flowcontrol & fcbits)
1883 bus->fc_xoff++; 1852 bus->sdcnt.fc_xoff++;
1884 1853
1885 if (bus->flowcontrol & ~fcbits) 1854 if (bus->flowcontrol & ~fcbits)
1886 bus->fc_xon++; 1855 bus->sdcnt.fc_xon++;
1887 1856
1888 bus->fc_rcvd++; 1857 bus->sdcnt.fc_rcvd++;
1889 bus->flowcontrol = fcbits; 1858 bus->flowcontrol = fcbits;
1890 } 1859 }
1891 1860
1892 /* Check and update sequence number */ 1861 /* Check and update sequence number */
1893 if (rxseq != seq) { 1862 if (rxseq != seq) {
1894 brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq); 1863 brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq);
1895 bus->rx_badseq++; 1864 bus->sdcnt.rx_badseq++;
1896 rxseq = seq; 1865 rxseq = seq;
1897 } 1866 }
1898 1867
@@ -1937,7 +1906,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1937 brcmf_dbg(ERROR, "too long: len %d rdlen %d\n", 1906 brcmf_dbg(ERROR, "too long: len %d rdlen %d\n",
1938 len, rdlen); 1907 len, rdlen);
1939 bus->sdiodev->bus_if->dstats.rx_errors++; 1908 bus->sdiodev->bus_if->dstats.rx_errors++;
1940 bus->rx_toolong++; 1909 bus->sdcnt.rx_toolong++;
1941 brcmf_sdbrcm_rxfail(bus, false, false); 1910 brcmf_sdbrcm_rxfail(bus, false, false);
1942 continue; 1911 continue;
1943 } 1912 }
@@ -1960,7 +1929,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1960 /* Read the remaining frame data */ 1929 /* Read the remaining frame data */
1961 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1930 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1962 SDIO_FUNC_2, F2SYNC, pkt); 1931 SDIO_FUNC_2, F2SYNC, pkt);
1963 bus->f2rxdata++; 1932 bus->sdcnt.f2rxdata++;
1964 1933
1965 if (sdret < 0) { 1934 if (sdret < 0) {
1966 brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen, 1935 brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen,
@@ -2147,18 +2116,18 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
2147 2116
2148 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, 2117 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
2149 SDIO_FUNC_2, F2SYNC, pkt); 2118 SDIO_FUNC_2, F2SYNC, pkt);
2150 bus->f2txdata++; 2119 bus->sdcnt.f2txdata++;
2151 2120
2152 if (ret < 0) { 2121 if (ret < 0) {
2153 /* On failure, abort the command and terminate the frame */ 2122 /* On failure, abort the command and terminate the frame */
2154 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", 2123 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2155 ret); 2124 ret);
2156 bus->tx_sderrs++; 2125 bus->sdcnt.tx_sderrs++;
2157 2126
2158 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2127 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2159 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, 2128 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2160 SFC_WF_TERM, NULL); 2129 SFC_WF_TERM, NULL);
2161 bus->f1regdata++; 2130 bus->sdcnt.f1regdata++;
2162 2131
2163 for (i = 0; i < 3; i++) { 2132 for (i = 0; i < 3; i++) {
2164 u8 hi, lo; 2133 u8 hi, lo;
@@ -2166,7 +2135,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
2166 SBSDIO_FUNC1_WFRAMEBCHI, NULL); 2135 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2167 lo = brcmf_sdio_regrb(bus->sdiodev, 2136 lo = brcmf_sdio_regrb(bus->sdiodev,
2168 SBSDIO_FUNC1_WFRAMEBCLO, NULL); 2137 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2169 bus->f1regdata += 2; 2138 bus->sdcnt.f1regdata += 2;
2170 if ((hi == 0) && (lo == 0)) 2139 if ((hi == 0) && (lo == 0))
2171 break; 2140 break;
2172 } 2141 }
@@ -2224,7 +2193,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2224 ret = r_sdreg32(bus, &intstatus, 2193 ret = r_sdreg32(bus, &intstatus,
2225 offsetof(struct sdpcmd_regs, 2194 offsetof(struct sdpcmd_regs,
2226 intstatus)); 2195 intstatus));
2227 bus->f2txdata++; 2196 bus->sdcnt.f2txdata++;
2228 if (ret != 0) 2197 if (ret != 0)
2229 break; 2198 break;
2230 if (intstatus & bus->hostintmask) 2199 if (intstatus & bus->hostintmask)
@@ -2417,7 +2386,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2417 bus->ipend = false; 2386 bus->ipend = false;
2418 err = r_sdreg32(bus, &newstatus, 2387 err = r_sdreg32(bus, &newstatus,
2419 offsetof(struct sdpcmd_regs, intstatus)); 2388 offsetof(struct sdpcmd_regs, intstatus));
2420 bus->f1regdata++; 2389 bus->sdcnt.f1regdata++;
2421 if (err != 0) 2390 if (err != 0)
2422 newstatus = 0; 2391 newstatus = 0;
2423 newstatus &= bus->hostintmask; 2392 newstatus &= bus->hostintmask;
@@ -2426,7 +2395,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2426 err = w_sdreg32(bus, newstatus, 2395 err = w_sdreg32(bus, newstatus,
2427 offsetof(struct sdpcmd_regs, 2396 offsetof(struct sdpcmd_regs,
2428 intstatus)); 2397 intstatus));
2429 bus->f1regdata++; 2398 bus->sdcnt.f1regdata++;
2430 } 2399 }
2431 } 2400 }
2432 2401
@@ -2445,7 +2414,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2445 2414
2446 err = r_sdreg32(bus, &newstatus, 2415 err = r_sdreg32(bus, &newstatus,
2447 offsetof(struct sdpcmd_regs, intstatus)); 2416 offsetof(struct sdpcmd_regs, intstatus));
2448 bus->f1regdata += 2; 2417 bus->sdcnt.f1regdata += 2;
2449 bus->fcstate = 2418 bus->fcstate =
2450 !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); 2419 !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
2451 intstatus |= (newstatus & bus->hostintmask); 2420 intstatus |= (newstatus & bus->hostintmask);
@@ -2510,13 +2479,13 @@ clkwait:
2510 terminate the frame */ 2479 terminate the frame */
2511 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", 2480 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2512 ret); 2481 ret);
2513 bus->tx_sderrs++; 2482 bus->sdcnt.tx_sderrs++;
2514 2483
2515 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2484 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2516 2485
2517 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, 2486 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2518 SFC_WF_TERM, &err); 2487 SFC_WF_TERM, &err);
2519 bus->f1regdata++; 2488 bus->sdcnt.f1regdata++;
2520 2489
2521 for (i = 0; i < 3; i++) { 2490 for (i = 0; i < 3; i++) {
2522 u8 hi, lo; 2491 u8 hi, lo;
@@ -2526,7 +2495,7 @@ clkwait:
2526 lo = brcmf_sdio_regrb(bus->sdiodev, 2495 lo = brcmf_sdio_regrb(bus->sdiodev,
2527 SBSDIO_FUNC1_WFRAMEBCLO, 2496 SBSDIO_FUNC1_WFRAMEBCLO,
2528 &err); 2497 &err);
2529 bus->f1regdata += 2; 2498 bus->sdcnt.f1regdata += 2;
2530 if ((hi == 0) && (lo == 0)) 2499 if ((hi == 0) && (lo == 0))
2531 break; 2500 break;
2532 } 2501 }
@@ -2657,7 +2626,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
2657 /* Check for existing queue, current flow-control, 2626 /* Check for existing queue, current flow-control,
2658 pending event, or pending clock */ 2627 pending event, or pending clock */
2659 brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq)); 2628 brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq));
2660 bus->fcqueued++; 2629 bus->sdcnt.fcqueued++;
2661 2630
2662 /* Priority based enq */ 2631 /* Priority based enq */
2663 spin_lock_bh(&bus->txqlock); 2632 spin_lock_bh(&bus->txqlock);
@@ -2845,13 +2814,13 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2845 /* On failure, abort the command and terminate the frame */ 2814 /* On failure, abort the command and terminate the frame */
2846 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", 2815 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2847 ret); 2816 ret);
2848 bus->tx_sderrs++; 2817 bus->sdcnt.tx_sderrs++;
2849 2818
2850 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2819 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
2851 2820
2852 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, 2821 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
2853 SFC_WF_TERM, NULL); 2822 SFC_WF_TERM, NULL);
2854 bus->f1regdata++; 2823 bus->sdcnt.f1regdata++;
2855 2824
2856 for (i = 0; i < 3; i++) { 2825 for (i = 0; i < 3; i++) {
2857 u8 hi, lo; 2826 u8 hi, lo;
@@ -2859,7 +2828,7 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2859 SBSDIO_FUNC1_WFRAMEBCHI, NULL); 2828 SBSDIO_FUNC1_WFRAMEBCHI, NULL);
2860 lo = brcmf_sdio_regrb(bus->sdiodev, 2829 lo = brcmf_sdio_regrb(bus->sdiodev,
2861 SBSDIO_FUNC1_WFRAMEBCLO, NULL); 2830 SBSDIO_FUNC1_WFRAMEBCLO, NULL);
2862 bus->f1regdata += 2; 2831 bus->sdcnt.f1regdata += 2;
2863 if (hi == 0 && lo == 0) 2832 if (hi == 0 && lo == 0)
2864 break; 2833 break;
2865 } 2834 }
@@ -2976,13 +2945,26 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2976 up(&bus->sdsem); 2945 up(&bus->sdsem);
2977 2946
2978 if (ret) 2947 if (ret)
2979 bus->tx_ctlerrs++; 2948 bus->sdcnt.tx_ctlerrs++;
2980 else 2949 else
2981 bus->tx_ctlpkts++; 2950 bus->sdcnt.tx_ctlpkts++;
2982 2951
2983 return ret ? -EIO : 0; 2952 return ret ? -EIO : 0;
2984} 2953}
2985 2954
2955#ifdef DEBUG
2956static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
2957{
2958 struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr;
2959
2960 brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
2961}
2962#else
2963static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
2964{
2965}
2966#endif /* DEBUG */
2967
2986static int 2968static int
2987brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) 2969brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
2988{ 2970{
@@ -3017,9 +2999,9 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
3017 } 2999 }
3018 3000
3019 if (rxlen) 3001 if (rxlen)
3020 bus->rx_ctlpkts++; 3002 bus->sdcnt.rx_ctlpkts++;
3021 else 3003 else
3022 bus->rx_ctlerrs++; 3004 bus->sdcnt.rx_ctlerrs++;
3023 3005
3024 return rxlen ? (int)rxlen : -ETIMEDOUT; 3006 return rxlen ? (int)rxlen : -ETIMEDOUT;
3025} 3007}
@@ -3419,7 +3401,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3419 return 0; 3401 return 0;
3420 3402
3421 /* Start the watchdog timer */ 3403 /* Start the watchdog timer */
3422 bus->tickcnt = 0; 3404 bus->sdcnt.tickcnt = 0;
3423 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); 3405 brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
3424 3406
3425 down(&bus->sdsem); 3407 down(&bus->sdsem);
@@ -3512,7 +3494,7 @@ void brcmf_sdbrcm_isr(void *arg)
3512 return; 3494 return;
3513 } 3495 }
3514 /* Count the interrupt call */ 3496 /* Count the interrupt call */
3515 bus->intrcount++; 3497 bus->sdcnt.intrcount++;
3516 bus->ipend = true; 3498 bus->ipend = true;
3517 3499
3518 /* Shouldn't get this interrupt if we're sleeping? */ 3500 /* Shouldn't get this interrupt if we're sleeping? */
@@ -3554,7 +3536,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3554 bus->polltick = 0; 3536 bus->polltick = 0;
3555 3537
3556 /* Check device if no interrupts */ 3538 /* Check device if no interrupts */
3557 if (!bus->intr || (bus->intrcount == bus->lastintrs)) { 3539 if (!bus->intr ||
3540 (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) {
3558 3541
3559 if (!bus->dpc_sched) { 3542 if (!bus->dpc_sched) {
3560 u8 devpend; 3543 u8 devpend;
@@ -3569,7 +3552,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3569 /* If there is something, make like the ISR and 3552 /* If there is something, make like the ISR and
3570 schedule the DPC */ 3553 schedule the DPC */
3571 if (intstatus) { 3554 if (intstatus) {
3572 bus->pollcnt++; 3555 bus->sdcnt.pollcnt++;
3573 bus->ipend = true; 3556 bus->ipend = true;
3574 3557
3575 bus->dpc_sched = true; 3558 bus->dpc_sched = true;
@@ -3581,7 +3564,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3581 } 3564 }
3582 3565
3583 /* Update interrupt tracking */ 3566 /* Update interrupt tracking */
3584 bus->lastintrs = bus->intrcount; 3567 bus->sdcnt.lastintrs = bus->sdcnt.intrcount;
3585 } 3568 }
3586#ifdef DEBUG 3569#ifdef DEBUG
3587 /* Poll for console output periodically */ 3570 /* Poll for console output periodically */
@@ -3793,7 +3776,7 @@ brcmf_sdbrcm_watchdog_thread(void *data)
3793 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { 3776 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) {
3794 brcmf_sdbrcm_bus_watchdog(bus); 3777 brcmf_sdbrcm_bus_watchdog(bus);
3795 /* Count the tick for reference */ 3778 /* Count the tick for reference */
3796 bus->tickcnt++; 3779 bus->sdcnt.tickcnt++;
3797 } else 3780 } else
3798 break; 3781 break;
3799 } 3782 }
@@ -3834,7 +3817,6 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
3834static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) 3817static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
3835{ 3818{
3836 brcmf_dbg(TRACE, "Enter\n"); 3819 brcmf_dbg(TRACE, "Enter\n");
3837
3838 if (bus) { 3820 if (bus) {
3839 /* De-register interrupt handler */ 3821 /* De-register interrupt handler */
3840 brcmf_sdio_intr_unregister(bus->sdiodev); 3822 brcmf_sdio_intr_unregister(bus->sdiodev);
@@ -3938,6 +3920,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3938 goto fail; 3920 goto fail;
3939 } 3921 }
3940 3922
3923 brcmf_sdio_debugfs_create(bus);
3941 brcmf_dbg(INFO, "completed!!\n"); 3924 brcmf_dbg(INFO, "completed!!\n");
3942 3925
3943 /* if firmware path present try to download and bring up bus */ 3926 /* if firmware path present try to download and bring up bus */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 95b5902bc4b3..01b190a25d94 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -735,10 +735,8 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
735 * a candidate for aggregation 735 * a candidate for aggregation
736 */ 736 */
737 p = pktq_ppeek(&qi->q, prec); 737 p = pktq_ppeek(&qi->q, prec);
738 /* tx_info must be checked with current p */
739 tx_info = IEEE80211_SKB_CB(p);
740
741 if (p) { 738 if (p) {
739 tx_info = IEEE80211_SKB_CB(p);
742 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && 740 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
743 ((u8) (p->priority) == tid)) { 741 ((u8) (p->priority) == tid)) {
744 plen = p->len + AMPDU_MAX_MPDU_OVERHEAD; 742 plen = p->len + AMPDU_MAX_MPDU_OVERHEAD;
@@ -759,6 +757,7 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
759 p = NULL; 757 p = NULL;
760 continue; 758 continue;
761 } 759 }
760 /* next packet fit for aggregation so dequeue */
762 p = brcmu_pktq_pdeq(&qi->q, prec); 761 p = brcmu_pktq_pdeq(&qi->q, prec);
763 } else { 762 } else {
764 p = NULL; 763 p = NULL;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 50f92a0b7c41..341e06a0d6ec 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -721,14 +721,6 @@ static const struct ieee80211_ops brcms_ops = {
721 .flush = brcms_ops_flush, 721 .flush = brcms_ops_flush,
722}; 722};
723 723
724/*
725 * is called in brcms_bcma_probe() context, therefore no locking required.
726 */
727static int brcms_set_hint(struct brcms_info *wl, char *abbrev)
728{
729 return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
730}
731
732void brcms_dpc(unsigned long data) 724void brcms_dpc(unsigned long data)
733{ 725{
734 struct brcms_info *wl; 726 struct brcms_info *wl;
@@ -1068,9 +1060,9 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
1068 wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status" 1060 wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
1069 "%d\n", __func__, err); 1061 "%d\n", __func__, err);
1070 1062
1071 if (wl->pub->srom_ccode[0] && brcms_set_hint(wl, wl->pub->srom_ccode)) 1063 if (wl->pub->srom_ccode[0] &&
1072 wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", 1064 regulatory_hint(wl->wiphy, wl->pub->srom_ccode))
1073 __func__, err); 1065 wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__);
1074 1066
1075 n_adapters_found++; 1067 n_adapters_found++;
1076 return wl; 1068 return wl;
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 98c8f6449649..170ec330d2a9 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,7 +1,3 @@
1obj-$(CONFIG_IWLDVM) += dvm/
2
3CFLAGS_iwl-devtrace.o := -I$(src)
4
5# common 1# common
6obj-$(CONFIG_IWLWIFI) += iwlwifi.o 2obj-$(CONFIG_IWLWIFI) += iwlwifi.o
7iwlwifi-objs += iwl-io.o 3iwlwifi-objs += iwl-io.o
@@ -13,5 +9,11 @@ iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
13iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o 9iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o
14 10
15iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 11iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
12iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
16 13
17ccflags-y += -D__CHECK_ENDIAN__ -I$(src) 14ccflags-y += -D__CHECK_ENDIAN__ -I$(src)
15
16
17obj-$(CONFIG_IWLDVM) += dvm/
18
19CFLAGS_iwl-devtrace.o := -I$(src)
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 2ae3608472a6..6d102413dd94 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -395,8 +395,10 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
395} 395}
396 396
397extern int iwl_alive_start(struct iwl_priv *priv); 397extern int iwl_alive_start(struct iwl_priv *priv);
398/* svtool */ 398
399/* testmode support */
399#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE 400#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
401
400extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, 402extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data,
401 int len); 403 int len);
402extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, 404extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw,
@@ -404,13 +406,16 @@ extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw,
404 struct netlink_callback *cb, 406 struct netlink_callback *cb,
405 void *data, int len); 407 void *data, int len);
406extern void iwl_testmode_init(struct iwl_priv *priv); 408extern void iwl_testmode_init(struct iwl_priv *priv);
407extern void iwl_testmode_cleanup(struct iwl_priv *priv); 409extern void iwl_testmode_free(struct iwl_priv *priv);
410
408#else 411#else
412
409static inline 413static inline
410int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) 414int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
411{ 415{
412 return -ENOSYS; 416 return -ENOSYS;
413} 417}
418
414static inline 419static inline
415int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 420int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
416 struct netlink_callback *cb, 421 struct netlink_callback *cb,
@@ -418,12 +423,12 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
418{ 423{
419 return -ENOSYS; 424 return -ENOSYS;
420} 425}
421static inline 426
422void iwl_testmode_init(struct iwl_priv *priv) 427static inline void iwl_testmode_init(struct iwl_priv *priv)
423{ 428{
424} 429}
425static inline 430
426void iwl_testmode_cleanup(struct iwl_priv *priv) 431static inline void iwl_testmode_free(struct iwl_priv *priv)
427{ 432{
428} 433}
429#endif 434#endif
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 89f2e1040e7f..4620b657948a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -52,6 +52,8 @@
52#include "rs.h" 52#include "rs.h"
53#include "tt.h" 53#include "tt.h"
54 54
55#include "iwl-test.h"
56
55/* CT-KILL constants */ 57/* CT-KILL constants */
56#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ 58#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */
57#define CT_KILL_THRESHOLD 114 /* in Celsius */ 59#define CT_KILL_THRESHOLD 114 /* in Celsius */
@@ -596,24 +598,6 @@ struct iwl_lib_ops {
596 void (*temperature)(struct iwl_priv *priv); 598 void (*temperature)(struct iwl_priv *priv);
597}; 599};
598 600
599#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
600struct iwl_testmode_trace {
601 u32 buff_size;
602 u32 total_size;
603 u32 num_chunks;
604 u8 *cpu_addr;
605 u8 *trace_addr;
606 dma_addr_t dma_addr;
607 bool trace_enabled;
608};
609struct iwl_testmode_mem {
610 u32 buff_size;
611 u32 num_chunks;
612 u8 *buff_addr;
613 bool read_in_progress;
614};
615#endif
616
617struct iwl_wipan_noa_data { 601struct iwl_wipan_noa_data {
618 struct rcu_head rcu_head; 602 struct rcu_head rcu_head;
619 u32 length; 603 u32 length;
@@ -670,8 +654,6 @@ struct iwl_priv {
670 enum ieee80211_band band; 654 enum ieee80211_band band;
671 u8 valid_contexts; 655 u8 valid_contexts;
672 656
673 void (*pre_rx_handler)(struct iwl_priv *priv,
674 struct iwl_rx_cmd_buffer *rxb);
675 int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, 657 int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
676 struct iwl_rx_cmd_buffer *rxb, 658 struct iwl_rx_cmd_buffer *rxb,
677 struct iwl_device_cmd *cmd); 659 struct iwl_device_cmd *cmd);
@@ -895,9 +877,9 @@ struct iwl_priv {
895 struct led_classdev led; 877 struct led_classdev led;
896 unsigned long blink_on, blink_off; 878 unsigned long blink_on, blink_off;
897 bool led_registered; 879 bool led_registered;
880
898#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE 881#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
899 struct iwl_testmode_trace testmode_trace; 882 struct iwl_test tst;
900 struct iwl_testmode_mem testmode_mem;
901 u32 tm_fixed_rate; 883 u32 tm_fixed_rate;
902#endif 884#endif
903 885
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index cb1ca7a25dd5..76f259283c3a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -1265,7 +1265,7 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1265 * the mutex, this ensures we don't try to send two 1265 * the mutex, this ensures we don't try to send two
1266 * (or more) synchronous commands at a time. 1266 * (or more) synchronous commands at a time.
1267 */ 1267 */
1268 if (cmd->flags & CMD_SYNC) 1268 if (!(cmd->flags & CMD_ASYNC))
1269 lockdep_assert_held(&priv->mutex); 1269 lockdep_assert_held(&priv->mutex);
1270 1270
1271 if (priv->ucode_owner == IWL_OWNERSHIP_TM && 1271 if (priv->ucode_owner == IWL_OWNERSHIP_TM &&
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 599e8b41f5a8..9d2374862314 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -476,7 +476,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
476 } 476 }
477 477
478 if (priv->wowlan_sram) 478 if (priv->wowlan_sram)
479 _iwl_read_targ_mem_words( 479 _iwl_read_targ_mem_dwords(
480 priv->trans, 0x800000, 480 priv->trans, 0x800000,
481 priv->wowlan_sram, 481 priv->wowlan_sram,
482 img->sec[IWL_UCODE_SECTION_DATA].len / 4); 482 img->sec[IWL_UCODE_SECTION_DATA].len / 4);
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 1c2d0233a405..e620af3d592d 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -406,7 +406,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
406 406
407 base = priv->device_pointers.log_event_table; 407 base = priv->device_pointers.log_event_table;
408 if (iwlagn_hw_valid_rtc_data_addr(base)) { 408 if (iwlagn_hw_valid_rtc_data_addr(base)) {
409 iwl_read_targ_mem_words(priv->trans, base, &read, sizeof(read)); 409 iwl_read_targ_mem_bytes(priv->trans, base, &read, sizeof(read));
410 capacity = read.capacity; 410 capacity = read.capacity;
411 mode = read.mode; 411 mode = read.mode;
412 num_wraps = read.wrap_counter; 412 num_wraps = read.wrap_counter;
@@ -1548,7 +1548,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
1548 1548
1549 iwl_dbgfs_unregister(priv); 1549 iwl_dbgfs_unregister(priv);
1550 1550
1551 iwl_testmode_cleanup(priv); 1551 iwl_testmode_free(priv);
1552 iwlagn_mac_unregister(priv); 1552 iwlagn_mac_unregister(priv);
1553 1553
1554 iwl_tt_exit(priv); 1554 iwl_tt_exit(priv);
@@ -1671,7 +1671,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
1671 } 1671 }
1672 1672
1673 /*TODO: Update dbgfs with ISR error stats obtained below */ 1673 /*TODO: Update dbgfs with ISR error stats obtained below */
1674 iwl_read_targ_mem_words(trans, base, &table, sizeof(table)); 1674 iwl_read_targ_mem_bytes(trans, base, &table, sizeof(table));
1675 1675
1676 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { 1676 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
1677 IWL_ERR(trans, "Start IWL Error Log Dump:\n"); 1677 IWL_ERR(trans, "Start IWL Error Log Dump:\n");
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index 0ed90bb8b56a..c1f7a18e08dd 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -1124,8 +1124,6 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
1124{ 1124{
1125 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1125 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1126 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 1126 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
1127 void (*pre_rx_handler)(struct iwl_priv *,
1128 struct iwl_rx_cmd_buffer *);
1129 int err = 0; 1127 int err = 0;
1130 1128
1131 /* 1129 /*
@@ -1135,19 +1133,19 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
1135 */ 1133 */
1136 iwl_notification_wait_notify(&priv->notif_wait, pkt); 1134 iwl_notification_wait_notify(&priv->notif_wait, pkt);
1137 1135
1138 /* RX data may be forwarded to userspace (using pre_rx_handler) in one 1136#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1139 * of two cases: the first, that the user owns the uCode through 1137 /*
1140 * testmode - in such case the pre_rx_handler is set and no further 1138 * RX data may be forwarded to userspace in one
1141 * processing takes place. The other case is when the user want to 1139 * of two cases: the user owns the fw through testmode or when
1142 * monitor the rx w/o affecting the regular flow - the pre_rx_handler 1140 * the user requested to monitor the rx w/o affecting the regular flow.
1143 * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow 1141 * In these cases the iwl_test object will handle forwarding the rx
1142 * data to user space.
1143 * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow
1144 * continues. 1144 * continues.
1145 * We need to use ACCESS_ONCE to prevent a case where the handler
1146 * changes between the check and the call.
1147 */ 1145 */
1148 pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler); 1146 iwl_test_rx(&priv->tst, rxb);
1149 if (pre_rx_handler) 1147#endif
1150 pre_rx_handler(priv, rxb); 1148
1151 if (priv->ucode_owner != IWL_OWNERSHIP_TM) { 1149 if (priv->ucode_owner != IWL_OWNERSHIP_TM) {
1152 /* Based on type of command response or notification, 1150 /* Based on type of command response or notification,
1153 * handle those that need handling via function in 1151 * handle those that need handling via function in
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c
index e08b1a383594..57b918ce3b5f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/testmode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c
@@ -60,6 +60,7 @@
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63
63#include <linux/init.h> 64#include <linux/init.h>
64#include <linux/kernel.h> 65#include <linux/kernel.h>
65#include <linux/module.h> 66#include <linux/module.h>
@@ -69,354 +70,83 @@
69#include <net/cfg80211.h> 70#include <net/cfg80211.h>
70#include <net/mac80211.h> 71#include <net/mac80211.h>
71#include <net/netlink.h> 72#include <net/netlink.h>
73
72#include "iwl-debug.h" 74#include "iwl-debug.h"
73#include "iwl-io.h"
74#include "iwl-trans.h" 75#include "iwl-trans.h"
75#include "iwl-fh.h"
76#include "iwl-prph.h"
77#include "dev.h" 76#include "dev.h"
78#include "agn.h" 77#include "agn.h"
79#include "testmode.h" 78#include "iwl-test.h"
80 79#include "iwl-testmode.h"
81
82/* Periphery registers absolute lower bound. This is used in order to
83 * differentiate registery access through HBUS_TARG_PRPH_* and
84 * HBUS_TARG_MEM_* accesses.
85 */
86#define IWL_TM_ABS_PRPH_START (0xA00000)
87
88/* The TLVs used in the gnl message policy between the kernel module and
89 * user space application. iwl_testmode_gnl_msg_policy is to be carried
90 * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
91 * See testmode.h
92 */
93static
94struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
95 [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
96
97 [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
98 [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
99
100 [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
101 [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
102 [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
103
104 [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
105 [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
106 80
107 [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, }, 81static int iwl_testmode_send_cmd(struct iwl_op_mode *op_mode,
108 82 struct iwl_host_cmd *cmd)
109 [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
110 [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
111 [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },
112
113 [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
114
115 [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
116
117 [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, },
118 [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, },
119 [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, },
120
121 [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
122 [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
123 [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
124 [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
125 [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
126
127 [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, },
128};
129
130/*
131 * See the struct iwl_rx_packet in commands.h for the format of the
132 * received events from the device
133 */
134static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb)
135{ 83{
136 struct iwl_rx_packet *pkt = rxb_addr(rxb); 84 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
137 if (pkt) 85 return iwl_dvm_send_cmd(priv, cmd);
138 return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
139 else
140 return 0;
141} 86}
142 87
143 88static bool iwl_testmode_valid_hw_addr(u32 addr)
144/*
145 * This function multicasts the spontaneous messages from the device to the
146 * user space. It is invoked whenever there is a received messages
147 * from the device. This function is called within the ISR of the rx handlers
148 * in iwlagn driver.
149 *
150 * The parsing of the message content is left to the user space application,
151 * The message content is treated as unattacked raw data and is encapsulated
152 * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space.
153 *
154 * @priv: the instance of iwlwifi device
155 * @rxb: pointer to rx data content received by the ISR
156 *
157 * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[].
158 * For the messages multicasting to the user application, the mandatory
159 * TLV fields are :
160 * IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
161 * IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content
162 */
163
164static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
165 struct iwl_rx_cmd_buffer *rxb)
166{ 89{
167 struct ieee80211_hw *hw = priv->hw; 90 if (iwlagn_hw_valid_rtc_data_addr(addr))
168 struct sk_buff *skb; 91 return true;
169 void *data;
170 int length;
171 92
172 data = rxb_addr(rxb); 93 if (IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
173 length = get_event_length(rxb); 94 addr < IWLAGN_RTC_INST_UPPER_BOUND)
95 return true;
174 96
175 if (!data || length == 0) 97 return false;
176 return;
177
178 skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
179 GFP_ATOMIC);
180 if (skb == NULL) {
181 IWL_ERR(priv,
182 "Run out of memory for messages to user space ?\n");
183 return;
184 }
185 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
186 /* the length doesn't include len_n_flags field, so add it manually */
187 nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data))
188 goto nla_put_failure;
189 cfg80211_testmode_event(skb, GFP_ATOMIC);
190 return;
191
192nla_put_failure:
193 kfree_skb(skb);
194 IWL_ERR(priv, "Ouch, overran buffer, check allocation!\n");
195} 98}
196 99
197void iwl_testmode_init(struct iwl_priv *priv) 100static u32 iwl_testmode_get_fw_ver(struct iwl_op_mode *op_mode)
198{ 101{
199 priv->pre_rx_handler = NULL; 102 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
200 priv->testmode_trace.trace_enabled = false; 103 return priv->fw->ucode_ver;
201 priv->testmode_mem.read_in_progress = false;
202} 104}
203 105
204static void iwl_mem_cleanup(struct iwl_priv *priv) 106static struct sk_buff*
107iwl_testmode_alloc_reply(struct iwl_op_mode *op_mode, int len)
205{ 108{
206 if (priv->testmode_mem.read_in_progress) { 109 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
207 kfree(priv->testmode_mem.buff_addr); 110 return cfg80211_testmode_alloc_reply_skb(priv->hw->wiphy, len);
208 priv->testmode_mem.buff_addr = NULL;
209 priv->testmode_mem.buff_size = 0;
210 priv->testmode_mem.num_chunks = 0;
211 priv->testmode_mem.read_in_progress = false;
212 }
213} 111}
214 112
215static void iwl_trace_cleanup(struct iwl_priv *priv) 113static int iwl_testmode_reply(struct iwl_op_mode *op_mode, struct sk_buff *skb)
216{ 114{
217 if (priv->testmode_trace.trace_enabled) { 115 return cfg80211_testmode_reply(skb);
218 if (priv->testmode_trace.cpu_addr &&
219 priv->testmode_trace.dma_addr)
220 dma_free_coherent(priv->trans->dev,
221 priv->testmode_trace.total_size,
222 priv->testmode_trace.cpu_addr,
223 priv->testmode_trace.dma_addr);
224 priv->testmode_trace.trace_enabled = false;
225 priv->testmode_trace.cpu_addr = NULL;
226 priv->testmode_trace.trace_addr = NULL;
227 priv->testmode_trace.dma_addr = 0;
228 priv->testmode_trace.buff_size = 0;
229 priv->testmode_trace.total_size = 0;
230 }
231} 116}
232 117
233 118static struct sk_buff *iwl_testmode_alloc_event(struct iwl_op_mode *op_mode,
234void iwl_testmode_cleanup(struct iwl_priv *priv) 119 int len)
235{ 120{
236 iwl_trace_cleanup(priv); 121 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
237 iwl_mem_cleanup(priv); 122 return cfg80211_testmode_alloc_event_skb(priv->hw->wiphy, len,
123 GFP_ATOMIC);
238} 124}
239 125
240 126static void iwl_testmode_event(struct iwl_op_mode *op_mode, struct sk_buff *skb)
241/*
242 * This function handles the user application commands to the ucode.
243 *
244 * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and
245 * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the
246 * host command to the ucode.
247 *
248 * If any mandatory field is missing, -ENOMSG is replied to the user space
249 * application; otherwise, waits for the host command to be sent and checks
250 * the return code. In case or error, it is returned, otherwise a reply is
251 * allocated and the reply RX packet
252 * is returned.
253 *
254 * @hw: ieee80211_hw object that represents the device
255 * @tb: gnl message fields from the user space
256 */
257static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
258{ 127{
259 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 128 return cfg80211_testmode_event(skb, GFP_ATOMIC);
260 struct iwl_host_cmd cmd;
261 struct iwl_rx_packet *pkt;
262 struct sk_buff *skb;
263 void *reply_buf;
264 u32 reply_len;
265 int ret;
266 bool cmd_want_skb;
267
268 memset(&cmd, 0, sizeof(struct iwl_host_cmd));
269
270 if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
271 !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
272 IWL_ERR(priv, "Missing ucode command mandatory fields\n");
273 return -ENOMSG;
274 }
275
276 cmd.flags = CMD_ON_DEMAND | CMD_SYNC;
277 cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]);
278 if (cmd_want_skb)
279 cmd.flags |= CMD_WANT_SKB;
280
281 cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
282 cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
283 cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
284 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
285 IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
286 " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
287
288 ret = iwl_dvm_send_cmd(priv, &cmd);
289 if (ret) {
290 IWL_ERR(priv, "Failed to send hcmd\n");
291 return ret;
292 }
293 if (!cmd_want_skb)
294 return ret;
295
296 /* Handling return of SKB to the user */
297 pkt = cmd.resp_pkt;
298 if (!pkt) {
299 IWL_ERR(priv, "HCMD received a null response packet\n");
300 return ret;
301 }
302
303 reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
304 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20);
305 reply_buf = kmalloc(reply_len, GFP_KERNEL);
306 if (!skb || !reply_buf) {
307 kfree_skb(skb);
308 kfree(reply_buf);
309 return -ENOMEM;
310 }
311
312 /* The reply is in a page, that we cannot send to user space. */
313 memcpy(reply_buf, &(pkt->hdr), reply_len);
314 iwl_free_resp(&cmd);
315
316 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
317 nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf))
318 goto nla_put_failure;
319 return cfg80211_testmode_reply(skb);
320
321nla_put_failure:
322 IWL_DEBUG_INFO(priv, "Failed creating NL attributes\n");
323 return -ENOMSG;
324} 129}
325 130
131static struct iwl_test_ops tst_ops = {
132 .send_cmd = iwl_testmode_send_cmd,
133 .valid_hw_addr = iwl_testmode_valid_hw_addr,
134 .get_fw_ver = iwl_testmode_get_fw_ver,
135 .alloc_reply = iwl_testmode_alloc_reply,
136 .reply = iwl_testmode_reply,
137 .alloc_event = iwl_testmode_alloc_event,
138 .event = iwl_testmode_event,
139};
326 140
327/* 141void iwl_testmode_init(struct iwl_priv *priv)
328 * This function handles the user application commands for register access.
329 *
330 * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
331 * handlers respectively.
332 *
333 * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
334 * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32,
335 * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating
336 * the success of the command execution.
337 *
338 * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read
339 * value is returned with IWL_TM_ATTR_REG_VALUE32.
340 *
341 * @hw: ieee80211_hw object that represents the device
342 * @tb: gnl message fields from the user space
343 */
344static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
345{ 142{
346 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 143 iwl_test_init(&priv->tst, priv->trans, &tst_ops);
347 u32 ofs, val32, cmd;
348 u8 val8;
349 struct sk_buff *skb;
350 int status = 0;
351
352 if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
353 IWL_ERR(priv, "Missing register offset\n");
354 return -ENOMSG;
355 }
356 ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
357 IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
358
359 /* Allow access only to FH/CSR/HBUS in direct mode.
360 Since we don't have the upper bounds for the CSR and HBUS segments,
361 we will use only the upper bound of FH for sanity check. */
362 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
363 if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 ||
364 cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 ||
365 cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) &&
366 (ofs >= FH_MEM_UPPER_BOUND)) {
367 IWL_ERR(priv, "offset out of segment (0x0 - 0x%x)\n",
368 FH_MEM_UPPER_BOUND);
369 return -EINVAL;
370 }
371
372 switch (cmd) {
373 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
374 val32 = iwl_read_direct32(priv->trans, ofs);
375 IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
376
377 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
378 if (!skb) {
379 IWL_ERR(priv, "Memory allocation fail\n");
380 return -ENOMEM;
381 }
382 if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32))
383 goto nla_put_failure;
384 status = cfg80211_testmode_reply(skb);
385 if (status < 0)
386 IWL_ERR(priv, "Error sending msg : %d\n", status);
387 break;
388 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
389 if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
390 IWL_ERR(priv, "Missing value to write\n");
391 return -ENOMSG;
392 } else {
393 val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
394 IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
395 iwl_write_direct32(priv->trans, ofs, val32);
396 }
397 break;
398 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
399 if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
400 IWL_ERR(priv, "Missing value to write\n");
401 return -ENOMSG;
402 } else {
403 val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
404 IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
405 iwl_write8(priv->trans, ofs, val8);
406 }
407 break;
408 default:
409 IWL_ERR(priv, "Unknown testmode register command ID\n");
410 return -ENOSYS;
411 }
412
413 return status;
414
415nla_put_failure:
416 kfree_skb(skb);
417 return -EMSGSIZE;
418} 144}
419 145
146void iwl_testmode_free(struct iwl_priv *priv)
147{
148 iwl_test_free(&priv->tst);
149}
420 150
421static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) 151static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
422{ 152{
@@ -469,7 +199,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
469 struct sk_buff *skb; 199 struct sk_buff *skb;
470 unsigned char *rsp_data_ptr = NULL; 200 unsigned char *rsp_data_ptr = NULL;
471 int status = 0, rsp_data_len = 0; 201 int status = 0, rsp_data_len = 0;
472 u32 devid, inst_size = 0, data_size = 0; 202 u32 inst_size = 0, data_size = 0;
473 const struct fw_img *img; 203 const struct fw_img *img;
474 204
475 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { 205 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
@@ -563,39 +293,6 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
563 priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); 293 priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
564 break; 294 break;
565 295
566 case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
567 IWL_INFO(priv, "uCode version raw: 0x%x\n",
568 priv->fw->ucode_ver);
569
570 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
571 if (!skb) {
572 IWL_ERR(priv, "Memory allocation fail\n");
573 return -ENOMEM;
574 }
575 if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION,
576 priv->fw->ucode_ver))
577 goto nla_put_failure;
578 status = cfg80211_testmode_reply(skb);
579 if (status < 0)
580 IWL_ERR(priv, "Error sending msg : %d\n", status);
581 break;
582
583 case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
584 devid = priv->trans->hw_id;
585 IWL_INFO(priv, "hw version: 0x%x\n", devid);
586
587 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
588 if (!skb) {
589 IWL_ERR(priv, "Memory allocation fail\n");
590 return -ENOMEM;
591 }
592 if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid))
593 goto nla_put_failure;
594 status = cfg80211_testmode_reply(skb);
595 if (status < 0)
596 IWL_ERR(priv, "Error sending msg : %d\n", status);
597 break;
598
599 case IWL_TM_CMD_APP2DEV_GET_FW_INFO: 296 case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
600 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8); 297 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
601 if (!skb) { 298 if (!skb) {
@@ -630,125 +327,6 @@ nla_put_failure:
630 return -EMSGSIZE; 327 return -EMSGSIZE;
631} 328}
632 329
633
634/*
635 * This function handles the user application commands for uCode trace
636 *
637 * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
638 * handlers respectively.
639 *
640 * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
641 * value of the actual command execution is replied to the user application.
642 *
643 * @hw: ieee80211_hw object that represents the device
644 * @tb: gnl message fields from the user space
645 */
646static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
647{
648 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
649 struct sk_buff *skb;
650 int status = 0;
651 struct device *dev = priv->trans->dev;
652
653 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
654 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
655 if (priv->testmode_trace.trace_enabled)
656 return -EBUSY;
657
658 if (!tb[IWL_TM_ATTR_TRACE_SIZE])
659 priv->testmode_trace.buff_size = TRACE_BUFF_SIZE_DEF;
660 else
661 priv->testmode_trace.buff_size =
662 nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]);
663 if (!priv->testmode_trace.buff_size)
664 return -EINVAL;
665 if (priv->testmode_trace.buff_size < TRACE_BUFF_SIZE_MIN ||
666 priv->testmode_trace.buff_size > TRACE_BUFF_SIZE_MAX)
667 return -EINVAL;
668
669 priv->testmode_trace.total_size =
670 priv->testmode_trace.buff_size + TRACE_BUFF_PADD;
671 priv->testmode_trace.cpu_addr =
672 dma_alloc_coherent(dev,
673 priv->testmode_trace.total_size,
674 &priv->testmode_trace.dma_addr,
675 GFP_KERNEL);
676 if (!priv->testmode_trace.cpu_addr)
677 return -ENOMEM;
678 priv->testmode_trace.trace_enabled = true;
679 priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN(
680 priv->testmode_trace.cpu_addr, 0x100);
681 memset(priv->testmode_trace.trace_addr, 0x03B,
682 priv->testmode_trace.buff_size);
683 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
684 sizeof(priv->testmode_trace.dma_addr) + 20);
685 if (!skb) {
686 IWL_ERR(priv, "Memory allocation fail\n");
687 iwl_trace_cleanup(priv);
688 return -ENOMEM;
689 }
690 if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR,
691 sizeof(priv->testmode_trace.dma_addr),
692 (u64 *)&priv->testmode_trace.dma_addr))
693 goto nla_put_failure;
694 status = cfg80211_testmode_reply(skb);
695 if (status < 0) {
696 IWL_ERR(priv, "Error sending msg : %d\n", status);
697 }
698 priv->testmode_trace.num_chunks =
699 DIV_ROUND_UP(priv->testmode_trace.buff_size,
700 DUMP_CHUNK_SIZE);
701 break;
702
703 case IWL_TM_CMD_APP2DEV_END_TRACE:
704 iwl_trace_cleanup(priv);
705 break;
706 default:
707 IWL_ERR(priv, "Unknown testmode mem command ID\n");
708 return -ENOSYS;
709 }
710 return status;
711
712nla_put_failure:
713 kfree_skb(skb);
714 if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
715 IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
716 iwl_trace_cleanup(priv);
717 return -EMSGSIZE;
718}
719
720static int iwl_testmode_trace_dump(struct ieee80211_hw *hw,
721 struct sk_buff *skb,
722 struct netlink_callback *cb)
723{
724 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
725 int idx, length;
726
727 if (priv->testmode_trace.trace_enabled &&
728 priv->testmode_trace.trace_addr) {
729 idx = cb->args[4];
730 if (idx >= priv->testmode_trace.num_chunks)
731 return -ENOENT;
732 length = DUMP_CHUNK_SIZE;
733 if (((idx + 1) == priv->testmode_trace.num_chunks) &&
734 (priv->testmode_trace.buff_size % DUMP_CHUNK_SIZE))
735 length = priv->testmode_trace.buff_size %
736 DUMP_CHUNK_SIZE;
737
738 if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length,
739 priv->testmode_trace.trace_addr +
740 (DUMP_CHUNK_SIZE * idx)))
741 goto nla_put_failure;
742 idx++;
743 cb->args[4] = idx;
744 return 0;
745 } else
746 return -EFAULT;
747
748 nla_put_failure:
749 return -ENOBUFS;
750}
751
752/* 330/*
753 * This function handles the user application switch ucode ownership. 331 * This function handles the user application switch ucode ownership.
754 * 332 *
@@ -777,10 +355,10 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
777 owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); 355 owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
778 if (owner == IWL_OWNERSHIP_DRIVER) { 356 if (owner == IWL_OWNERSHIP_DRIVER) {
779 priv->ucode_owner = owner; 357 priv->ucode_owner = owner;
780 priv->pre_rx_handler = NULL; 358 iwl_test_enable_notifications(&priv->tst, false);
781 } else if (owner == IWL_OWNERSHIP_TM) { 359 } else if (owner == IWL_OWNERSHIP_TM) {
782 priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
783 priv->ucode_owner = owner; 360 priv->ucode_owner = owner;
361 iwl_test_enable_notifications(&priv->tst, true);
784 } else { 362 } else {
785 IWL_ERR(priv, "Invalid owner\n"); 363 IWL_ERR(priv, "Invalid owner\n");
786 return -EINVAL; 364 return -EINVAL;
@@ -788,180 +366,6 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
788 return 0; 366 return 0;
789} 367}
790 368
791static int iwl_testmode_indirect_read(struct iwl_priv *priv, u32 addr, u32 size)
792{
793 struct iwl_trans *trans = priv->trans;
794 unsigned long flags;
795 int i;
796
797 if (size & 0x3)
798 return -EINVAL;
799 priv->testmode_mem.buff_size = size;
800 priv->testmode_mem.buff_addr =
801 kmalloc(priv->testmode_mem.buff_size, GFP_KERNEL);
802 if (priv->testmode_mem.buff_addr == NULL)
803 return -ENOMEM;
804
805 /* Hard-coded periphery absolute address */
806 if (IWL_TM_ABS_PRPH_START <= addr &&
807 addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
808 spin_lock_irqsave(&trans->reg_lock, flags);
809 iwl_grab_nic_access(trans);
810 iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
811 addr | (3 << 24));
812 for (i = 0; i < size; i += 4)
813 *(u32 *)(priv->testmode_mem.buff_addr + i) =
814 iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
815 iwl_release_nic_access(trans);
816 spin_unlock_irqrestore(&trans->reg_lock, flags);
817 } else { /* target memory (SRAM) */
818 _iwl_read_targ_mem_words(trans, addr,
819 priv->testmode_mem.buff_addr,
820 priv->testmode_mem.buff_size / 4);
821 }
822
823 priv->testmode_mem.num_chunks =
824 DIV_ROUND_UP(priv->testmode_mem.buff_size, DUMP_CHUNK_SIZE);
825 priv->testmode_mem.read_in_progress = true;
826 return 0;
827
828}
829
830static int iwl_testmode_indirect_write(struct iwl_priv *priv, u32 addr,
831 u32 size, unsigned char *buf)
832{
833 struct iwl_trans *trans = priv->trans;
834 u32 val, i;
835 unsigned long flags;
836
837 if (IWL_TM_ABS_PRPH_START <= addr &&
838 addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
839 /* Periphery writes can be 1-3 bytes long, or DWORDs */
840 if (size < 4) {
841 memcpy(&val, buf, size);
842 spin_lock_irqsave(&trans->reg_lock, flags);
843 iwl_grab_nic_access(trans);
844 iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
845 (addr & 0x0000FFFF) |
846 ((size - 1) << 24));
847 iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
848 iwl_release_nic_access(trans);
849 /* needed after consecutive writes w/o read */
850 mmiowb();
851 spin_unlock_irqrestore(&trans->reg_lock, flags);
852 } else {
853 if (size % 4)
854 return -EINVAL;
855 for (i = 0; i < size; i += 4)
856 iwl_write_prph(trans, addr+i,
857 *(u32 *)(buf+i));
858 }
859 } else if (iwlagn_hw_valid_rtc_data_addr(addr) ||
860 (IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
861 addr < IWLAGN_RTC_INST_UPPER_BOUND)) {
862 _iwl_write_targ_mem_words(trans, addr, buf, size/4);
863 } else
864 return -EINVAL;
865 return 0;
866}
867
868/*
869 * This function handles the user application commands for SRAM data dump
870 *
871 * It retrieves the mandatory fields IWL_TM_ATTR_SRAM_ADDR and
872 * IWL_TM_ATTR_SRAM_SIZE to decide the memory area for SRAM data reading
873 *
874 * Several error will be retured, -EBUSY if the SRAM data retrieved by
875 * previous command has not been delivered to userspace, or -ENOMSG if
876 * the mandatory fields (IWL_TM_ATTR_SRAM_ADDR,IWL_TM_ATTR_SRAM_SIZE)
877 * are missing, or -ENOMEM if the buffer allocation fails.
878 *
879 * Otherwise 0 is replied indicating the success of the SRAM reading.
880 *
881 * @hw: ieee80211_hw object that represents the device
882 * @tb: gnl message fields from the user space
883 */
884static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw,
885 struct nlattr **tb)
886{
887 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
888 u32 addr, size, cmd;
889 unsigned char *buf;
890
891 /* Both read and write should be blocked, for atomicity */
892 if (priv->testmode_mem.read_in_progress)
893 return -EBUSY;
894
895 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
896 if (!tb[IWL_TM_ATTR_MEM_ADDR]) {
897 IWL_ERR(priv, "Error finding memory offset address\n");
898 return -ENOMSG;
899 }
900 addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]);
901 if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) {
902 IWL_ERR(priv, "Error finding size for memory reading\n");
903 return -ENOMSG;
904 }
905 size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]);
906
907 if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ)
908 return iwl_testmode_indirect_read(priv, addr, size);
909 else {
910 if (!tb[IWL_TM_ATTR_BUFFER_DUMP])
911 return -EINVAL;
912 buf = (unsigned char *) nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]);
913 return iwl_testmode_indirect_write(priv, addr, size, buf);
914 }
915}
916
917static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw,
918 struct sk_buff *skb,
919 struct netlink_callback *cb)
920{
921 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
922 int idx, length;
923
924 if (priv->testmode_mem.read_in_progress) {
925 idx = cb->args[4];
926 if (idx >= priv->testmode_mem.num_chunks) {
927 iwl_mem_cleanup(priv);
928 return -ENOENT;
929 }
930 length = DUMP_CHUNK_SIZE;
931 if (((idx + 1) == priv->testmode_mem.num_chunks) &&
932 (priv->testmode_mem.buff_size % DUMP_CHUNK_SIZE))
933 length = priv->testmode_mem.buff_size %
934 DUMP_CHUNK_SIZE;
935
936 if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
937 priv->testmode_mem.buff_addr +
938 (DUMP_CHUNK_SIZE * idx)))
939 goto nla_put_failure;
940 idx++;
941 cb->args[4] = idx;
942 return 0;
943 } else
944 return -EFAULT;
945
946 nla_put_failure:
947 return -ENOBUFS;
948}
949
950static int iwl_testmode_notifications(struct ieee80211_hw *hw,
951 struct nlattr **tb)
952{
953 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
954 bool enable;
955
956 enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]);
957 if (enable)
958 priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
959 else
960 priv->pre_rx_handler = NULL;
961 return 0;
962}
963
964
965/* The testmode gnl message handler that takes the gnl message from the 369/* The testmode gnl message handler that takes the gnl message from the
966 * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then 370 * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
967 * invoke the corresponding handlers. 371 * invoke the corresponding handlers.
@@ -987,32 +391,27 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
987 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 391 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
988 int result; 392 int result;
989 393
990 result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, 394 result = iwl_test_parse(&priv->tst, tb, data, len);
991 iwl_testmode_gnl_msg_policy); 395 if (result)
992 if (result != 0) {
993 IWL_ERR(priv, "Error parsing the gnl message : %d\n", result);
994 return result; 396 return result;
995 }
996 397
997 /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
998 if (!tb[IWL_TM_ATTR_COMMAND]) {
999 IWL_ERR(priv, "Missing testmode command type\n");
1000 return -ENOMSG;
1001 }
1002 /* in case multiple accesses to the device happens */ 398 /* in case multiple accesses to the device happens */
1003 mutex_lock(&priv->mutex); 399 mutex_lock(&priv->mutex);
1004
1005 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { 400 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
1006 case IWL_TM_CMD_APP2DEV_UCODE: 401 case IWL_TM_CMD_APP2DEV_UCODE:
1007 IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n");
1008 result = iwl_testmode_ucode(hw, tb);
1009 break;
1010 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: 402 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
1011 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: 403 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
1012 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: 404 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
1013 IWL_DEBUG_INFO(priv, "testmode cmd to register\n"); 405 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
1014 result = iwl_testmode_reg(hw, tb); 406 case IWL_TM_CMD_APP2DEV_END_TRACE:
407 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
408 case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
409 case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
410 case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
411 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
412 result = iwl_test_handle_cmd(&priv->tst, tb);
1015 break; 413 break;
414
1016 case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: 415 case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
1017 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: 416 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
1018 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: 417 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
@@ -1020,45 +419,25 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
1020 case IWL_TM_CMD_APP2DEV_GET_EEPROM: 419 case IWL_TM_CMD_APP2DEV_GET_EEPROM:
1021 case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: 420 case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
1022 case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: 421 case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
1023 case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
1024 case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
1025 case IWL_TM_CMD_APP2DEV_GET_FW_INFO: 422 case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
1026 IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); 423 IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
1027 result = iwl_testmode_driver(hw, tb); 424 result = iwl_testmode_driver(hw, tb);
1028 break; 425 break;
1029 426
1030 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
1031 case IWL_TM_CMD_APP2DEV_END_TRACE:
1032 case IWL_TM_CMD_APP2DEV_READ_TRACE:
1033 IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n");
1034 result = iwl_testmode_trace(hw, tb);
1035 break;
1036
1037 case IWL_TM_CMD_APP2DEV_OWNERSHIP: 427 case IWL_TM_CMD_APP2DEV_OWNERSHIP:
1038 IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n"); 428 IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
1039 result = iwl_testmode_ownership(hw, tb); 429 result = iwl_testmode_ownership(hw, tb);
1040 break; 430 break;
1041 431
1042 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
1043 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
1044 IWL_DEBUG_INFO(priv, "testmode indirect memory cmd "
1045 "to driver\n");
1046 result = iwl_testmode_indirect_mem(hw, tb);
1047 break;
1048
1049 case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
1050 IWL_DEBUG_INFO(priv, "testmode notifications cmd "
1051 "to driver\n");
1052 result = iwl_testmode_notifications(hw, tb);
1053 break;
1054
1055 default: 432 default:
1056 IWL_ERR(priv, "Unknown testmode command\n"); 433 IWL_ERR(priv, "Unknown testmode command\n");
1057 result = -ENOSYS; 434 result = -ENOSYS;
1058 break; 435 break;
1059 } 436 }
1060
1061 mutex_unlock(&priv->mutex); 437 mutex_unlock(&priv->mutex);
438
439 if (result)
440 IWL_ERR(priv, "Test cmd failed result=%d\n", result);
1062 return result; 441 return result;
1063} 442}
1064 443
@@ -1066,7 +445,6 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
1066 struct netlink_callback *cb, 445 struct netlink_callback *cb,
1067 void *data, int len) 446 void *data, int len)
1068{ 447{
1069 struct nlattr *tb[IWL_TM_ATTR_MAX];
1070 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 448 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1071 int result; 449 int result;
1072 u32 cmd; 450 u32 cmd;
@@ -1075,39 +453,19 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
1075 /* offset by 1 since commands start at 0 */ 453 /* offset by 1 since commands start at 0 */
1076 cmd = cb->args[3] - 1; 454 cmd = cb->args[3] - 1;
1077 } else { 455 } else {
1078 result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, 456 struct nlattr *tb[IWL_TM_ATTR_MAX];
1079 iwl_testmode_gnl_msg_policy); 457
1080 if (result) { 458 result = iwl_test_parse(&priv->tst, tb, data, len);
1081 IWL_ERR(priv, 459 if (result)
1082 "Error parsing the gnl message : %d\n", result);
1083 return result; 460 return result;
1084 }
1085 461
1086 /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
1087 if (!tb[IWL_TM_ATTR_COMMAND]) {
1088 IWL_ERR(priv, "Missing testmode command type\n");
1089 return -ENOMSG;
1090 }
1091 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); 462 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
1092 cb->args[3] = cmd + 1; 463 cb->args[3] = cmd + 1;
1093 } 464 }
1094 465
1095 /* in case multiple accesses to the device happens */ 466 /* in case multiple accesses to the device happens */
1096 mutex_lock(&priv->mutex); 467 mutex_lock(&priv->mutex);
1097 switch (cmd) { 468 result = iwl_test_dump(&priv->tst, cmd, skb, cb);
1098 case IWL_TM_CMD_APP2DEV_READ_TRACE:
1099 IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n");
1100 result = iwl_testmode_trace_dump(hw, skb, cb);
1101 break;
1102 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
1103 IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n");
1104 result = iwl_testmode_buffer_dump(hw, skb, cb);
1105 break;
1106 default:
1107 result = -EINVAL;
1108 break;
1109 }
1110
1111 mutex_unlock(&priv->mutex); 469 mutex_unlock(&priv->mutex);
1112 return result; 470 return result;
1113} 471}
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 0dfaf649b257..5971a23aa47d 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -403,6 +403,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
403 403
404 info->driver_data[0] = ctx; 404 info->driver_data[0] = ctx;
405 info->driver_data[1] = dev_cmd; 405 info->driver_data[1] = dev_cmd;
406 /* From now on, we cannot access info->control */
406 407
407 spin_lock(&priv->sta_lock); 408 spin_lock(&priv->sta_lock);
408 409
@@ -1182,7 +1183,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1182 } 1183 }
1183 1184
1184 /*we can free until ssn % q.n_bd not inclusive */ 1185 /*we can free until ssn % q.n_bd not inclusive */
1185 WARN_ON(iwl_reclaim(priv, sta_id, tid, txq_id, ssn, &skbs)); 1186 WARN_ON_ONCE(iwl_reclaim(priv, sta_id, tid,
1187 txq_id, ssn, &skbs));
1186 iwlagn_check_ratid_empty(priv, sta_id, tid); 1188 iwlagn_check_ratid_empty(priv, sta_id, tid);
1187 freed = 0; 1189 freed = 0;
1188 1190
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 49df0e9d5c5f..a175997e7829 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -131,6 +131,8 @@ struct iwl_drv {
131#define DVM_OP_MODE 0 131#define DVM_OP_MODE 0
132#define MVM_OP_MODE 1 132#define MVM_OP_MODE 1
133 133
134/* Protects the table contents, i.e. the ops pointer & drv list */
135static struct mutex iwlwifi_opmode_table_mtx;
134static struct iwlwifi_opmode_table { 136static struct iwlwifi_opmode_table {
135 const char *name; /* name: iwldvm, iwlmvm, etc */ 137 const char *name; /* name: iwldvm, iwlmvm, etc */
136 const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */ 138 const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */
@@ -776,6 +778,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
776 const unsigned int api_min = drv->cfg->ucode_api_min; 778 const unsigned int api_min = drv->cfg->ucode_api_min;
777 u32 api_ver; 779 u32 api_ver;
778 int i; 780 int i;
781 bool load_module = false;
779 782
780 fw->ucode_capa.max_probe_length = 200; 783 fw->ucode_capa.max_probe_length = 200;
781 fw->ucode_capa.standard_phy_calibration_size = 784 fw->ucode_capa.standard_phy_calibration_size =
@@ -898,6 +901,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
898 /* We have our copies now, allow OS release its copies */ 901 /* We have our copies now, allow OS release its copies */
899 release_firmware(ucode_raw); 902 release_firmware(ucode_raw);
900 903
904 mutex_lock(&iwlwifi_opmode_table_mtx);
901 op = &iwlwifi_opmode_table[DVM_OP_MODE]; 905 op = &iwlwifi_opmode_table[DVM_OP_MODE];
902 906
903 /* add this device to the list of devices using this op_mode */ 907 /* add this device to the list of devices using this op_mode */
@@ -907,11 +911,14 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
907 const struct iwl_op_mode_ops *ops = op->ops; 911 const struct iwl_op_mode_ops *ops = op->ops;
908 drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw); 912 drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw);
909 913
910 if (!drv->op_mode) 914 if (!drv->op_mode) {
915 mutex_unlock(&iwlwifi_opmode_table_mtx);
911 goto out_unbind; 916 goto out_unbind;
917 }
912 } else { 918 } else {
913 request_module_nowait("%s", op->name); 919 load_module = true;
914 } 920 }
921 mutex_unlock(&iwlwifi_opmode_table_mtx);
915 922
916 /* 923 /*
917 * Complete the firmware request last so that 924 * Complete the firmware request last so that
@@ -919,6 +926,14 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
919 * are doing the start() above. 926 * are doing the start() above.
920 */ 927 */
921 complete(&drv->request_firmware_complete); 928 complete(&drv->request_firmware_complete);
929
930 /*
931 * Load the module last so we don't block anything
932 * else from proceeding if the module fails to load
933 * or hangs loading.
934 */
935 if (load_module)
936 request_module("%s", op->name);
922 return; 937 return;
923 938
924 try_again: 939 try_again:
@@ -952,6 +967,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
952 drv->cfg = cfg; 967 drv->cfg = cfg;
953 968
954 init_completion(&drv->request_firmware_complete); 969 init_completion(&drv->request_firmware_complete);
970 INIT_LIST_HEAD(&drv->list);
955 971
956 ret = iwl_request_firmware(drv, true); 972 ret = iwl_request_firmware(drv, true);
957 973
@@ -974,6 +990,16 @@ void iwl_drv_stop(struct iwl_drv *drv)
974 990
975 iwl_dealloc_ucode(drv); 991 iwl_dealloc_ucode(drv);
976 992
993 mutex_lock(&iwlwifi_opmode_table_mtx);
994 /*
995 * List is empty (this item wasn't added)
996 * when firmware loading failed -- in that
997 * case we can't remove it from any list.
998 */
999 if (!list_empty(&drv->list))
1000 list_del(&drv->list);
1001 mutex_unlock(&iwlwifi_opmode_table_mtx);
1002
977 kfree(drv); 1003 kfree(drv);
978} 1004}
979 1005
@@ -996,6 +1022,7 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)
996 int i; 1022 int i;
997 struct iwl_drv *drv; 1023 struct iwl_drv *drv;
998 1024
1025 mutex_lock(&iwlwifi_opmode_table_mtx);
999 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { 1026 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) {
1000 if (strcmp(iwlwifi_opmode_table[i].name, name)) 1027 if (strcmp(iwlwifi_opmode_table[i].name, name))
1001 continue; 1028 continue;
@@ -1003,8 +1030,10 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)
1003 list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) 1030 list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list)
1004 drv->op_mode = ops->start(drv->trans, drv->cfg, 1031 drv->op_mode = ops->start(drv->trans, drv->cfg,
1005 &drv->fw); 1032 &drv->fw);
1033 mutex_unlock(&iwlwifi_opmode_table_mtx);
1006 return 0; 1034 return 0;
1007 } 1035 }
1036 mutex_unlock(&iwlwifi_opmode_table_mtx);
1008 return -EIO; 1037 return -EIO;
1009} 1038}
1010EXPORT_SYMBOL_GPL(iwl_opmode_register); 1039EXPORT_SYMBOL_GPL(iwl_opmode_register);
@@ -1014,6 +1043,7 @@ void iwl_opmode_deregister(const char *name)
1014 int i; 1043 int i;
1015 struct iwl_drv *drv; 1044 struct iwl_drv *drv;
1016 1045
1046 mutex_lock(&iwlwifi_opmode_table_mtx);
1017 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { 1047 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) {
1018 if (strcmp(iwlwifi_opmode_table[i].name, name)) 1048 if (strcmp(iwlwifi_opmode_table[i].name, name))
1019 continue; 1049 continue;
@@ -1026,8 +1056,10 @@ void iwl_opmode_deregister(const char *name)
1026 drv->op_mode = NULL; 1056 drv->op_mode = NULL;
1027 } 1057 }
1028 } 1058 }
1059 mutex_unlock(&iwlwifi_opmode_table_mtx);
1029 return; 1060 return;
1030 } 1061 }
1062 mutex_unlock(&iwlwifi_opmode_table_mtx);
1031} 1063}
1032EXPORT_SYMBOL_GPL(iwl_opmode_deregister); 1064EXPORT_SYMBOL_GPL(iwl_opmode_deregister);
1033 1065
@@ -1035,6 +1067,8 @@ static int __init iwl_drv_init(void)
1035{ 1067{
1036 int i; 1068 int i;
1037 1069
1070 mutex_init(&iwlwifi_opmode_table_mtx);
1071
1038 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) 1072 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++)
1039 INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); 1073 INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv);
1040 1074
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 74bce97a8600..806046641747 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -421,6 +421,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
421 (FH_SRVC_LOWER_BOUND + ((_chnl) - 9) * 0x4) 421 (FH_SRVC_LOWER_BOUND + ((_chnl) - 9) * 0x4)
422 422
423#define FH_TX_CHICKEN_BITS_REG (FH_MEM_LOWER_BOUND + 0xE98) 423#define FH_TX_CHICKEN_BITS_REG (FH_MEM_LOWER_BOUND + 0xE98)
424#define FH_TX_TRB_REG(_chan) (FH_MEM_LOWER_BOUND + 0x958 + (_chan) * 4)
425
424/* Instruct FH to increment the retry count of a packet when 426/* Instruct FH to increment the retry count of a packet when
425 * it is brought from the memory to TX-FIFO 427 * it is brought from the memory to TX-FIFO
426 */ 428 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 5f2df70b73c1..66c873399aba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -298,8 +298,8 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
298} 298}
299EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); 299EXPORT_SYMBOL_GPL(iwl_clear_bits_prph);
300 300
301void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, 301void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
302 void *buf, int words) 302 void *buf, int dwords)
303{ 303{
304 unsigned long flags; 304 unsigned long flags;
305 int offs; 305 int offs;
@@ -308,26 +308,26 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
308 spin_lock_irqsave(&trans->reg_lock, flags); 308 spin_lock_irqsave(&trans->reg_lock, flags);
309 if (likely(iwl_grab_nic_access(trans))) { 309 if (likely(iwl_grab_nic_access(trans))) {
310 iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); 310 iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
311 for (offs = 0; offs < words; offs++) 311 for (offs = 0; offs < dwords; offs++)
312 vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); 312 vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
313 iwl_release_nic_access(trans); 313 iwl_release_nic_access(trans);
314 } 314 }
315 spin_unlock_irqrestore(&trans->reg_lock, flags); 315 spin_unlock_irqrestore(&trans->reg_lock, flags);
316} 316}
317EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_words); 317EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_dwords);
318 318
319u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) 319u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr)
320{ 320{
321 u32 value; 321 u32 value;
322 322
323 _iwl_read_targ_mem_words(trans, addr, &value, 1); 323 _iwl_read_targ_mem_dwords(trans, addr, &value, 1);
324 324
325 return value; 325 return value;
326} 326}
327EXPORT_SYMBOL_GPL(iwl_read_targ_mem); 327EXPORT_SYMBOL_GPL(iwl_read_targ_mem);
328 328
329int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, 329int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
330 void *buf, int words) 330 void *buf, int dwords)
331{ 331{
332 unsigned long flags; 332 unsigned long flags;
333 int offs, result = 0; 333 int offs, result = 0;
@@ -336,7 +336,7 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
336 spin_lock_irqsave(&trans->reg_lock, flags); 336 spin_lock_irqsave(&trans->reg_lock, flags);
337 if (likely(iwl_grab_nic_access(trans))) { 337 if (likely(iwl_grab_nic_access(trans))) {
338 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 338 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
339 for (offs = 0; offs < words; offs++) 339 for (offs = 0; offs < dwords; offs++)
340 iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); 340 iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
341 iwl_release_nic_access(trans); 341 iwl_release_nic_access(trans);
342 } else 342 } else
@@ -345,10 +345,10 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
345 345
346 return result; 346 return result;
347} 347}
348EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_words); 348EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_dwords);
349 349
350int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) 350int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val)
351{ 351{
352 return _iwl_write_targ_mem_words(trans, addr, &val, 1); 352 return _iwl_write_targ_mem_dwords(trans, addr, &val, 1);
353} 353}
354EXPORT_SYMBOL_GPL(iwl_write_targ_mem); 354EXPORT_SYMBOL_GPL(iwl_write_targ_mem);
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 4a9a45f771ed..50d3819739d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -76,18 +76,18 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg,
76 u32 bits, u32 mask); 76 u32 bits, u32 mask);
77void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); 77void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask);
78 78
79void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, 79void _iwl_read_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
80 void *buf, int words); 80 void *buf, int dwords);
81 81
82#define iwl_read_targ_mem_words(trans, addr, buf, bufsize) \ 82#define iwl_read_targ_mem_bytes(trans, addr, buf, bufsize) \
83 do { \ 83 do { \
84 BUILD_BUG_ON((bufsize) % sizeof(u32)); \ 84 BUILD_BUG_ON((bufsize) % sizeof(u32)); \
85 _iwl_read_targ_mem_words(trans, addr, buf, \ 85 _iwl_read_targ_mem_dwords(trans, addr, buf, \
86 (bufsize) / sizeof(u32));\ 86 (bufsize) / sizeof(u32));\
87 } while (0) 87 } while (0)
88 88
89int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, 89int _iwl_write_targ_mem_dwords(struct iwl_trans *trans, u32 addr,
90 void *buf, int words); 90 void *buf, int dwords);
91 91
92u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); 92u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr);
93int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); 93int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val);
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c
new file mode 100644
index 000000000000..81e8c7126d72
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-test.c
@@ -0,0 +1,856 @@
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) 2010 - 2012 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) 2010 - 2012 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
64#include <linux/export.h>
65#include <net/netlink.h>
66
67#include "iwl-io.h"
68#include "iwl-fh.h"
69#include "iwl-prph.h"
70#include "iwl-trans.h"
71#include "iwl-test.h"
72#include "iwl-csr.h"
73#include "iwl-testmode.h"
74
75/*
76 * Periphery registers absolute lower bound. This is used in order to
77 * differentiate registery access through HBUS_TARG_PRPH_* and
78 * HBUS_TARG_MEM_* accesses.
79 */
80#define IWL_ABS_PRPH_START (0xA00000)
81
82/*
83 * The TLVs used in the gnl message policy between the kernel module and
84 * user space application. iwl_testmode_gnl_msg_policy is to be carried
85 * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
86 * See iwl-testmode.h
87 */
88static
89struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
90 [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
91
92 [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
93 [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
94
95 [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
96 [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
97 [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
98
99 [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
100 [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
101
102 [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },
103
104 [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
105 [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
106 [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },
107
108 [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
109
110 [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
111
112 [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, },
113 [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, },
114 [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, },
115
116 [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
117 [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
118 [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
119 [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
120 [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
121
122 [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, },
123};
124
125static inline void iwl_test_trace_clear(struct iwl_test *tst)
126{
127 memset(&tst->trace, 0, sizeof(struct iwl_test_trace));
128}
129
130static void iwl_test_trace_stop(struct iwl_test *tst)
131{
132 if (!tst->trace.enabled)
133 return;
134
135 if (tst->trace.cpu_addr && tst->trace.dma_addr)
136 dma_free_coherent(tst->trans->dev,
137 tst->trace.tsize,
138 tst->trace.cpu_addr,
139 tst->trace.dma_addr);
140
141 iwl_test_trace_clear(tst);
142}
143
144static inline void iwl_test_mem_clear(struct iwl_test *tst)
145{
146 memset(&tst->mem, 0, sizeof(struct iwl_test_mem));
147}
148
149static inline void iwl_test_mem_stop(struct iwl_test *tst)
150{
151 if (!tst->mem.in_read)
152 return;
153
154 iwl_test_mem_clear(tst);
155}
156
157/*
158 * Initializes the test object
159 * During the lifetime of the test object it is assumed that the transport is
160 * started. The test object should be stopped before the transport is stopped.
161 */
162void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans,
163 struct iwl_test_ops *ops)
164{
165 tst->trans = trans;
166 tst->ops = ops;
167
168 iwl_test_trace_clear(tst);
169 iwl_test_mem_clear(tst);
170}
171EXPORT_SYMBOL_GPL(iwl_test_init);
172
173/*
174 * Stop the test object
175 */
176void iwl_test_free(struct iwl_test *tst)
177{
178 iwl_test_mem_stop(tst);
179 iwl_test_trace_stop(tst);
180}
181EXPORT_SYMBOL_GPL(iwl_test_free);
182
183static inline int iwl_test_send_cmd(struct iwl_test *tst,
184 struct iwl_host_cmd *cmd)
185{
186 return tst->ops->send_cmd(tst->trans->op_mode, cmd);
187}
188
189static inline bool iwl_test_valid_hw_addr(struct iwl_test *tst, u32 addr)
190{
191 return tst->ops->valid_hw_addr(addr);
192}
193
194static inline u32 iwl_test_fw_ver(struct iwl_test *tst)
195{
196 return tst->ops->get_fw_ver(tst->trans->op_mode);
197}
198
199static inline struct sk_buff*
200iwl_test_alloc_reply(struct iwl_test *tst, int len)
201{
202 return tst->ops->alloc_reply(tst->trans->op_mode, len);
203}
204
205static inline int iwl_test_reply(struct iwl_test *tst, struct sk_buff *skb)
206{
207 return tst->ops->reply(tst->trans->op_mode, skb);
208}
209
210static inline struct sk_buff*
211iwl_test_alloc_event(struct iwl_test *tst, int len)
212{
213 return tst->ops->alloc_event(tst->trans->op_mode, len);
214}
215
216static inline void
217iwl_test_event(struct iwl_test *tst, struct sk_buff *skb)
218{
219 return tst->ops->event(tst->trans->op_mode, skb);
220}
221
222/*
223 * This function handles the user application commands to the fw. The fw
224 * commands are sent in a synchronuous manner. In case that the user requested
225 * to get commands response, it is send to the user.
226 */
227static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
228{
229 struct iwl_host_cmd cmd;
230 struct iwl_rx_packet *pkt;
231 struct sk_buff *skb;
232 void *reply_buf;
233 u32 reply_len;
234 int ret;
235 bool cmd_want_skb;
236
237 memset(&cmd, 0, sizeof(struct iwl_host_cmd));
238
239 if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
240 !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
241 IWL_ERR(tst->trans, "Missing fw command mandatory fields\n");
242 return -ENOMSG;
243 }
244
245 cmd.flags = CMD_ON_DEMAND | CMD_SYNC;
246 cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]);
247 if (cmd_want_skb)
248 cmd.flags |= CMD_WANT_SKB;
249
250 cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
251 cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
252 cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
253 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
254 IWL_DEBUG_INFO(tst->trans, "test fw cmd=0x%x, flags 0x%x, len %d\n",
255 cmd.id, cmd.flags, cmd.len[0]);
256
257 ret = iwl_test_send_cmd(tst, &cmd);
258 if (ret) {
259 IWL_ERR(tst->trans, "Failed to send hcmd\n");
260 return ret;
261 }
262 if (!cmd_want_skb)
263 return ret;
264
265 /* Handling return of SKB to the user */
266 pkt = cmd.resp_pkt;
267 if (!pkt) {
268 IWL_ERR(tst->trans, "HCMD received a null response packet\n");
269 return ret;
270 }
271
272 reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
273 skb = iwl_test_alloc_reply(tst, reply_len + 20);
274 reply_buf = kmalloc(reply_len, GFP_KERNEL);
275 if (!skb || !reply_buf) {
276 kfree_skb(skb);
277 kfree(reply_buf);
278 return -ENOMEM;
279 }
280
281 /* The reply is in a page, that we cannot send to user space. */
282 memcpy(reply_buf, &(pkt->hdr), reply_len);
283 iwl_free_resp(&cmd);
284
285 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
286 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
287 nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf))
288 goto nla_put_failure;
289 return iwl_test_reply(tst, skb);
290
291nla_put_failure:
292 IWL_DEBUG_INFO(tst->trans, "Failed creating NL attributes\n");
293 kfree(reply_buf);
294 kfree_skb(skb);
295 return -ENOMSG;
296}
297
298/*
299 * Handles the user application commands for register access.
300 */
301static int iwl_test_reg(struct iwl_test *tst, struct nlattr **tb)
302{
303 u32 ofs, val32, cmd;
304 u8 val8;
305 struct sk_buff *skb;
306 int status = 0;
307 struct iwl_trans *trans = tst->trans;
308
309 if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
310 IWL_ERR(trans, "Missing reg offset\n");
311 return -ENOMSG;
312 }
313
314 ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
315 IWL_DEBUG_INFO(trans, "test reg access cmd offset=0x%x\n", ofs);
316
317 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
318
319 /*
320 * Allow access only to FH/CSR/HBUS in direct mode.
321 * Since we don't have the upper bounds for the CSR and HBUS segments,
322 * we will use only the upper bound of FH for sanity check.
323 */
324 if (ofs >= FH_MEM_UPPER_BOUND) {
325 IWL_ERR(trans, "offset out of segment (0x0 - 0x%x)\n",
326 FH_MEM_UPPER_BOUND);
327 return -EINVAL;
328 }
329
330 switch (cmd) {
331 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
332 val32 = iwl_read_direct32(tst->trans, ofs);
333 IWL_DEBUG_INFO(trans, "32 value to read 0x%x\n", val32);
334
335 skb = iwl_test_alloc_reply(tst, 20);
336 if (!skb) {
337 IWL_ERR(trans, "Memory allocation fail\n");
338 return -ENOMEM;
339 }
340 if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32))
341 goto nla_put_failure;
342 status = iwl_test_reply(tst, skb);
343 if (status < 0)
344 IWL_ERR(trans, "Error sending msg : %d\n", status);
345 break;
346
347 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
348 if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
349 IWL_ERR(trans, "Missing value to write\n");
350 return -ENOMSG;
351 } else {
352 val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
353 IWL_DEBUG_INFO(trans, "32b write val=0x%x\n", val32);
354 iwl_write_direct32(tst->trans, ofs, val32);
355 }
356 break;
357
358 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
359 if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
360 IWL_ERR(trans, "Missing value to write\n");
361 return -ENOMSG;
362 } else {
363 val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
364 IWL_DEBUG_INFO(trans, "8b write val=0x%x\n", val8);
365 iwl_write8(tst->trans, ofs, val8);
366 }
367 break;
368
369 default:
370 IWL_ERR(trans, "Unknown test register cmd ID\n");
371 return -ENOMSG;
372 }
373
374 return status;
375
376nla_put_failure:
377 kfree_skb(skb);
378 return -EMSGSIZE;
379}
380
381/*
382 * Handles the request to start FW tracing. Allocates of the trace buffer
383 * and sends a reply to user space with the address of the allocated buffer.
384 */
385static int iwl_test_trace_begin(struct iwl_test *tst, struct nlattr **tb)
386{
387 struct sk_buff *skb;
388 int status = 0;
389
390 if (tst->trace.enabled)
391 return -EBUSY;
392
393 if (!tb[IWL_TM_ATTR_TRACE_SIZE])
394 tst->trace.size = TRACE_BUFF_SIZE_DEF;
395 else
396 tst->trace.size =
397 nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]);
398
399 if (!tst->trace.size)
400 return -EINVAL;
401
402 if (tst->trace.size < TRACE_BUFF_SIZE_MIN ||
403 tst->trace.size > TRACE_BUFF_SIZE_MAX)
404 return -EINVAL;
405
406 tst->trace.tsize = tst->trace.size + TRACE_BUFF_PADD;
407 tst->trace.cpu_addr = dma_alloc_coherent(tst->trans->dev,
408 tst->trace.tsize,
409 &tst->trace.dma_addr,
410 GFP_KERNEL);
411 if (!tst->trace.cpu_addr)
412 return -ENOMEM;
413
414 tst->trace.enabled = true;
415 tst->trace.trace_addr = (u8 *)PTR_ALIGN(tst->trace.cpu_addr, 0x100);
416
417 memset(tst->trace.trace_addr, 0x03B, tst->trace.size);
418
419 skb = iwl_test_alloc_reply(tst, sizeof(tst->trace.dma_addr) + 20);
420 if (!skb) {
421 IWL_ERR(tst->trans, "Memory allocation fail\n");
422 iwl_test_trace_stop(tst);
423 return -ENOMEM;
424 }
425
426 if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR,
427 sizeof(tst->trace.dma_addr),
428 (u64 *)&tst->trace.dma_addr))
429 goto nla_put_failure;
430
431 status = iwl_test_reply(tst, skb);
432 if (status < 0)
433 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
434
435 tst->trace.nchunks = DIV_ROUND_UP(tst->trace.size,
436 DUMP_CHUNK_SIZE);
437
438 return status;
439
440nla_put_failure:
441 kfree_skb(skb);
442 if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
443 IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
444 iwl_test_trace_stop(tst);
445 return -EMSGSIZE;
446}
447
448/*
449 * Handles indirect read from the periphery or the SRAM. The read is performed
450 * to a temporary buffer. The user space application should later issue a dump
451 */
452static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
453{
454 struct iwl_trans *trans = tst->trans;
455 unsigned long flags;
456 int i;
457
458 if (size & 0x3)
459 return -EINVAL;
460
461 tst->mem.size = size;
462 tst->mem.addr = kmalloc(tst->mem.size, GFP_KERNEL);
463 if (tst->mem.addr == NULL)
464 return -ENOMEM;
465
466 /* Hard-coded periphery absolute address */
467 if (IWL_ABS_PRPH_START <= addr &&
468 addr < IWL_ABS_PRPH_START + PRPH_END) {
469 spin_lock_irqsave(&trans->reg_lock, flags);
470 iwl_grab_nic_access(trans);
471 iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
472 addr | (3 << 24));
473 for (i = 0; i < size; i += 4)
474 *(u32 *)(tst->mem.addr + i) =
475 iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
476 iwl_release_nic_access(trans);
477 spin_unlock_irqrestore(&trans->reg_lock, flags);
478 } else { /* target memory (SRAM) */
479 _iwl_read_targ_mem_dwords(trans, addr,
480 tst->mem.addr,
481 tst->mem.size / 4);
482 }
483
484 tst->mem.nchunks =
485 DIV_ROUND_UP(tst->mem.size, DUMP_CHUNK_SIZE);
486 tst->mem.in_read = true;
487 return 0;
488
489}
490
491/*
492 * Handles indirect write to the periphery or SRAM. The is performed to a
493 * temporary buffer.
494 */
495static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr,
496 u32 size, unsigned char *buf)
497{
498 struct iwl_trans *trans = tst->trans;
499 u32 val, i;
500 unsigned long flags;
501
502 if (IWL_ABS_PRPH_START <= addr &&
503 addr < IWL_ABS_PRPH_START + PRPH_END) {
504 /* Periphery writes can be 1-3 bytes long, or DWORDs */
505 if (size < 4) {
506 memcpy(&val, buf, size);
507 spin_lock_irqsave(&trans->reg_lock, flags);
508 iwl_grab_nic_access(trans);
509 iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
510 (addr & 0x0000FFFF) |
511 ((size - 1) << 24));
512 iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
513 iwl_release_nic_access(trans);
514 /* needed after consecutive writes w/o read */
515 mmiowb();
516 spin_unlock_irqrestore(&trans->reg_lock, flags);
517 } else {
518 if (size % 4)
519 return -EINVAL;
520 for (i = 0; i < size; i += 4)
521 iwl_write_prph(trans, addr+i,
522 *(u32 *)(buf+i));
523 }
524 } else if (iwl_test_valid_hw_addr(tst, addr)) {
525 _iwl_write_targ_mem_dwords(trans, addr, buf, size / 4);
526 } else {
527 return -EINVAL;
528 }
529 return 0;
530}
531
532/*
533 * Handles the user application commands for indirect read/write
534 * to/from the periphery or the SRAM.
535 */
536static int iwl_test_indirect_mem(struct iwl_test *tst, struct nlattr **tb)
537{
538 u32 addr, size, cmd;
539 unsigned char *buf;
540
541 /* Both read and write should be blocked, for atomicity */
542 if (tst->mem.in_read)
543 return -EBUSY;
544
545 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
546 if (!tb[IWL_TM_ATTR_MEM_ADDR]) {
547 IWL_ERR(tst->trans, "Error finding memory offset address\n");
548 return -ENOMSG;
549 }
550 addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]);
551 if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) {
552 IWL_ERR(tst->trans, "Error finding size for memory reading\n");
553 return -ENOMSG;
554 }
555 size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]);
556
557 if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ) {
558 return iwl_test_indirect_read(tst, addr, size);
559 } else {
560 if (!tb[IWL_TM_ATTR_BUFFER_DUMP])
561 return -EINVAL;
562 buf = (unsigned char *)nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]);
563 return iwl_test_indirect_write(tst, addr, size, buf);
564 }
565}
566
567/*
568 * Enable notifications to user space
569 */
570static int iwl_test_notifications(struct iwl_test *tst,
571 struct nlattr **tb)
572{
573 tst->notify = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]);
574 return 0;
575}
576
577/*
578 * Handles the request to get the device id
579 */
580static int iwl_test_get_dev_id(struct iwl_test *tst, struct nlattr **tb)
581{
582 u32 devid = tst->trans->hw_id;
583 struct sk_buff *skb;
584 int status;
585
586 IWL_DEBUG_INFO(tst->trans, "hw version: 0x%x\n", devid);
587
588 skb = iwl_test_alloc_reply(tst, 20);
589 if (!skb) {
590 IWL_ERR(tst->trans, "Memory allocation fail\n");
591 return -ENOMEM;
592 }
593
594 if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid))
595 goto nla_put_failure;
596 status = iwl_test_reply(tst, skb);
597 if (status < 0)
598 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
599
600 return 0;
601
602nla_put_failure:
603 kfree_skb(skb);
604 return -EMSGSIZE;
605}
606
607/*
608 * Handles the request to get the FW version
609 */
610static int iwl_test_get_fw_ver(struct iwl_test *tst, struct nlattr **tb)
611{
612 struct sk_buff *skb;
613 int status;
614 u32 ver = iwl_test_fw_ver(tst);
615
616 IWL_DEBUG_INFO(tst->trans, "uCode version raw: 0x%x\n", ver);
617
618 skb = iwl_test_alloc_reply(tst, 20);
619 if (!skb) {
620 IWL_ERR(tst->trans, "Memory allocation fail\n");
621 return -ENOMEM;
622 }
623
624 if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, ver))
625 goto nla_put_failure;
626
627 status = iwl_test_reply(tst, skb);
628 if (status < 0)
629 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
630
631 return 0;
632
633nla_put_failure:
634 kfree_skb(skb);
635 return -EMSGSIZE;
636}
637
638/*
639 * Parse the netlink message and validate that the IWL_TM_ATTR_CMD exists
640 */
641int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
642 void *data, int len)
643{
644 int result;
645
646 result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
647 iwl_testmode_gnl_msg_policy);
648 if (result) {
649 IWL_ERR(tst->trans, "Fail parse gnl msg: %d\n", result);
650 return result;
651 }
652
653 /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
654 if (!tb[IWL_TM_ATTR_COMMAND]) {
655 IWL_ERR(tst->trans, "Missing testmode command type\n");
656 return -ENOMSG;
657 }
658 return 0;
659}
660EXPORT_SYMBOL_GPL(iwl_test_parse);
661
662/*
663 * Handle test commands.
664 * Returns 1 for unknown commands (not handled by the test object); negative
665 * value in case of error.
666 */
667int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb)
668{
669 int result;
670
671 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
672 case IWL_TM_CMD_APP2DEV_UCODE:
673 IWL_DEBUG_INFO(tst->trans, "test cmd to uCode\n");
674 result = iwl_test_fw_cmd(tst, tb);
675 break;
676
677 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
678 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
679 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
680 IWL_DEBUG_INFO(tst->trans, "test cmd to register\n");
681 result = iwl_test_reg(tst, tb);
682 break;
683
684 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
685 IWL_DEBUG_INFO(tst->trans, "test uCode trace cmd to driver\n");
686 result = iwl_test_trace_begin(tst, tb);
687 break;
688
689 case IWL_TM_CMD_APP2DEV_END_TRACE:
690 iwl_test_trace_stop(tst);
691 result = 0;
692 break;
693
694 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
695 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
696 IWL_DEBUG_INFO(tst->trans, "test indirect memory cmd\n");
697 result = iwl_test_indirect_mem(tst, tb);
698 break;
699
700 case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
701 IWL_DEBUG_INFO(tst->trans, "test notifications cmd\n");
702 result = iwl_test_notifications(tst, tb);
703 break;
704
705 case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
706 IWL_DEBUG_INFO(tst->trans, "test get FW ver cmd\n");
707 result = iwl_test_get_fw_ver(tst, tb);
708 break;
709
710 case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
711 IWL_DEBUG_INFO(tst->trans, "test Get device ID cmd\n");
712 result = iwl_test_get_dev_id(tst, tb);
713 break;
714
715 default:
716 IWL_DEBUG_INFO(tst->trans, "Unknown test command\n");
717 result = 1;
718 break;
719 }
720 return result;
721}
722EXPORT_SYMBOL_GPL(iwl_test_handle_cmd);
723
724static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb,
725 struct netlink_callback *cb)
726{
727 int idx, length;
728
729 if (!tst->trace.enabled || !tst->trace.trace_addr)
730 return -EFAULT;
731
732 idx = cb->args[4];
733 if (idx >= tst->trace.nchunks)
734 return -ENOENT;
735
736 length = DUMP_CHUNK_SIZE;
737 if (((idx + 1) == tst->trace.nchunks) &&
738 (tst->trace.size % DUMP_CHUNK_SIZE))
739 length = tst->trace.size %
740 DUMP_CHUNK_SIZE;
741
742 if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length,
743 tst->trace.trace_addr + (DUMP_CHUNK_SIZE * idx)))
744 goto nla_put_failure;
745
746 cb->args[4] = ++idx;
747 return 0;
748
749 nla_put_failure:
750 return -ENOBUFS;
751}
752
753static int iwl_test_buffer_dump(struct iwl_test *tst, struct sk_buff *skb,
754 struct netlink_callback *cb)
755{
756 int idx, length;
757
758 if (!tst->mem.in_read)
759 return -EFAULT;
760
761 idx = cb->args[4];
762 if (idx >= tst->mem.nchunks) {
763 iwl_test_mem_stop(tst);
764 return -ENOENT;
765 }
766
767 length = DUMP_CHUNK_SIZE;
768 if (((idx + 1) == tst->mem.nchunks) &&
769 (tst->mem.size % DUMP_CHUNK_SIZE))
770 length = tst->mem.size % DUMP_CHUNK_SIZE;
771
772 if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
773 tst->mem.addr + (DUMP_CHUNK_SIZE * idx)))
774 goto nla_put_failure;
775
776 cb->args[4] = ++idx;
777 return 0;
778
779 nla_put_failure:
780 return -ENOBUFS;
781}
782
783/*
784 * Handle dump commands.
785 * Returns 1 for unknown commands (not handled by the test object); negative
786 * value in case of error.
787 */
788int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
789 struct netlink_callback *cb)
790{
791 int result;
792
793 switch (cmd) {
794 case IWL_TM_CMD_APP2DEV_READ_TRACE:
795 IWL_DEBUG_INFO(tst->trans, "uCode trace cmd\n");
796 result = iwl_test_trace_dump(tst, skb, cb);
797 break;
798
799 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
800 IWL_DEBUG_INFO(tst->trans, "testmode sram dump cmd\n");
801 result = iwl_test_buffer_dump(tst, skb, cb);
802 break;
803
804 default:
805 result = 1;
806 break;
807 }
808 return result;
809}
810EXPORT_SYMBOL_GPL(iwl_test_dump);
811
812/*
813 * Multicast a spontaneous messages from the device to the user space.
814 */
815static void iwl_test_send_rx(struct iwl_test *tst,
816 struct iwl_rx_cmd_buffer *rxb)
817{
818 struct sk_buff *skb;
819 struct iwl_rx_packet *data;
820 int length;
821
822 data = rxb_addr(rxb);
823 length = le32_to_cpu(data->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
824
825 /* the length doesn't include len_n_flags field, so add it manually */
826 length += sizeof(__le32);
827
828 skb = iwl_test_alloc_event(tst, length + 20);
829 if (skb == NULL) {
830 IWL_ERR(tst->trans, "Out of memory for message to user\n");
831 return;
832 }
833
834 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
835 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
836 nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data))
837 goto nla_put_failure;
838
839 iwl_test_event(tst, skb);
840 return;
841
842nla_put_failure:
843 kfree_skb(skb);
844 IWL_ERR(tst->trans, "Ouch, overran buffer, check allocation!\n");
845}
846
847/*
848 * Called whenever a Rx frames is recevied from the device. If notifications to
849 * the user space are requested, sends the frames to the user.
850 */
851void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb)
852{
853 if (tst->notify)
854 iwl_test_send_rx(tst, rxb);
855}
856EXPORT_SYMBOL_GPL(iwl_test_rx);
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h
new file mode 100644
index 000000000000..e13ffa8acc02
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-test.h
@@ -0,0 +1,161 @@
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) 2010 - 2012 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) 2010 - 2012 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
64#ifndef __IWL_TEST_H__
65#define __IWL_TEST_H__
66
67#include <linux/types.h>
68#include "iwl-trans.h"
69
70struct iwl_test_trace {
71 u32 size;
72 u32 tsize;
73 u32 nchunks;
74 u8 *cpu_addr;
75 u8 *trace_addr;
76 dma_addr_t dma_addr;
77 bool enabled;
78};
79
80struct iwl_test_mem {
81 u32 size;
82 u32 nchunks;
83 u8 *addr;
84 bool in_read;
85};
86
87/*
88 * struct iwl_test_ops: callback to the op mode
89 *
90 * The structure defines the callbacks that the op_mode should handle,
91 * inorder to handle logic that is out of the scope of iwl_test. The
92 * op_mode must set all the callbacks.
93
94 * @send_cmd: handler that is used by the test object to request the
95 * op_mode to send a command to the fw.
96 *
97 * @valid_hw_addr: handler that is used by the test object to request the
98 * op_mode to check if the given address is a valid address.
99 *
100 * @get_fw_ver: handler used to get the FW version.
101 *
102 * @alloc_reply: handler used by the test object to request the op_mode
103 * to allocate an skb for sending a reply to the user, and initialize
104 * the skb. It is assumed that the test object only fills the required
105 * attributes.
106 *
107 * @reply: handler used by the test object to request the op_mode to reply
108 * to a request. The skb is an skb previously allocated by the the
109 * alloc_reply callback.
110 I
111 * @alloc_event: handler used by the test object to request the op_mode
112 * to allocate an skb for sending an event, and initialize
113 * the skb. It is assumed that the test object only fills the required
114 * attributes.
115 *
116 * @reply: handler used by the test object to request the op_mode to send
117 * an event. The skb is an skb previously allocated by the the
118 * alloc_event callback.
119 */
120struct iwl_test_ops {
121 int (*send_cmd)(struct iwl_op_mode *op_modes,
122 struct iwl_host_cmd *cmd);
123 bool (*valid_hw_addr)(u32 addr);
124 u32 (*get_fw_ver)(struct iwl_op_mode *op_mode);
125
126 struct sk_buff *(*alloc_reply)(struct iwl_op_mode *op_mode, int len);
127 int (*reply)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
128 struct sk_buff* (*alloc_event)(struct iwl_op_mode *op_mode, int len);
129 void (*event)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
130};
131
132struct iwl_test {
133 struct iwl_trans *trans;
134 struct iwl_test_ops *ops;
135 struct iwl_test_trace trace;
136 struct iwl_test_mem mem;
137 bool notify;
138};
139
140void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans,
141 struct iwl_test_ops *ops);
142
143void iwl_test_free(struct iwl_test *tst);
144
145int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
146 void *data, int len);
147
148int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb);
149
150int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
151 struct netlink_callback *cb);
152
153void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb);
154
155static inline void iwl_test_enable_notifications(struct iwl_test *tst,
156 bool enable)
157{
158 tst->notify = enable;
159}
160
161#endif
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
index 6ba211b09426..6ba211b09426 100644
--- a/drivers/net/wireless/iwlwifi/dvm/testmode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c
index cb08ba03aae7..4a57624afc40 100644
--- a/drivers/net/wireless/iwlwifi/pcie/6000.c
+++ b/drivers/net/wireless/iwlwifi/pcie/6000.c
@@ -258,6 +258,7 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
258 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 258 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
259 .base_params = &iwl6000_g2_base_params, \ 259 .base_params = &iwl6000_g2_base_params, \
260 .bt_params = &iwl6000_bt_params, \ 260 .bt_params = &iwl6000_bt_params, \
261 .eeprom_params = &iwl6000_eeprom_params, \
261 .need_temp_offset_calib = true, \ 262 .need_temp_offset_calib = true, \
262 .led_mode = IWL_LED_RF_STATE, \ 263 .led_mode = IWL_LED_RF_STATE, \
263 .adv_pm = true 264 .adv_pm = true
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 94201c4d6227..5024fb662bf6 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -339,16 +339,9 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans,
339void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, 339void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
340 struct iwl_tx_queue *txq, 340 struct iwl_tx_queue *txq,
341 u16 byte_cnt); 341 u16 byte_cnt);
342void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue);
343void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index);
344void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
345 struct iwl_tx_queue *txq,
346 int tx_fifo_id, bool active);
347void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id,
348 int fifo, int sta_id, int tid,
349 int frame_limit, u16 ssn);
350void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, 342void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
351 int sta_id, int tid, int frame_limit, u16 ssn); 343 int sta_id, int tid, int frame_limit, u16 ssn);
344void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue);
352void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, 345void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq,
353 enum dma_data_direction dma_dir); 346 enum dma_data_direction dma_dir);
354int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, 347int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index,
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 7461a6a14338..32ab8ea56135 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -298,6 +298,10 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
298 struct iwl_tx_queue *txq = (void *)data; 298 struct iwl_tx_queue *txq = (void *)data;
299 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; 299 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
300 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); 300 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
301 u32 scd_sram_addr = trans_pcie->scd_base_addr +
302 SCD_TX_STTS_MEM_LOWER_BOUND + (16 * txq->q.id);
303 u8 buf[16];
304 int i;
301 305
302 spin_lock(&txq->lock); 306 spin_lock(&txq->lock);
303 /* check if triggered erroneously */ 307 /* check if triggered erroneously */
@@ -307,15 +311,40 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
307 } 311 }
308 spin_unlock(&txq->lock); 312 spin_unlock(&txq->lock);
309 313
310
311 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, 314 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id,
312 jiffies_to_msecs(trans_pcie->wd_timeout)); 315 jiffies_to_msecs(trans_pcie->wd_timeout));
313 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", 316 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
314 txq->q.read_ptr, txq->q.write_ptr); 317 txq->q.read_ptr, txq->q.write_ptr);
315 IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", 318
316 iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq->q.id)) 319 iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf));
317 & (TFD_QUEUE_SIZE_MAX - 1), 320
318 iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq->q.id))); 321 iwl_print_hex_error(trans, buf, sizeof(buf));
322
323 for (i = 0; i < FH_TCSR_CHNL_NUM; i++)
324 IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i,
325 iwl_read_direct32(trans, FH_TX_TRB_REG(i)));
326
327 for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
328 u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(i));
329 u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7;
330 bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE));
331 u32 tbl_dw =
332 iwl_read_targ_mem(trans,
333 trans_pcie->scd_base_addr +
334 SCD_TRANS_TBL_OFFSET_QUEUE(i));
335
336 if (i & 0x1)
337 tbl_dw = (tbl_dw & 0xFFFF0000) >> 16;
338 else
339 tbl_dw = tbl_dw & 0x0000FFFF;
340
341 IWL_ERR(trans,
342 "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n",
343 i, active ? "" : "in", fifo, tbl_dw,
344 iwl_read_prph(trans,
345 SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1),
346 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
347 }
319 348
320 iwl_op_mode_nic_error(trans->op_mode); 349 iwl_op_mode_nic_error(trans->op_mode);
321} 350}
@@ -1054,23 +1083,21 @@ static void iwl_tx_start(struct iwl_trans *trans)
1054 iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, 1083 iwl_write_prph(trans, SCD_DRAM_BASE_ADDR,
1055 trans_pcie->scd_bc_tbls.dma >> 10); 1084 trans_pcie->scd_bc_tbls.dma >> 10);
1056 1085
1086 /* The chain extension of the SCD doesn't work well. This feature is
1087 * enabled by default by the HW, so we need to disable it manually.
1088 */
1089 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
1090
1057 for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { 1091 for (i = 0; i < trans_pcie->n_q_to_fifo; i++) {
1058 int fifo = trans_pcie->setup_q_to_fifo[i]; 1092 int fifo = trans_pcie->setup_q_to_fifo[i];
1059 1093
1060 __iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION, 1094 iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION,
1061 IWL_TID_NON_QOS, 1095 IWL_TID_NON_QOS, SCD_FRAME_LIMIT, 0);
1062 SCD_FRAME_LIMIT, 0);
1063 } 1096 }
1064 1097
1065 /* Activate all Tx DMA/FIFO channels */ 1098 /* Activate all Tx DMA/FIFO channels */
1066 iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); 1099 iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7));
1067 1100
1068 /* The chain extension of the SCD doesn't work well. This feature is
1069 * enabled by default by the HW, so we need to disable it manually.
1070 */
1071 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
1072
1073
1074 /* Enable DMA channel */ 1101 /* Enable DMA channel */
1075 for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) 1102 for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++)
1076 iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), 1103 iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
@@ -1239,6 +1266,19 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1239 1266
1240 spin_lock(&txq->lock); 1267 spin_lock(&txq->lock);
1241 1268
1269 /* In AGG mode, the index in the ring must correspond to the WiFi
1270 * sequence number. This is a HW requirements to help the SCD to parse
1271 * the BA.
1272 * Check here that the packets are in the right place on the ring.
1273 */
1274#ifdef CONFIG_IWLWIFI_DEBUG
1275 wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
1276 WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) &&
1277 ((wifi_seq & 0xff) != q->write_ptr),
1278 "Q: %d WiFi Seq %d tfdNum %d",
1279 txq_id, wifi_seq, q->write_ptr);
1280#endif
1281
1242 /* Set up driver data for this TFD */ 1282 /* Set up driver data for this TFD */
1243 txq->entries[q->write_ptr].skb = skb; 1283 txq->entries[q->write_ptr].skb = skb;
1244 txq->entries[q->write_ptr].cmd = dev_cmd; 1284 txq->entries[q->write_ptr].cmd = dev_cmd;
@@ -1332,7 +1372,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1332 skb->data + hdr_len, secondlen); 1372 skb->data + hdr_len, secondlen);
1333 1373
1334 /* start timer if queue currently empty */ 1374 /* start timer if queue currently empty */
1335 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) 1375 if (txq->need_update && q->read_ptr == q->write_ptr &&
1376 trans_pcie->wd_timeout)
1336 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1377 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1337 1378
1338 /* Tell device the write index *just past* this latest filled TFD */ 1379 /* Tell device the write index *just past* this latest filled TFD */
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 35e82161ca43..6baf8deef519 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -380,8 +380,8 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans,
380 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; 380 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
381} 381}
382 382
383static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, 383static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
384 u16 txq_id) 384 u16 txq_id)
385{ 385{
386 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 386 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
387 u32 tbl_dw_addr; 387 u32 tbl_dw_addr;
@@ -405,7 +405,7 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid,
405 return 0; 405 return 0;
406} 406}
407 407
408static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) 408static inline void iwl_txq_set_inactive(struct iwl_trans *trans, u16 txq_id)
409{ 409{
410 /* Simply stop the queue, but don't change any configuration; 410 /* Simply stop the queue, but don't change any configuration;
411 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ 411 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
@@ -415,46 +415,16 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id)
415 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); 415 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
416} 416}
417 417
418void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index) 418void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
419{ 419 int sta_id, int tid, int frame_limit, u16 ssn)
420 IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d\n", txq_id, index & 0xff);
421 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
422 (index & 0xff) | (txq_id << 8));
423 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index);
424}
425
426void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
427 struct iwl_tx_queue *txq,
428 int tx_fifo_id, bool active)
429{
430 int txq_id = txq->q.id;
431
432 iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
433 (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
434 (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) |
435 (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
436 SCD_QUEUE_STTS_REG_MSK);
437
438 if (active)
439 IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d\n",
440 txq_id, tx_fifo_id);
441 else
442 IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
443}
444
445void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id,
446 int fifo, int sta_id, int tid,
447 int frame_limit, u16 ssn)
448{ 420{
449 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 421 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
450 422
451 lockdep_assert_held(&trans_pcie->irq_lock);
452
453 if (test_and_set_bit(txq_id, trans_pcie->queue_used)) 423 if (test_and_set_bit(txq_id, trans_pcie->queue_used))
454 WARN_ONCE(1, "queue %d already used - expect issues", txq_id); 424 WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
455 425
456 /* Stop this Tx queue before configuring it */ 426 /* Stop this Tx queue before configuring it */
457 iwlagn_tx_queue_stop_scheduler(trans, txq_id); 427 iwl_txq_set_inactive(trans, txq_id);
458 428
459 /* Set this queue as a chain-building queue unless it is CMD queue */ 429 /* Set this queue as a chain-building queue unless it is CMD queue */
460 if (txq_id != trans_pcie->cmd_queue) 430 if (txq_id != trans_pcie->cmd_queue)
@@ -465,17 +435,27 @@ void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id,
465 u16 ra_tid = BUILD_RAxTID(sta_id, tid); 435 u16 ra_tid = BUILD_RAxTID(sta_id, tid);
466 436
467 /* Map receiver-address / traffic-ID to this queue */ 437 /* Map receiver-address / traffic-ID to this queue */
468 iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); 438 iwl_txq_set_ratid_map(trans, ra_tid, txq_id);
469 439
470 /* enable aggregations for the queue */ 440 /* enable aggregations for the queue */
471 iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); 441 iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
442 } else {
443 /*
444 * disable aggregations for the queue, this will also make the
445 * ra_tid mapping configuration irrelevant since it is now a
446 * non-AGG queue.
447 */
448 iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
472 } 449 }
473 450
474 /* Place first TFD at index corresponding to start sequence number. 451 /* Place first TFD at index corresponding to start sequence number.
475 * Assumes that ssn_idx is valid (!= 0xFFF) */ 452 * Assumes that ssn_idx is valid (!= 0xFFF) */
476 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); 453 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff);
477 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); 454 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff);
478 iwl_trans_set_wr_ptrs(trans, txq_id, ssn); 455
456 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
457 (ssn & 0xff) | (txq_id << 8));
458 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);
479 459
480 /* Set up Tx window size and frame limit for this queue */ 460 /* Set up Tx window size and frame limit for this queue */
481 iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + 461 iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
@@ -488,43 +468,34 @@ void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id,
488 SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); 468 SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
489 469
490 /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ 470 /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
491 iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 471 iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
492 fifo, true); 472 (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
493} 473 (fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
494 474 (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
495void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, 475 SCD_QUEUE_STTS_REG_MSK);
496 int sta_id, int tid, int frame_limit, u16 ssn) 476 IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
497{ 477 txq_id, fifo, ssn & 0xff);
498 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
499 unsigned long flags;
500
501 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
502
503 __iwl_trans_pcie_txq_enable(trans, txq_id, fifo, sta_id,
504 tid, frame_limit, ssn);
505
506 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
507} 478}
508 479
509void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) 480void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
510{ 481{
511 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 482 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
483 u16 rd_ptr, wr_ptr;
484 int n_bd = trans_pcie->txq[txq_id].q.n_bd;
512 485
513 if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { 486 if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {
514 WARN_ONCE(1, "queue %d not used", txq_id); 487 WARN_ONCE(1, "queue %d not used", txq_id);
515 return; 488 return;
516 } 489 }
517 490
518 iwlagn_tx_queue_stop_scheduler(trans, txq_id); 491 rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1);
519 492 wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id));
520 iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
521 493
522 trans_pcie->txq[txq_id].q.read_ptr = 0; 494 WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]",
523 trans_pcie->txq[txq_id].q.write_ptr = 0; 495 txq_id, rd_ptr, wr_ptr);
524 iwl_trans_set_wr_ptrs(trans, txq_id, 0);
525 496
526 iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 497 iwl_txq_set_inactive(trans, txq_id);
527 0, false); 498 IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
528} 499}
529 500
530/*************** HOST COMMAND QUEUE FUNCTIONS *****/ 501/*************** HOST COMMAND QUEUE FUNCTIONS *****/
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 8173ab66066d..89f9a2a45de3 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -27,6 +27,17 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
27 struct cfg80211_ap_settings *params) { 27 struct cfg80211_ap_settings *params) {
28 int i; 28 int i;
29 29
30 if (!params->privacy) {
31 bss_config->protocol = PROTOCOL_NO_SECURITY;
32 bss_config->key_mgmt = KEY_MGMT_NONE;
33 bss_config->wpa_cfg.length = 0;
34 priv->sec_info.wep_enabled = 0;
35 priv->sec_info.wpa_enabled = 0;
36 priv->sec_info.wpa2_enabled = 0;
37
38 return 0;
39 }
40
30 switch (params->auth_type) { 41 switch (params->auth_type) {
31 case NL80211_AUTHTYPE_OPEN_SYSTEM: 42 case NL80211_AUTHTYPE_OPEN_SYSTEM:
32 bss_config->auth_mode = WLAN_AUTH_OPEN; 43 bss_config->auth_mode = WLAN_AUTH_OPEN;
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 2e9e6af21362..dfcd02ab6cae 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2110,7 +2110,7 @@ resize_buf:
2110 while (check_bssid_list_item(bssid, bssid_len, buf, len)) { 2110 while (check_bssid_list_item(bssid, bssid_len, buf, len)) {
2111 if (rndis_bss_info_update(usbdev, bssid) && match_bssid && 2111 if (rndis_bss_info_update(usbdev, bssid) && match_bssid &&
2112 matched) { 2112 matched) {
2113 if (!ether_addr_equal(bssid->mac, match_bssid)) 2113 if (ether_addr_equal(bssid->mac, match_bssid))
2114 *matched = true; 2114 *matched = true;
2115 } 2115 }
2116 2116