aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c1265
1 files changed, 909 insertions, 356 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 746532ebe5a8..0cb5ecc822a8 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/sched.h>
15#include <linux/spinlock.h> 16#include <linux/spinlock.h>
16#include <linux/list.h> 17#include <linux/list.h>
17#include <linux/pci.h> 18#include <linux/pci.h>
@@ -27,18 +28,6 @@
27#define MWL8K_NAME KBUILD_MODNAME 28#define MWL8K_NAME KBUILD_MODNAME
28#define MWL8K_VERSION "0.10" 29#define MWL8K_VERSION "0.10"
29 30
30MODULE_DESCRIPTION(MWL8K_DESC);
31MODULE_VERSION(MWL8K_VERSION);
32MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
33MODULE_LICENSE("GPL");
34
35static DEFINE_PCI_DEVICE_TABLE(mwl8k_table) = {
36 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = 8687, },
37 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = 8687, },
38 { }
39};
40MODULE_DEVICE_TABLE(pci, mwl8k_table);
41
42/* Register definitions */ 31/* Register definitions */
43#define MWL8K_HIU_GEN_PTR 0x00000c10 32#define MWL8K_HIU_GEN_PTR 0x00000c10
44#define MWL8K_MODE_STA 0x0000005a 33#define MWL8K_MODE_STA 0x0000005a
@@ -88,72 +77,89 @@ MODULE_DEVICE_TABLE(pci, mwl8k_table);
88 MWL8K_A2H_INT_RX_READY | \ 77 MWL8K_A2H_INT_RX_READY | \
89 MWL8K_A2H_INT_TX_DONE) 78 MWL8K_A2H_INT_TX_DONE)
90 79
91/* WME stream classes */
92#define WME_AC_BE 0 /* best effort */
93#define WME_AC_BK 1 /* background */
94#define WME_AC_VI 2 /* video */
95#define WME_AC_VO 3 /* voice */
96
97#define MWL8K_RX_QUEUES 1 80#define MWL8K_RX_QUEUES 1
98#define MWL8K_TX_QUEUES 4 81#define MWL8K_TX_QUEUES 4
99 82
83struct rxd_ops {
84 int rxd_size;
85 void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
86 void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
87 int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status);
88};
89
90struct mwl8k_device_info {
91 char *part_name;
92 char *helper_image;
93 char *fw_image;
94 struct rxd_ops *rxd_ops;
95 u16 modes;
96};
97
100struct mwl8k_rx_queue { 98struct mwl8k_rx_queue {
101 int rx_desc_count; 99 int rxd_count;
102 100
103 /* hw receives here */ 101 /* hw receives here */
104 int rx_head; 102 int head;
105 103
106 /* refill descs here */ 104 /* refill descs here */
107 int rx_tail; 105 int tail;
108 106
109 struct mwl8k_rx_desc *rx_desc_area; 107 void *rxd;
110 dma_addr_t rx_desc_dma; 108 dma_addr_t rxd_dma;
111 struct sk_buff **rx_skb; 109 struct {
110 struct sk_buff *skb;
111 DECLARE_PCI_UNMAP_ADDR(dma)
112 } *buf;
112}; 113};
113 114
114struct mwl8k_tx_queue { 115struct mwl8k_tx_queue {
115 /* hw transmits here */ 116 /* hw transmits here */
116 int tx_head; 117 int head;
117 118
118 /* sw appends here */ 119 /* sw appends here */
119 int tx_tail; 120 int tail;
120 121
121 struct ieee80211_tx_queue_stats tx_stats; 122 struct ieee80211_tx_queue_stats stats;
122 struct mwl8k_tx_desc *tx_desc_area; 123 struct mwl8k_tx_desc *txd;
123 dma_addr_t tx_desc_dma; 124 dma_addr_t txd_dma;
124 struct sk_buff **tx_skb; 125 struct sk_buff **skb;
125}; 126};
126 127
127/* Pointers to the firmware data and meta information about it. */ 128/* Pointers to the firmware data and meta information about it. */
128struct mwl8k_firmware { 129struct mwl8k_firmware {
129 /* Microcode */
130 struct firmware *ucode;
131
132 /* Boot helper code */ 130 /* Boot helper code */
133 struct firmware *helper; 131 struct firmware *helper;
132
133 /* Microcode */
134 struct firmware *ucode;
134}; 135};
135 136
136struct mwl8k_priv { 137struct mwl8k_priv {
138 void __iomem *sram;
137 void __iomem *regs; 139 void __iomem *regs;
138 struct ieee80211_hw *hw; 140 struct ieee80211_hw *hw;
139 141
140 struct pci_dev *pdev; 142 struct pci_dev *pdev;
141 u8 name[16]; 143
144 struct mwl8k_device_info *device_info;
145 bool ap_fw;
146 struct rxd_ops *rxd_ops;
142 147
143 /* firmware files and meta data */ 148 /* firmware files and meta data */
144 struct mwl8k_firmware fw; 149 struct mwl8k_firmware fw;
145 u32 part_num;
146 150
147 /* firmware access */ 151 /* firmware access */
148 struct mutex fw_mutex; 152 struct mutex fw_mutex;
149 struct task_struct *fw_mutex_owner; 153 struct task_struct *fw_mutex_owner;
150 int fw_mutex_depth; 154 int fw_mutex_depth;
151 struct completion *tx_wait;
152 struct completion *hostcmd_wait; 155 struct completion *hostcmd_wait;
153 156
154 /* lock held over TX and TX reap */ 157 /* lock held over TX and TX reap */
155 spinlock_t tx_lock; 158 spinlock_t tx_lock;
156 159
160 /* TX quiesce completion, protected by fw_mutex and tx_lock */
161 struct completion *tx_wait;
162
157 struct ieee80211_vif *vif; 163 struct ieee80211_vif *vif;
158 164
159 struct ieee80211_channel *current_channel; 165 struct ieee80211_channel *current_channel;
@@ -178,10 +184,11 @@ struct mwl8k_priv {
178 /* PHY parameters */ 184 /* PHY parameters */
179 struct ieee80211_supported_band band; 185 struct ieee80211_supported_band band;
180 struct ieee80211_channel channels[14]; 186 struct ieee80211_channel channels[14];
181 struct ieee80211_rate rates[12]; 187 struct ieee80211_rate rates[13];
182 188
183 bool radio_on; 189 bool radio_on;
184 bool radio_short_preamble; 190 bool radio_short_preamble;
191 bool sniffer_enabled;
185 bool wmm_enabled; 192 bool wmm_enabled;
186 193
187 /* XXX need to convert this to handle multiple interfaces */ 194 /* XXX need to convert this to handle multiple interfaces */
@@ -199,9 +206,6 @@ struct mwl8k_priv {
199 206
200 /* Tasklet to reclaim TX descriptors and buffers after tx */ 207 /* Tasklet to reclaim TX descriptors and buffers after tx */
201 struct tasklet_struct tx_reclaim_task; 208 struct tasklet_struct tx_reclaim_task;
202
203 /* Work thread to serialize configuration requests */
204 struct workqueue_struct *config_wq;
205}; 209};
206 210
207/* Per interface specific private data */ 211/* Per interface specific private data */
@@ -220,7 +224,7 @@ struct mwl8k_vif {
220 * Subset of supported legacy rates. 224 * Subset of supported legacy rates.
221 * Intersection of AP and STA supported rates. 225 * Intersection of AP and STA supported rates.
222 */ 226 */
223 struct ieee80211_rate legacy_rates[12]; 227 struct ieee80211_rate legacy_rates[13];
224 228
225 /* number of supported legacy rates */ 229 /* number of supported legacy rates */
226 u8 legacy_nrates; 230 u8 legacy_nrates;
@@ -252,9 +256,10 @@ static const struct ieee80211_rate mwl8k_rates[] = {
252 { .bitrate = 10, .hw_value = 2, }, 256 { .bitrate = 10, .hw_value = 2, },
253 { .bitrate = 20, .hw_value = 4, }, 257 { .bitrate = 20, .hw_value = 4, },
254 { .bitrate = 55, .hw_value = 11, }, 258 { .bitrate = 55, .hw_value = 11, },
259 { .bitrate = 110, .hw_value = 22, },
260 { .bitrate = 220, .hw_value = 44, },
255 { .bitrate = 60, .hw_value = 12, }, 261 { .bitrate = 60, .hw_value = 12, },
256 { .bitrate = 90, .hw_value = 18, }, 262 { .bitrate = 90, .hw_value = 18, },
257 { .bitrate = 110, .hw_value = 22, },
258 { .bitrate = 120, .hw_value = 24, }, 263 { .bitrate = 120, .hw_value = 24, },
259 { .bitrate = 180, .hw_value = 36, }, 264 { .bitrate = 180, .hw_value = 36, },
260 { .bitrate = 240, .hw_value = 48, }, 265 { .bitrate = 240, .hw_value = 48, },
@@ -270,10 +275,12 @@ static const struct ieee80211_rate mwl8k_rates[] = {
270/* Firmware command codes */ 275/* Firmware command codes */
271#define MWL8K_CMD_CODE_DNLD 0x0001 276#define MWL8K_CMD_CODE_DNLD 0x0001
272#define MWL8K_CMD_GET_HW_SPEC 0x0003 277#define MWL8K_CMD_GET_HW_SPEC 0x0003
278#define MWL8K_CMD_SET_HW_SPEC 0x0004
273#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010 279#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010
274#define MWL8K_CMD_GET_STAT 0x0014 280#define MWL8K_CMD_GET_STAT 0x0014
275#define MWL8K_CMD_RADIO_CONTROL 0x001c 281#define MWL8K_CMD_RADIO_CONTROL 0x001c
276#define MWL8K_CMD_RF_TX_POWER 0x001e 282#define MWL8K_CMD_RF_TX_POWER 0x001e
283#define MWL8K_CMD_RF_ANTENNA 0x0020
277#define MWL8K_CMD_SET_PRE_SCAN 0x0107 284#define MWL8K_CMD_SET_PRE_SCAN 0x0107
278#define MWL8K_CMD_SET_POST_SCAN 0x0108 285#define MWL8K_CMD_SET_POST_SCAN 0x0108
279#define MWL8K_CMD_SET_RF_CHANNEL 0x010a 286#define MWL8K_CMD_SET_RF_CHANNEL 0x010a
@@ -287,6 +294,7 @@ static const struct ieee80211_rate mwl8k_rates[] = {
287#define MWL8K_CMD_MIMO_CONFIG 0x0125 294#define MWL8K_CMD_MIMO_CONFIG 0x0125
288#define MWL8K_CMD_USE_FIXED_RATE 0x0126 295#define MWL8K_CMD_USE_FIXED_RATE 0x0126
289#define MWL8K_CMD_ENABLE_SNIFFER 0x0150 296#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
297#define MWL8K_CMD_SET_MAC_ADDR 0x0202
290#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 298#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
291#define MWL8K_CMD_UPDATE_STADB 0x1123 299#define MWL8K_CMD_UPDATE_STADB 0x1123
292 300
@@ -299,10 +307,12 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
299 switch (cmd & ~0x8000) { 307 switch (cmd & ~0x8000) {
300 MWL8K_CMDNAME(CODE_DNLD); 308 MWL8K_CMDNAME(CODE_DNLD);
301 MWL8K_CMDNAME(GET_HW_SPEC); 309 MWL8K_CMDNAME(GET_HW_SPEC);
310 MWL8K_CMDNAME(SET_HW_SPEC);
302 MWL8K_CMDNAME(MAC_MULTICAST_ADR); 311 MWL8K_CMDNAME(MAC_MULTICAST_ADR);
303 MWL8K_CMDNAME(GET_STAT); 312 MWL8K_CMDNAME(GET_STAT);
304 MWL8K_CMDNAME(RADIO_CONTROL); 313 MWL8K_CMDNAME(RADIO_CONTROL);
305 MWL8K_CMDNAME(RF_TX_POWER); 314 MWL8K_CMDNAME(RF_TX_POWER);
315 MWL8K_CMDNAME(RF_ANTENNA);
306 MWL8K_CMDNAME(SET_PRE_SCAN); 316 MWL8K_CMDNAME(SET_PRE_SCAN);
307 MWL8K_CMDNAME(SET_POST_SCAN); 317 MWL8K_CMDNAME(SET_POST_SCAN);
308 MWL8K_CMDNAME(SET_RF_CHANNEL); 318 MWL8K_CMDNAME(SET_RF_CHANNEL);
@@ -316,6 +326,7 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
316 MWL8K_CMDNAME(MIMO_CONFIG); 326 MWL8K_CMDNAME(MIMO_CONFIG);
317 MWL8K_CMDNAME(USE_FIXED_RATE); 327 MWL8K_CMDNAME(USE_FIXED_RATE);
318 MWL8K_CMDNAME(ENABLE_SNIFFER); 328 MWL8K_CMDNAME(ENABLE_SNIFFER);
329 MWL8K_CMDNAME(SET_MAC_ADDR);
319 MWL8K_CMDNAME(SET_RATEADAPT_MODE); 330 MWL8K_CMDNAME(SET_RATEADAPT_MODE);
320 MWL8K_CMDNAME(UPDATE_STADB); 331 MWL8K_CMDNAME(UPDATE_STADB);
321 default: 332 default:
@@ -353,41 +364,35 @@ static void mwl8k_release_firmware(struct mwl8k_priv *priv)
353 364
354/* Request fw image */ 365/* Request fw image */
355static int mwl8k_request_fw(struct mwl8k_priv *priv, 366static int mwl8k_request_fw(struct mwl8k_priv *priv,
356 const char *fname, struct firmware **fw) 367 const char *fname, struct firmware **fw)
357{ 368{
358 /* release current image */ 369 /* release current image */
359 if (*fw != NULL) 370 if (*fw != NULL)
360 mwl8k_release_fw(fw); 371 mwl8k_release_fw(fw);
361 372
362 return request_firmware((const struct firmware **)fw, 373 return request_firmware((const struct firmware **)fw,
363 fname, &priv->pdev->dev); 374 fname, &priv->pdev->dev);
364} 375}
365 376
366static int mwl8k_request_firmware(struct mwl8k_priv *priv, u32 part_num) 377static int mwl8k_request_firmware(struct mwl8k_priv *priv)
367{ 378{
368 u8 filename[64]; 379 struct mwl8k_device_info *di = priv->device_info;
369 int rc; 380 int rc;
370 381
371 priv->part_num = part_num; 382 if (di->helper_image != NULL) {
372 383 rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw.helper);
373 snprintf(filename, sizeof(filename), 384 if (rc) {
374 "mwl8k/helper_%u.fw", priv->part_num); 385 printk(KERN_ERR "%s: Error requesting helper "
375 386 "firmware file %s\n", pci_name(priv->pdev),
376 rc = mwl8k_request_fw(priv, filename, &priv->fw.helper); 387 di->helper_image);
377 if (rc) { 388 return rc;
378 printk(KERN_ERR 389 }
379 "%s Error requesting helper firmware file %s\n",
380 pci_name(priv->pdev), filename);
381 return rc;
382 } 390 }
383 391
384 snprintf(filename, sizeof(filename), 392 rc = mwl8k_request_fw(priv, di->fw_image, &priv->fw.ucode);
385 "mwl8k/fmimage_%u.fw", priv->part_num);
386
387 rc = mwl8k_request_fw(priv, filename, &priv->fw.ucode);
388 if (rc) { 393 if (rc) {
389 printk(KERN_ERR "%s Error requesting firmware file %s\n", 394 printk(KERN_ERR "%s: Error requesting firmware file %s\n",
390 pci_name(priv->pdev), filename); 395 pci_name(priv->pdev), di->fw_image);
391 mwl8k_release_fw(&priv->fw.helper); 396 mwl8k_release_fw(&priv->fw.helper);
392 return rc; 397 return rc;
393 } 398 }
@@ -395,6 +400,9 @@ static int mwl8k_request_firmware(struct mwl8k_priv *priv, u32 part_num)
395 return 0; 400 return 0;
396} 401}
397 402
403MODULE_FIRMWARE("mwl8k/helper_8687.fw");
404MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
405
398struct mwl8k_cmd_pkt { 406struct mwl8k_cmd_pkt {
399 __le16 code; 407 __le16 code;
400 __le16 length; 408 __le16 length;
@@ -434,6 +442,7 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
434 break; 442 break;
435 } 443 }
436 444
445 cond_resched();
437 udelay(1); 446 udelay(1);
438 } while (--loops); 447 } while (--loops);
439 448
@@ -542,43 +551,62 @@ static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
542 return rc; 551 return rc;
543} 552}
544 553
545static int mwl8k_load_firmware(struct mwl8k_priv *priv) 554static int mwl8k_load_firmware(struct ieee80211_hw *hw)
546{ 555{
547 int loops, rc; 556 struct mwl8k_priv *priv = hw->priv;
557 struct firmware *fw = priv->fw.ucode;
558 struct mwl8k_device_info *di = priv->device_info;
559 int rc;
560 int loops;
548 561
549 const u8 *ucode = priv->fw.ucode->data; 562 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
550 size_t ucode_len = priv->fw.ucode->size; 563 struct firmware *helper = priv->fw.helper;
551 const u8 *helper = priv->fw.helper->data;
552 size_t helper_len = priv->fw.helper->size;
553 564
554 if (!memcmp(ucode, "\x01\x00\x00\x00", 4)) { 565 if (helper == NULL) {
555 rc = mwl8k_load_fw_image(priv, helper, helper_len); 566 printk(KERN_ERR "%s: helper image needed but none "
567 "given\n", pci_name(priv->pdev));
568 return -EINVAL;
569 }
570
571 rc = mwl8k_load_fw_image(priv, helper->data, helper->size);
556 if (rc) { 572 if (rc) {
557 printk(KERN_ERR "%s: unable to load firmware " 573 printk(KERN_ERR "%s: unable to load firmware "
558 "helper image\n", pci_name(priv->pdev)); 574 "helper image\n", pci_name(priv->pdev));
559 return rc; 575 return rc;
560 } 576 }
561 msleep(1); 577 msleep(1);
562 578
563 rc = mwl8k_feed_fw_image(priv, ucode, ucode_len); 579 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
564 } else { 580 } else {
565 rc = mwl8k_load_fw_image(priv, ucode, ucode_len); 581 rc = mwl8k_load_fw_image(priv, fw->data, fw->size);
566 } 582 }
567 583
568 if (rc) { 584 if (rc) {
569 printk(KERN_ERR "%s: unable to load firmware data\n", 585 printk(KERN_ERR "%s: unable to load firmware image\n",
570 pci_name(priv->pdev)); 586 pci_name(priv->pdev));
571 return rc; 587 return rc;
572 } 588 }
573 589
574 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); 590 if (di->modes & BIT(NL80211_IFTYPE_AP))
591 iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR);
592 else
593 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
575 msleep(1); 594 msleep(1);
576 595
577 loops = 200000; 596 loops = 200000;
578 do { 597 do {
579 if (ioread32(priv->regs + MWL8K_HIU_INT_CODE) 598 u32 ready_code;
580 == MWL8K_FWSTA_READY) 599
600 ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE);
601 if (ready_code == MWL8K_FWAP_READY) {
602 priv->ap_fw = 1;
603 break;
604 } else if (ready_code == MWL8K_FWSTA_READY) {
605 priv->ap_fw = 0;
581 break; 606 break;
607 }
608
609 cond_resched();
582 udelay(1); 610 udelay(1);
583 } while (--loops); 611 } while (--loops);
584 612
@@ -605,7 +633,7 @@ struct ewc_ht_info {
605/* Peer Entry flags - used to define the type of the peer node */ 633/* Peer Entry flags - used to define the type of the peer node */
606#define MWL8K_PEER_TYPE_ACCESSPOINT 2 634#define MWL8K_PEER_TYPE_ACCESSPOINT 2
607 635
608#define MWL8K_IEEE_LEGACY_DATA_RATES 12 636#define MWL8K_IEEE_LEGACY_DATA_RATES 13
609#define MWL8K_MCS_BITMAP_SIZE 16 637#define MWL8K_MCS_BITMAP_SIZE 16
610 638
611struct peer_capability_info { 639struct peer_capability_info {
@@ -731,16 +759,96 @@ static inline void mwl8k_add_dma_header(struct sk_buff *skb)
731 759
732 760
733/* 761/*
734 * Packet reception. 762 * Packet reception for 88w8366.
735 */ 763 */
736#define MWL8K_RX_CTRL_OWNED_BY_HOST 0x02 764struct mwl8k_rxd_8366 {
765 __le16 pkt_len;
766 __u8 sq2;
767 __u8 rate;
768 __le32 pkt_phys_addr;
769 __le32 next_rxd_phys_addr;
770 __le16 qos_control;
771 __le16 htsig2;
772 __le32 hw_rssi_info;
773 __le32 hw_noise_floor_info;
774 __u8 noise_floor;
775 __u8 pad0[3];
776 __u8 rssi;
777 __u8 rx_status;
778 __u8 channel;
779 __u8 rx_ctrl;
780} __attribute__((packed));
781
782#define MWL8K_8366_RX_CTRL_OWNED_BY_HOST 0x80
783
784static void mwl8k_rxd_8366_init(void *_rxd, dma_addr_t next_dma_addr)
785{
786 struct mwl8k_rxd_8366 *rxd = _rxd;
787
788 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
789 rxd->rx_ctrl = MWL8K_8366_RX_CTRL_OWNED_BY_HOST;
790}
791
792static void mwl8k_rxd_8366_refill(void *_rxd, dma_addr_t addr, int len)
793{
794 struct mwl8k_rxd_8366 *rxd = _rxd;
795
796 rxd->pkt_len = cpu_to_le16(len);
797 rxd->pkt_phys_addr = cpu_to_le32(addr);
798 wmb();
799 rxd->rx_ctrl = 0;
800}
801
802static int
803mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status)
804{
805 struct mwl8k_rxd_8366 *rxd = _rxd;
806
807 if (!(rxd->rx_ctrl & MWL8K_8366_RX_CTRL_OWNED_BY_HOST))
808 return -1;
809 rmb();
810
811 memset(status, 0, sizeof(*status));
812
813 status->signal = -rxd->rssi;
814 status->noise = -rxd->noise_floor;
737 815
738struct mwl8k_rx_desc { 816 if (rxd->rate & 0x80) {
817 status->flag |= RX_FLAG_HT;
818 status->rate_idx = rxd->rate & 0x7f;
819 } else {
820 int i;
821
822 for (i = 0; i < ARRAY_SIZE(mwl8k_rates); i++) {
823 if (mwl8k_rates[i].hw_value == rxd->rate) {
824 status->rate_idx = i;
825 break;
826 }
827 }
828 }
829
830 status->band = IEEE80211_BAND_2GHZ;
831 status->freq = ieee80211_channel_to_frequency(rxd->channel);
832
833 return le16_to_cpu(rxd->pkt_len);
834}
835
836static struct rxd_ops rxd_8366_ops = {
837 .rxd_size = sizeof(struct mwl8k_rxd_8366),
838 .rxd_init = mwl8k_rxd_8366_init,
839 .rxd_refill = mwl8k_rxd_8366_refill,
840 .rxd_process = mwl8k_rxd_8366_process,
841};
842
843/*
844 * Packet reception for 88w8687.
845 */
846struct mwl8k_rxd_8687 {
739 __le16 pkt_len; 847 __le16 pkt_len;
740 __u8 link_quality; 848 __u8 link_quality;
741 __u8 noise_level; 849 __u8 noise_level;
742 __le32 pkt_phys_addr; 850 __le32 pkt_phys_addr;
743 __le32 next_rx_desc_phys_addr; 851 __le32 next_rxd_phys_addr;
744 __le16 qos_control; 852 __le16 qos_control;
745 __le16 rate_info; 853 __le16 rate_info;
746 __le32 pad0[4]; 854 __le32 pad0[4];
@@ -752,6 +860,76 @@ struct mwl8k_rx_desc {
752 __u8 pad2[2]; 860 __u8 pad2[2];
753} __attribute__((packed)); 861} __attribute__((packed));
754 862
863#define MWL8K_8687_RATE_INFO_SHORTPRE 0x8000
864#define MWL8K_8687_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3)
865#define MWL8K_8687_RATE_INFO_RATEID(x) (((x) >> 3) & 0x3f)
866#define MWL8K_8687_RATE_INFO_40MHZ 0x0004
867#define MWL8K_8687_RATE_INFO_SHORTGI 0x0002
868#define MWL8K_8687_RATE_INFO_MCS_FORMAT 0x0001
869
870#define MWL8K_8687_RX_CTRL_OWNED_BY_HOST 0x02
871
872static void mwl8k_rxd_8687_init(void *_rxd, dma_addr_t next_dma_addr)
873{
874 struct mwl8k_rxd_8687 *rxd = _rxd;
875
876 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
877 rxd->rx_ctrl = MWL8K_8687_RX_CTRL_OWNED_BY_HOST;
878}
879
880static void mwl8k_rxd_8687_refill(void *_rxd, dma_addr_t addr, int len)
881{
882 struct mwl8k_rxd_8687 *rxd = _rxd;
883
884 rxd->pkt_len = cpu_to_le16(len);
885 rxd->pkt_phys_addr = cpu_to_le32(addr);
886 wmb();
887 rxd->rx_ctrl = 0;
888}
889
890static int
891mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status)
892{
893 struct mwl8k_rxd_8687 *rxd = _rxd;
894 u16 rate_info;
895
896 if (!(rxd->rx_ctrl & MWL8K_8687_RX_CTRL_OWNED_BY_HOST))
897 return -1;
898 rmb();
899
900 rate_info = le16_to_cpu(rxd->rate_info);
901
902 memset(status, 0, sizeof(*status));
903
904 status->signal = -rxd->rssi;
905 status->noise = -rxd->noise_level;
906 status->qual = rxd->link_quality;
907 status->antenna = MWL8K_8687_RATE_INFO_ANTSELECT(rate_info);
908 status->rate_idx = MWL8K_8687_RATE_INFO_RATEID(rate_info);
909
910 if (rate_info & MWL8K_8687_RATE_INFO_SHORTPRE)
911 status->flag |= RX_FLAG_SHORTPRE;
912 if (rate_info & MWL8K_8687_RATE_INFO_40MHZ)
913 status->flag |= RX_FLAG_40MHZ;
914 if (rate_info & MWL8K_8687_RATE_INFO_SHORTGI)
915 status->flag |= RX_FLAG_SHORT_GI;
916 if (rate_info & MWL8K_8687_RATE_INFO_MCS_FORMAT)
917 status->flag |= RX_FLAG_HT;
918
919 status->band = IEEE80211_BAND_2GHZ;
920 status->freq = ieee80211_channel_to_frequency(rxd->channel);
921
922 return le16_to_cpu(rxd->pkt_len);
923}
924
925static struct rxd_ops rxd_8687_ops = {
926 .rxd_size = sizeof(struct mwl8k_rxd_8687),
927 .rxd_init = mwl8k_rxd_8687_init,
928 .rxd_refill = mwl8k_rxd_8687_refill,
929 .rxd_process = mwl8k_rxd_8687_process,
930};
931
932
755#define MWL8K_RX_DESCS 256 933#define MWL8K_RX_DESCS 256
756#define MWL8K_RX_MAXSZ 3800 934#define MWL8K_RX_MAXSZ 3800
757 935
@@ -762,43 +940,44 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
762 int size; 940 int size;
763 int i; 941 int i;
764 942
765 rxq->rx_desc_count = 0; 943 rxq->rxd_count = 0;
766 rxq->rx_head = 0; 944 rxq->head = 0;
767 rxq->rx_tail = 0; 945 rxq->tail = 0;
768 946
769 size = MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc); 947 size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size;
770 948
771 rxq->rx_desc_area = 949 rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
772 pci_alloc_consistent(priv->pdev, size, &rxq->rx_desc_dma); 950 if (rxq->rxd == NULL) {
773 if (rxq->rx_desc_area == NULL) {
774 printk(KERN_ERR "%s: failed to alloc RX descriptors\n", 951 printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
775 priv->name); 952 wiphy_name(hw->wiphy));
776 return -ENOMEM; 953 return -ENOMEM;
777 } 954 }
778 memset(rxq->rx_desc_area, 0, size); 955 memset(rxq->rxd, 0, size);
779 956
780 rxq->rx_skb = kmalloc(MWL8K_RX_DESCS * 957 rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL);
781 sizeof(*rxq->rx_skb), GFP_KERNEL); 958 if (rxq->buf == NULL) {
782 if (rxq->rx_skb == NULL) {
783 printk(KERN_ERR "%s: failed to alloc RX skbuff list\n", 959 printk(KERN_ERR "%s: failed to alloc RX skbuff list\n",
784 priv->name); 960 wiphy_name(hw->wiphy));
785 pci_free_consistent(priv->pdev, size, 961 pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
786 rxq->rx_desc_area, rxq->rx_desc_dma);
787 return -ENOMEM; 962 return -ENOMEM;
788 } 963 }
789 memset(rxq->rx_skb, 0, MWL8K_RX_DESCS * sizeof(*rxq->rx_skb)); 964 memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf));
790 965
791 for (i = 0; i < MWL8K_RX_DESCS; i++) { 966 for (i = 0; i < MWL8K_RX_DESCS; i++) {
792 struct mwl8k_rx_desc *rx_desc; 967 int desc_size;
968 void *rxd;
793 int nexti; 969 int nexti;
970 dma_addr_t next_dma_addr;
794 971
795 rx_desc = rxq->rx_desc_area + i; 972 desc_size = priv->rxd_ops->rxd_size;
796 nexti = (i + 1) % MWL8K_RX_DESCS; 973 rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size);
797 974
798 rx_desc->next_rx_desc_phys_addr = 975 nexti = i + 1;
799 cpu_to_le32(rxq->rx_desc_dma 976 if (nexti == MWL8K_RX_DESCS)
800 + nexti * sizeof(*rx_desc)); 977 nexti = 0;
801 rx_desc->rx_ctrl = MWL8K_RX_CTRL_OWNED_BY_HOST; 978 next_dma_addr = rxq->rxd_dma + (nexti * desc_size);
979
980 priv->rxd_ops->rxd_init(rxd, next_dma_addr);
802 } 981 }
803 982
804 return 0; 983 return 0;
@@ -811,27 +990,28 @@ static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
811 int refilled; 990 int refilled;
812 991
813 refilled = 0; 992 refilled = 0;
814 while (rxq->rx_desc_count < MWL8K_RX_DESCS && limit--) { 993 while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) {
815 struct sk_buff *skb; 994 struct sk_buff *skb;
995 dma_addr_t addr;
816 int rx; 996 int rx;
997 void *rxd;
817 998
818 skb = dev_alloc_skb(MWL8K_RX_MAXSZ); 999 skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
819 if (skb == NULL) 1000 if (skb == NULL)
820 break; 1001 break;
821 1002
822 rxq->rx_desc_count++; 1003 addr = pci_map_single(priv->pdev, skb->data,
823 1004 MWL8K_RX_MAXSZ, DMA_FROM_DEVICE);
824 rx = rxq->rx_tail;
825 rxq->rx_tail = (rx + 1) % MWL8K_RX_DESCS;
826 1005
827 rxq->rx_desc_area[rx].pkt_phys_addr = 1006 rxq->rxd_count++;
828 cpu_to_le32(pci_map_single(priv->pdev, skb->data, 1007 rx = rxq->tail++;
829 MWL8K_RX_MAXSZ, DMA_FROM_DEVICE)); 1008 if (rxq->tail == MWL8K_RX_DESCS)
1009 rxq->tail = 0;
1010 rxq->buf[rx].skb = skb;
1011 pci_unmap_addr_set(&rxq->buf[rx], dma, addr);
830 1012
831 rxq->rx_desc_area[rx].pkt_len = cpu_to_le16(MWL8K_RX_MAXSZ); 1013 rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size);
832 rxq->rx_skb[rx] = skb; 1014 priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ);
833 wmb();
834 rxq->rx_desc_area[rx].rx_ctrl = 0;
835 1015
836 refilled++; 1016 refilled++;
837 } 1017 }
@@ -847,24 +1027,24 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
847 int i; 1027 int i;
848 1028
849 for (i = 0; i < MWL8K_RX_DESCS; i++) { 1029 for (i = 0; i < MWL8K_RX_DESCS; i++) {
850 if (rxq->rx_skb[i] != NULL) { 1030 if (rxq->buf[i].skb != NULL) {
851 unsigned long addr; 1031 pci_unmap_single(priv->pdev,
852 1032 pci_unmap_addr(&rxq->buf[i], dma),
853 addr = le32_to_cpu(rxq->rx_desc_area[i].pkt_phys_addr); 1033 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
854 pci_unmap_single(priv->pdev, addr, MWL8K_RX_MAXSZ, 1034 pci_unmap_addr_set(&rxq->buf[i], dma, 0);
855 PCI_DMA_FROMDEVICE); 1035
856 kfree_skb(rxq->rx_skb[i]); 1036 kfree_skb(rxq->buf[i].skb);
857 rxq->rx_skb[i] = NULL; 1037 rxq->buf[i].skb = NULL;
858 } 1038 }
859 } 1039 }
860 1040
861 kfree(rxq->rx_skb); 1041 kfree(rxq->buf);
862 rxq->rx_skb = NULL; 1042 rxq->buf = NULL;
863 1043
864 pci_free_consistent(priv->pdev, 1044 pci_free_consistent(priv->pdev,
865 MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc), 1045 MWL8K_RX_DESCS * priv->rxd_ops->rxd_size,
866 rxq->rx_desc_area, rxq->rx_desc_dma); 1046 rxq->rxd, rxq->rxd_dma);
867 rxq->rx_desc_area = NULL; 1047 rxq->rxd = NULL;
868} 1048}
869 1049
870 1050
@@ -880,9 +1060,11 @@ mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
880 !compare_ether_addr(wh->addr3, priv->capture_bssid); 1060 !compare_ether_addr(wh->addr3, priv->capture_bssid);
881} 1061}
882 1062
883static inline void mwl8k_save_beacon(struct mwl8k_priv *priv, 1063static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
884 struct sk_buff *skb) 1064 struct sk_buff *skb)
885{ 1065{
1066 struct mwl8k_priv *priv = hw->priv;
1067
886 priv->capture_beacon = false; 1068 priv->capture_beacon = false;
887 memset(priv->capture_bssid, 0, ETH_ALEN); 1069 memset(priv->capture_bssid, 0, ETH_ALEN);
888 1070
@@ -893,8 +1075,7 @@ static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
893 */ 1075 */
894 priv->beacon_skb = skb_copy(skb, GFP_ATOMIC); 1076 priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
895 if (priv->beacon_skb != NULL) 1077 if (priv->beacon_skb != NULL)
896 queue_work(priv->config_wq, 1078 ieee80211_queue_work(hw, &priv->finalize_join_worker);
897 &priv->finalize_join_worker);
898} 1079}
899 1080
900static int rxq_process(struct ieee80211_hw *hw, int index, int limit) 1081static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
@@ -904,53 +1085,46 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
904 int processed; 1085 int processed;
905 1086
906 processed = 0; 1087 processed = 0;
907 while (rxq->rx_desc_count && limit--) { 1088 while (rxq->rxd_count && limit--) {
908 struct mwl8k_rx_desc *rx_desc;
909 struct sk_buff *skb; 1089 struct sk_buff *skb;
1090 void *rxd;
1091 int pkt_len;
910 struct ieee80211_rx_status status; 1092 struct ieee80211_rx_status status;
911 unsigned long addr;
912 struct ieee80211_hdr *wh;
913 1093
914 rx_desc = rxq->rx_desc_area + rxq->rx_head; 1094 skb = rxq->buf[rxq->head].skb;
915 if (!(rx_desc->rx_ctrl & MWL8K_RX_CTRL_OWNED_BY_HOST)) 1095 if (skb == NULL)
916 break; 1096 break;
917 rmb();
918 1097
919 skb = rxq->rx_skb[rxq->rx_head]; 1098 rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
920 if (skb == NULL) 1099
1100 pkt_len = priv->rxd_ops->rxd_process(rxd, &status);
1101 if (pkt_len < 0)
921 break; 1102 break;
922 rxq->rx_skb[rxq->rx_head] = NULL;
923 1103
924 rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS; 1104 rxq->buf[rxq->head].skb = NULL;
925 rxq->rx_desc_count--;
926 1105
927 addr = le32_to_cpu(rx_desc->pkt_phys_addr); 1106 pci_unmap_single(priv->pdev,
928 pci_unmap_single(priv->pdev, addr, 1107 pci_unmap_addr(&rxq->buf[rxq->head], dma),
929 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); 1108 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
1109 pci_unmap_addr_set(&rxq->buf[rxq->head], dma, 0);
930 1110
931 skb_put(skb, le16_to_cpu(rx_desc->pkt_len)); 1111 rxq->head++;
932 mwl8k_remove_dma_header(skb); 1112 if (rxq->head == MWL8K_RX_DESCS)
1113 rxq->head = 0;
1114
1115 rxq->rxd_count--;
933 1116
934 wh = (struct ieee80211_hdr *)skb->data; 1117 skb_put(skb, pkt_len);
1118 mwl8k_remove_dma_header(skb);
935 1119
936 /* 1120 /*
937 * Check for pending join operation. save a copy of 1121 * Check for a pending join operation. Save a
938 * the beacon and schedule a tasklet to send finalize 1122 * copy of the beacon and schedule a tasklet to
939 * join command to the firmware. 1123 * send a FINALIZE_JOIN command to the firmware.
940 */ 1124 */
941 if (mwl8k_capture_bssid(priv, wh)) 1125 if (mwl8k_capture_bssid(priv, (void *)skb->data))
942 mwl8k_save_beacon(priv, skb); 1126 mwl8k_save_beacon(hw, skb);
943 1127
944 memset(&status, 0, sizeof(status));
945 status.mactime = 0;
946 status.signal = -rx_desc->rssi;
947 status.noise = -rx_desc->noise_level;
948 status.qual = rx_desc->link_quality;
949 status.antenna = 1;
950 status.rate_idx = 1;
951 status.flag = 0;
952 status.band = IEEE80211_BAND_2GHZ;
953 status.freq = ieee80211_channel_to_frequency(rx_desc->channel);
954 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 1128 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
955 ieee80211_rx_irqsafe(hw, skb); 1129 ieee80211_rx_irqsafe(hw, skb);
956 1130
@@ -965,24 +1139,10 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
965 * Packet transmission. 1139 * Packet transmission.
966 */ 1140 */
967 1141
968/* Transmit queue assignment. */
969enum {
970 MWL8K_WME_AC_BK = 0, /* background access */
971 MWL8K_WME_AC_BE = 1, /* best effort access */
972 MWL8K_WME_AC_VI = 2, /* video access */
973 MWL8K_WME_AC_VO = 3, /* voice access */
974};
975
976/* Transmit packet ACK policy */ 1142/* Transmit packet ACK policy */
977#define MWL8K_TXD_ACK_POLICY_NORMAL 0 1143#define MWL8K_TXD_ACK_POLICY_NORMAL 0
978#define MWL8K_TXD_ACK_POLICY_BLOCKACK 3 1144#define MWL8K_TXD_ACK_POLICY_BLOCKACK 3
979 1145
980#define GET_TXQ(_ac) (\
981 ((_ac) == WME_AC_VO) ? MWL8K_WME_AC_VO : \
982 ((_ac) == WME_AC_VI) ? MWL8K_WME_AC_VI : \
983 ((_ac) == WME_AC_BK) ? MWL8K_WME_AC_BK : \
984 MWL8K_WME_AC_BE)
985
986#define MWL8K_TXD_STATUS_OK 0x00000001 1146#define MWL8K_TXD_STATUS_OK 0x00000001
987#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002 1147#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002
988#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004 1148#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004
@@ -997,7 +1157,7 @@ struct mwl8k_tx_desc {
997 __le32 pkt_phys_addr; 1157 __le32 pkt_phys_addr;
998 __le16 pkt_len; 1158 __le16 pkt_len;
999 __u8 dest_MAC_addr[ETH_ALEN]; 1159 __u8 dest_MAC_addr[ETH_ALEN];
1000 __le32 next_tx_desc_phys_addr; 1160 __le32 next_txd_phys_addr;
1001 __le32 reserved; 1161 __le32 reserved;
1002 __le16 rate_info; 1162 __le16 rate_info;
1003 __u8 peer_id; 1163 __u8 peer_id;
@@ -1013,44 +1173,40 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1013 int size; 1173 int size;
1014 int i; 1174 int i;
1015 1175
1016 memset(&txq->tx_stats, 0, sizeof(struct ieee80211_tx_queue_stats)); 1176 memset(&txq->stats, 0, sizeof(struct ieee80211_tx_queue_stats));
1017 txq->tx_stats.limit = MWL8K_TX_DESCS; 1177 txq->stats.limit = MWL8K_TX_DESCS;
1018 txq->tx_head = 0; 1178 txq->head = 0;
1019 txq->tx_tail = 0; 1179 txq->tail = 0;
1020 1180
1021 size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc); 1181 size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc);
1022 1182
1023 txq->tx_desc_area = 1183 txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma);
1024 pci_alloc_consistent(priv->pdev, size, &txq->tx_desc_dma); 1184 if (txq->txd == NULL) {
1025 if (txq->tx_desc_area == NULL) {
1026 printk(KERN_ERR "%s: failed to alloc TX descriptors\n", 1185 printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
1027 priv->name); 1186 wiphy_name(hw->wiphy));
1028 return -ENOMEM; 1187 return -ENOMEM;
1029 } 1188 }
1030 memset(txq->tx_desc_area, 0, size); 1189 memset(txq->txd, 0, size);
1031 1190
1032 txq->tx_skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->tx_skb), 1191 txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL);
1033 GFP_KERNEL); 1192 if (txq->skb == NULL) {
1034 if (txq->tx_skb == NULL) {
1035 printk(KERN_ERR "%s: failed to alloc TX skbuff list\n", 1193 printk(KERN_ERR "%s: failed to alloc TX skbuff list\n",
1036 priv->name); 1194 wiphy_name(hw->wiphy));
1037 pci_free_consistent(priv->pdev, size, 1195 pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
1038 txq->tx_desc_area, txq->tx_desc_dma);
1039 return -ENOMEM; 1196 return -ENOMEM;
1040 } 1197 }
1041 memset(txq->tx_skb, 0, MWL8K_TX_DESCS * sizeof(*txq->tx_skb)); 1198 memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb));
1042 1199
1043 for (i = 0; i < MWL8K_TX_DESCS; i++) { 1200 for (i = 0; i < MWL8K_TX_DESCS; i++) {
1044 struct mwl8k_tx_desc *tx_desc; 1201 struct mwl8k_tx_desc *tx_desc;
1045 int nexti; 1202 int nexti;
1046 1203
1047 tx_desc = txq->tx_desc_area + i; 1204 tx_desc = txq->txd + i;
1048 nexti = (i + 1) % MWL8K_TX_DESCS; 1205 nexti = (i + 1) % MWL8K_TX_DESCS;
1049 1206
1050 tx_desc->status = 0; 1207 tx_desc->status = 0;
1051 tx_desc->next_tx_desc_phys_addr = 1208 tx_desc->next_txd_phys_addr =
1052 cpu_to_le32(txq->tx_desc_dma + 1209 cpu_to_le32(txq->txd_dma + nexti * sizeof(*tx_desc));
1053 nexti * sizeof(*tx_desc));
1054 } 1210 }
1055 1211
1056 return 0; 1212 return 0;
@@ -1065,11 +1221,6 @@ static inline void mwl8k_tx_start(struct mwl8k_priv *priv)
1065 ioread32(priv->regs + MWL8K_HIU_INT_CODE); 1221 ioread32(priv->regs + MWL8K_HIU_INT_CODE);
1066} 1222}
1067 1223
1068static inline int mwl8k_txq_busy(struct mwl8k_priv *priv)
1069{
1070 return priv->pending_tx_pkts;
1071}
1072
1073struct mwl8k_txq_info { 1224struct mwl8k_txq_info {
1074 u32 fw_owned; 1225 u32 fw_owned;
1075 u32 drv_owned; 1226 u32 drv_owned;
@@ -1089,14 +1240,13 @@ static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
1089 1240
1090 memset(txinfo, 0, MWL8K_TX_QUEUES * sizeof(struct mwl8k_txq_info)); 1241 memset(txinfo, 0, MWL8K_TX_QUEUES * sizeof(struct mwl8k_txq_info));
1091 1242
1092 spin_lock_bh(&priv->tx_lock);
1093 for (count = 0; count < MWL8K_TX_QUEUES; count++) { 1243 for (count = 0; count < MWL8K_TX_QUEUES; count++) {
1094 txq = priv->txq + count; 1244 txq = priv->txq + count;
1095 txinfo[count].len = txq->tx_stats.len; 1245 txinfo[count].len = txq->stats.len;
1096 txinfo[count].head = txq->tx_head; 1246 txinfo[count].head = txq->head;
1097 txinfo[count].tail = txq->tx_tail; 1247 txinfo[count].tail = txq->tail;
1098 for (desc = 0; desc < MWL8K_TX_DESCS; desc++) { 1248 for (desc = 0; desc < MWL8K_TX_DESCS; desc++) {
1099 tx_desc = txq->tx_desc_area + desc; 1249 tx_desc = txq->txd + desc;
1100 status = le32_to_cpu(tx_desc->status); 1250 status = le32_to_cpu(tx_desc->status);
1101 1251
1102 if (status & MWL8K_TXD_STATUS_FW_OWNED) 1252 if (status & MWL8K_TXD_STATUS_FW_OWNED)
@@ -1108,30 +1258,26 @@ static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
1108 txinfo[count].unused++; 1258 txinfo[count].unused++;
1109 } 1259 }
1110 } 1260 }
1111 spin_unlock_bh(&priv->tx_lock);
1112 1261
1113 return ndescs; 1262 return ndescs;
1114} 1263}
1115 1264
1116/* 1265/*
1117 * Must be called with hw->fw_mutex held and tx queues stopped. 1266 * Must be called with priv->fw_mutex held and tx queues stopped.
1118 */ 1267 */
1119static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) 1268static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1120{ 1269{
1121 struct mwl8k_priv *priv = hw->priv; 1270 struct mwl8k_priv *priv = hw->priv;
1122 DECLARE_COMPLETION_ONSTACK(cmd_wait); 1271 DECLARE_COMPLETION_ONSTACK(tx_wait);
1123 u32 count; 1272 u32 count;
1124 unsigned long timeout; 1273 unsigned long timeout;
1125 1274
1126 might_sleep(); 1275 might_sleep();
1127 1276
1128 spin_lock_bh(&priv->tx_lock); 1277 spin_lock_bh(&priv->tx_lock);
1129 count = mwl8k_txq_busy(priv); 1278 count = priv->pending_tx_pkts;
1130 if (count) { 1279 if (count)
1131 priv->tx_wait = &cmd_wait; 1280 priv->tx_wait = &tx_wait;
1132 if (priv->radio_on)
1133 mwl8k_tx_start(priv);
1134 }
1135 spin_unlock_bh(&priv->tx_lock); 1281 spin_unlock_bh(&priv->tx_lock);
1136 1282
1137 if (count) { 1283 if (count) {
@@ -1139,23 +1285,23 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1139 int index; 1285 int index;
1140 int newcount; 1286 int newcount;
1141 1287
1142 timeout = wait_for_completion_timeout(&cmd_wait, 1288 timeout = wait_for_completion_timeout(&tx_wait,
1143 msecs_to_jiffies(5000)); 1289 msecs_to_jiffies(5000));
1144 if (timeout) 1290 if (timeout)
1145 return 0; 1291 return 0;
1146 1292
1147 spin_lock_bh(&priv->tx_lock); 1293 spin_lock_bh(&priv->tx_lock);
1148 priv->tx_wait = NULL; 1294 priv->tx_wait = NULL;
1149 newcount = mwl8k_txq_busy(priv); 1295 newcount = priv->pending_tx_pkts;
1296 mwl8k_scan_tx_ring(priv, txinfo);
1150 spin_unlock_bh(&priv->tx_lock); 1297 spin_unlock_bh(&priv->tx_lock);
1151 1298
1152 printk(KERN_ERR "%s(%u) TIMEDOUT:5000ms Pend:%u-->%u\n", 1299 printk(KERN_ERR "%s(%u) TIMEDOUT:5000ms Pend:%u-->%u\n",
1153 __func__, __LINE__, count, newcount); 1300 __func__, __LINE__, count, newcount);
1154 1301
1155 mwl8k_scan_tx_ring(priv, txinfo);
1156 for (index = 0; index < MWL8K_TX_QUEUES; index++) 1302 for (index = 0; index < MWL8K_TX_QUEUES; index++)
1157 printk(KERN_ERR 1303 printk(KERN_ERR "TXQ:%u L:%u H:%u T:%u FW:%u "
1158 "TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n", 1304 "DRV:%u U:%u\n",
1159 index, 1305 index,
1160 txinfo[index].len, 1306 txinfo[index].len,
1161 txinfo[index].head, 1307 txinfo[index].head,
@@ -1181,7 +1327,7 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1181 struct mwl8k_tx_queue *txq = priv->txq + index; 1327 struct mwl8k_tx_queue *txq = priv->txq + index;
1182 int wake = 0; 1328 int wake = 0;
1183 1329
1184 while (txq->tx_stats.len > 0) { 1330 while (txq->stats.len > 0) {
1185 int tx; 1331 int tx;
1186 struct mwl8k_tx_desc *tx_desc; 1332 struct mwl8k_tx_desc *tx_desc;
1187 unsigned long addr; 1333 unsigned long addr;
@@ -1190,8 +1336,8 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1190 struct ieee80211_tx_info *info; 1336 struct ieee80211_tx_info *info;
1191 u32 status; 1337 u32 status;
1192 1338
1193 tx = txq->tx_head; 1339 tx = txq->head;
1194 tx_desc = txq->tx_desc_area + tx; 1340 tx_desc = txq->txd + tx;
1195 1341
1196 status = le32_to_cpu(tx_desc->status); 1342 status = le32_to_cpu(tx_desc->status);
1197 1343
@@ -1202,15 +1348,15 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1202 ~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED); 1348 ~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED);
1203 } 1349 }
1204 1350
1205 txq->tx_head = (tx + 1) % MWL8K_TX_DESCS; 1351 txq->head = (tx + 1) % MWL8K_TX_DESCS;
1206 BUG_ON(txq->tx_stats.len == 0); 1352 BUG_ON(txq->stats.len == 0);
1207 txq->tx_stats.len--; 1353 txq->stats.len--;
1208 priv->pending_tx_pkts--; 1354 priv->pending_tx_pkts--;
1209 1355
1210 addr = le32_to_cpu(tx_desc->pkt_phys_addr); 1356 addr = le32_to_cpu(tx_desc->pkt_phys_addr);
1211 size = le16_to_cpu(tx_desc->pkt_len); 1357 size = le16_to_cpu(tx_desc->pkt_len);
1212 skb = txq->tx_skb[tx]; 1358 skb = txq->skb[tx];
1213 txq->tx_skb[tx] = NULL; 1359 txq->skb[tx] = NULL;
1214 1360
1215 BUG_ON(skb == NULL); 1361 BUG_ON(skb == NULL);
1216 pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE); 1362 pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
@@ -1243,13 +1389,13 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1243 1389
1244 mwl8k_txq_reclaim(hw, index, 1); 1390 mwl8k_txq_reclaim(hw, index, 1);
1245 1391
1246 kfree(txq->tx_skb); 1392 kfree(txq->skb);
1247 txq->tx_skb = NULL; 1393 txq->skb = NULL;
1248 1394
1249 pci_free_consistent(priv->pdev, 1395 pci_free_consistent(priv->pdev,
1250 MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc), 1396 MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc),
1251 txq->tx_desc_area, txq->tx_desc_dma); 1397 txq->txd, txq->txd_dma);
1252 txq->tx_desc_area = NULL; 1398 txq->txd = NULL;
1253} 1399}
1254 1400
1255static int 1401static int
@@ -1317,7 +1463,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1317 1463
1318 if (pci_dma_mapping_error(priv->pdev, dma)) { 1464 if (pci_dma_mapping_error(priv->pdev, dma)) {
1319 printk(KERN_DEBUG "%s: failed to dma map skb, " 1465 printk(KERN_DEBUG "%s: failed to dma map skb, "
1320 "dropping TX frame.\n", priv->name); 1466 "dropping TX frame.\n", wiphy_name(hw->wiphy));
1321 dev_kfree_skb(skb); 1467 dev_kfree_skb(skb);
1322 return NETDEV_TX_OK; 1468 return NETDEV_TX_OK;
1323 } 1469 }
@@ -1326,10 +1472,10 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1326 1472
1327 txq = priv->txq + index; 1473 txq = priv->txq + index;
1328 1474
1329 BUG_ON(txq->tx_skb[txq->tx_tail] != NULL); 1475 BUG_ON(txq->skb[txq->tail] != NULL);
1330 txq->tx_skb[txq->tx_tail] = skb; 1476 txq->skb[txq->tail] = skb;
1331 1477
1332 tx = txq->tx_desc_area + txq->tx_tail; 1478 tx = txq->txd + txq->tail;
1333 tx->data_rate = txdatarate; 1479 tx->data_rate = txdatarate;
1334 tx->tx_priority = index; 1480 tx->tx_priority = index;
1335 tx->qos_control = cpu_to_le16(qos); 1481 tx->qos_control = cpu_to_le16(qos);
@@ -1340,15 +1486,15 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1340 wmb(); 1486 wmb();
1341 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 1487 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1342 1488
1343 txq->tx_stats.count++; 1489 txq->stats.count++;
1344 txq->tx_stats.len++; 1490 txq->stats.len++;
1345 priv->pending_tx_pkts++; 1491 priv->pending_tx_pkts++;
1346 1492
1347 txq->tx_tail++; 1493 txq->tail++;
1348 if (txq->tx_tail == MWL8K_TX_DESCS) 1494 if (txq->tail == MWL8K_TX_DESCS)
1349 txq->tx_tail = 0; 1495 txq->tail = 0;
1350 1496
1351 if (txq->tx_head == txq->tx_tail) 1497 if (txq->head == txq->tail)
1352 ieee80211_stop_queue(hw, index); 1498 ieee80211_stop_queue(hw, index);
1353 1499
1354 mwl8k_tx_start(priv); 1500 mwl8k_tx_start(priv);
@@ -1431,7 +1577,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1431 unsigned long timeout = 0; 1577 unsigned long timeout = 0;
1432 u8 buf[32]; 1578 u8 buf[32];
1433 1579
1434 cmd->result = 0xFFFF; 1580 cmd->result = 0xffff;
1435 dma_size = le16_to_cpu(cmd->length); 1581 dma_size = le16_to_cpu(cmd->length);
1436 dma_addr = pci_map_single(priv->pdev, cmd, dma_size, 1582 dma_addr = pci_map_single(priv->pdev, cmd, dma_size,
1437 PCI_DMA_BIDIRECTIONAL); 1583 PCI_DMA_BIDIRECTIONAL);
@@ -1464,7 +1610,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1464 1610
1465 if (!timeout) { 1611 if (!timeout) {
1466 printk(KERN_ERR "%s: Command %s timeout after %u ms\n", 1612 printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
1467 priv->name, 1613 wiphy_name(hw->wiphy),
1468 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), 1614 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1469 MWL8K_CMD_TIMEOUT_MS); 1615 MWL8K_CMD_TIMEOUT_MS);
1470 rc = -ETIMEDOUT; 1616 rc = -ETIMEDOUT;
@@ -1472,7 +1618,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1472 rc = cmd->result ? -EINVAL : 0; 1618 rc = cmd->result ? -EINVAL : 0;
1473 if (rc) 1619 if (rc)
1474 printk(KERN_ERR "%s: Command %s error 0x%x\n", 1620 printk(KERN_ERR "%s: Command %s error 0x%x\n",
1475 priv->name, 1621 wiphy_name(hw->wiphy),
1476 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), 1622 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1477 le16_to_cpu(cmd->result)); 1623 le16_to_cpu(cmd->result));
1478 } 1624 }
@@ -1481,9 +1627,9 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1481} 1627}
1482 1628
1483/* 1629/*
1484 * GET_HW_SPEC. 1630 * CMD_GET_HW_SPEC (STA version).
1485 */ 1631 */
1486struct mwl8k_cmd_get_hw_spec { 1632struct mwl8k_cmd_get_hw_spec_sta {
1487 struct mwl8k_cmd_pkt header; 1633 struct mwl8k_cmd_pkt header;
1488 __u8 hw_rev; 1634 __u8 hw_rev;
1489 __u8 host_interface; 1635 __u8 host_interface;
@@ -1499,13 +1645,13 @@ struct mwl8k_cmd_get_hw_spec {
1499 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; 1645 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
1500 __le32 caps2; 1646 __le32 caps2;
1501 __le32 num_tx_desc_per_queue; 1647 __le32 num_tx_desc_per_queue;
1502 __le32 total_rx_desc; 1648 __le32 total_rxd;
1503} __attribute__((packed)); 1649} __attribute__((packed));
1504 1650
1505static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw) 1651static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1506{ 1652{
1507 struct mwl8k_priv *priv = hw->priv; 1653 struct mwl8k_priv *priv = hw->priv;
1508 struct mwl8k_cmd_get_hw_spec *cmd; 1654 struct mwl8k_cmd_get_hw_spec_sta *cmd;
1509 int rc; 1655 int rc;
1510 int i; 1656 int i;
1511 1657
@@ -1518,12 +1664,12 @@ static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
1518 1664
1519 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); 1665 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1520 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 1666 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1521 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma); 1667 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
1522 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 1668 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1523 for (i = 0; i < MWL8K_TX_QUEUES; i++) 1669 for (i = 0; i < MWL8K_TX_QUEUES; i++)
1524 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].tx_desc_dma); 1670 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1525 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); 1671 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1526 cmd->total_rx_desc = cpu_to_le32(MWL8K_RX_DESCS); 1672 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
1527 1673
1528 rc = mwl8k_post_cmd(hw, &cmd->header); 1674 rc = mwl8k_post_cmd(hw, &cmd->header);
1529 1675
@@ -1539,6 +1685,129 @@ static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
1539} 1685}
1540 1686
1541/* 1687/*
1688 * CMD_GET_HW_SPEC (AP version).
1689 */
1690struct mwl8k_cmd_get_hw_spec_ap {
1691 struct mwl8k_cmd_pkt header;
1692 __u8 hw_rev;
1693 __u8 host_interface;
1694 __le16 num_wcb;
1695 __le16 num_mcaddrs;
1696 __u8 perm_addr[ETH_ALEN];
1697 __le16 region_code;
1698 __le16 num_antenna;
1699 __le32 fw_rev;
1700 __le32 wcbbase0;
1701 __le32 rxwrptr;
1702 __le32 rxrdptr;
1703 __le32 ps_cookie;
1704 __le32 wcbbase1;
1705 __le32 wcbbase2;
1706 __le32 wcbbase3;
1707} __attribute__((packed));
1708
1709static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1710{
1711 struct mwl8k_priv *priv = hw->priv;
1712 struct mwl8k_cmd_get_hw_spec_ap *cmd;
1713 int rc;
1714
1715 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1716 if (cmd == NULL)
1717 return -ENOMEM;
1718
1719 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
1720 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1721
1722 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1723 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1724
1725 rc = mwl8k_post_cmd(hw, &cmd->header);
1726
1727 if (!rc) {
1728 int off;
1729
1730 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
1731 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1732 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1733 priv->hw_rev = cmd->hw_rev;
1734
1735 off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
1736 iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off);
1737
1738 off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
1739 iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off);
1740
1741 off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
1742 iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off);
1743
1744 off = le32_to_cpu(cmd->wcbbase1) & 0xffff;
1745 iowrite32(cpu_to_le32(priv->txq[1].txd_dma), priv->sram + off);
1746
1747 off = le32_to_cpu(cmd->wcbbase2) & 0xffff;
1748 iowrite32(cpu_to_le32(priv->txq[2].txd_dma), priv->sram + off);
1749
1750 off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
1751 iowrite32(cpu_to_le32(priv->txq[3].txd_dma), priv->sram + off);
1752 }
1753
1754 kfree(cmd);
1755 return rc;
1756}
1757
1758/*
1759 * CMD_SET_HW_SPEC.
1760 */
1761struct mwl8k_cmd_set_hw_spec {
1762 struct mwl8k_cmd_pkt header;
1763 __u8 hw_rev;
1764 __u8 host_interface;
1765 __le16 num_mcaddrs;
1766 __u8 perm_addr[ETH_ALEN];
1767 __le16 region_code;
1768 __le32 fw_rev;
1769 __le32 ps_cookie;
1770 __le32 caps;
1771 __le32 rx_queue_ptr;
1772 __le32 num_tx_queues;
1773 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
1774 __le32 flags;
1775 __le32 num_tx_desc_per_queue;
1776 __le32 total_rxd;
1777} __attribute__((packed));
1778
1779#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
1780
1781static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
1782{
1783 struct mwl8k_priv *priv = hw->priv;
1784 struct mwl8k_cmd_set_hw_spec *cmd;
1785 int rc;
1786 int i;
1787
1788 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1789 if (cmd == NULL)
1790 return -ENOMEM;
1791
1792 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC);
1793 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1794
1795 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1796 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
1797 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1798 for (i = 0; i < MWL8K_TX_QUEUES; i++)
1799 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1800 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT);
1801 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1802 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
1803
1804 rc = mwl8k_post_cmd(hw, &cmd->header);
1805 kfree(cmd);
1806
1807 return rc;
1808}
1809
1810/*
1542 * CMD_MAC_MULTICAST_ADR. 1811 * CMD_MAC_MULTICAST_ADR.
1543 */ 1812 */
1544struct mwl8k_cmd_mac_multicast_adr { 1813struct mwl8k_cmd_mac_multicast_adr {
@@ -1548,19 +1817,23 @@ struct mwl8k_cmd_mac_multicast_adr {
1548 __u8 addr[0][ETH_ALEN]; 1817 __u8 addr[0][ETH_ALEN];
1549}; 1818};
1550 1819
1551#define MWL8K_ENABLE_RX_MULTICAST 0x000F 1820#define MWL8K_ENABLE_RX_DIRECTED 0x0001
1821#define MWL8K_ENABLE_RX_MULTICAST 0x0002
1822#define MWL8K_ENABLE_RX_ALL_MULTICAST 0x0004
1823#define MWL8K_ENABLE_RX_BROADCAST 0x0008
1552 1824
1553static struct mwl8k_cmd_pkt * 1825static struct mwl8k_cmd_pkt *
1554__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, 1826__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
1555 int mc_count, struct dev_addr_list *mclist) 1827 int mc_count, struct dev_addr_list *mclist)
1556{ 1828{
1557 struct mwl8k_priv *priv = hw->priv; 1829 struct mwl8k_priv *priv = hw->priv;
1558 struct mwl8k_cmd_mac_multicast_adr *cmd; 1830 struct mwl8k_cmd_mac_multicast_adr *cmd;
1559 int size; 1831 int size;
1560 int i;
1561 1832
1562 if (mc_count > priv->num_mcaddrs) 1833 if (allmulti || mc_count > priv->num_mcaddrs) {
1563 mc_count = priv->num_mcaddrs; 1834 allmulti = 1;
1835 mc_count = 0;
1836 }
1564 1837
1565 size = sizeof(*cmd) + mc_count * ETH_ALEN; 1838 size = sizeof(*cmd) + mc_count * ETH_ALEN;
1566 1839
@@ -1570,16 +1843,24 @@ __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
1570 1843
1571 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR); 1844 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
1572 cmd->header.length = cpu_to_le16(size); 1845 cmd->header.length = cpu_to_le16(size);
1573 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); 1846 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_DIRECTED |
1574 cmd->numaddr = cpu_to_le16(mc_count); 1847 MWL8K_ENABLE_RX_BROADCAST);
1575 1848
1576 for (i = 0; i < mc_count && mclist; i++) { 1849 if (allmulti) {
1577 if (mclist->da_addrlen != ETH_ALEN) { 1850 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST);
1578 kfree(cmd); 1851 } else if (mc_count) {
1579 return NULL; 1852 int i;
1853
1854 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
1855 cmd->numaddr = cpu_to_le16(mc_count);
1856 for (i = 0; i < mc_count && mclist; i++) {
1857 if (mclist->da_addrlen != ETH_ALEN) {
1858 kfree(cmd);
1859 return NULL;
1860 }
1861 memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
1862 mclist = mclist->next;
1580 } 1863 }
1581 memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
1582 mclist = mclist->next;
1583 } 1864 }
1584 1865
1585 return &cmd->header; 1866 return &cmd->header;
@@ -1590,7 +1871,6 @@ __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
1590 */ 1871 */
1591struct mwl8k_cmd_802_11_get_stat { 1872struct mwl8k_cmd_802_11_get_stat {
1592 struct mwl8k_cmd_pkt header; 1873 struct mwl8k_cmd_pkt header;
1593 __le16 action;
1594 __le32 stats[64]; 1874 __le32 stats[64];
1595} __attribute__((packed)); 1875} __attribute__((packed));
1596 1876
@@ -1611,7 +1891,6 @@ static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw,
1611 1891
1612 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT); 1892 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT);
1613 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1893 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1614 cmd->action = cpu_to_le16(MWL8K_CMD_GET);
1615 1894
1616 rc = mwl8k_post_cmd(hw, &cmd->header); 1895 rc = mwl8k_post_cmd(hw, &cmd->header);
1617 if (!rc) { 1896 if (!rc) {
@@ -1727,6 +2006,39 @@ static int mwl8k_cmd_802_11_rf_tx_power(struct ieee80211_hw *hw, int dBm)
1727} 2006}
1728 2007
1729/* 2008/*
2009 * CMD_RF_ANTENNA.
2010 */
2011struct mwl8k_cmd_rf_antenna {
2012 struct mwl8k_cmd_pkt header;
2013 __le16 antenna;
2014 __le16 mode;
2015} __attribute__((packed));
2016
2017#define MWL8K_RF_ANTENNA_RX 1
2018#define MWL8K_RF_ANTENNA_TX 2
2019
2020static int
2021mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask)
2022{
2023 struct mwl8k_cmd_rf_antenna *cmd;
2024 int rc;
2025
2026 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2027 if (cmd == NULL)
2028 return -ENOMEM;
2029
2030 cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_ANTENNA);
2031 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2032 cmd->antenna = cpu_to_le16(antenna);
2033 cmd->mode = cpu_to_le16(mask);
2034
2035 rc = mwl8k_post_cmd(hw, &cmd->header);
2036 kfree(cmd);
2037
2038 return rc;
2039}
2040
2041/*
1730 * CMD_SET_PRE_SCAN. 2042 * CMD_SET_PRE_SCAN.
1731 */ 2043 */
1732struct mwl8k_cmd_set_pre_scan { 2044struct mwl8k_cmd_set_pre_scan {
@@ -1904,6 +2216,46 @@ static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
1904} 2216}
1905 2217
1906/* 2218/*
2219 * CMD_SET_MAC_ADDR.
2220 */
2221struct mwl8k_cmd_set_mac_addr {
2222 struct mwl8k_cmd_pkt header;
2223 union {
2224 struct {
2225 __le16 mac_type;
2226 __u8 mac_addr[ETH_ALEN];
2227 } mbss;
2228 __u8 mac_addr[ETH_ALEN];
2229 };
2230} __attribute__((packed));
2231
2232static int mwl8k_set_mac_addr(struct ieee80211_hw *hw, u8 *mac)
2233{
2234 struct mwl8k_priv *priv = hw->priv;
2235 struct mwl8k_cmd_set_mac_addr *cmd;
2236 int rc;
2237
2238 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2239 if (cmd == NULL)
2240 return -ENOMEM;
2241
2242 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
2243 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2244 if (priv->ap_fw) {
2245 cmd->mbss.mac_type = 0;
2246 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
2247 } else {
2248 memcpy(cmd->mac_addr, mac, ETH_ALEN);
2249 }
2250
2251 rc = mwl8k_post_cmd(hw, &cmd->header);
2252 kfree(cmd);
2253
2254 return rc;
2255}
2256
2257
2258/*
1907 * CMD_SET_RATEADAPT_MODE. 2259 * CMD_SET_RATEADAPT_MODE.
1908 */ 2260 */
1909struct mwl8k_cmd_set_rate_adapt_mode { 2261struct mwl8k_cmd_set_rate_adapt_mode {
@@ -2005,17 +2357,34 @@ struct mwl8k_cmd_set_edca_params {
2005 /* TX opportunity in units of 32 us */ 2357 /* TX opportunity in units of 32 us */
2006 __le16 txop; 2358 __le16 txop;
2007 2359
2008 /* Log exponent of max contention period: 0...15*/ 2360 union {
2009 __u8 log_cw_max; 2361 struct {
2362 /* Log exponent of max contention period: 0...15 */
2363 __le32 log_cw_max;
2364
2365 /* Log exponent of min contention period: 0...15 */
2366 __le32 log_cw_min;
2367
2368 /* Adaptive interframe spacing in units of 32us */
2369 __u8 aifs;
2370
2371 /* TX queue to configure */
2372 __u8 txq;
2373 } ap;
2374 struct {
2375 /* Log exponent of max contention period: 0...15 */
2376 __u8 log_cw_max;
2010 2377
2011 /* Log exponent of min contention period: 0...15 */ 2378 /* Log exponent of min contention period: 0...15 */
2012 __u8 log_cw_min; 2379 __u8 log_cw_min;
2013 2380
2014 /* Adaptive interframe spacing in units of 32us */ 2381 /* Adaptive interframe spacing in units of 32us */
2015 __u8 aifs; 2382 __u8 aifs;
2016 2383
2017 /* TX queue to configure */ 2384 /* TX queue to configure */
2018 __u8 txq; 2385 __u8 txq;
2386 } sta;
2387 };
2019} __attribute__((packed)); 2388} __attribute__((packed));
2020 2389
2021#define MWL8K_SET_EDCA_CW 0x01 2390#define MWL8K_SET_EDCA_CW 0x01
@@ -2031,6 +2400,7 @@ mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2031 __u16 cw_min, __u16 cw_max, 2400 __u16 cw_min, __u16 cw_max,
2032 __u8 aifs, __u16 txop) 2401 __u8 aifs, __u16 txop)
2033{ 2402{
2403 struct mwl8k_priv *priv = hw->priv;
2034 struct mwl8k_cmd_set_edca_params *cmd; 2404 struct mwl8k_cmd_set_edca_params *cmd;
2035 int rc; 2405 int rc;
2036 2406
@@ -2038,14 +2408,27 @@ mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2038 if (cmd == NULL) 2408 if (cmd == NULL)
2039 return -ENOMEM; 2409 return -ENOMEM;
2040 2410
2411 /*
2412 * Queues 0 (BE) and 1 (BK) are swapped in hardware for
2413 * this call.
2414 */
2415 qnum ^= !(qnum >> 1);
2416
2041 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS); 2417 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
2042 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2418 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2043 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL); 2419 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
2044 cmd->txop = cpu_to_le16(txop); 2420 cmd->txop = cpu_to_le16(txop);
2045 cmd->log_cw_max = (u8)ilog2(cw_max + 1); 2421 if (priv->ap_fw) {
2046 cmd->log_cw_min = (u8)ilog2(cw_min + 1); 2422 cmd->ap.log_cw_max = cpu_to_le32(ilog2(cw_max + 1));
2047 cmd->aifs = aifs; 2423 cmd->ap.log_cw_min = cpu_to_le32(ilog2(cw_min + 1));
2048 cmd->txq = qnum; 2424 cmd->ap.aifs = aifs;
2425 cmd->ap.txq = qnum;
2426 } else {
2427 cmd->sta.log_cw_max = (u8)ilog2(cw_max + 1);
2428 cmd->sta.log_cw_min = (u8)ilog2(cw_min + 1);
2429 cmd->sta.aifs = aifs;
2430 cmd->sta.txq = qnum;
2431 }
2049 2432
2050 rc = mwl8k_post_cmd(hw, &cmd->header); 2433 rc = mwl8k_post_cmd(hw, &cmd->header);
2051 kfree(cmd); 2434 kfree(cmd);
@@ -2093,8 +2476,8 @@ static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
2093 /* XXX TBD Might just have to abort and return an error */ 2476 /* XXX TBD Might just have to abort and return an error */
2094 if (payload_len > MWL8K_FJ_BEACON_MAXLEN) 2477 if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2095 printk(KERN_ERR "%s(): WARNING: Incomplete beacon " 2478 printk(KERN_ERR "%s(): WARNING: Incomplete beacon "
2096 "sent to firmware. Sz=%u MAX=%u\n", __func__, 2479 "sent to firmware. Sz=%u MAX=%u\n", __func__,
2097 payload_len, MWL8K_FJ_BEACON_MAXLEN); 2480 payload_len, MWL8K_FJ_BEACON_MAXLEN);
2098 2481
2099 if (payload_len > MWL8K_FJ_BEACON_MAXLEN) 2482 if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2100 payload_len = MWL8K_FJ_BEACON_MAXLEN; 2483 payload_len = MWL8K_FJ_BEACON_MAXLEN;
@@ -2341,9 +2724,10 @@ static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw,
2341 cmd->rate_type = cpu_to_le32(rate_type); 2724 cmd->rate_type = cpu_to_le32(rate_type);
2342 2725
2343 if (rate_table != NULL) { 2726 if (rate_table != NULL) {
2344 /* Copy over each field manually so 2727 /*
2345 * that bitflipping can be done 2728 * Copy over each field manually so that endian
2346 */ 2729 * conversion can be done.
2730 */
2347 cmd->rate_table.allow_rate_drop = 2731 cmd->rate_table.allow_rate_drop =
2348 cpu_to_le32(rate_table->allow_rate_drop); 2732 cpu_to_le32(rate_table->allow_rate_drop);
2349 cmd->rate_table.num_rates = 2733 cmd->rate_table.num_rates =
@@ -2399,7 +2783,7 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2399 2783
2400 if (status & MWL8K_A2H_INT_QUEUE_EMPTY) { 2784 if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
2401 if (!mutex_is_locked(&priv->fw_mutex) && 2785 if (!mutex_is_locked(&priv->fw_mutex) &&
2402 priv->radio_on && mwl8k_txq_busy(priv)) 2786 priv->radio_on && priv->pending_tx_pkts)
2403 mwl8k_tx_start(priv); 2787 mwl8k_tx_start(priv);
2404 } 2788 }
2405 2789
@@ -2418,7 +2802,7 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2418 2802
2419 if (priv->current_channel == NULL) { 2803 if (priv->current_channel == NULL) {
2420 printk(KERN_DEBUG "%s: dropped TX frame since radio " 2804 printk(KERN_DEBUG "%s: dropped TX frame since radio "
2421 "disabled\n", priv->name); 2805 "disabled\n", wiphy_name(hw->wiphy));
2422 dev_kfree_skb(skb); 2806 dev_kfree_skb(skb);
2423 return NETDEV_TX_OK; 2807 return NETDEV_TX_OK;
2424 } 2808 }
@@ -2433,11 +2817,11 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2433 struct mwl8k_priv *priv = hw->priv; 2817 struct mwl8k_priv *priv = hw->priv;
2434 int rc; 2818 int rc;
2435 2819
2436 rc = request_irq(priv->pdev->irq, &mwl8k_interrupt, 2820 rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
2437 IRQF_SHARED, MWL8K_NAME, hw); 2821 IRQF_SHARED, MWL8K_NAME, hw);
2438 if (rc) { 2822 if (rc) {
2439 printk(KERN_ERR "%s: failed to register IRQ handler\n", 2823 printk(KERN_ERR "%s: failed to register IRQ handler\n",
2440 priv->name); 2824 wiphy_name(hw->wiphy));
2441 return -EIO; 2825 return -EIO;
2442 } 2826 }
2443 2827
@@ -2451,12 +2835,17 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2451 if (!rc) { 2835 if (!rc) {
2452 rc = mwl8k_cmd_802_11_radio_enable(hw); 2836 rc = mwl8k_cmd_802_11_radio_enable(hw);
2453 2837
2454 if (!rc) 2838 if (!priv->ap_fw) {
2455 rc = mwl8k_cmd_set_pre_scan(hw); 2839 if (!rc)
2840 rc = mwl8k_enable_sniffer(hw, 0);
2456 2841
2457 if (!rc) 2842 if (!rc)
2458 rc = mwl8k_cmd_set_post_scan(hw, 2843 rc = mwl8k_cmd_set_pre_scan(hw);
2459 "\x00\x00\x00\x00\x00\x00"); 2844
2845 if (!rc)
2846 rc = mwl8k_cmd_set_post_scan(hw,
2847 "\x00\x00\x00\x00\x00\x00");
2848 }
2460 2849
2461 if (!rc) 2850 if (!rc)
2462 rc = mwl8k_cmd_setrateadaptmode(hw, 0); 2851 rc = mwl8k_cmd_setrateadaptmode(hw, 0);
@@ -2464,9 +2853,6 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2464 if (!rc) 2853 if (!rc)
2465 rc = mwl8k_set_wmm(hw, 0); 2854 rc = mwl8k_set_wmm(hw, 0);
2466 2855
2467 if (!rc)
2468 rc = mwl8k_enable_sniffer(hw, 0);
2469
2470 mwl8k_fw_unlock(hw); 2856 mwl8k_fw_unlock(hw);
2471 } 2857 }
2472 2858
@@ -2500,9 +2886,6 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
2500 /* Stop tx reclaim tasklet */ 2886 /* Stop tx reclaim tasklet */
2501 tasklet_disable(&priv->tx_reclaim_task); 2887 tasklet_disable(&priv->tx_reclaim_task);
2502 2888
2503 /* Stop config thread */
2504 flush_workqueue(priv->config_wq);
2505
2506 /* Return all skbs to mac80211 */ 2889 /* Return all skbs to mac80211 */
2507 for (i = 0; i < MWL8K_TX_QUEUES; i++) 2890 for (i = 0; i < MWL8K_TX_QUEUES; i++)
2508 mwl8k_txq_reclaim(hw, i, 1); 2891 mwl8k_txq_reclaim(hw, i, 1);
@@ -2526,11 +2909,24 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
2526 if (conf->type != NL80211_IFTYPE_STATION) 2909 if (conf->type != NL80211_IFTYPE_STATION)
2527 return -EINVAL; 2910 return -EINVAL;
2528 2911
2912 /*
2913 * Reject interface creation if sniffer mode is active, as
2914 * STA operation is mutually exclusive with hardware sniffer
2915 * mode.
2916 */
2917 if (priv->sniffer_enabled) {
2918 printk(KERN_INFO "%s: unable to create STA "
2919 "interface due to sniffer mode being enabled\n",
2920 wiphy_name(hw->wiphy));
2921 return -EINVAL;
2922 }
2923
2529 /* Clean out driver private area */ 2924 /* Clean out driver private area */
2530 mwl8k_vif = MWL8K_VIF(conf->vif); 2925 mwl8k_vif = MWL8K_VIF(conf->vif);
2531 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif)); 2926 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
2532 2927
2533 /* Save the mac address */ 2928 /* Set and save the mac address */
2929 mwl8k_set_mac_addr(hw, conf->mac_addr);
2534 memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN); 2930 memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN);
2535 2931
2536 /* Back pointer to parent config block */ 2932 /* Back pointer to parent config block */
@@ -2558,6 +2954,8 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
2558 if (priv->vif == NULL) 2954 if (priv->vif == NULL)
2559 return; 2955 return;
2560 2956
2957 mwl8k_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00");
2958
2561 priv->vif = NULL; 2959 priv->vif = NULL;
2562} 2960}
2563 2961
@@ -2593,8 +2991,13 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2593 if (rc) 2991 if (rc)
2594 goto out; 2992 goto out;
2595 2993
2596 if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7)) 2994 if (priv->ap_fw) {
2597 rc = -EINVAL; 2995 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7);
2996 if (!rc)
2997 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
2998 } else {
2999 rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7);
3000 }
2598 3001
2599out: 3002out:
2600 mwl8k_fw_unlock(hw); 3003 mwl8k_fw_unlock(hw);
@@ -2681,32 +3084,108 @@ static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
2681{ 3084{
2682 struct mwl8k_cmd_pkt *cmd; 3085 struct mwl8k_cmd_pkt *cmd;
2683 3086
2684 cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist); 3087 /*
3088 * Synthesize and return a command packet that programs the
3089 * hardware multicast address filter. At this point we don't
3090 * know whether FIF_ALLMULTI is being requested, but if it is,
3091 * we'll end up throwing this packet away and creating a new
3092 * one in mwl8k_configure_filter().
3093 */
3094 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_count, mclist);
2685 3095
2686 return (unsigned long)cmd; 3096 return (unsigned long)cmd;
2687} 3097}
2688 3098
3099static int
3100mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
3101 unsigned int changed_flags,
3102 unsigned int *total_flags)
3103{
3104 struct mwl8k_priv *priv = hw->priv;
3105
3106 /*
3107 * Hardware sniffer mode is mutually exclusive with STA
3108 * operation, so refuse to enable sniffer mode if a STA
3109 * interface is active.
3110 */
3111 if (priv->vif != NULL) {
3112 if (net_ratelimit())
3113 printk(KERN_INFO "%s: not enabling sniffer "
3114 "mode because STA interface is active\n",
3115 wiphy_name(hw->wiphy));
3116 return 0;
3117 }
3118
3119 if (!priv->sniffer_enabled) {
3120 if (mwl8k_enable_sniffer(hw, 1))
3121 return 0;
3122 priv->sniffer_enabled = true;
3123 }
3124
3125 *total_flags &= FIF_PROMISC_IN_BSS | FIF_ALLMULTI |
3126 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL |
3127 FIF_OTHER_BSS;
3128
3129 return 1;
3130}
3131
2689static void mwl8k_configure_filter(struct ieee80211_hw *hw, 3132static void mwl8k_configure_filter(struct ieee80211_hw *hw,
2690 unsigned int changed_flags, 3133 unsigned int changed_flags,
2691 unsigned int *total_flags, 3134 unsigned int *total_flags,
2692 u64 multicast) 3135 u64 multicast)
2693{ 3136{
2694 struct mwl8k_priv *priv = hw->priv; 3137 struct mwl8k_priv *priv = hw->priv;
2695 struct mwl8k_cmd_pkt *multicast_adr_cmd; 3138 struct mwl8k_cmd_pkt *cmd = (void *)(unsigned long)multicast;
3139
3140 /*
3141 * AP firmware doesn't allow fine-grained control over
3142 * the receive filter.
3143 */
3144 if (priv->ap_fw) {
3145 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
3146 kfree(cmd);
3147 return;
3148 }
3149
3150 /*
3151 * Enable hardware sniffer mode if FIF_CONTROL or
3152 * FIF_OTHER_BSS is requested.
3153 */
3154 if (*total_flags & (FIF_CONTROL | FIF_OTHER_BSS) &&
3155 mwl8k_configure_filter_sniffer(hw, changed_flags, total_flags)) {
3156 kfree(cmd);
3157 return;
3158 }
2696 3159
2697 /* Clear unsupported feature flags */ 3160 /* Clear unsupported feature flags */
2698 *total_flags &= FIF_BCN_PRBRESP_PROMISC; 3161 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
2699 3162
2700 if (mwl8k_fw_lock(hw)) 3163 if (mwl8k_fw_lock(hw))
2701 return; 3164 return;
2702 3165
3166 if (priv->sniffer_enabled) {
3167 mwl8k_enable_sniffer(hw, 0);
3168 priv->sniffer_enabled = false;
3169 }
3170
2703 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { 3171 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
2704 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) 3172 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
3173 /*
3174 * Disable the BSS filter.
3175 */
2705 mwl8k_cmd_set_pre_scan(hw); 3176 mwl8k_cmd_set_pre_scan(hw);
2706 else { 3177 } else {
2707 u8 *bssid; 3178 u8 *bssid;
2708 3179
2709 bssid = "\x00\x00\x00\x00\x00\x00"; 3180 /*
3181 * Enable the BSS filter.
3182 *
3183 * If there is an active STA interface, use that
3184 * interface's BSSID, otherwise use a dummy one
3185 * (where the OUI part needs to be nonzero for
3186 * the BSSID to be accepted by POST_SCAN).
3187 */
3188 bssid = "\x01\x00\x00\x00\x00\x00";
2710 if (priv->vif != NULL) 3189 if (priv->vif != NULL)
2711 bssid = MWL8K_VIF(priv->vif)->bssid; 3190 bssid = MWL8K_VIF(priv->vif)->bssid;
2712 3191
@@ -2714,10 +3193,20 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
2714 } 3193 }
2715 } 3194 }
2716 3195
2717 multicast_adr_cmd = (void *)(unsigned long)multicast; 3196 /*
2718 if (multicast_adr_cmd != NULL) { 3197 * If FIF_ALLMULTI is being requested, throw away the command
2719 mwl8k_post_cmd(hw, multicast_adr_cmd); 3198 * packet that ->prepare_multicast() built and replace it with
2720 kfree(multicast_adr_cmd); 3199 * a command packet that enables reception of all multicast
3200 * packets.
3201 */
3202 if (*total_flags & FIF_ALLMULTI) {
3203 kfree(cmd);
3204 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, 0, NULL);
3205 }
3206
3207 if (cmd != NULL) {
3208 mwl8k_post_cmd(hw, cmd);
3209 kfree(cmd);
2721 } 3210 }
2722 3211
2723 mwl8k_fw_unlock(hw); 3212 mwl8k_fw_unlock(hw);
@@ -2762,7 +3251,7 @@ static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
2762 spin_lock_bh(&priv->tx_lock); 3251 spin_lock_bh(&priv->tx_lock);
2763 for (index = 0; index < MWL8K_TX_QUEUES; index++) { 3252 for (index = 0; index < MWL8K_TX_QUEUES; index++) {
2764 txq = priv->txq + index; 3253 txq = priv->txq + index;
2765 memcpy(&stats[index], &txq->tx_stats, 3254 memcpy(&stats[index], &txq->stats,
2766 sizeof(struct ieee80211_tx_queue_stats)); 3255 sizeof(struct ieee80211_tx_queue_stats));
2767 } 3256 }
2768 spin_unlock_bh(&priv->tx_lock); 3257 spin_unlock_bh(&priv->tx_lock);
@@ -2802,7 +3291,7 @@ static void mwl8k_tx_reclaim_handler(unsigned long data)
2802 for (i = 0; i < MWL8K_TX_QUEUES; i++) 3291 for (i = 0; i < MWL8K_TX_QUEUES; i++)
2803 mwl8k_txq_reclaim(hw, i, 0); 3292 mwl8k_txq_reclaim(hw, i, 0);
2804 3293
2805 if (priv->tx_wait != NULL && mwl8k_txq_busy(priv) == 0) { 3294 if (priv->tx_wait != NULL && !priv->pending_tx_pkts) {
2806 complete(priv->tx_wait); 3295 complete(priv->tx_wait);
2807 priv->tx_wait = NULL; 3296 priv->tx_wait = NULL;
2808 } 3297 }
@@ -2822,6 +3311,36 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
2822 priv->beacon_skb = NULL; 3311 priv->beacon_skb = NULL;
2823} 3312}
2824 3313
3314enum {
3315 MWL8687 = 0,
3316 MWL8366,
3317};
3318
3319static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
3320 {
3321 .part_name = "88w8687",
3322 .helper_image = "mwl8k/helper_8687.fw",
3323 .fw_image = "mwl8k/fmimage_8687.fw",
3324 .rxd_ops = &rxd_8687_ops,
3325 .modes = BIT(NL80211_IFTYPE_STATION),
3326 },
3327 {
3328 .part_name = "88w8366",
3329 .helper_image = "mwl8k/helper_8366.fw",
3330 .fw_image = "mwl8k/fmimage_8366.fw",
3331 .rxd_ops = &rxd_8366_ops,
3332 .modes = 0,
3333 },
3334};
3335
3336static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
3337 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
3338 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
3339 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
3340 { },
3341};
3342MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
3343
2825static int __devinit mwl8k_probe(struct pci_dev *pdev, 3344static int __devinit mwl8k_probe(struct pci_dev *pdev,
2826 const struct pci_device_id *id) 3345 const struct pci_device_id *id)
2827{ 3346{
@@ -2862,17 +3381,34 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2862 priv = hw->priv; 3381 priv = hw->priv;
2863 priv->hw = hw; 3382 priv->hw = hw;
2864 priv->pdev = pdev; 3383 priv->pdev = pdev;
3384 priv->device_info = &mwl8k_info_tbl[id->driver_data];
3385 priv->rxd_ops = priv->device_info->rxd_ops;
3386 priv->sniffer_enabled = false;
2865 priv->wmm_enabled = false; 3387 priv->wmm_enabled = false;
2866 priv->pending_tx_pkts = 0; 3388 priv->pending_tx_pkts = 0;
2867 strncpy(priv->name, MWL8K_NAME, sizeof(priv->name));
2868 3389
2869 SET_IEEE80211_DEV(hw, &pdev->dev); 3390 SET_IEEE80211_DEV(hw, &pdev->dev);
2870 pci_set_drvdata(pdev, hw); 3391 pci_set_drvdata(pdev, hw);
2871 3392
3393 priv->sram = pci_iomap(pdev, 0, 0x10000);
3394 if (priv->sram == NULL) {
3395 printk(KERN_ERR "%s: Cannot map device SRAM\n",
3396 wiphy_name(hw->wiphy));
3397 goto err_iounmap;
3398 }
3399
3400 /*
3401 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
3402 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
3403 */
2872 priv->regs = pci_iomap(pdev, 1, 0x10000); 3404 priv->regs = pci_iomap(pdev, 1, 0x10000);
2873 if (priv->regs == NULL) { 3405 if (priv->regs == NULL) {
2874 printk(KERN_ERR "%s: Cannot map device memory\n", priv->name); 3406 priv->regs = pci_iomap(pdev, 2, 0x10000);
2875 goto err_iounmap; 3407 if (priv->regs == NULL) {
3408 printk(KERN_ERR "%s: Cannot map device registers\n",
3409 wiphy_name(hw->wiphy));
3410 goto err_iounmap;
3411 }
2876 } 3412 }
2877 3413
2878 memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels)); 3414 memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
@@ -2897,7 +3433,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2897 3433
2898 hw->queues = MWL8K_TX_QUEUES; 3434 hw->queues = MWL8K_TX_QUEUES;
2899 3435
2900 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 3436 hw->wiphy->interface_modes = priv->device_info->modes;
2901 3437
2902 /* Set rssi and noise values to dBm */ 3438 /* Set rssi and noise values to dBm */
2903 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; 3439 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM;
@@ -2916,11 +3452,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2916 mwl8k_tx_reclaim_handler, (unsigned long)hw); 3452 mwl8k_tx_reclaim_handler, (unsigned long)hw);
2917 tasklet_disable(&priv->tx_reclaim_task); 3453 tasklet_disable(&priv->tx_reclaim_task);
2918 3454
2919 /* Config workthread */
2920 priv->config_wq = create_singlethread_workqueue("mwl8k_config");
2921 if (priv->config_wq == NULL)
2922 goto err_iounmap;
2923
2924 /* Power management cookie */ 3455 /* Power management cookie */
2925 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); 3456 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
2926 if (priv->cookie == NULL) 3457 if (priv->cookie == NULL)
@@ -2934,11 +3465,12 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2934 mutex_init(&priv->fw_mutex); 3465 mutex_init(&priv->fw_mutex);
2935 priv->fw_mutex_owner = NULL; 3466 priv->fw_mutex_owner = NULL;
2936 priv->fw_mutex_depth = 0; 3467 priv->fw_mutex_depth = 0;
2937 priv->tx_wait = NULL;
2938 priv->hostcmd_wait = NULL; 3468 priv->hostcmd_wait = NULL;
2939 3469
2940 spin_lock_init(&priv->tx_lock); 3470 spin_lock_init(&priv->tx_lock);
2941 3471
3472 priv->tx_wait = NULL;
3473
2942 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 3474 for (i = 0; i < MWL8K_TX_QUEUES; i++) {
2943 rc = mwl8k_txq_init(hw, i); 3475 rc = mwl8k_txq_init(hw, i);
2944 if (rc) 3476 if (rc)
@@ -2950,11 +3482,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2950 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 3482 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
2951 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 3483 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
2952 3484
2953 rc = request_irq(priv->pdev->irq, &mwl8k_interrupt, 3485 rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
2954 IRQF_SHARED, MWL8K_NAME, hw); 3486 IRQF_SHARED, MWL8K_NAME, hw);
2955 if (rc) { 3487 if (rc) {
2956 printk(KERN_ERR "%s: failed to register IRQ handler\n", 3488 printk(KERN_ERR "%s: failed to register IRQ handler\n",
2957 priv->name); 3489 wiphy_name(hw->wiphy));
2958 goto err_free_queues; 3490 goto err_free_queues;
2959 } 3491 }
2960 3492
@@ -2962,16 +3494,18 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2962 mwl8k_hw_reset(priv); 3494 mwl8k_hw_reset(priv);
2963 3495
2964 /* Ask userland hotplug daemon for the device firmware */ 3496 /* Ask userland hotplug daemon for the device firmware */
2965 rc = mwl8k_request_firmware(priv, (u32)id->driver_data); 3497 rc = mwl8k_request_firmware(priv);
2966 if (rc) { 3498 if (rc) {
2967 printk(KERN_ERR "%s: Firmware files not found\n", priv->name); 3499 printk(KERN_ERR "%s: Firmware files not found\n",
3500 wiphy_name(hw->wiphy));
2968 goto err_free_irq; 3501 goto err_free_irq;
2969 } 3502 }
2970 3503
2971 /* Load firmware into hardware */ 3504 /* Load firmware into hardware */
2972 rc = mwl8k_load_firmware(priv); 3505 rc = mwl8k_load_firmware(hw);
2973 if (rc) { 3506 if (rc) {
2974 printk(KERN_ERR "%s: Cannot start firmware\n", priv->name); 3507 printk(KERN_ERR "%s: Cannot start firmware\n",
3508 wiphy_name(hw->wiphy));
2975 goto err_stop_firmware; 3509 goto err_stop_firmware;
2976 } 3510 }
2977 3511
@@ -2986,16 +3520,31 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2986 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3520 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2987 3521
2988 /* Get config data, mac addrs etc */ 3522 /* Get config data, mac addrs etc */
2989 rc = mwl8k_cmd_get_hw_spec(hw); 3523 if (priv->ap_fw) {
3524 rc = mwl8k_cmd_get_hw_spec_ap(hw);
3525 if (!rc)
3526 rc = mwl8k_cmd_set_hw_spec(hw);
3527 } else {
3528 rc = mwl8k_cmd_get_hw_spec_sta(hw);
3529 }
2990 if (rc) { 3530 if (rc) {
2991 printk(KERN_ERR "%s: Cannot initialise firmware\n", priv->name); 3531 printk(KERN_ERR "%s: Cannot initialise firmware\n",
3532 wiphy_name(hw->wiphy));
2992 goto err_stop_firmware; 3533 goto err_stop_firmware;
2993 } 3534 }
2994 3535
2995 /* Turn radio off */ 3536 /* Turn radio off */
2996 rc = mwl8k_cmd_802_11_radio_disable(hw); 3537 rc = mwl8k_cmd_802_11_radio_disable(hw);
2997 if (rc) { 3538 if (rc) {
2998 printk(KERN_ERR "%s: Cannot disable\n", priv->name); 3539 printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
3540 goto err_stop_firmware;
3541 }
3542
3543 /* Clear MAC address */
3544 rc = mwl8k_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00");
3545 if (rc) {
3546 printk(KERN_ERR "%s: Cannot clear MAC address\n",
3547 wiphy_name(hw->wiphy));
2999 goto err_stop_firmware; 3548 goto err_stop_firmware;
3000 } 3549 }
3001 3550
@@ -3005,13 +3554,15 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3005 3554
3006 rc = ieee80211_register_hw(hw); 3555 rc = ieee80211_register_hw(hw);
3007 if (rc) { 3556 if (rc) {
3008 printk(KERN_ERR "%s: Cannot register device\n", priv->name); 3557 printk(KERN_ERR "%s: Cannot register device\n",
3558 wiphy_name(hw->wiphy));
3009 goto err_stop_firmware; 3559 goto err_stop_firmware;
3010 } 3560 }
3011 3561
3012 printk(KERN_INFO "%s: 88w%u v%d, %pM, firmware version %u.%u.%u.%u\n", 3562 printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
3013 wiphy_name(hw->wiphy), priv->part_num, priv->hw_rev, 3563 wiphy_name(hw->wiphy), priv->device_info->part_name,
3014 hw->wiphy->perm_addr, 3564 priv->hw_rev, hw->wiphy->perm_addr,
3565 priv->ap_fw ? "AP" : "STA",
3015 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, 3566 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
3016 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); 3567 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
3017 3568
@@ -3038,8 +3589,8 @@ err_iounmap:
3038 if (priv->regs != NULL) 3589 if (priv->regs != NULL)
3039 pci_iounmap(pdev, priv->regs); 3590 pci_iounmap(pdev, priv->regs);
3040 3591
3041 if (priv->config_wq != NULL) 3592 if (priv->sram != NULL)
3042 destroy_workqueue(priv->config_wq); 3593 pci_iounmap(pdev, priv->sram);
3043 3594
3044 pci_set_drvdata(pdev, NULL); 3595 pci_set_drvdata(pdev, NULL);
3045 ieee80211_free_hw(hw); 3596 ieee80211_free_hw(hw);
@@ -3073,9 +3624,6 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
3073 /* Remove tx reclaim tasklet */ 3624 /* Remove tx reclaim tasklet */
3074 tasklet_kill(&priv->tx_reclaim_task); 3625 tasklet_kill(&priv->tx_reclaim_task);
3075 3626
3076 /* Stop config thread */
3077 destroy_workqueue(priv->config_wq);
3078
3079 /* Stop hardware */ 3627 /* Stop hardware */
3080 mwl8k_hw_reset(priv); 3628 mwl8k_hw_reset(priv);
3081 3629
@@ -3088,10 +3636,10 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
3088 3636
3089 mwl8k_rxq_deinit(hw, 0); 3637 mwl8k_rxq_deinit(hw, 0);
3090 3638
3091 pci_free_consistent(priv->pdev, 4, 3639 pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma);
3092 priv->cookie, priv->cookie_dma);
3093 3640
3094 pci_iounmap(pdev, priv->regs); 3641 pci_iounmap(pdev, priv->regs);
3642 pci_iounmap(pdev, priv->sram);
3095 pci_set_drvdata(pdev, NULL); 3643 pci_set_drvdata(pdev, NULL);
3096 ieee80211_free_hw(hw); 3644 ieee80211_free_hw(hw);
3097 pci_release_regions(pdev); 3645 pci_release_regions(pdev);
@@ -3100,7 +3648,7 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
3100 3648
3101static struct pci_driver mwl8k_driver = { 3649static struct pci_driver mwl8k_driver = {
3102 .name = MWL8K_NAME, 3650 .name = MWL8K_NAME,
3103 .id_table = mwl8k_table, 3651 .id_table = mwl8k_pci_id_table,
3104 .probe = mwl8k_probe, 3652 .probe = mwl8k_probe,
3105 .remove = __devexit_p(mwl8k_remove), 3653 .remove = __devexit_p(mwl8k_remove),
3106 .shutdown = __devexit_p(mwl8k_shutdown), 3654 .shutdown = __devexit_p(mwl8k_shutdown),
@@ -3118,3 +3666,8 @@ static void __exit mwl8k_exit(void)
3118 3666
3119module_init(mwl8k_init); 3667module_init(mwl8k_init);
3120module_exit(mwl8k_exit); 3668module_exit(mwl8k_exit);
3669
3670MODULE_DESCRIPTION(MWL8K_DESC);
3671MODULE_VERSION(MWL8K_VERSION);
3672MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
3673MODULE_LICENSE("GPL");