aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/mwl8k.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c3236
1 files changed, 2166 insertions, 1070 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 746532ebe5a8..12fdcb25fd38 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2,7 +2,7 @@
2 * drivers/net/wireless/mwl8k.c 2 * drivers/net/wireless/mwl8k.c
3 * Driver for Marvell TOPDOG 802.11 Wireless cards 3 * Driver for Marvell TOPDOG 802.11 Wireless cards
4 * 4 *
5 * Copyright (C) 2008-2009 Marvell Semiconductor Inc. 5 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc.
6 * 6 *
7 * This file is licensed under the terms of the GNU General Public 7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any 8 * License version 2. This program is licensed "as is" without any
@@ -12,12 +12,14 @@
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>
18#include <linux/delay.h> 19#include <linux/delay.h>
19#include <linux/completion.h> 20#include <linux/completion.h>
20#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
22#include <linux/slab.h>
21#include <net/mac80211.h> 23#include <net/mac80211.h>
22#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
23#include <linux/firmware.h> 25#include <linux/firmware.h>
@@ -25,19 +27,7 @@
25 27
26#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver" 28#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
27#define MWL8K_NAME KBUILD_MODNAME 29#define MWL8K_NAME KBUILD_MODNAME
28#define MWL8K_VERSION "0.10" 30#define MWL8K_VERSION "0.12"
29
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 31
42/* Register definitions */ 32/* Register definitions */
43#define MWL8K_HIU_GEN_PTR 0x00000c10 33#define MWL8K_HIU_GEN_PTR 0x00000c10
@@ -88,75 +78,94 @@ MODULE_DEVICE_TABLE(pci, mwl8k_table);
88 MWL8K_A2H_INT_RX_READY | \ 78 MWL8K_A2H_INT_RX_READY | \
89 MWL8K_A2H_INT_TX_DONE) 79 MWL8K_A2H_INT_TX_DONE)
90 80
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 81#define MWL8K_RX_QUEUES 1
98#define MWL8K_TX_QUEUES 4 82#define MWL8K_TX_QUEUES 4
99 83
84struct rxd_ops {
85 int rxd_size;
86 void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
87 void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
88 int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
89 __le16 *qos);
90};
91
92struct mwl8k_device_info {
93 char *part_name;
94 char *helper_image;
95 char *fw_image;
96 struct rxd_ops *ap_rxd_ops;
97};
98
100struct mwl8k_rx_queue { 99struct mwl8k_rx_queue {
101 int rx_desc_count; 100 int rxd_count;
102 101
103 /* hw receives here */ 102 /* hw receives here */
104 int rx_head; 103 int head;
105 104
106 /* refill descs here */ 105 /* refill descs here */
107 int rx_tail; 106 int tail;
108 107
109 struct mwl8k_rx_desc *rx_desc_area; 108 void *rxd;
110 dma_addr_t rx_desc_dma; 109 dma_addr_t rxd_dma;
111 struct sk_buff **rx_skb; 110 struct {
111 struct sk_buff *skb;
112 DECLARE_PCI_UNMAP_ADDR(dma)
113 } *buf;
112}; 114};
113 115
114struct mwl8k_tx_queue { 116struct mwl8k_tx_queue {
115 /* hw transmits here */ 117 /* hw transmits here */
116 int tx_head; 118 int head;
117 119
118 /* sw appends here */ 120 /* sw appends here */
119 int tx_tail; 121 int tail;
120 122
121 struct ieee80211_tx_queue_stats tx_stats; 123 unsigned int len;
122 struct mwl8k_tx_desc *tx_desc_area; 124 struct mwl8k_tx_desc *txd;
123 dma_addr_t tx_desc_dma; 125 dma_addr_t txd_dma;
124 struct sk_buff **tx_skb; 126 struct sk_buff **skb;
125};
126
127/* Pointers to the firmware data and meta information about it. */
128struct mwl8k_firmware {
129 /* Microcode */
130 struct firmware *ucode;
131
132 /* Boot helper code */
133 struct firmware *helper;
134}; 127};
135 128
136struct mwl8k_priv { 129struct mwl8k_priv {
137 void __iomem *regs;
138 struct ieee80211_hw *hw; 130 struct ieee80211_hw *hw;
139
140 struct pci_dev *pdev; 131 struct pci_dev *pdev;
141 u8 name[16];
142 132
143 /* firmware files and meta data */ 133 struct mwl8k_device_info *device_info;
144 struct mwl8k_firmware fw; 134
145 u32 part_num; 135 void __iomem *sram;
136 void __iomem *regs;
137
138 /* firmware */
139 struct firmware *fw_helper;
140 struct firmware *fw_ucode;
141
142 /* hardware/firmware parameters */
143 bool ap_fw;
144 struct rxd_ops *rxd_ops;
145 struct ieee80211_supported_band band_24;
146 struct ieee80211_channel channels_24[14];
147 struct ieee80211_rate rates_24[14];
148 struct ieee80211_supported_band band_50;
149 struct ieee80211_channel channels_50[4];
150 struct ieee80211_rate rates_50[9];
151 u32 ap_macids_supported;
152 u32 sta_macids_supported;
146 153
147 /* firmware access */ 154 /* firmware access */
148 struct mutex fw_mutex; 155 struct mutex fw_mutex;
149 struct task_struct *fw_mutex_owner; 156 struct task_struct *fw_mutex_owner;
150 int fw_mutex_depth; 157 int fw_mutex_depth;
151 struct completion *tx_wait;
152 struct completion *hostcmd_wait; 158 struct completion *hostcmd_wait;
153 159
154 /* lock held over TX and TX reap */ 160 /* lock held over TX and TX reap */
155 spinlock_t tx_lock; 161 spinlock_t tx_lock;
156 162
157 struct ieee80211_vif *vif; 163 /* TX quiesce completion, protected by fw_mutex and tx_lock */
164 struct completion *tx_wait;
158 165
159 struct ieee80211_channel *current_channel; 166 /* List of interfaces. */
167 u32 macids_used;
168 struct list_head vif_list;
160 169
161 /* power management status cookie from firmware */ 170 /* power management status cookie from firmware */
162 u32 *cookie; 171 u32 *cookie;
@@ -175,13 +184,9 @@ struct mwl8k_priv {
175 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; 184 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
176 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; 185 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
177 186
178 /* PHY parameters */
179 struct ieee80211_supported_band band;
180 struct ieee80211_channel channels[14];
181 struct ieee80211_rate rates[12];
182
183 bool radio_on; 187 bool radio_on;
184 bool radio_short_preamble; 188 bool radio_short_preamble;
189 bool sniffer_enabled;
185 bool wmm_enabled; 190 bool wmm_enabled;
186 191
187 /* XXX need to convert this to handle multiple interfaces */ 192 /* XXX need to convert this to handle multiple interfaces */
@@ -197,44 +202,33 @@ struct mwl8k_priv {
197 */ 202 */
198 struct work_struct finalize_join_worker; 203 struct work_struct finalize_join_worker;
199 204
200 /* Tasklet to reclaim TX descriptors and buffers after tx */ 205 /* Tasklet to perform TX reclaim. */
201 struct tasklet_struct tx_reclaim_task; 206 struct tasklet_struct poll_tx_task;
202 207
203 /* Work thread to serialize configuration requests */ 208 /* Tasklet to perform RX. */
204 struct workqueue_struct *config_wq; 209 struct tasklet_struct poll_rx_task;
205}; 210};
206 211
207/* Per interface specific private data */ 212/* Per interface specific private data */
208struct mwl8k_vif { 213struct mwl8k_vif {
209 /* backpointer to parent config block */ 214 struct list_head list;
210 struct mwl8k_priv *priv; 215 struct ieee80211_vif *vif;
211
212 /* BSS config of AP or IBSS from mac80211*/
213 struct ieee80211_bss_conf bss_info;
214
215 /* BSSID of AP or IBSS */
216 u8 bssid[ETH_ALEN];
217 u8 mac_addr[ETH_ALEN];
218
219 /*
220 * Subset of supported legacy rates.
221 * Intersection of AP and STA supported rates.
222 */
223 struct ieee80211_rate legacy_rates[12];
224
225 /* number of supported legacy rates */
226 u8 legacy_nrates;
227 216
228 /* Index into station database.Returned by update_sta_db call */ 217 /* Firmware macid for this vif. */
229 u8 peer_id; 218 int macid;
230 219
231 /* Non AMPDU sequence number assigned by driver */ 220 /* Non AMPDU sequence number assigned by driver. */
232 u16 seqno; 221 u16 seqno;
233}; 222};
234
235#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) 223#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
236 224
237static const struct ieee80211_channel mwl8k_channels[] = { 225struct mwl8k_sta {
226 /* Index into station database. Returned by UPDATE_STADB. */
227 u8 peer_id;
228};
229#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
230
231static const struct ieee80211_channel mwl8k_channels_24[] = {
238 { .center_freq = 2412, .hw_value = 1, }, 232 { .center_freq = 2412, .hw_value = 1, },
239 { .center_freq = 2417, .hw_value = 2, }, 233 { .center_freq = 2417, .hw_value = 2, },
240 { .center_freq = 2422, .hw_value = 3, }, 234 { .center_freq = 2422, .hw_value = 3, },
@@ -246,21 +240,45 @@ static const struct ieee80211_channel mwl8k_channels[] = {
246 { .center_freq = 2452, .hw_value = 9, }, 240 { .center_freq = 2452, .hw_value = 9, },
247 { .center_freq = 2457, .hw_value = 10, }, 241 { .center_freq = 2457, .hw_value = 10, },
248 { .center_freq = 2462, .hw_value = 11, }, 242 { .center_freq = 2462, .hw_value = 11, },
243 { .center_freq = 2467, .hw_value = 12, },
244 { .center_freq = 2472, .hw_value = 13, },
245 { .center_freq = 2484, .hw_value = 14, },
249}; 246};
250 247
251static const struct ieee80211_rate mwl8k_rates[] = { 248static const struct ieee80211_rate mwl8k_rates_24[] = {
252 { .bitrate = 10, .hw_value = 2, }, 249 { .bitrate = 10, .hw_value = 2, },
253 { .bitrate = 20, .hw_value = 4, }, 250 { .bitrate = 20, .hw_value = 4, },
254 { .bitrate = 55, .hw_value = 11, }, 251 { .bitrate = 55, .hw_value = 11, },
252 { .bitrate = 110, .hw_value = 22, },
253 { .bitrate = 220, .hw_value = 44, },
255 { .bitrate = 60, .hw_value = 12, }, 254 { .bitrate = 60, .hw_value = 12, },
256 { .bitrate = 90, .hw_value = 18, }, 255 { .bitrate = 90, .hw_value = 18, },
257 { .bitrate = 110, .hw_value = 22, },
258 { .bitrate = 120, .hw_value = 24, }, 256 { .bitrate = 120, .hw_value = 24, },
259 { .bitrate = 180, .hw_value = 36, }, 257 { .bitrate = 180, .hw_value = 36, },
260 { .bitrate = 240, .hw_value = 48, }, 258 { .bitrate = 240, .hw_value = 48, },
261 { .bitrate = 360, .hw_value = 72, }, 259 { .bitrate = 360, .hw_value = 72, },
262 { .bitrate = 480, .hw_value = 96, }, 260 { .bitrate = 480, .hw_value = 96, },
263 { .bitrate = 540, .hw_value = 108, }, 261 { .bitrate = 540, .hw_value = 108, },
262 { .bitrate = 720, .hw_value = 144, },
263};
264
265static const struct ieee80211_channel mwl8k_channels_50[] = {
266 { .center_freq = 5180, .hw_value = 36, },
267 { .center_freq = 5200, .hw_value = 40, },
268 { .center_freq = 5220, .hw_value = 44, },
269 { .center_freq = 5240, .hw_value = 48, },
270};
271
272static const struct ieee80211_rate mwl8k_rates_50[] = {
273 { .bitrate = 60, .hw_value = 12, },
274 { .bitrate = 90, .hw_value = 18, },
275 { .bitrate = 120, .hw_value = 24, },
276 { .bitrate = 180, .hw_value = 36, },
277 { .bitrate = 240, .hw_value = 48, },
278 { .bitrate = 360, .hw_value = 72, },
279 { .bitrate = 480, .hw_value = 96, },
280 { .bitrate = 540, .hw_value = 108, },
281 { .bitrate = 720, .hw_value = 144, },
264}; 282};
265 283
266/* Set or get info from Firmware */ 284/* Set or get info from Firmware */
@@ -270,10 +288,13 @@ static const struct ieee80211_rate mwl8k_rates[] = {
270/* Firmware command codes */ 288/* Firmware command codes */
271#define MWL8K_CMD_CODE_DNLD 0x0001 289#define MWL8K_CMD_CODE_DNLD 0x0001
272#define MWL8K_CMD_GET_HW_SPEC 0x0003 290#define MWL8K_CMD_GET_HW_SPEC 0x0003
291#define MWL8K_CMD_SET_HW_SPEC 0x0004
273#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010 292#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010
274#define MWL8K_CMD_GET_STAT 0x0014 293#define MWL8K_CMD_GET_STAT 0x0014
275#define MWL8K_CMD_RADIO_CONTROL 0x001c 294#define MWL8K_CMD_RADIO_CONTROL 0x001c
276#define MWL8K_CMD_RF_TX_POWER 0x001e 295#define MWL8K_CMD_RF_TX_POWER 0x001e
296#define MWL8K_CMD_RF_ANTENNA 0x0020
297#define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */
277#define MWL8K_CMD_SET_PRE_SCAN 0x0107 298#define MWL8K_CMD_SET_PRE_SCAN 0x0107
278#define MWL8K_CMD_SET_POST_SCAN 0x0108 299#define MWL8K_CMD_SET_POST_SCAN 0x0108
279#define MWL8K_CMD_SET_RF_CHANNEL 0x010a 300#define MWL8K_CMD_SET_RF_CHANNEL 0x010a
@@ -287,7 +308,10 @@ static const struct ieee80211_rate mwl8k_rates[] = {
287#define MWL8K_CMD_MIMO_CONFIG 0x0125 308#define MWL8K_CMD_MIMO_CONFIG 0x0125
288#define MWL8K_CMD_USE_FIXED_RATE 0x0126 309#define MWL8K_CMD_USE_FIXED_RATE 0x0126
289#define MWL8K_CMD_ENABLE_SNIFFER 0x0150 310#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
311#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */
290#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 312#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
313#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */
314#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */
291#define MWL8K_CMD_UPDATE_STADB 0x1123 315#define MWL8K_CMD_UPDATE_STADB 0x1123
292 316
293static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize) 317static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
@@ -299,10 +323,13 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
299 switch (cmd & ~0x8000) { 323 switch (cmd & ~0x8000) {
300 MWL8K_CMDNAME(CODE_DNLD); 324 MWL8K_CMDNAME(CODE_DNLD);
301 MWL8K_CMDNAME(GET_HW_SPEC); 325 MWL8K_CMDNAME(GET_HW_SPEC);
326 MWL8K_CMDNAME(SET_HW_SPEC);
302 MWL8K_CMDNAME(MAC_MULTICAST_ADR); 327 MWL8K_CMDNAME(MAC_MULTICAST_ADR);
303 MWL8K_CMDNAME(GET_STAT); 328 MWL8K_CMDNAME(GET_STAT);
304 MWL8K_CMDNAME(RADIO_CONTROL); 329 MWL8K_CMDNAME(RADIO_CONTROL);
305 MWL8K_CMDNAME(RF_TX_POWER); 330 MWL8K_CMDNAME(RF_TX_POWER);
331 MWL8K_CMDNAME(RF_ANTENNA);
332 MWL8K_CMDNAME(SET_BEACON);
306 MWL8K_CMDNAME(SET_PRE_SCAN); 333 MWL8K_CMDNAME(SET_PRE_SCAN);
307 MWL8K_CMDNAME(SET_POST_SCAN); 334 MWL8K_CMDNAME(SET_POST_SCAN);
308 MWL8K_CMDNAME(SET_RF_CHANNEL); 335 MWL8K_CMDNAME(SET_RF_CHANNEL);
@@ -316,7 +343,10 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
316 MWL8K_CMDNAME(MIMO_CONFIG); 343 MWL8K_CMDNAME(MIMO_CONFIG);
317 MWL8K_CMDNAME(USE_FIXED_RATE); 344 MWL8K_CMDNAME(USE_FIXED_RATE);
318 MWL8K_CMDNAME(ENABLE_SNIFFER); 345 MWL8K_CMDNAME(ENABLE_SNIFFER);
346 MWL8K_CMDNAME(SET_MAC_ADDR);
319 MWL8K_CMDNAME(SET_RATEADAPT_MODE); 347 MWL8K_CMDNAME(SET_RATEADAPT_MODE);
348 MWL8K_CMDNAME(BSS_START);
349 MWL8K_CMDNAME(SET_NEW_STN);
320 MWL8K_CMDNAME(UPDATE_STADB); 350 MWL8K_CMDNAME(UPDATE_STADB);
321 default: 351 default:
322 snprintf(buf, bufsize, "0x%x", cmd); 352 snprintf(buf, bufsize, "0x%x", cmd);
@@ -347,48 +377,42 @@ static void mwl8k_release_fw(struct firmware **fw)
347 377
348static void mwl8k_release_firmware(struct mwl8k_priv *priv) 378static void mwl8k_release_firmware(struct mwl8k_priv *priv)
349{ 379{
350 mwl8k_release_fw(&priv->fw.ucode); 380 mwl8k_release_fw(&priv->fw_ucode);
351 mwl8k_release_fw(&priv->fw.helper); 381 mwl8k_release_fw(&priv->fw_helper);
352} 382}
353 383
354/* Request fw image */ 384/* Request fw image */
355static int mwl8k_request_fw(struct mwl8k_priv *priv, 385static int mwl8k_request_fw(struct mwl8k_priv *priv,
356 const char *fname, struct firmware **fw) 386 const char *fname, struct firmware **fw)
357{ 387{
358 /* release current image */ 388 /* release current image */
359 if (*fw != NULL) 389 if (*fw != NULL)
360 mwl8k_release_fw(fw); 390 mwl8k_release_fw(fw);
361 391
362 return request_firmware((const struct firmware **)fw, 392 return request_firmware((const struct firmware **)fw,
363 fname, &priv->pdev->dev); 393 fname, &priv->pdev->dev);
364} 394}
365 395
366static int mwl8k_request_firmware(struct mwl8k_priv *priv, u32 part_num) 396static int mwl8k_request_firmware(struct mwl8k_priv *priv)
367{ 397{
368 u8 filename[64]; 398 struct mwl8k_device_info *di = priv->device_info;
369 int rc; 399 int rc;
370 400
371 priv->part_num = part_num; 401 if (di->helper_image != NULL) {
372 402 rc = mwl8k_request_fw(priv, di->helper_image, &priv->fw_helper);
373 snprintf(filename, sizeof(filename), 403 if (rc) {
374 "mwl8k/helper_%u.fw", priv->part_num); 404 printk(KERN_ERR "%s: Error requesting helper "
375 405 "firmware file %s\n", pci_name(priv->pdev),
376 rc = mwl8k_request_fw(priv, filename, &priv->fw.helper); 406 di->helper_image);
377 if (rc) { 407 return rc;
378 printk(KERN_ERR 408 }
379 "%s Error requesting helper firmware file %s\n",
380 pci_name(priv->pdev), filename);
381 return rc;
382 } 409 }
383 410
384 snprintf(filename, sizeof(filename), 411 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) { 412 if (rc) {
389 printk(KERN_ERR "%s Error requesting firmware file %s\n", 413 printk(KERN_ERR "%s: Error requesting firmware file %s\n",
390 pci_name(priv->pdev), filename); 414 pci_name(priv->pdev), di->fw_image);
391 mwl8k_release_fw(&priv->fw.helper); 415 mwl8k_release_fw(&priv->fw_helper);
392 return rc; 416 return rc;
393 } 417 }
394 418
@@ -398,7 +422,8 @@ static int mwl8k_request_firmware(struct mwl8k_priv *priv, u32 part_num)
398struct mwl8k_cmd_pkt { 422struct mwl8k_cmd_pkt {
399 __le16 code; 423 __le16 code;
400 __le16 length; 424 __le16 length;
401 __le16 seq_num; 425 __u8 seq_num;
426 __u8 macid;
402 __le16 result; 427 __le16 result;
403 char payload[0]; 428 char payload[0];
404} __attribute__((packed)); 429} __attribute__((packed));
@@ -434,6 +459,7 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
434 break; 459 break;
435 } 460 }
436 461
462 cond_resched();
437 udelay(1); 463 udelay(1);
438 } while (--loops); 464 } while (--loops);
439 465
@@ -455,6 +481,7 @@ static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
455 481
456 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD); 482 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
457 cmd->seq_num = 0; 483 cmd->seq_num = 0;
484 cmd->macid = 0;
458 cmd->result = 0; 485 cmd->result = 0;
459 486
460 done = 0; 487 done = 0;
@@ -542,43 +569,57 @@ static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
542 return rc; 569 return rc;
543} 570}
544 571
545static int mwl8k_load_firmware(struct mwl8k_priv *priv) 572static int mwl8k_load_firmware(struct ieee80211_hw *hw)
546{ 573{
547 int loops, rc; 574 struct mwl8k_priv *priv = hw->priv;
575 struct firmware *fw = priv->fw_ucode;
576 int rc;
577 int loops;
548 578
549 const u8 *ucode = priv->fw.ucode->data; 579 if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
550 size_t ucode_len = priv->fw.ucode->size; 580 struct firmware *helper = priv->fw_helper;
551 const u8 *helper = priv->fw.helper->data;
552 size_t helper_len = priv->fw.helper->size;
553 581
554 if (!memcmp(ucode, "\x01\x00\x00\x00", 4)) { 582 if (helper == NULL) {
555 rc = mwl8k_load_fw_image(priv, helper, helper_len); 583 printk(KERN_ERR "%s: helper image needed but none "
584 "given\n", pci_name(priv->pdev));
585 return -EINVAL;
586 }
587
588 rc = mwl8k_load_fw_image(priv, helper->data, helper->size);
556 if (rc) { 589 if (rc) {
557 printk(KERN_ERR "%s: unable to load firmware " 590 printk(KERN_ERR "%s: unable to load firmware "
558 "helper image\n", pci_name(priv->pdev)); 591 "helper image\n", pci_name(priv->pdev));
559 return rc; 592 return rc;
560 } 593 }
561 msleep(1); 594 msleep(5);
562 595
563 rc = mwl8k_feed_fw_image(priv, ucode, ucode_len); 596 rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
564 } else { 597 } else {
565 rc = mwl8k_load_fw_image(priv, ucode, ucode_len); 598 rc = mwl8k_load_fw_image(priv, fw->data, fw->size);
566 } 599 }
567 600
568 if (rc) { 601 if (rc) {
569 printk(KERN_ERR "%s: unable to load firmware data\n", 602 printk(KERN_ERR "%s: unable to load firmware image\n",
570 pci_name(priv->pdev)); 603 pci_name(priv->pdev));
571 return rc; 604 return rc;
572 } 605 }
573 606
574 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); 607 iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
575 msleep(1);
576 608
577 loops = 200000; 609 loops = 500000;
578 do { 610 do {
579 if (ioread32(priv->regs + MWL8K_HIU_INT_CODE) 611 u32 ready_code;
580 == MWL8K_FWSTA_READY) 612
613 ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE);
614 if (ready_code == MWL8K_FWAP_READY) {
615 priv->ap_fw = 1;
581 break; 616 break;
617 } else if (ready_code == MWL8K_FWSTA_READY) {
618 priv->ap_fw = 0;
619 break;
620 }
621
622 cond_resched();
582 udelay(1); 623 udelay(1);
583 } while (--loops); 624 } while (--loops);
584 625
@@ -586,161 +627,177 @@ static int mwl8k_load_firmware(struct mwl8k_priv *priv)
586} 627}
587 628
588 629
589/* 630/* DMA header used by firmware and hardware. */
590 * Defines shared between transmission and reception. 631struct mwl8k_dma_data {
591 */ 632 __le16 fwlen;
592/* HT control fields for firmware */ 633 struct ieee80211_hdr wh;
593struct ewc_ht_info { 634 char data[0];
594 __le16 control1;
595 __le16 control2;
596 __le16 control3;
597} __attribute__((packed)); 635} __attribute__((packed));
598 636
599/* Firmware Station database operations */ 637/* Routines to add/remove DMA header from skb. */
600#define MWL8K_STA_DB_ADD_ENTRY 0 638static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
601#define MWL8K_STA_DB_MODIFY_ENTRY 1 639{
602#define MWL8K_STA_DB_DEL_ENTRY 2 640 struct mwl8k_dma_data *tr;
603#define MWL8K_STA_DB_FLUSH 3 641 int hdrlen;
604 642
605/* Peer Entry flags - used to define the type of the peer node */ 643 tr = (struct mwl8k_dma_data *)skb->data;
606#define MWL8K_PEER_TYPE_ACCESSPOINT 2 644 hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
607 645
608#define MWL8K_IEEE_LEGACY_DATA_RATES 12 646 if (hdrlen != sizeof(tr->wh)) {
609#define MWL8K_MCS_BITMAP_SIZE 16 647 if (ieee80211_is_data_qos(tr->wh.frame_control)) {
648 memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2);
649 *((__le16 *)(tr->data - 2)) = qos;
650 } else {
651 memmove(tr->data - hdrlen, &tr->wh, hdrlen);
652 }
653 }
610 654
611struct peer_capability_info { 655 if (hdrlen != sizeof(*tr))
612 /* Peer type - AP vs. STA. */ 656 skb_pull(skb, sizeof(*tr) - hdrlen);
613 __u8 peer_type; 657}
614 658
615 /* Basic 802.11 capabilities from assoc resp. */ 659static inline void mwl8k_add_dma_header(struct sk_buff *skb)
616 __le16 basic_caps; 660{
661 struct ieee80211_hdr *wh;
662 int hdrlen;
663 struct mwl8k_dma_data *tr;
617 664
618 /* Set if peer supports 802.11n high throughput (HT). */ 665 /*
619 __u8 ht_support; 666 * Add a firmware DMA header; the firmware requires that we
667 * present a 2-byte payload length followed by a 4-address
668 * header (without QoS field), followed (optionally) by any
669 * WEP/ExtIV header (but only filled in for CCMP).
670 */
671 wh = (struct ieee80211_hdr *)skb->data;
620 672
621 /* Valid if HT is supported. */ 673 hdrlen = ieee80211_hdrlen(wh->frame_control);
622 __le16 ht_caps; 674 if (hdrlen != sizeof(*tr))
623 __u8 extended_ht_caps; 675 skb_push(skb, sizeof(*tr) - hdrlen);
624 struct ewc_ht_info ewc_info;
625 676
626 /* Legacy rate table. Intersection of our rates and peer rates. */ 677 if (ieee80211_is_data_qos(wh->frame_control))
627 __u8 legacy_rates[MWL8K_IEEE_LEGACY_DATA_RATES]; 678 hdrlen -= 2;
628 679
629 /* HT rate table. Intersection of our rates and peer rates. */ 680 tr = (struct mwl8k_dma_data *)skb->data;
630 __u8 ht_rates[MWL8K_MCS_BITMAP_SIZE]; 681 if (wh != &tr->wh)
631 __u8 pad[16]; 682 memmove(&tr->wh, wh, hdrlen);
683 if (hdrlen != sizeof(tr->wh))
684 memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
632 685
633 /* If set, interoperability mode, no proprietary extensions. */ 686 /*
634 __u8 interop; 687 * Firmware length is the length of the fully formed "802.11
635 __u8 pad2; 688 * payload". That is, everything except for the 802.11 header.
636 __u8 station_id; 689 * This includes all crypto material including the MIC.
637 __le16 amsdu_enabled; 690 */
638} __attribute__((packed)); 691 tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr));
692}
639 693
640/* Inline functions to manipulate QoS field in data descriptor. */
641static inline u16 mwl8k_qos_setbit_eosp(u16 qos)
642{
643 u16 val_mask = 1 << 4;
644 694
645 /* End of Service Period Bit 4 */ 695/*
646 return qos | val_mask; 696 * Packet reception for 88w8366 AP firmware.
647} 697 */
698struct mwl8k_rxd_8366_ap {
699 __le16 pkt_len;
700 __u8 sq2;
701 __u8 rate;
702 __le32 pkt_phys_addr;
703 __le32 next_rxd_phys_addr;
704 __le16 qos_control;
705 __le16 htsig2;
706 __le32 hw_rssi_info;
707 __le32 hw_noise_floor_info;
708 __u8 noise_floor;
709 __u8 pad0[3];
710 __u8 rssi;
711 __u8 rx_status;
712 __u8 channel;
713 __u8 rx_ctrl;
714} __attribute__((packed));
648 715
649static inline u16 mwl8k_qos_setbit_ack(u16 qos, u8 ack_policy) 716#define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT 0x80
650{ 717#define MWL8K_8366_AP_RATE_INFO_40MHZ 0x40
651 u16 val_mask = 0x3; 718#define MWL8K_8366_AP_RATE_INFO_RATEID(x) ((x) & 0x3f)
652 u8 shift = 5;
653 u16 qos_mask = ~(val_mask << shift);
654 719
655 /* Ack Policy Bit 5-6 */ 720#define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST 0x80
656 return (qos & qos_mask) | ((ack_policy & val_mask) << shift);
657}
658 721
659static inline u16 mwl8k_qos_setbit_amsdu(u16 qos) 722static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr)
660{ 723{
661 u16 val_mask = 1 << 7; 724 struct mwl8k_rxd_8366_ap *rxd = _rxd;
662 725
663 /* AMSDU present Bit 7 */ 726 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
664 return qos | val_mask; 727 rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST;
665} 728}
666 729
667static inline u16 mwl8k_qos_setbit_qlen(u16 qos, u8 len) 730static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len)
668{ 731{
669 u16 val_mask = 0xff; 732 struct mwl8k_rxd_8366_ap *rxd = _rxd;
670 u8 shift = 8;
671 u16 qos_mask = ~(val_mask << shift);
672 733
673 /* Queue Length Bits 8-15 */ 734 rxd->pkt_len = cpu_to_le16(len);
674 return (qos & qos_mask) | ((len & val_mask) << shift); 735 rxd->pkt_phys_addr = cpu_to_le32(addr);
736 wmb();
737 rxd->rx_ctrl = 0;
675} 738}
676 739
677/* DMA header used by firmware and hardware. */ 740static int
678struct mwl8k_dma_data { 741mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
679 __le16 fwlen; 742 __le16 *qos)
680 struct ieee80211_hdr wh;
681} __attribute__((packed));
682
683/* Routines to add/remove DMA header from skb. */
684static inline void mwl8k_remove_dma_header(struct sk_buff *skb)
685{ 743{
686 struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)skb->data; 744 struct mwl8k_rxd_8366_ap *rxd = _rxd;
687 void *dst, *src = &tr->wh;
688 int hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
689 u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
690 745
691 dst = (void *)tr + space; 746 if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST))
692 if (dst != src) { 747 return -1;
693 memmove(dst, src, hdrlen); 748 rmb();
694 skb_pull(skb, space);
695 }
696}
697 749
698static inline void mwl8k_add_dma_header(struct sk_buff *skb) 750 memset(status, 0, sizeof(*status));
699{
700 struct ieee80211_hdr *wh;
701 u32 hdrlen, pktlen;
702 struct mwl8k_dma_data *tr;
703 751
704 wh = (struct ieee80211_hdr *)skb->data; 752 status->signal = -rxd->rssi;
705 hdrlen = ieee80211_hdrlen(wh->frame_control); 753 status->noise = -rxd->noise_floor;
706 pktlen = skb->len;
707 754
708 /* 755 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
709 * Copy up/down the 802.11 header; the firmware requires 756 status->flag |= RX_FLAG_HT;
710 * we present a 2-byte payload length followed by a 757 if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ)
711 * 4-address header (w/o QoS), followed (optionally) by 758 status->flag |= RX_FLAG_40MHZ;
712 * any WEP/ExtIV header (but only filled in for CCMP). 759 status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate);
713 */ 760 } else {
714 if (hdrlen != sizeof(struct mwl8k_dma_data)) 761 int i;
715 skb_push(skb, sizeof(struct mwl8k_dma_data) - hdrlen);
716 762
717 tr = (struct mwl8k_dma_data *)skb->data; 763 for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) {
718 if (wh != &tr->wh) 764 if (mwl8k_rates_24[i].hw_value == rxd->rate) {
719 memmove(&tr->wh, wh, hdrlen); 765 status->rate_idx = i;
766 break;
767 }
768 }
769 }
720 770
721 /* Clear addr4 */ 771 if (rxd->channel > 14) {
722 memset(tr->wh.addr4, 0, ETH_ALEN); 772 status->band = IEEE80211_BAND_5GHZ;
773 if (!(status->flag & RX_FLAG_HT))
774 status->rate_idx -= 5;
775 } else {
776 status->band = IEEE80211_BAND_2GHZ;
777 }
778 status->freq = ieee80211_channel_to_frequency(rxd->channel);
723 779
724 /* 780 *qos = rxd->qos_control;
725 * Firmware length is the length of the fully formed "802.11 781
726 * payload". That is, everything except for the 802.11 header. 782 return le16_to_cpu(rxd->pkt_len);
727 * This includes all crypto material including the MIC.
728 */
729 tr->fwlen = cpu_to_le16(pktlen - hdrlen);
730} 783}
731 784
785static struct rxd_ops rxd_8366_ap_ops = {
786 .rxd_size = sizeof(struct mwl8k_rxd_8366_ap),
787 .rxd_init = mwl8k_rxd_8366_ap_init,
788 .rxd_refill = mwl8k_rxd_8366_ap_refill,
789 .rxd_process = mwl8k_rxd_8366_ap_process,
790};
732 791
733/* 792/*
734 * Packet reception. 793 * Packet reception for STA firmware.
735 */ 794 */
736#define MWL8K_RX_CTRL_OWNED_BY_HOST 0x02 795struct mwl8k_rxd_sta {
737
738struct mwl8k_rx_desc {
739 __le16 pkt_len; 796 __le16 pkt_len;
740 __u8 link_quality; 797 __u8 link_quality;
741 __u8 noise_level; 798 __u8 noise_level;
742 __le32 pkt_phys_addr; 799 __le32 pkt_phys_addr;
743 __le32 next_rx_desc_phys_addr; 800 __le32 next_rxd_phys_addr;
744 __le16 qos_control; 801 __le16 qos_control;
745 __le16 rate_info; 802 __le16 rate_info;
746 __le32 pad0[4]; 803 __le32 pad0[4];
@@ -752,6 +809,84 @@ struct mwl8k_rx_desc {
752 __u8 pad2[2]; 809 __u8 pad2[2];
753} __attribute__((packed)); 810} __attribute__((packed));
754 811
812#define MWL8K_STA_RATE_INFO_SHORTPRE 0x8000
813#define MWL8K_STA_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3)
814#define MWL8K_STA_RATE_INFO_RATEID(x) (((x) >> 3) & 0x3f)
815#define MWL8K_STA_RATE_INFO_40MHZ 0x0004
816#define MWL8K_STA_RATE_INFO_SHORTGI 0x0002
817#define MWL8K_STA_RATE_INFO_MCS_FORMAT 0x0001
818
819#define MWL8K_STA_RX_CTRL_OWNED_BY_HOST 0x02
820
821static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr)
822{
823 struct mwl8k_rxd_sta *rxd = _rxd;
824
825 rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
826 rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST;
827}
828
829static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
830{
831 struct mwl8k_rxd_sta *rxd = _rxd;
832
833 rxd->pkt_len = cpu_to_le16(len);
834 rxd->pkt_phys_addr = cpu_to_le32(addr);
835 wmb();
836 rxd->rx_ctrl = 0;
837}
838
839static int
840mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
841 __le16 *qos)
842{
843 struct mwl8k_rxd_sta *rxd = _rxd;
844 u16 rate_info;
845
846 if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST))
847 return -1;
848 rmb();
849
850 rate_info = le16_to_cpu(rxd->rate_info);
851
852 memset(status, 0, sizeof(*status));
853
854 status->signal = -rxd->rssi;
855 status->noise = -rxd->noise_level;
856 status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
857 status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
858
859 if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE)
860 status->flag |= RX_FLAG_SHORTPRE;
861 if (rate_info & MWL8K_STA_RATE_INFO_40MHZ)
862 status->flag |= RX_FLAG_40MHZ;
863 if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI)
864 status->flag |= RX_FLAG_SHORT_GI;
865 if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
866 status->flag |= RX_FLAG_HT;
867
868 if (rxd->channel > 14) {
869 status->band = IEEE80211_BAND_5GHZ;
870 if (!(status->flag & RX_FLAG_HT))
871 status->rate_idx -= 5;
872 } else {
873 status->band = IEEE80211_BAND_2GHZ;
874 }
875 status->freq = ieee80211_channel_to_frequency(rxd->channel);
876
877 *qos = rxd->qos_control;
878
879 return le16_to_cpu(rxd->pkt_len);
880}
881
882static struct rxd_ops rxd_sta_ops = {
883 .rxd_size = sizeof(struct mwl8k_rxd_sta),
884 .rxd_init = mwl8k_rxd_sta_init,
885 .rxd_refill = mwl8k_rxd_sta_refill,
886 .rxd_process = mwl8k_rxd_sta_process,
887};
888
889
755#define MWL8K_RX_DESCS 256 890#define MWL8K_RX_DESCS 256
756#define MWL8K_RX_MAXSZ 3800 891#define MWL8K_RX_MAXSZ 3800
757 892
@@ -762,43 +897,44 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
762 int size; 897 int size;
763 int i; 898 int i;
764 899
765 rxq->rx_desc_count = 0; 900 rxq->rxd_count = 0;
766 rxq->rx_head = 0; 901 rxq->head = 0;
767 rxq->rx_tail = 0; 902 rxq->tail = 0;
768 903
769 size = MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc); 904 size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size;
770 905
771 rxq->rx_desc_area = 906 rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
772 pci_alloc_consistent(priv->pdev, size, &rxq->rx_desc_dma); 907 if (rxq->rxd == NULL) {
773 if (rxq->rx_desc_area == NULL) {
774 printk(KERN_ERR "%s: failed to alloc RX descriptors\n", 908 printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
775 priv->name); 909 wiphy_name(hw->wiphy));
776 return -ENOMEM; 910 return -ENOMEM;
777 } 911 }
778 memset(rxq->rx_desc_area, 0, size); 912 memset(rxq->rxd, 0, size);
779 913
780 rxq->rx_skb = kmalloc(MWL8K_RX_DESCS * 914 rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL);
781 sizeof(*rxq->rx_skb), GFP_KERNEL); 915 if (rxq->buf == NULL) {
782 if (rxq->rx_skb == NULL) {
783 printk(KERN_ERR "%s: failed to alloc RX skbuff list\n", 916 printk(KERN_ERR "%s: failed to alloc RX skbuff list\n",
784 priv->name); 917 wiphy_name(hw->wiphy));
785 pci_free_consistent(priv->pdev, size, 918 pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
786 rxq->rx_desc_area, rxq->rx_desc_dma);
787 return -ENOMEM; 919 return -ENOMEM;
788 } 920 }
789 memset(rxq->rx_skb, 0, MWL8K_RX_DESCS * sizeof(*rxq->rx_skb)); 921 memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf));
790 922
791 for (i = 0; i < MWL8K_RX_DESCS; i++) { 923 for (i = 0; i < MWL8K_RX_DESCS; i++) {
792 struct mwl8k_rx_desc *rx_desc; 924 int desc_size;
925 void *rxd;
793 int nexti; 926 int nexti;
927 dma_addr_t next_dma_addr;
794 928
795 rx_desc = rxq->rx_desc_area + i; 929 desc_size = priv->rxd_ops->rxd_size;
796 nexti = (i + 1) % MWL8K_RX_DESCS; 930 rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size);
797 931
798 rx_desc->next_rx_desc_phys_addr = 932 nexti = i + 1;
799 cpu_to_le32(rxq->rx_desc_dma 933 if (nexti == MWL8K_RX_DESCS)
800 + nexti * sizeof(*rx_desc)); 934 nexti = 0;
801 rx_desc->rx_ctrl = MWL8K_RX_CTRL_OWNED_BY_HOST; 935 next_dma_addr = rxq->rxd_dma + (nexti * desc_size);
936
937 priv->rxd_ops->rxd_init(rxd, next_dma_addr);
802 } 938 }
803 939
804 return 0; 940 return 0;
@@ -811,27 +947,28 @@ static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
811 int refilled; 947 int refilled;
812 948
813 refilled = 0; 949 refilled = 0;
814 while (rxq->rx_desc_count < MWL8K_RX_DESCS && limit--) { 950 while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) {
815 struct sk_buff *skb; 951 struct sk_buff *skb;
952 dma_addr_t addr;
816 int rx; 953 int rx;
954 void *rxd;
817 955
818 skb = dev_alloc_skb(MWL8K_RX_MAXSZ); 956 skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
819 if (skb == NULL) 957 if (skb == NULL)
820 break; 958 break;
821 959
822 rxq->rx_desc_count++; 960 addr = pci_map_single(priv->pdev, skb->data,
823 961 MWL8K_RX_MAXSZ, DMA_FROM_DEVICE);
824 rx = rxq->rx_tail;
825 rxq->rx_tail = (rx + 1) % MWL8K_RX_DESCS;
826 962
827 rxq->rx_desc_area[rx].pkt_phys_addr = 963 rxq->rxd_count++;
828 cpu_to_le32(pci_map_single(priv->pdev, skb->data, 964 rx = rxq->tail++;
829 MWL8K_RX_MAXSZ, DMA_FROM_DEVICE)); 965 if (rxq->tail == MWL8K_RX_DESCS)
966 rxq->tail = 0;
967 rxq->buf[rx].skb = skb;
968 pci_unmap_addr_set(&rxq->buf[rx], dma, addr);
830 969
831 rxq->rx_desc_area[rx].pkt_len = cpu_to_le16(MWL8K_RX_MAXSZ); 970 rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size);
832 rxq->rx_skb[rx] = skb; 971 priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ);
833 wmb();
834 rxq->rx_desc_area[rx].rx_ctrl = 0;
835 972
836 refilled++; 973 refilled++;
837 } 974 }
@@ -847,24 +984,24 @@ static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
847 int i; 984 int i;
848 985
849 for (i = 0; i < MWL8K_RX_DESCS; i++) { 986 for (i = 0; i < MWL8K_RX_DESCS; i++) {
850 if (rxq->rx_skb[i] != NULL) { 987 if (rxq->buf[i].skb != NULL) {
851 unsigned long addr; 988 pci_unmap_single(priv->pdev,
852 989 pci_unmap_addr(&rxq->buf[i], dma),
853 addr = le32_to_cpu(rxq->rx_desc_area[i].pkt_phys_addr); 990 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
854 pci_unmap_single(priv->pdev, addr, MWL8K_RX_MAXSZ, 991 pci_unmap_addr_set(&rxq->buf[i], dma, 0);
855 PCI_DMA_FROMDEVICE); 992
856 kfree_skb(rxq->rx_skb[i]); 993 kfree_skb(rxq->buf[i].skb);
857 rxq->rx_skb[i] = NULL; 994 rxq->buf[i].skb = NULL;
858 } 995 }
859 } 996 }
860 997
861 kfree(rxq->rx_skb); 998 kfree(rxq->buf);
862 rxq->rx_skb = NULL; 999 rxq->buf = NULL;
863 1000
864 pci_free_consistent(priv->pdev, 1001 pci_free_consistent(priv->pdev,
865 MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc), 1002 MWL8K_RX_DESCS * priv->rxd_ops->rxd_size,
866 rxq->rx_desc_area, rxq->rx_desc_dma); 1003 rxq->rxd, rxq->rxd_dma);
867 rxq->rx_desc_area = NULL; 1004 rxq->rxd = NULL;
868} 1005}
869 1006
870 1007
@@ -880,9 +1017,11 @@ mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
880 !compare_ether_addr(wh->addr3, priv->capture_bssid); 1017 !compare_ether_addr(wh->addr3, priv->capture_bssid);
881} 1018}
882 1019
883static inline void mwl8k_save_beacon(struct mwl8k_priv *priv, 1020static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
884 struct sk_buff *skb) 1021 struct sk_buff *skb)
885{ 1022{
1023 struct mwl8k_priv *priv = hw->priv;
1024
886 priv->capture_beacon = false; 1025 priv->capture_beacon = false;
887 memset(priv->capture_bssid, 0, ETH_ALEN); 1026 memset(priv->capture_bssid, 0, ETH_ALEN);
888 1027
@@ -893,8 +1032,7 @@ static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
893 */ 1032 */
894 priv->beacon_skb = skb_copy(skb, GFP_ATOMIC); 1033 priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
895 if (priv->beacon_skb != NULL) 1034 if (priv->beacon_skb != NULL)
896 queue_work(priv->config_wq, 1035 ieee80211_queue_work(hw, &priv->finalize_join_worker);
897 &priv->finalize_join_worker);
898} 1036}
899 1037
900static int rxq_process(struct ieee80211_hw *hw, int index, int limit) 1038static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
@@ -904,53 +1042,47 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
904 int processed; 1042 int processed;
905 1043
906 processed = 0; 1044 processed = 0;
907 while (rxq->rx_desc_count && limit--) { 1045 while (rxq->rxd_count && limit--) {
908 struct mwl8k_rx_desc *rx_desc;
909 struct sk_buff *skb; 1046 struct sk_buff *skb;
1047 void *rxd;
1048 int pkt_len;
910 struct ieee80211_rx_status status; 1049 struct ieee80211_rx_status status;
911 unsigned long addr; 1050 __le16 qos;
912 struct ieee80211_hdr *wh;
913 1051
914 rx_desc = rxq->rx_desc_area + rxq->rx_head; 1052 skb = rxq->buf[rxq->head].skb;
915 if (!(rx_desc->rx_ctrl & MWL8K_RX_CTRL_OWNED_BY_HOST)) 1053 if (skb == NULL)
916 break; 1054 break;
917 rmb();
918 1055
919 skb = rxq->rx_skb[rxq->rx_head]; 1056 rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
920 if (skb == NULL) 1057
1058 pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos);
1059 if (pkt_len < 0)
921 break; 1060 break;
922 rxq->rx_skb[rxq->rx_head] = NULL;
923 1061
924 rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS; 1062 rxq->buf[rxq->head].skb = NULL;
925 rxq->rx_desc_count--; 1063
1064 pci_unmap_single(priv->pdev,
1065 pci_unmap_addr(&rxq->buf[rxq->head], dma),
1066 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
1067 pci_unmap_addr_set(&rxq->buf[rxq->head], dma, 0);
926 1068
927 addr = le32_to_cpu(rx_desc->pkt_phys_addr); 1069 rxq->head++;
928 pci_unmap_single(priv->pdev, addr, 1070 if (rxq->head == MWL8K_RX_DESCS)
929 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); 1071 rxq->head = 0;
930 1072
931 skb_put(skb, le16_to_cpu(rx_desc->pkt_len)); 1073 rxq->rxd_count--;
932 mwl8k_remove_dma_header(skb);
933 1074
934 wh = (struct ieee80211_hdr *)skb->data; 1075 skb_put(skb, pkt_len);
1076 mwl8k_remove_dma_header(skb, qos);
935 1077
936 /* 1078 /*
937 * Check for pending join operation. save a copy of 1079 * Check for a pending join operation. Save a
938 * the beacon and schedule a tasklet to send finalize 1080 * copy of the beacon and schedule a tasklet to
939 * join command to the firmware. 1081 * send a FINALIZE_JOIN command to the firmware.
940 */ 1082 */
941 if (mwl8k_capture_bssid(priv, wh)) 1083 if (mwl8k_capture_bssid(priv, (void *)skb->data))
942 mwl8k_save_beacon(priv, skb); 1084 mwl8k_save_beacon(hw, skb);
943 1085
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)); 1086 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
955 ieee80211_rx_irqsafe(hw, skb); 1087 ieee80211_rx_irqsafe(hw, skb);
956 1088
@@ -965,30 +1097,18 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
965 * Packet transmission. 1097 * Packet transmission.
966 */ 1098 */
967 1099
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 */
977#define MWL8K_TXD_ACK_POLICY_NORMAL 0
978#define MWL8K_TXD_ACK_POLICY_BLOCKACK 3
979
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 1100#define MWL8K_TXD_STATUS_OK 0x00000001
987#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002 1101#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002
988#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004 1102#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004
989#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008 1103#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008
990#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000 1104#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000
991 1105
1106#define MWL8K_QOS_QLEN_UNSPEC 0xff00
1107#define MWL8K_QOS_ACK_POLICY_MASK 0x0060
1108#define MWL8K_QOS_ACK_POLICY_NORMAL 0x0000
1109#define MWL8K_QOS_ACK_POLICY_BLOCKACK 0x0060
1110#define MWL8K_QOS_EOSP 0x0010
1111
992struct mwl8k_tx_desc { 1112struct mwl8k_tx_desc {
993 __le32 status; 1113 __le32 status;
994 __u8 data_rate; 1114 __u8 data_rate;
@@ -997,7 +1117,7 @@ struct mwl8k_tx_desc {
997 __le32 pkt_phys_addr; 1117 __le32 pkt_phys_addr;
998 __le16 pkt_len; 1118 __le16 pkt_len;
999 __u8 dest_MAC_addr[ETH_ALEN]; 1119 __u8 dest_MAC_addr[ETH_ALEN];
1000 __le32 next_tx_desc_phys_addr; 1120 __le32 next_txd_phys_addr;
1001 __le32 reserved; 1121 __le32 reserved;
1002 __le16 rate_info; 1122 __le16 rate_info;
1003 __u8 peer_id; 1123 __u8 peer_id;
@@ -1013,44 +1133,39 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1013 int size; 1133 int size;
1014 int i; 1134 int i;
1015 1135
1016 memset(&txq->tx_stats, 0, sizeof(struct ieee80211_tx_queue_stats)); 1136 txq->len = 0;
1017 txq->tx_stats.limit = MWL8K_TX_DESCS; 1137 txq->head = 0;
1018 txq->tx_head = 0; 1138 txq->tail = 0;
1019 txq->tx_tail = 0;
1020 1139
1021 size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc); 1140 size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc);
1022 1141
1023 txq->tx_desc_area = 1142 txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma);
1024 pci_alloc_consistent(priv->pdev, size, &txq->tx_desc_dma); 1143 if (txq->txd == NULL) {
1025 if (txq->tx_desc_area == NULL) {
1026 printk(KERN_ERR "%s: failed to alloc TX descriptors\n", 1144 printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
1027 priv->name); 1145 wiphy_name(hw->wiphy));
1028 return -ENOMEM; 1146 return -ENOMEM;
1029 } 1147 }
1030 memset(txq->tx_desc_area, 0, size); 1148 memset(txq->txd, 0, size);
1031 1149
1032 txq->tx_skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->tx_skb), 1150 txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL);
1033 GFP_KERNEL); 1151 if (txq->skb == NULL) {
1034 if (txq->tx_skb == NULL) {
1035 printk(KERN_ERR "%s: failed to alloc TX skbuff list\n", 1152 printk(KERN_ERR "%s: failed to alloc TX skbuff list\n",
1036 priv->name); 1153 wiphy_name(hw->wiphy));
1037 pci_free_consistent(priv->pdev, size, 1154 pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
1038 txq->tx_desc_area, txq->tx_desc_dma);
1039 return -ENOMEM; 1155 return -ENOMEM;
1040 } 1156 }
1041 memset(txq->tx_skb, 0, MWL8K_TX_DESCS * sizeof(*txq->tx_skb)); 1157 memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb));
1042 1158
1043 for (i = 0; i < MWL8K_TX_DESCS; i++) { 1159 for (i = 0; i < MWL8K_TX_DESCS; i++) {
1044 struct mwl8k_tx_desc *tx_desc; 1160 struct mwl8k_tx_desc *tx_desc;
1045 int nexti; 1161 int nexti;
1046 1162
1047 tx_desc = txq->tx_desc_area + i; 1163 tx_desc = txq->txd + i;
1048 nexti = (i + 1) % MWL8K_TX_DESCS; 1164 nexti = (i + 1) % MWL8K_TX_DESCS;
1049 1165
1050 tx_desc->status = 0; 1166 tx_desc->status = 0;
1051 tx_desc->next_tx_desc_phys_addr = 1167 tx_desc->next_txd_phys_addr =
1052 cpu_to_le32(txq->tx_desc_dma + 1168 cpu_to_le32(txq->txd_dma + nexti * sizeof(*tx_desc));
1053 nexti * sizeof(*tx_desc));
1054 } 1169 }
1055 1170
1056 return 0; 1171 return 0;
@@ -1065,109 +1180,106 @@ static inline void mwl8k_tx_start(struct mwl8k_priv *priv)
1065 ioread32(priv->regs + MWL8K_HIU_INT_CODE); 1180 ioread32(priv->regs + MWL8K_HIU_INT_CODE);
1066} 1181}
1067 1182
1068static inline int mwl8k_txq_busy(struct mwl8k_priv *priv) 1183static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
1069{ 1184{
1070 return priv->pending_tx_pkts; 1185 struct mwl8k_priv *priv = hw->priv;
1071} 1186 int i;
1072
1073struct mwl8k_txq_info {
1074 u32 fw_owned;
1075 u32 drv_owned;
1076 u32 unused;
1077 u32 len;
1078 u32 head;
1079 u32 tail;
1080};
1081
1082static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
1083 struct mwl8k_txq_info *txinfo)
1084{
1085 int count, desc, status;
1086 struct mwl8k_tx_queue *txq;
1087 struct mwl8k_tx_desc *tx_desc;
1088 int ndescs = 0;
1089 1187
1090 memset(txinfo, 0, MWL8K_TX_QUEUES * sizeof(struct mwl8k_txq_info)); 1188 for (i = 0; i < MWL8K_TX_QUEUES; i++) {
1189 struct mwl8k_tx_queue *txq = priv->txq + i;
1190 int fw_owned = 0;
1191 int drv_owned = 0;
1192 int unused = 0;
1193 int desc;
1091 1194
1092 spin_lock_bh(&priv->tx_lock);
1093 for (count = 0; count < MWL8K_TX_QUEUES; count++) {
1094 txq = priv->txq + count;
1095 txinfo[count].len = txq->tx_stats.len;
1096 txinfo[count].head = txq->tx_head;
1097 txinfo[count].tail = txq->tx_tail;
1098 for (desc = 0; desc < MWL8K_TX_DESCS; desc++) { 1195 for (desc = 0; desc < MWL8K_TX_DESCS; desc++) {
1099 tx_desc = txq->tx_desc_area + desc; 1196 struct mwl8k_tx_desc *tx_desc = txq->txd + desc;
1100 status = le32_to_cpu(tx_desc->status); 1197 u32 status;
1101 1198
1199 status = le32_to_cpu(tx_desc->status);
1102 if (status & MWL8K_TXD_STATUS_FW_OWNED) 1200 if (status & MWL8K_TXD_STATUS_FW_OWNED)
1103 txinfo[count].fw_owned++; 1201 fw_owned++;
1104 else 1202 else
1105 txinfo[count].drv_owned++; 1203 drv_owned++;
1106 1204
1107 if (tx_desc->pkt_len == 0) 1205 if (tx_desc->pkt_len == 0)
1108 txinfo[count].unused++; 1206 unused++;
1109 } 1207 }
1110 }
1111 spin_unlock_bh(&priv->tx_lock);
1112 1208
1113 return ndescs; 1209 printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d "
1210 "fw_owned=%d drv_owned=%d unused=%d\n",
1211 wiphy_name(hw->wiphy), i,
1212 txq->len, txq->head, txq->tail,
1213 fw_owned, drv_owned, unused);
1214 }
1114} 1215}
1115 1216
1116/* 1217/*
1117 * Must be called with hw->fw_mutex held and tx queues stopped. 1218 * Must be called with priv->fw_mutex held and tx queues stopped.
1118 */ 1219 */
1220#define MWL8K_TX_WAIT_TIMEOUT_MS 5000
1221
1119static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) 1222static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1120{ 1223{
1121 struct mwl8k_priv *priv = hw->priv; 1224 struct mwl8k_priv *priv = hw->priv;
1122 DECLARE_COMPLETION_ONSTACK(cmd_wait); 1225 DECLARE_COMPLETION_ONSTACK(tx_wait);
1123 u32 count; 1226 int retry;
1124 unsigned long timeout; 1227 int rc;
1125 1228
1126 might_sleep(); 1229 might_sleep();
1127 1230
1128 spin_lock_bh(&priv->tx_lock); 1231 /*
1129 count = mwl8k_txq_busy(priv); 1232 * The TX queues are stopped at this point, so this test
1130 if (count) { 1233 * doesn't need to take ->tx_lock.
1131 priv->tx_wait = &cmd_wait; 1234 */
1132 if (priv->radio_on) 1235 if (!priv->pending_tx_pkts)
1133 mwl8k_tx_start(priv); 1236 return 0;
1134 }
1135 spin_unlock_bh(&priv->tx_lock);
1136 1237
1137 if (count) { 1238 retry = 0;
1138 struct mwl8k_txq_info txinfo[MWL8K_TX_QUEUES]; 1239 rc = 0;
1139 int index;
1140 int newcount;
1141 1240
1142 timeout = wait_for_completion_timeout(&cmd_wait, 1241 spin_lock_bh(&priv->tx_lock);
1143 msecs_to_jiffies(5000)); 1242 priv->tx_wait = &tx_wait;
1144 if (timeout) 1243 while (!rc) {
1145 return 0; 1244 int oldcount;
1245 unsigned long timeout;
1246
1247 oldcount = priv->pending_tx_pkts;
1146 1248
1147 spin_lock_bh(&priv->tx_lock);
1148 priv->tx_wait = NULL;
1149 newcount = mwl8k_txq_busy(priv);
1150 spin_unlock_bh(&priv->tx_lock); 1249 spin_unlock_bh(&priv->tx_lock);
1250 timeout = wait_for_completion_timeout(&tx_wait,
1251 msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS));
1252 spin_lock_bh(&priv->tx_lock);
1253
1254 if (timeout) {
1255 WARN_ON(priv->pending_tx_pkts);
1256 if (retry) {
1257 printk(KERN_NOTICE "%s: tx rings drained\n",
1258 wiphy_name(hw->wiphy));
1259 }
1260 break;
1261 }
1262
1263 if (priv->pending_tx_pkts < oldcount) {
1264 printk(KERN_NOTICE "%s: waiting for tx rings "
1265 "to drain (%d -> %d pkts)\n",
1266 wiphy_name(hw->wiphy), oldcount,
1267 priv->pending_tx_pkts);
1268 retry = 1;
1269 continue;
1270 }
1151 1271
1152 printk(KERN_ERR "%s(%u) TIMEDOUT:5000ms Pend:%u-->%u\n", 1272 priv->tx_wait = NULL;
1153 __func__, __LINE__, count, newcount);
1154 1273
1155 mwl8k_scan_tx_ring(priv, txinfo); 1274 printk(KERN_ERR "%s: tx rings stuck for %d ms\n",
1156 for (index = 0; index < MWL8K_TX_QUEUES; index++) 1275 wiphy_name(hw->wiphy), MWL8K_TX_WAIT_TIMEOUT_MS);
1157 printk(KERN_ERR 1276 mwl8k_dump_tx_rings(hw);
1158 "TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n",
1159 index,
1160 txinfo[index].len,
1161 txinfo[index].head,
1162 txinfo[index].tail,
1163 txinfo[index].fw_owned,
1164 txinfo[index].drv_owned,
1165 txinfo[index].unused);
1166 1277
1167 return -ETIMEDOUT; 1278 rc = -ETIMEDOUT;
1168 } 1279 }
1280 spin_unlock_bh(&priv->tx_lock);
1169 1281
1170 return 0; 1282 return rc;
1171} 1283}
1172 1284
1173#define MWL8K_TXD_SUCCESS(status) \ 1285#define MWL8K_TXD_SUCCESS(status) \
@@ -1175,13 +1287,15 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1175 MWL8K_TXD_STATUS_OK_RETRY | \ 1287 MWL8K_TXD_STATUS_OK_RETRY | \
1176 MWL8K_TXD_STATUS_OK_MORE_RETRY)) 1288 MWL8K_TXD_STATUS_OK_MORE_RETRY))
1177 1289
1178static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force) 1290static int
1291mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1179{ 1292{
1180 struct mwl8k_priv *priv = hw->priv; 1293 struct mwl8k_priv *priv = hw->priv;
1181 struct mwl8k_tx_queue *txq = priv->txq + index; 1294 struct mwl8k_tx_queue *txq = priv->txq + index;
1182 int wake = 0; 1295 int processed;
1183 1296
1184 while (txq->tx_stats.len > 0) { 1297 processed = 0;
1298 while (txq->len > 0 && limit--) {
1185 int tx; 1299 int tx;
1186 struct mwl8k_tx_desc *tx_desc; 1300 struct mwl8k_tx_desc *tx_desc;
1187 unsigned long addr; 1301 unsigned long addr;
@@ -1190,8 +1304,8 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1190 struct ieee80211_tx_info *info; 1304 struct ieee80211_tx_info *info;
1191 u32 status; 1305 u32 status;
1192 1306
1193 tx = txq->tx_head; 1307 tx = txq->head;
1194 tx_desc = txq->tx_desc_area + tx; 1308 tx_desc = txq->txd + tx;
1195 1309
1196 status = le32_to_cpu(tx_desc->status); 1310 status = le32_to_cpu(tx_desc->status);
1197 1311
@@ -1202,20 +1316,20 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1202 ~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED); 1316 ~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED);
1203 } 1317 }
1204 1318
1205 txq->tx_head = (tx + 1) % MWL8K_TX_DESCS; 1319 txq->head = (tx + 1) % MWL8K_TX_DESCS;
1206 BUG_ON(txq->tx_stats.len == 0); 1320 BUG_ON(txq->len == 0);
1207 txq->tx_stats.len--; 1321 txq->len--;
1208 priv->pending_tx_pkts--; 1322 priv->pending_tx_pkts--;
1209 1323
1210 addr = le32_to_cpu(tx_desc->pkt_phys_addr); 1324 addr = le32_to_cpu(tx_desc->pkt_phys_addr);
1211 size = le16_to_cpu(tx_desc->pkt_len); 1325 size = le16_to_cpu(tx_desc->pkt_len);
1212 skb = txq->tx_skb[tx]; 1326 skb = txq->skb[tx];
1213 txq->tx_skb[tx] = NULL; 1327 txq->skb[tx] = NULL;
1214 1328
1215 BUG_ON(skb == NULL); 1329 BUG_ON(skb == NULL);
1216 pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE); 1330 pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
1217 1331
1218 mwl8k_remove_dma_header(skb); 1332 mwl8k_remove_dma_header(skb, tx_desc->qos_control);
1219 1333
1220 /* Mark descriptor as unused */ 1334 /* Mark descriptor as unused */
1221 tx_desc->pkt_phys_addr = 0; 1335 tx_desc->pkt_phys_addr = 0;
@@ -1228,11 +1342,13 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1228 1342
1229 ieee80211_tx_status_irqsafe(hw, skb); 1343 ieee80211_tx_status_irqsafe(hw, skb);
1230 1344
1231 wake = 1; 1345 processed++;
1232 } 1346 }
1233 1347
1234 if (wake && priv->radio_on && !mutex_is_locked(&priv->fw_mutex)) 1348 if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
1235 ieee80211_wake_queue(hw, index); 1349 ieee80211_wake_queue(hw, index);
1350
1351 return processed;
1236} 1352}
1237 1353
1238/* must be called only when the card's transmit is completely halted */ 1354/* must be called only when the card's transmit is completely halted */
@@ -1241,15 +1357,15 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1241 struct mwl8k_priv *priv = hw->priv; 1357 struct mwl8k_priv *priv = hw->priv;
1242 struct mwl8k_tx_queue *txq = priv->txq + index; 1358 struct mwl8k_tx_queue *txq = priv->txq + index;
1243 1359
1244 mwl8k_txq_reclaim(hw, index, 1); 1360 mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
1245 1361
1246 kfree(txq->tx_skb); 1362 kfree(txq->skb);
1247 txq->tx_skb = NULL; 1363 txq->skb = NULL;
1248 1364
1249 pci_free_consistent(priv->pdev, 1365 pci_free_consistent(priv->pdev,
1250 MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc), 1366 MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc),
1251 txq->tx_desc_area, txq->tx_desc_dma); 1367 txq->txd, txq->txd_dma);
1252 txq->tx_desc_area = NULL; 1368 txq->txd = NULL;
1253} 1369}
1254 1370
1255static int 1371static int
@@ -1279,11 +1395,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1279 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); 1395 mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
1280 1396
1281 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 1397 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1282 u16 seqno = mwl8k_vif->seqno;
1283
1284 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 1398 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
1285 wh->seq_ctrl |= cpu_to_le16(seqno << 4); 1399 wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno);
1286 mwl8k_vif->seqno = seqno++ % 4096; 1400 mwl8k_vif->seqno += 0x10;
1287 } 1401 }
1288 1402
1289 /* Setup firmware control bit fields for each frame type. */ 1403 /* Setup firmware control bit fields for each frame type. */
@@ -1292,24 +1406,17 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1292 if (ieee80211_is_mgmt(wh->frame_control) || 1406 if (ieee80211_is_mgmt(wh->frame_control) ||
1293 ieee80211_is_ctl(wh->frame_control)) { 1407 ieee80211_is_ctl(wh->frame_control)) {
1294 txdatarate = 0; 1408 txdatarate = 0;
1295 qos = mwl8k_qos_setbit_eosp(qos); 1409 qos |= MWL8K_QOS_QLEN_UNSPEC | MWL8K_QOS_EOSP;
1296 /* Set Queue size to unspecified */
1297 qos = mwl8k_qos_setbit_qlen(qos, 0xff);
1298 } else if (ieee80211_is_data(wh->frame_control)) { 1410 } else if (ieee80211_is_data(wh->frame_control)) {
1299 txdatarate = 1; 1411 txdatarate = 1;
1300 if (is_multicast_ether_addr(wh->addr1)) 1412 if (is_multicast_ether_addr(wh->addr1))
1301 txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX; 1413 txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX;
1302 1414
1303 /* Send pkt in an aggregate if AMPDU frame. */ 1415 qos &= ~MWL8K_QOS_ACK_POLICY_MASK;
1304 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) 1416 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
1305 qos = mwl8k_qos_setbit_ack(qos, 1417 qos |= MWL8K_QOS_ACK_POLICY_BLOCKACK;
1306 MWL8K_TXD_ACK_POLICY_BLOCKACK);
1307 else 1418 else
1308 qos = mwl8k_qos_setbit_ack(qos, 1419 qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
1309 MWL8K_TXD_ACK_POLICY_NORMAL);
1310
1311 if (qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
1312 qos = mwl8k_qos_setbit_amsdu(qos);
1313 } 1420 }
1314 1421
1315 dma = pci_map_single(priv->pdev, skb->data, 1422 dma = pci_map_single(priv->pdev, skb->data,
@@ -1317,7 +1424,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1317 1424
1318 if (pci_dma_mapping_error(priv->pdev, dma)) { 1425 if (pci_dma_mapping_error(priv->pdev, dma)) {
1319 printk(KERN_DEBUG "%s: failed to dma map skb, " 1426 printk(KERN_DEBUG "%s: failed to dma map skb, "
1320 "dropping TX frame.\n", priv->name); 1427 "dropping TX frame.\n", wiphy_name(hw->wiphy));
1321 dev_kfree_skb(skb); 1428 dev_kfree_skb(skb);
1322 return NETDEV_TX_OK; 1429 return NETDEV_TX_OK;
1323 } 1430 }
@@ -1326,29 +1433,31 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1326 1433
1327 txq = priv->txq + index; 1434 txq = priv->txq + index;
1328 1435
1329 BUG_ON(txq->tx_skb[txq->tx_tail] != NULL); 1436 BUG_ON(txq->skb[txq->tail] != NULL);
1330 txq->tx_skb[txq->tx_tail] = skb; 1437 txq->skb[txq->tail] = skb;
1331 1438
1332 tx = txq->tx_desc_area + txq->tx_tail; 1439 tx = txq->txd + txq->tail;
1333 tx->data_rate = txdatarate; 1440 tx->data_rate = txdatarate;
1334 tx->tx_priority = index; 1441 tx->tx_priority = index;
1335 tx->qos_control = cpu_to_le16(qos); 1442 tx->qos_control = cpu_to_le16(qos);
1336 tx->pkt_phys_addr = cpu_to_le32(dma); 1443 tx->pkt_phys_addr = cpu_to_le32(dma);
1337 tx->pkt_len = cpu_to_le16(skb->len); 1444 tx->pkt_len = cpu_to_le16(skb->len);
1338 tx->rate_info = 0; 1445 tx->rate_info = 0;
1339 tx->peer_id = mwl8k_vif->peer_id; 1446 if (!priv->ap_fw && tx_info->control.sta != NULL)
1447 tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
1448 else
1449 tx->peer_id = 0;
1340 wmb(); 1450 wmb();
1341 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 1451 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1342 1452
1343 txq->tx_stats.count++; 1453 txq->len++;
1344 txq->tx_stats.len++;
1345 priv->pending_tx_pkts++; 1454 priv->pending_tx_pkts++;
1346 1455
1347 txq->tx_tail++; 1456 txq->tail++;
1348 if (txq->tx_tail == MWL8K_TX_DESCS) 1457 if (txq->tail == MWL8K_TX_DESCS)
1349 txq->tx_tail = 0; 1458 txq->tail = 0;
1350 1459
1351 if (txq->tx_head == txq->tx_tail) 1460 if (txq->head == txq->tail)
1352 ieee80211_stop_queue(hw, index); 1461 ieee80211_stop_queue(hw, index);
1353 1462
1354 mwl8k_tx_start(priv); 1463 mwl8k_tx_start(priv);
@@ -1417,8 +1526,8 @@ static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
1417 * Command processing. 1526 * Command processing.
1418 */ 1527 */
1419 1528
1420/* Timeout firmware commands after 2000ms */ 1529/* Timeout firmware commands after 10s */
1421#define MWL8K_CMD_TIMEOUT_MS 2000 1530#define MWL8K_CMD_TIMEOUT_MS 10000
1422 1531
1423static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) 1532static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1424{ 1533{
@@ -1431,7 +1540,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1431 unsigned long timeout = 0; 1540 unsigned long timeout = 0;
1432 u8 buf[32]; 1541 u8 buf[32];
1433 1542
1434 cmd->result = 0xFFFF; 1543 cmd->result = 0xffff;
1435 dma_size = le16_to_cpu(cmd->length); 1544 dma_size = le16_to_cpu(cmd->length);
1436 dma_addr = pci_map_single(priv->pdev, cmd, dma_size, 1545 dma_addr = pci_map_single(priv->pdev, cmd, dma_size,
1437 PCI_DMA_BIDIRECTIONAL); 1546 PCI_DMA_BIDIRECTIONAL);
@@ -1464,26 +1573,85 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1464 1573
1465 if (!timeout) { 1574 if (!timeout) {
1466 printk(KERN_ERR "%s: Command %s timeout after %u ms\n", 1575 printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
1467 priv->name, 1576 wiphy_name(hw->wiphy),
1468 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), 1577 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1469 MWL8K_CMD_TIMEOUT_MS); 1578 MWL8K_CMD_TIMEOUT_MS);
1470 rc = -ETIMEDOUT; 1579 rc = -ETIMEDOUT;
1471 } else { 1580 } else {
1581 int ms;
1582
1583 ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(timeout);
1584
1472 rc = cmd->result ? -EINVAL : 0; 1585 rc = cmd->result ? -EINVAL : 0;
1473 if (rc) 1586 if (rc)
1474 printk(KERN_ERR "%s: Command %s error 0x%x\n", 1587 printk(KERN_ERR "%s: Command %s error 0x%x\n",
1475 priv->name, 1588 wiphy_name(hw->wiphy),
1476 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), 1589 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1477 le16_to_cpu(cmd->result)); 1590 le16_to_cpu(cmd->result));
1591 else if (ms > 2000)
1592 printk(KERN_NOTICE "%s: Command %s took %d ms\n",
1593 wiphy_name(hw->wiphy),
1594 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1595 ms);
1478 } 1596 }
1479 1597
1480 return rc; 1598 return rc;
1481} 1599}
1482 1600
1601static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw,
1602 struct ieee80211_vif *vif,
1603 struct mwl8k_cmd_pkt *cmd)
1604{
1605 if (vif != NULL)
1606 cmd->macid = MWL8K_VIF(vif)->macid;
1607 return mwl8k_post_cmd(hw, cmd);
1608}
1609
1483/* 1610/*
1484 * GET_HW_SPEC. 1611 * Setup code shared between STA and AP firmware images.
1485 */ 1612 */
1486struct mwl8k_cmd_get_hw_spec { 1613static void mwl8k_setup_2ghz_band(struct ieee80211_hw *hw)
1614{
1615 struct mwl8k_priv *priv = hw->priv;
1616
1617 BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24));
1618 memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24));
1619
1620 BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24));
1621 memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24));
1622
1623 priv->band_24.band = IEEE80211_BAND_2GHZ;
1624 priv->band_24.channels = priv->channels_24;
1625 priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24);
1626 priv->band_24.bitrates = priv->rates_24;
1627 priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24);
1628
1629 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24;
1630}
1631
1632static void mwl8k_setup_5ghz_band(struct ieee80211_hw *hw)
1633{
1634 struct mwl8k_priv *priv = hw->priv;
1635
1636 BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50));
1637 memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50));
1638
1639 BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50));
1640 memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50));
1641
1642 priv->band_50.band = IEEE80211_BAND_5GHZ;
1643 priv->band_50.channels = priv->channels_50;
1644 priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50);
1645 priv->band_50.bitrates = priv->rates_50;
1646 priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50);
1647
1648 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50;
1649}
1650
1651/*
1652 * CMD_GET_HW_SPEC (STA version).
1653 */
1654struct mwl8k_cmd_get_hw_spec_sta {
1487 struct mwl8k_cmd_pkt header; 1655 struct mwl8k_cmd_pkt header;
1488 __u8 hw_rev; 1656 __u8 hw_rev;
1489 __u8 host_interface; 1657 __u8 host_interface;
@@ -1499,13 +1667,96 @@ struct mwl8k_cmd_get_hw_spec {
1499 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES]; 1667 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
1500 __le32 caps2; 1668 __le32 caps2;
1501 __le32 num_tx_desc_per_queue; 1669 __le32 num_tx_desc_per_queue;
1502 __le32 total_rx_desc; 1670 __le32 total_rxd;
1503} __attribute__((packed)); 1671} __attribute__((packed));
1504 1672
1505static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw) 1673#define MWL8K_CAP_MAX_AMSDU 0x20000000
1674#define MWL8K_CAP_GREENFIELD 0x08000000
1675#define MWL8K_CAP_AMPDU 0x04000000
1676#define MWL8K_CAP_RX_STBC 0x01000000
1677#define MWL8K_CAP_TX_STBC 0x00800000
1678#define MWL8K_CAP_SHORTGI_40MHZ 0x00400000
1679#define MWL8K_CAP_SHORTGI_20MHZ 0x00200000
1680#define MWL8K_CAP_RX_ANTENNA_MASK 0x000e0000
1681#define MWL8K_CAP_TX_ANTENNA_MASK 0x0001c000
1682#define MWL8K_CAP_DELAY_BA 0x00003000
1683#define MWL8K_CAP_MIMO 0x00000200
1684#define MWL8K_CAP_40MHZ 0x00000100
1685#define MWL8K_CAP_BAND_MASK 0x00000007
1686#define MWL8K_CAP_5GHZ 0x00000004
1687#define MWL8K_CAP_2GHZ4 0x00000001
1688
1689static void
1690mwl8k_set_ht_caps(struct ieee80211_hw *hw,
1691 struct ieee80211_supported_band *band, u32 cap)
1692{
1693 int rx_streams;
1694 int tx_streams;
1695
1696 band->ht_cap.ht_supported = 1;
1697
1698 if (cap & MWL8K_CAP_MAX_AMSDU)
1699 band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
1700 if (cap & MWL8K_CAP_GREENFIELD)
1701 band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD;
1702 if (cap & MWL8K_CAP_AMPDU) {
1703 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
1704 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
1705 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1706 }
1707 if (cap & MWL8K_CAP_RX_STBC)
1708 band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC;
1709 if (cap & MWL8K_CAP_TX_STBC)
1710 band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
1711 if (cap & MWL8K_CAP_SHORTGI_40MHZ)
1712 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
1713 if (cap & MWL8K_CAP_SHORTGI_20MHZ)
1714 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
1715 if (cap & MWL8K_CAP_DELAY_BA)
1716 band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA;
1717 if (cap & MWL8K_CAP_40MHZ)
1718 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1719
1720 rx_streams = hweight32(cap & MWL8K_CAP_RX_ANTENNA_MASK);
1721 tx_streams = hweight32(cap & MWL8K_CAP_TX_ANTENNA_MASK);
1722
1723 band->ht_cap.mcs.rx_mask[0] = 0xff;
1724 if (rx_streams >= 2)
1725 band->ht_cap.mcs.rx_mask[1] = 0xff;
1726 if (rx_streams >= 3)
1727 band->ht_cap.mcs.rx_mask[2] = 0xff;
1728 band->ht_cap.mcs.rx_mask[4] = 0x01;
1729 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1730
1731 if (rx_streams != tx_streams) {
1732 band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
1733 band->ht_cap.mcs.tx_params |= (tx_streams - 1) <<
1734 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
1735 }
1736}
1737
1738static void
1739mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps)
1506{ 1740{
1507 struct mwl8k_priv *priv = hw->priv; 1741 struct mwl8k_priv *priv = hw->priv;
1508 struct mwl8k_cmd_get_hw_spec *cmd; 1742
1743 if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
1744 mwl8k_setup_2ghz_band(hw);
1745 if (caps & MWL8K_CAP_MIMO)
1746 mwl8k_set_ht_caps(hw, &priv->band_24, caps);
1747 }
1748
1749 if (caps & MWL8K_CAP_5GHZ) {
1750 mwl8k_setup_5ghz_band(hw);
1751 if (caps & MWL8K_CAP_MIMO)
1752 mwl8k_set_ht_caps(hw, &priv->band_50, caps);
1753 }
1754}
1755
1756static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1757{
1758 struct mwl8k_priv *priv = hw->priv;
1759 struct mwl8k_cmd_get_hw_spec_sta *cmd;
1509 int rc; 1760 int rc;
1510 int i; 1761 int i;
1511 1762
@@ -1518,20 +1769,97 @@ static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
1518 1769
1519 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr)); 1770 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1520 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); 1771 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1521 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma); 1772 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
1522 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 1773 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1523 for (i = 0; i < MWL8K_TX_QUEUES; i++) 1774 for (i = 0; i < MWL8K_TX_QUEUES; i++)
1524 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].tx_desc_dma); 1775 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); 1776 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1526 cmd->total_rx_desc = cpu_to_le32(MWL8K_RX_DESCS); 1777 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
1778
1779 rc = mwl8k_post_cmd(hw, &cmd->header);
1780
1781 if (!rc) {
1782 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
1783 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1784 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1785 priv->hw_rev = cmd->hw_rev;
1786 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
1787 priv->ap_macids_supported = 0x00000000;
1788 priv->sta_macids_supported = 0x00000001;
1789 }
1790
1791 kfree(cmd);
1792 return rc;
1793}
1794
1795/*
1796 * CMD_GET_HW_SPEC (AP version).
1797 */
1798struct mwl8k_cmd_get_hw_spec_ap {
1799 struct mwl8k_cmd_pkt header;
1800 __u8 hw_rev;
1801 __u8 host_interface;
1802 __le16 num_wcb;
1803 __le16 num_mcaddrs;
1804 __u8 perm_addr[ETH_ALEN];
1805 __le16 region_code;
1806 __le16 num_antenna;
1807 __le32 fw_rev;
1808 __le32 wcbbase0;
1809 __le32 rxwrptr;
1810 __le32 rxrdptr;
1811 __le32 ps_cookie;
1812 __le32 wcbbase1;
1813 __le32 wcbbase2;
1814 __le32 wcbbase3;
1815} __attribute__((packed));
1816
1817static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1818{
1819 struct mwl8k_priv *priv = hw->priv;
1820 struct mwl8k_cmd_get_hw_spec_ap *cmd;
1821 int rc;
1822
1823 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1824 if (cmd == NULL)
1825 return -ENOMEM;
1826
1827 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
1828 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1829
1830 memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1831 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1527 1832
1528 rc = mwl8k_post_cmd(hw, &cmd->header); 1833 rc = mwl8k_post_cmd(hw, &cmd->header);
1529 1834
1530 if (!rc) { 1835 if (!rc) {
1836 int off;
1837
1531 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr); 1838 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
1532 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1839 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1533 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1840 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1534 priv->hw_rev = cmd->hw_rev; 1841 priv->hw_rev = cmd->hw_rev;
1842 mwl8k_setup_2ghz_band(hw);
1843 priv->ap_macids_supported = 0x000000ff;
1844 priv->sta_macids_supported = 0x00000000;
1845
1846 off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
1847 iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off);
1848
1849 off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
1850 iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off);
1851
1852 off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
1853 iowrite32(cpu_to_le32(priv->rxq[0].rxd_dma), priv->sram + off);
1854
1855 off = le32_to_cpu(cmd->wcbbase1) & 0xffff;
1856 iowrite32(cpu_to_le32(priv->txq[1].txd_dma), priv->sram + off);
1857
1858 off = le32_to_cpu(cmd->wcbbase2) & 0xffff;
1859 iowrite32(cpu_to_le32(priv->txq[2].txd_dma), priv->sram + off);
1860
1861 off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
1862 iowrite32(cpu_to_le32(priv->txq[3].txd_dma), priv->sram + off);
1535 } 1863 }
1536 1864
1537 kfree(cmd); 1865 kfree(cmd);
@@ -1539,6 +1867,62 @@ static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
1539} 1867}
1540 1868
1541/* 1869/*
1870 * CMD_SET_HW_SPEC.
1871 */
1872struct mwl8k_cmd_set_hw_spec {
1873 struct mwl8k_cmd_pkt header;
1874 __u8 hw_rev;
1875 __u8 host_interface;
1876 __le16 num_mcaddrs;
1877 __u8 perm_addr[ETH_ALEN];
1878 __le16 region_code;
1879 __le32 fw_rev;
1880 __le32 ps_cookie;
1881 __le32 caps;
1882 __le32 rx_queue_ptr;
1883 __le32 num_tx_queues;
1884 __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
1885 __le32 flags;
1886 __le32 num_tx_desc_per_queue;
1887 __le32 total_rxd;
1888} __attribute__((packed));
1889
1890#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
1891#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
1892#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
1893
1894static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
1895{
1896 struct mwl8k_priv *priv = hw->priv;
1897 struct mwl8k_cmd_set_hw_spec *cmd;
1898 int rc;
1899 int i;
1900
1901 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1902 if (cmd == NULL)
1903 return -ENOMEM;
1904
1905 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC);
1906 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1907
1908 cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1909 cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
1910 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1911 for (i = 0; i < MWL8K_TX_QUEUES; i++)
1912 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1913 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
1914 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
1915 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON);
1916 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1917 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
1918
1919 rc = mwl8k_post_cmd(hw, &cmd->header);
1920 kfree(cmd);
1921
1922 return rc;
1923}
1924
1925/*
1542 * CMD_MAC_MULTICAST_ADR. 1926 * CMD_MAC_MULTICAST_ADR.
1543 */ 1927 */
1544struct mwl8k_cmd_mac_multicast_adr { 1928struct mwl8k_cmd_mac_multicast_adr {
@@ -1548,19 +1932,23 @@ struct mwl8k_cmd_mac_multicast_adr {
1548 __u8 addr[0][ETH_ALEN]; 1932 __u8 addr[0][ETH_ALEN];
1549}; 1933};
1550 1934
1551#define MWL8K_ENABLE_RX_MULTICAST 0x000F 1935#define MWL8K_ENABLE_RX_DIRECTED 0x0001
1936#define MWL8K_ENABLE_RX_MULTICAST 0x0002
1937#define MWL8K_ENABLE_RX_ALL_MULTICAST 0x0004
1938#define MWL8K_ENABLE_RX_BROADCAST 0x0008
1552 1939
1553static struct mwl8k_cmd_pkt * 1940static struct mwl8k_cmd_pkt *
1554__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, 1941__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
1555 int mc_count, struct dev_addr_list *mclist) 1942 int mc_count, struct dev_addr_list *mclist)
1556{ 1943{
1557 struct mwl8k_priv *priv = hw->priv; 1944 struct mwl8k_priv *priv = hw->priv;
1558 struct mwl8k_cmd_mac_multicast_adr *cmd; 1945 struct mwl8k_cmd_mac_multicast_adr *cmd;
1559 int size; 1946 int size;
1560 int i;
1561 1947
1562 if (mc_count > priv->num_mcaddrs) 1948 if (allmulti || mc_count > priv->num_mcaddrs) {
1563 mc_count = priv->num_mcaddrs; 1949 allmulti = 1;
1950 mc_count = 0;
1951 }
1564 1952
1565 size = sizeof(*cmd) + mc_count * ETH_ALEN; 1953 size = sizeof(*cmd) + mc_count * ETH_ALEN;
1566 1954
@@ -1570,27 +1958,34 @@ __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
1570 1958
1571 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR); 1959 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
1572 cmd->header.length = cpu_to_le16(size); 1960 cmd->header.length = cpu_to_le16(size);
1573 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); 1961 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_DIRECTED |
1574 cmd->numaddr = cpu_to_le16(mc_count); 1962 MWL8K_ENABLE_RX_BROADCAST);
1575 1963
1576 for (i = 0; i < mc_count && mclist; i++) { 1964 if (allmulti) {
1577 if (mclist->da_addrlen != ETH_ALEN) { 1965 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST);
1578 kfree(cmd); 1966 } else if (mc_count) {
1579 return NULL; 1967 int i;
1968
1969 cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
1970 cmd->numaddr = cpu_to_le16(mc_count);
1971 for (i = 0; i < mc_count && mclist; i++) {
1972 if (mclist->da_addrlen != ETH_ALEN) {
1973 kfree(cmd);
1974 return NULL;
1975 }
1976 memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
1977 mclist = mclist->next;
1580 } 1978 }
1581 memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
1582 mclist = mclist->next;
1583 } 1979 }
1584 1980
1585 return &cmd->header; 1981 return &cmd->header;
1586} 1982}
1587 1983
1588/* 1984/*
1589 * CMD_802_11_GET_STAT. 1985 * CMD_GET_STAT.
1590 */ 1986 */
1591struct mwl8k_cmd_802_11_get_stat { 1987struct mwl8k_cmd_get_stat {
1592 struct mwl8k_cmd_pkt header; 1988 struct mwl8k_cmd_pkt header;
1593 __le16 action;
1594 __le32 stats[64]; 1989 __le32 stats[64];
1595} __attribute__((packed)); 1990} __attribute__((packed));
1596 1991
@@ -1599,10 +1994,10 @@ struct mwl8k_cmd_802_11_get_stat {
1599#define MWL8K_STAT_FCS_ERROR 24 1994#define MWL8K_STAT_FCS_ERROR 24
1600#define MWL8K_STAT_RTS_SUCCESS 11 1995#define MWL8K_STAT_RTS_SUCCESS 11
1601 1996
1602static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw, 1997static int mwl8k_cmd_get_stat(struct ieee80211_hw *hw,
1603 struct ieee80211_low_level_stats *stats) 1998 struct ieee80211_low_level_stats *stats)
1604{ 1999{
1605 struct mwl8k_cmd_802_11_get_stat *cmd; 2000 struct mwl8k_cmd_get_stat *cmd;
1606 int rc; 2001 int rc;
1607 2002
1608 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2003 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -1611,7 +2006,6 @@ static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw,
1611 2006
1612 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT); 2007 cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT);
1613 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2008 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1614 cmd->action = cpu_to_le16(MWL8K_CMD_GET);
1615 2009
1616 rc = mwl8k_post_cmd(hw, &cmd->header); 2010 rc = mwl8k_post_cmd(hw, &cmd->header);
1617 if (!rc) { 2011 if (!rc) {
@@ -1630,9 +2024,9 @@ static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw,
1630} 2024}
1631 2025
1632/* 2026/*
1633 * CMD_802_11_RADIO_CONTROL. 2027 * CMD_RADIO_CONTROL.
1634 */ 2028 */
1635struct mwl8k_cmd_802_11_radio_control { 2029struct mwl8k_cmd_radio_control {
1636 struct mwl8k_cmd_pkt header; 2030 struct mwl8k_cmd_pkt header;
1637 __le16 action; 2031 __le16 action;
1638 __le16 control; 2032 __le16 control;
@@ -1640,10 +2034,10 @@ struct mwl8k_cmd_802_11_radio_control {
1640} __attribute__((packed)); 2034} __attribute__((packed));
1641 2035
1642static int 2036static int
1643mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, bool enable, bool force) 2037mwl8k_cmd_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
1644{ 2038{
1645 struct mwl8k_priv *priv = hw->priv; 2039 struct mwl8k_priv *priv = hw->priv;
1646 struct mwl8k_cmd_802_11_radio_control *cmd; 2040 struct mwl8k_cmd_radio_control *cmd;
1647 int rc; 2041 int rc;
1648 2042
1649 if (enable == priv->radio_on && !force) 2043 if (enable == priv->radio_on && !force)
@@ -1668,36 +2062,32 @@ mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
1668 return rc; 2062 return rc;
1669} 2063}
1670 2064
1671static int mwl8k_cmd_802_11_radio_disable(struct ieee80211_hw *hw) 2065static int mwl8k_cmd_radio_disable(struct ieee80211_hw *hw)
1672{ 2066{
1673 return mwl8k_cmd_802_11_radio_control(hw, 0, 0); 2067 return mwl8k_cmd_radio_control(hw, 0, 0);
1674} 2068}
1675 2069
1676static int mwl8k_cmd_802_11_radio_enable(struct ieee80211_hw *hw) 2070static int mwl8k_cmd_radio_enable(struct ieee80211_hw *hw)
1677{ 2071{
1678 return mwl8k_cmd_802_11_radio_control(hw, 1, 0); 2072 return mwl8k_cmd_radio_control(hw, 1, 0);
1679} 2073}
1680 2074
1681static int 2075static int
1682mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble) 2076mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
1683{ 2077{
1684 struct mwl8k_priv *priv; 2078 struct mwl8k_priv *priv = hw->priv;
1685
1686 if (hw == NULL || hw->priv == NULL)
1687 return -EINVAL;
1688 priv = hw->priv;
1689 2079
1690 priv->radio_short_preamble = short_preamble; 2080 priv->radio_short_preamble = short_preamble;
1691 2081
1692 return mwl8k_cmd_802_11_radio_control(hw, 1, 1); 2082 return mwl8k_cmd_radio_control(hw, 1, 1);
1693} 2083}
1694 2084
1695/* 2085/*
1696 * CMD_802_11_RF_TX_POWER. 2086 * CMD_RF_TX_POWER.
1697 */ 2087 */
1698#define MWL8K_TX_POWER_LEVEL_TOTAL 8 2088#define MWL8K_TX_POWER_LEVEL_TOTAL 8
1699 2089
1700struct mwl8k_cmd_802_11_rf_tx_power { 2090struct mwl8k_cmd_rf_tx_power {
1701 struct mwl8k_cmd_pkt header; 2091 struct mwl8k_cmd_pkt header;
1702 __le16 action; 2092 __le16 action;
1703 __le16 support_level; 2093 __le16 support_level;
@@ -1706,9 +2096,9 @@ struct mwl8k_cmd_802_11_rf_tx_power {
1706 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; 2096 __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
1707} __attribute__((packed)); 2097} __attribute__((packed));
1708 2098
1709static int mwl8k_cmd_802_11_rf_tx_power(struct ieee80211_hw *hw, int dBm) 2099static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
1710{ 2100{
1711 struct mwl8k_cmd_802_11_rf_tx_power *cmd; 2101 struct mwl8k_cmd_rf_tx_power *cmd;
1712 int rc; 2102 int rc;
1713 2103
1714 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2104 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -1727,6 +2117,69 @@ static int mwl8k_cmd_802_11_rf_tx_power(struct ieee80211_hw *hw, int dBm)
1727} 2117}
1728 2118
1729/* 2119/*
2120 * CMD_RF_ANTENNA.
2121 */
2122struct mwl8k_cmd_rf_antenna {
2123 struct mwl8k_cmd_pkt header;
2124 __le16 antenna;
2125 __le16 mode;
2126} __attribute__((packed));
2127
2128#define MWL8K_RF_ANTENNA_RX 1
2129#define MWL8K_RF_ANTENNA_TX 2
2130
2131static int
2132mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask)
2133{
2134 struct mwl8k_cmd_rf_antenna *cmd;
2135 int rc;
2136
2137 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2138 if (cmd == NULL)
2139 return -ENOMEM;
2140
2141 cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_ANTENNA);
2142 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2143 cmd->antenna = cpu_to_le16(antenna);
2144 cmd->mode = cpu_to_le16(mask);
2145
2146 rc = mwl8k_post_cmd(hw, &cmd->header);
2147 kfree(cmd);
2148
2149 return rc;
2150}
2151
2152/*
2153 * CMD_SET_BEACON.
2154 */
2155struct mwl8k_cmd_set_beacon {
2156 struct mwl8k_cmd_pkt header;
2157 __le16 beacon_len;
2158 __u8 beacon[0];
2159};
2160
2161static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw,
2162 struct ieee80211_vif *vif, u8 *beacon, int len)
2163{
2164 struct mwl8k_cmd_set_beacon *cmd;
2165 int rc;
2166
2167 cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL);
2168 if (cmd == NULL)
2169 return -ENOMEM;
2170
2171 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON);
2172 cmd->header.length = cpu_to_le16(sizeof(*cmd) + len);
2173 cmd->beacon_len = cpu_to_le16(len);
2174 memcpy(cmd->beacon, beacon, len);
2175
2176 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2177 kfree(cmd);
2178
2179 return rc;
2180}
2181
2182/*
1730 * CMD_SET_PRE_SCAN. 2183 * CMD_SET_PRE_SCAN.
1731 */ 2184 */
1732struct mwl8k_cmd_set_pre_scan { 2185struct mwl8k_cmd_set_pre_scan {
@@ -1761,7 +2214,7 @@ struct mwl8k_cmd_set_post_scan {
1761} __attribute__((packed)); 2214} __attribute__((packed));
1762 2215
1763static int 2216static int
1764mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 *mac) 2217mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac)
1765{ 2218{
1766 struct mwl8k_cmd_set_post_scan *cmd; 2219 struct mwl8k_cmd_set_post_scan *cmd;
1767 int rc; 2220 int rc;
@@ -1792,8 +2245,9 @@ struct mwl8k_cmd_set_rf_channel {
1792} __attribute__((packed)); 2245} __attribute__((packed));
1793 2246
1794static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, 2247static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
1795 struct ieee80211_channel *channel) 2248 struct ieee80211_conf *conf)
1796{ 2249{
2250 struct ieee80211_channel *channel = conf->channel;
1797 struct mwl8k_cmd_set_rf_channel *cmd; 2251 struct mwl8k_cmd_set_rf_channel *cmd;
1798 int rc; 2252 int rc;
1799 2253
@@ -1805,10 +2259,19 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
1805 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2259 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1806 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2260 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1807 cmd->current_channel = channel->hw_value; 2261 cmd->current_channel = channel->hw_value;
2262
1808 if (channel->band == IEEE80211_BAND_2GHZ) 2263 if (channel->band == IEEE80211_BAND_2GHZ)
1809 cmd->channel_flags = cpu_to_le32(0x00000081); 2264 cmd->channel_flags |= cpu_to_le32(0x00000001);
1810 else 2265 else if (channel->band == IEEE80211_BAND_5GHZ)
1811 cmd->channel_flags = cpu_to_le32(0x00000000); 2266 cmd->channel_flags |= cpu_to_le32(0x00000004);
2267
2268 if (conf->channel_type == NL80211_CHAN_NO_HT ||
2269 conf->channel_type == NL80211_CHAN_HT20)
2270 cmd->channel_flags |= cpu_to_le32(0x00000080);
2271 else if (conf->channel_type == NL80211_CHAN_HT40MINUS)
2272 cmd->channel_flags |= cpu_to_le32(0x000001900);
2273 else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
2274 cmd->channel_flags |= cpu_to_le32(0x000000900);
1812 2275
1813 rc = mwl8k_post_cmd(hw, &cmd->header); 2276 rc = mwl8k_post_cmd(hw, &cmd->header);
1814 kfree(cmd); 2277 kfree(cmd);
@@ -1817,58 +2280,75 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
1817} 2280}
1818 2281
1819/* 2282/*
1820 * CMD_SET_SLOT. 2283 * CMD_SET_AID.
1821 */ 2284 */
1822struct mwl8k_cmd_set_slot { 2285#define MWL8K_FRAME_PROT_DISABLED 0x00
1823 struct mwl8k_cmd_pkt header; 2286#define MWL8K_FRAME_PROT_11G 0x07
1824 __le16 action; 2287#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02
1825 __u8 short_slot; 2288#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06
1826} __attribute__((packed));
1827 2289
1828static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time) 2290struct mwl8k_cmd_update_set_aid {
1829{ 2291 struct mwl8k_cmd_pkt header;
1830 struct mwl8k_cmd_set_slot *cmd; 2292 __le16 aid;
1831 int rc;
1832 2293
1833 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2294 /* AP's MAC address (BSSID) */
1834 if (cmd == NULL) 2295 __u8 bssid[ETH_ALEN];
1835 return -ENOMEM; 2296 __le16 protection_mode;
2297 __u8 supp_rates[14];
2298} __attribute__((packed));
1836 2299
1837 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT); 2300static void legacy_rate_mask_to_array(u8 *rates, u32 mask)
1838 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2301{
1839 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2302 int i;
1840 cmd->short_slot = short_slot_time; 2303 int j;
1841 2304
1842 rc = mwl8k_post_cmd(hw, &cmd->header); 2305 /*
1843 kfree(cmd); 2306 * Clear nonstandard rates 4 and 13.
2307 */
2308 mask &= 0x1fef;
1844 2309
1845 return rc; 2310 for (i = 0, j = 0; i < 14; i++) {
2311 if (mask & (1 << i))
2312 rates[j++] = mwl8k_rates_24[i].hw_value;
2313 }
1846} 2314}
1847 2315
1848/* 2316static int
1849 * CMD_MIMO_CONFIG. 2317mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
1850 */ 2318 struct ieee80211_vif *vif, u32 legacy_rate_mask)
1851struct mwl8k_cmd_mimo_config {
1852 struct mwl8k_cmd_pkt header;
1853 __le32 action;
1854 __u8 rx_antenna_map;
1855 __u8 tx_antenna_map;
1856} __attribute__((packed));
1857
1858static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
1859{ 2319{
1860 struct mwl8k_cmd_mimo_config *cmd; 2320 struct mwl8k_cmd_update_set_aid *cmd;
2321 u16 prot_mode;
1861 int rc; 2322 int rc;
1862 2323
1863 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2324 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1864 if (cmd == NULL) 2325 if (cmd == NULL)
1865 return -ENOMEM; 2326 return -ENOMEM;
1866 2327
1867 cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG); 2328 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
1868 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2329 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1869 cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET); 2330 cmd->aid = cpu_to_le16(vif->bss_conf.aid);
1870 cmd->rx_antenna_map = rx; 2331 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
1871 cmd->tx_antenna_map = tx; 2332
2333 if (vif->bss_conf.use_cts_prot) {
2334 prot_mode = MWL8K_FRAME_PROT_11G;
2335 } else {
2336 switch (vif->bss_conf.ht_operation_mode &
2337 IEEE80211_HT_OP_MODE_PROTECTION) {
2338 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
2339 prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
2340 break;
2341 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
2342 prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
2343 break;
2344 default:
2345 prot_mode = MWL8K_FRAME_PROT_DISABLED;
2346 break;
2347 }
2348 }
2349 cmd->protection_mode = cpu_to_le16(prot_mode);
2350
2351 legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask);
1872 2352
1873 rc = mwl8k_post_cmd(hw, &cmd->header); 2353 rc = mwl8k_post_cmd(hw, &cmd->header);
1874 kfree(cmd); 2354 kfree(cmd);
@@ -1877,25 +2357,32 @@ static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
1877} 2357}
1878 2358
1879/* 2359/*
1880 * CMD_ENABLE_SNIFFER. 2360 * CMD_SET_RATE.
1881 */ 2361 */
1882struct mwl8k_cmd_enable_sniffer { 2362struct mwl8k_cmd_set_rate {
1883 struct mwl8k_cmd_pkt header; 2363 struct mwl8k_cmd_pkt header;
1884 __le32 action; 2364 __u8 legacy_rates[14];
2365
2366 /* Bitmap for supported MCS codes. */
2367 __u8 mcs_set[16];
2368 __u8 reserved[16];
1885} __attribute__((packed)); 2369} __attribute__((packed));
1886 2370
1887static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable) 2371static int
2372mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2373 u32 legacy_rate_mask, u8 *mcs_rates)
1888{ 2374{
1889 struct mwl8k_cmd_enable_sniffer *cmd; 2375 struct mwl8k_cmd_set_rate *cmd;
1890 int rc; 2376 int rc;
1891 2377
1892 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2378 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1893 if (cmd == NULL) 2379 if (cmd == NULL)
1894 return -ENOMEM; 2380 return -ENOMEM;
1895 2381
1896 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER); 2382 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
1897 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2383 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1898 cmd->action = cpu_to_le32(!!enable); 2384 legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask);
2385 memcpy(cmd->mcs_set, mcs_rates, 16);
1899 2386
1900 rc = mwl8k_post_cmd(hw, &cmd->header); 2387 rc = mwl8k_post_cmd(hw, &cmd->header);
1901 kfree(cmd); 2388 kfree(cmd);
@@ -1904,27 +2391,39 @@ static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
1904} 2391}
1905 2392
1906/* 2393/*
1907 * CMD_SET_RATEADAPT_MODE. 2394 * CMD_FINALIZE_JOIN.
1908 */ 2395 */
1909struct mwl8k_cmd_set_rate_adapt_mode { 2396#define MWL8K_FJ_BEACON_MAXLEN 128
2397
2398struct mwl8k_cmd_finalize_join {
1910 struct mwl8k_cmd_pkt header; 2399 struct mwl8k_cmd_pkt header;
1911 __le16 action; 2400 __le32 sleep_interval; /* Number of beacon periods to sleep */
1912 __le16 mode; 2401 __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
1913} __attribute__((packed)); 2402} __attribute__((packed));
1914 2403
1915static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode) 2404static int mwl8k_cmd_finalize_join(struct ieee80211_hw *hw, void *frame,
2405 int framelen, int dtim)
1916{ 2406{
1917 struct mwl8k_cmd_set_rate_adapt_mode *cmd; 2407 struct mwl8k_cmd_finalize_join *cmd;
2408 struct ieee80211_mgmt *payload = frame;
2409 int payload_len;
1918 int rc; 2410 int rc;
1919 2411
1920 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2412 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1921 if (cmd == NULL) 2413 if (cmd == NULL)
1922 return -ENOMEM; 2414 return -ENOMEM;
1923 2415
1924 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE); 2416 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
1925 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2417 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1926 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2418 cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
1927 cmd->mode = cpu_to_le16(mode); 2419
2420 payload_len = framelen - ieee80211_hdrlen(payload->frame_control);
2421 if (payload_len < 0)
2422 payload_len = 0;
2423 else if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2424 payload_len = MWL8K_FJ_BEACON_MAXLEN;
2425
2426 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
1928 2427
1929 rc = mwl8k_post_cmd(hw, &cmd->header); 2428 rc = mwl8k_post_cmd(hw, &cmd->header);
1930 kfree(cmd); 2429 kfree(cmd);
@@ -1933,59 +2432,57 @@ static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode)
1933} 2432}
1934 2433
1935/* 2434/*
1936 * CMD_SET_WMM_MODE. 2435 * CMD_SET_RTS_THRESHOLD.
1937 */ 2436 */
1938struct mwl8k_cmd_set_wmm { 2437struct mwl8k_cmd_set_rts_threshold {
1939 struct mwl8k_cmd_pkt header; 2438 struct mwl8k_cmd_pkt header;
1940 __le16 action; 2439 __le16 action;
2440 __le16 threshold;
1941} __attribute__((packed)); 2441} __attribute__((packed));
1942 2442
1943static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable) 2443static int
2444mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh)
1944{ 2445{
1945 struct mwl8k_priv *priv = hw->priv; 2446 struct mwl8k_cmd_set_rts_threshold *cmd;
1946 struct mwl8k_cmd_set_wmm *cmd;
1947 int rc; 2447 int rc;
1948 2448
1949 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2449 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1950 if (cmd == NULL) 2450 if (cmd == NULL)
1951 return -ENOMEM; 2451 return -ENOMEM;
1952 2452
1953 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE); 2453 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
1954 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2454 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1955 cmd->action = cpu_to_le16(!!enable); 2455 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2456 cmd->threshold = cpu_to_le16(rts_thresh);
1956 2457
1957 rc = mwl8k_post_cmd(hw, &cmd->header); 2458 rc = mwl8k_post_cmd(hw, &cmd->header);
1958 kfree(cmd); 2459 kfree(cmd);
1959 2460
1960 if (!rc)
1961 priv->wmm_enabled = enable;
1962
1963 return rc; 2461 return rc;
1964} 2462}
1965 2463
1966/* 2464/*
1967 * CMD_SET_RTS_THRESHOLD. 2465 * CMD_SET_SLOT.
1968 */ 2466 */
1969struct mwl8k_cmd_rts_threshold { 2467struct mwl8k_cmd_set_slot {
1970 struct mwl8k_cmd_pkt header; 2468 struct mwl8k_cmd_pkt header;
1971 __le16 action; 2469 __le16 action;
1972 __le16 threshold; 2470 __u8 short_slot;
1973} __attribute__((packed)); 2471} __attribute__((packed));
1974 2472
1975static int mwl8k_rts_threshold(struct ieee80211_hw *hw, 2473static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
1976 u16 action, u16 threshold)
1977{ 2474{
1978 struct mwl8k_cmd_rts_threshold *cmd; 2475 struct mwl8k_cmd_set_slot *cmd;
1979 int rc; 2476 int rc;
1980 2477
1981 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2478 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1982 if (cmd == NULL) 2479 if (cmd == NULL)
1983 return -ENOMEM; 2480 return -ENOMEM;
1984 2481
1985 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD); 2482 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
1986 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2483 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1987 cmd->action = cpu_to_le16(action); 2484 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1988 cmd->threshold = cpu_to_le16(threshold); 2485 cmd->short_slot = short_slot_time;
1989 2486
1990 rc = mwl8k_post_cmd(hw, &cmd->header); 2487 rc = mwl8k_post_cmd(hw, &cmd->header);
1991 kfree(cmd); 2488 kfree(cmd);
@@ -2005,17 +2502,34 @@ struct mwl8k_cmd_set_edca_params {
2005 /* TX opportunity in units of 32 us */ 2502 /* TX opportunity in units of 32 us */
2006 __le16 txop; 2503 __le16 txop;
2007 2504
2008 /* Log exponent of max contention period: 0...15*/ 2505 union {
2009 __u8 log_cw_max; 2506 struct {
2507 /* Log exponent of max contention period: 0...15 */
2508 __le32 log_cw_max;
2010 2509
2011 /* Log exponent of min contention period: 0...15 */ 2510 /* Log exponent of min contention period: 0...15 */
2012 __u8 log_cw_min; 2511 __le32 log_cw_min;
2013 2512
2014 /* Adaptive interframe spacing in units of 32us */ 2513 /* Adaptive interframe spacing in units of 32us */
2015 __u8 aifs; 2514 __u8 aifs;
2016 2515
2017 /* TX queue to configure */ 2516 /* TX queue to configure */
2018 __u8 txq; 2517 __u8 txq;
2518 } ap;
2519 struct {
2520 /* Log exponent of max contention period: 0...15 */
2521 __u8 log_cw_max;
2522
2523 /* Log exponent of min contention period: 0...15 */
2524 __u8 log_cw_min;
2525
2526 /* Adaptive interframe spacing in units of 32us */
2527 __u8 aifs;
2528
2529 /* TX queue to configure */
2530 __u8 txq;
2531 } sta;
2532 };
2019} __attribute__((packed)); 2533} __attribute__((packed));
2020 2534
2021#define MWL8K_SET_EDCA_CW 0x01 2535#define MWL8K_SET_EDCA_CW 0x01
@@ -2027,10 +2541,11 @@ struct mwl8k_cmd_set_edca_params {
2027 MWL8K_SET_EDCA_AIFS) 2541 MWL8K_SET_EDCA_AIFS)
2028 2542
2029static int 2543static int
2030mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum, 2544mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2031 __u16 cw_min, __u16 cw_max, 2545 __u16 cw_min, __u16 cw_max,
2032 __u8 aifs, __u16 txop) 2546 __u8 aifs, __u16 txop)
2033{ 2547{
2548 struct mwl8k_priv *priv = hw->priv;
2034 struct mwl8k_cmd_set_edca_params *cmd; 2549 struct mwl8k_cmd_set_edca_params *cmd;
2035 int rc; 2550 int rc;
2036 2551
@@ -2042,10 +2557,17 @@ mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2042 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2557 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2043 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL); 2558 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
2044 cmd->txop = cpu_to_le16(txop); 2559 cmd->txop = cpu_to_le16(txop);
2045 cmd->log_cw_max = (u8)ilog2(cw_max + 1); 2560 if (priv->ap_fw) {
2046 cmd->log_cw_min = (u8)ilog2(cw_min + 1); 2561 cmd->ap.log_cw_max = cpu_to_le32(ilog2(cw_max + 1));
2047 cmd->aifs = aifs; 2562 cmd->ap.log_cw_min = cpu_to_le32(ilog2(cw_min + 1));
2048 cmd->txq = qnum; 2563 cmd->ap.aifs = aifs;
2564 cmd->ap.txq = qnum;
2565 } else {
2566 cmd->sta.log_cw_max = (u8)ilog2(cw_max + 1);
2567 cmd->sta.log_cw_min = (u8)ilog2(cw_min + 1);
2568 cmd->sta.aifs = aifs;
2569 cmd->sta.txq = qnum;
2570 }
2049 2571
2050 rc = mwl8k_post_cmd(hw, &cmd->header); 2572 rc = mwl8k_post_cmd(hw, &cmd->header);
2051 kfree(cmd); 2573 kfree(cmd);
@@ -2054,313 +2576,516 @@ mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2054} 2576}
2055 2577
2056/* 2578/*
2057 * CMD_FINALIZE_JOIN. 2579 * CMD_SET_WMM_MODE.
2058 */ 2580 */
2059 2581struct mwl8k_cmd_set_wmm_mode {
2060/* FJ beacon buffer size is compiled into the firmware. */
2061#define MWL8K_FJ_BEACON_MAXLEN 128
2062
2063struct mwl8k_cmd_finalize_join {
2064 struct mwl8k_cmd_pkt header; 2582 struct mwl8k_cmd_pkt header;
2065 __le32 sleep_interval; /* Number of beacon periods to sleep */ 2583 __le16 action;
2066 __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
2067} __attribute__((packed)); 2584} __attribute__((packed));
2068 2585
2069static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame, 2586static int mwl8k_cmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable)
2070 __u16 framelen, __u16 dtim)
2071{ 2587{
2072 struct mwl8k_cmd_finalize_join *cmd; 2588 struct mwl8k_priv *priv = hw->priv;
2073 struct ieee80211_mgmt *payload = frame; 2589 struct mwl8k_cmd_set_wmm_mode *cmd;
2074 u16 hdrlen;
2075 u32 payload_len;
2076 int rc; 2590 int rc;
2077 2591
2078 if (frame == NULL)
2079 return -EINVAL;
2080
2081 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2592 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2082 if (cmd == NULL) 2593 if (cmd == NULL)
2083 return -ENOMEM; 2594 return -ENOMEM;
2084 2595
2085 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN); 2596 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
2086 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2597 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2087 cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1); 2598 cmd->action = cpu_to_le16(!!enable);
2088 2599
2089 hdrlen = ieee80211_hdrlen(payload->frame_control); 2600 rc = mwl8k_post_cmd(hw, &cmd->header);
2601 kfree(cmd);
2090 2602
2091 payload_len = framelen > hdrlen ? framelen - hdrlen : 0; 2603 if (!rc)
2604 priv->wmm_enabled = enable;
2092 2605
2093 /* XXX TBD Might just have to abort and return an error */ 2606 return rc;
2094 if (payload_len > MWL8K_FJ_BEACON_MAXLEN) 2607}
2095 printk(KERN_ERR "%s(): WARNING: Incomplete beacon "
2096 "sent to firmware. Sz=%u MAX=%u\n", __func__,
2097 payload_len, MWL8K_FJ_BEACON_MAXLEN);
2098 2608
2099 if (payload_len > MWL8K_FJ_BEACON_MAXLEN) 2609/*
2100 payload_len = MWL8K_FJ_BEACON_MAXLEN; 2610 * CMD_MIMO_CONFIG.
2611 */
2612struct mwl8k_cmd_mimo_config {
2613 struct mwl8k_cmd_pkt header;
2614 __le32 action;
2615 __u8 rx_antenna_map;
2616 __u8 tx_antenna_map;
2617} __attribute__((packed));
2618
2619static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
2620{
2621 struct mwl8k_cmd_mimo_config *cmd;
2622 int rc;
2101 2623
2102 if (payload && payload_len) 2624 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2103 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len); 2625 if (cmd == NULL)
2626 return -ENOMEM;
2627
2628 cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
2629 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2630 cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
2631 cmd->rx_antenna_map = rx;
2632 cmd->tx_antenna_map = tx;
2104 2633
2105 rc = mwl8k_post_cmd(hw, &cmd->header); 2634 rc = mwl8k_post_cmd(hw, &cmd->header);
2106 kfree(cmd); 2635 kfree(cmd);
2636
2107 return rc; 2637 return rc;
2108} 2638}
2109 2639
2110/* 2640/*
2111 * CMD_UPDATE_STADB. 2641 * CMD_USE_FIXED_RATE (STA version).
2112 */ 2642 */
2113struct mwl8k_cmd_update_sta_db { 2643struct mwl8k_cmd_use_fixed_rate_sta {
2114 struct mwl8k_cmd_pkt header; 2644 struct mwl8k_cmd_pkt header;
2645 __le32 action;
2646 __le32 allow_rate_drop;
2647 __le32 num_rates;
2648 struct {
2649 __le32 is_ht_rate;
2650 __le32 enable_retry;
2651 __le32 rate;
2652 __le32 retry_count;
2653 } rate_entry[8];
2654 __le32 rate_type;
2655 __le32 reserved1;
2656 __le32 reserved2;
2657} __attribute__((packed));
2115 2658
2116 /* See STADB_ACTION_TYPE */ 2659#define MWL8K_USE_AUTO_RATE 0x0002
2117 __le32 action; 2660#define MWL8K_UCAST_RATE 0
2118 2661
2119 /* Peer MAC address */ 2662static int mwl8k_cmd_use_fixed_rate_sta(struct ieee80211_hw *hw)
2120 __u8 peer_addr[ETH_ALEN]; 2663{
2664 struct mwl8k_cmd_use_fixed_rate_sta *cmd;
2665 int rc;
2121 2666
2122 __le32 reserved; 2667 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2668 if (cmd == NULL)
2669 return -ENOMEM;
2123 2670
2124 /* Peer info - valid during add/update. */ 2671 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2125 struct peer_capability_info peer_info; 2672 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2673 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
2674 cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE);
2675
2676 rc = mwl8k_post_cmd(hw, &cmd->header);
2677 kfree(cmd);
2678
2679 return rc;
2680}
2681
2682/*
2683 * CMD_USE_FIXED_RATE (AP version).
2684 */
2685struct mwl8k_cmd_use_fixed_rate_ap {
2686 struct mwl8k_cmd_pkt header;
2687 __le32 action;
2688 __le32 allow_rate_drop;
2689 __le32 num_rates;
2690 struct mwl8k_rate_entry_ap {
2691 __le32 is_ht_rate;
2692 __le32 enable_retry;
2693 __le32 rate;
2694 __le32 retry_count;
2695 } rate_entry[4];
2696 u8 multicast_rate;
2697 u8 multicast_rate_type;
2698 u8 management_rate;
2126} __attribute__((packed)); 2699} __attribute__((packed));
2127 2700
2128static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw, 2701static int
2129 struct ieee80211_vif *vif, __u32 action) 2702mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt)
2130{ 2703{
2131 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif); 2704 struct mwl8k_cmd_use_fixed_rate_ap *cmd;
2132 struct ieee80211_bss_conf *info = &mv_vif->bss_info;
2133 struct mwl8k_cmd_update_sta_db *cmd;
2134 struct peer_capability_info *peer_info;
2135 struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
2136 int rc; 2705 int rc;
2137 __u8 count, *rates;
2138 2706
2139 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2707 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2140 if (cmd == NULL) 2708 if (cmd == NULL)
2141 return -ENOMEM; 2709 return -ENOMEM;
2142 2710
2143 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); 2711 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2144 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2712 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2713 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
2714 cmd->multicast_rate = mcast;
2715 cmd->management_rate = mgmt;
2145 2716
2146 cmd->action = cpu_to_le32(action); 2717 rc = mwl8k_post_cmd(hw, &cmd->header);
2147 peer_info = &cmd->peer_info; 2718 kfree(cmd);
2148 memcpy(cmd->peer_addr, mv_vif->bssid, ETH_ALEN);
2149 2719
2150 switch (action) { 2720 return rc;
2151 case MWL8K_STA_DB_ADD_ENTRY: 2721}
2152 case MWL8K_STA_DB_MODIFY_ENTRY:
2153 /* Build peer_info block */
2154 peer_info->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
2155 peer_info->basic_caps = cpu_to_le16(info->assoc_capability);
2156 peer_info->interop = 1;
2157 peer_info->amsdu_enabled = 0;
2158
2159 rates = peer_info->legacy_rates;
2160 for (count = 0; count < mv_vif->legacy_nrates; count++)
2161 rates[count] = bitrates[count].hw_value;
2162
2163 rc = mwl8k_post_cmd(hw, &cmd->header);
2164 if (rc == 0)
2165 mv_vif->peer_id = peer_info->station_id;
2166 2722
2167 break; 2723/*
2724 * CMD_ENABLE_SNIFFER.
2725 */
2726struct mwl8k_cmd_enable_sniffer {
2727 struct mwl8k_cmd_pkt header;
2728 __le32 action;
2729} __attribute__((packed));
2168 2730
2169 case MWL8K_STA_DB_DEL_ENTRY: 2731static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable)
2170 case MWL8K_STA_DB_FLUSH: 2732{
2171 default: 2733 struct mwl8k_cmd_enable_sniffer *cmd;
2172 rc = mwl8k_post_cmd(hw, &cmd->header); 2734 int rc;
2173 if (rc == 0) 2735
2174 mv_vif->peer_id = 0; 2736 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2175 break; 2737 if (cmd == NULL)
2176 } 2738 return -ENOMEM;
2739
2740 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
2741 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2742 cmd->action = cpu_to_le32(!!enable);
2743
2744 rc = mwl8k_post_cmd(hw, &cmd->header);
2177 kfree(cmd); 2745 kfree(cmd);
2178 2746
2179 return rc; 2747 return rc;
2180} 2748}
2181 2749
2182/* 2750/*
2183 * CMD_SET_AID. 2751 * CMD_SET_MAC_ADDR.
2184 */ 2752 */
2185#define MWL8K_RATE_INDEX_MAX_ARRAY 14 2753struct mwl8k_cmd_set_mac_addr {
2754 struct mwl8k_cmd_pkt header;
2755 union {
2756 struct {
2757 __le16 mac_type;
2758 __u8 mac_addr[ETH_ALEN];
2759 } mbss;
2760 __u8 mac_addr[ETH_ALEN];
2761 };
2762} __attribute__((packed));
2186 2763
2187#define MWL8K_FRAME_PROT_DISABLED 0x00 2764#define MWL8K_MAC_TYPE_PRIMARY_CLIENT 0
2188#define MWL8K_FRAME_PROT_11G 0x07 2765#define MWL8K_MAC_TYPE_SECONDARY_CLIENT 1
2189#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02 2766#define MWL8K_MAC_TYPE_PRIMARY_AP 2
2190#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06 2767#define MWL8K_MAC_TYPE_SECONDARY_AP 3
2191 2768
2192struct mwl8k_cmd_update_set_aid { 2769static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
2193 struct mwl8k_cmd_pkt header; 2770 struct ieee80211_vif *vif, u8 *mac)
2194 __le16 aid; 2771{
2772 struct mwl8k_priv *priv = hw->priv;
2773 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
2774 struct mwl8k_cmd_set_mac_addr *cmd;
2775 int mac_type;
2776 int rc;
2195 2777
2196 /* AP's MAC address (BSSID) */ 2778 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
2197 __u8 bssid[ETH_ALEN]; 2779 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) {
2198 __le16 protection_mode; 2780 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported))
2199 __u8 supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY]; 2781 mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT;
2782 else
2783 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
2784 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) {
2785 if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported))
2786 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
2787 else
2788 mac_type = MWL8K_MAC_TYPE_SECONDARY_AP;
2789 }
2790
2791 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2792 if (cmd == NULL)
2793 return -ENOMEM;
2794
2795 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
2796 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2797 if (priv->ap_fw) {
2798 cmd->mbss.mac_type = cpu_to_le16(mac_type);
2799 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
2800 } else {
2801 memcpy(cmd->mac_addr, mac, ETH_ALEN);
2802 }
2803
2804 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2805 kfree(cmd);
2806
2807 return rc;
2808}
2809
2810/*
2811 * CMD_SET_RATEADAPT_MODE.
2812 */
2813struct mwl8k_cmd_set_rate_adapt_mode {
2814 struct mwl8k_cmd_pkt header;
2815 __le16 action;
2816 __le16 mode;
2200} __attribute__((packed)); 2817} __attribute__((packed));
2201 2818
2202static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw, 2819static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode)
2203 struct ieee80211_vif *vif)
2204{ 2820{
2205 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif); 2821 struct mwl8k_cmd_set_rate_adapt_mode *cmd;
2206 struct ieee80211_bss_conf *info = &mv_vif->bss_info;
2207 struct mwl8k_cmd_update_set_aid *cmd;
2208 struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
2209 int count;
2210 u16 prot_mode;
2211 int rc; 2822 int rc;
2212 2823
2213 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2824 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2214 if (cmd == NULL) 2825 if (cmd == NULL)
2215 return -ENOMEM; 2826 return -ENOMEM;
2216 2827
2217 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID); 2828 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE);
2218 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2829 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2219 cmd->aid = cpu_to_le16(info->aid); 2830 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2831 cmd->mode = cpu_to_le16(mode);
2220 2832
2221 memcpy(cmd->bssid, mv_vif->bssid, ETH_ALEN); 2833 rc = mwl8k_post_cmd(hw, &cmd->header);
2834 kfree(cmd);
2222 2835
2223 if (info->use_cts_prot) { 2836 return rc;
2224 prot_mode = MWL8K_FRAME_PROT_11G; 2837}
2225 } else {
2226 switch (info->ht_operation_mode &
2227 IEEE80211_HT_OP_MODE_PROTECTION) {
2228 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
2229 prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
2230 break;
2231 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
2232 prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
2233 break;
2234 default:
2235 prot_mode = MWL8K_FRAME_PROT_DISABLED;
2236 break;
2237 }
2238 }
2239 cmd->protection_mode = cpu_to_le16(prot_mode);
2240 2838
2241 for (count = 0; count < mv_vif->legacy_nrates; count++) 2839/*
2242 cmd->supp_rates[count] = bitrates[count].hw_value; 2840 * CMD_BSS_START.
2841 */
2842struct mwl8k_cmd_bss_start {
2843 struct mwl8k_cmd_pkt header;
2844 __le32 enable;
2845} __attribute__((packed));
2243 2846
2244 rc = mwl8k_post_cmd(hw, &cmd->header); 2847static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
2848 struct ieee80211_vif *vif, int enable)
2849{
2850 struct mwl8k_cmd_bss_start *cmd;
2851 int rc;
2852
2853 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2854 if (cmd == NULL)
2855 return -ENOMEM;
2856
2857 cmd->header.code = cpu_to_le16(MWL8K_CMD_BSS_START);
2858 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2859 cmd->enable = cpu_to_le32(enable);
2860
2861 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2245 kfree(cmd); 2862 kfree(cmd);
2246 2863
2247 return rc; 2864 return rc;
2248} 2865}
2249 2866
2250/* 2867/*
2251 * CMD_SET_RATE. 2868 * CMD_SET_NEW_STN.
2252 */ 2869 */
2253struct mwl8k_cmd_update_rateset { 2870struct mwl8k_cmd_set_new_stn {
2254 struct mwl8k_cmd_pkt header; 2871 struct mwl8k_cmd_pkt header;
2255 __u8 legacy_rates[MWL8K_RATE_INDEX_MAX_ARRAY]; 2872 __le16 aid;
2256 2873 __u8 mac_addr[6];
2257 /* Bitmap for supported MCS codes. */ 2874 __le16 stn_id;
2258 __u8 mcs_set[MWL8K_IEEE_LEGACY_DATA_RATES]; 2875 __le16 action;
2259 __u8 reserved[MWL8K_IEEE_LEGACY_DATA_RATES]; 2876 __le16 rsvd;
2877 __le32 legacy_rates;
2878 __u8 ht_rates[4];
2879 __le16 cap_info;
2880 __le16 ht_capabilities_info;
2881 __u8 mac_ht_param_info;
2882 __u8 rev;
2883 __u8 control_channel;
2884 __u8 add_channel;
2885 __le16 op_mode;
2886 __le16 stbc;
2887 __u8 add_qos_info;
2888 __u8 is_qos_sta;
2889 __le32 fw_sta_ptr;
2260} __attribute__((packed)); 2890} __attribute__((packed));
2261 2891
2262static int mwl8k_update_rateset(struct ieee80211_hw *hw, 2892#define MWL8K_STA_ACTION_ADD 0
2263 struct ieee80211_vif *vif) 2893#define MWL8K_STA_ACTION_REMOVE 2
2894
2895static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
2896 struct ieee80211_vif *vif,
2897 struct ieee80211_sta *sta)
2264{ 2898{
2265 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif); 2899 struct mwl8k_cmd_set_new_stn *cmd;
2266 struct mwl8k_cmd_update_rateset *cmd; 2900 u32 rates;
2267 struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
2268 int count;
2269 int rc; 2901 int rc;
2270 2902
2271 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2903 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2272 if (cmd == NULL) 2904 if (cmd == NULL)
2273 return -ENOMEM; 2905 return -ENOMEM;
2274 2906
2275 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE); 2907 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2908 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2909 cmd->aid = cpu_to_le16(sta->aid);
2910 memcpy(cmd->mac_addr, sta->addr, ETH_ALEN);
2911 cmd->stn_id = cpu_to_le16(sta->aid);
2912 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
2913 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
2914 rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
2915 else
2916 rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
2917 cmd->legacy_rates = cpu_to_le32(rates);
2918 if (sta->ht_cap.ht_supported) {
2919 cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0];
2920 cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1];
2921 cmd->ht_rates[2] = sta->ht_cap.mcs.rx_mask[2];
2922 cmd->ht_rates[3] = sta->ht_cap.mcs.rx_mask[3];
2923 cmd->ht_capabilities_info = cpu_to_le16(sta->ht_cap.cap);
2924 cmd->mac_ht_param_info = (sta->ht_cap.ampdu_factor & 3) |
2925 ((sta->ht_cap.ampdu_density & 7) << 2);
2926 cmd->is_qos_sta = 1;
2927 }
2928
2929 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2930 kfree(cmd);
2931
2932 return rc;
2933}
2934
2935static int mwl8k_cmd_set_new_stn_add_self(struct ieee80211_hw *hw,
2936 struct ieee80211_vif *vif)
2937{
2938 struct mwl8k_cmd_set_new_stn *cmd;
2939 int rc;
2940
2941 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2942 if (cmd == NULL)
2943 return -ENOMEM;
2944
2945 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2276 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2946 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2947 memcpy(cmd->mac_addr, vif->addr, ETH_ALEN);
2277 2948
2278 for (count = 0; count < mv_vif->legacy_nrates; count++) 2949 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2279 cmd->legacy_rates[count] = bitrates[count].hw_value; 2950 kfree(cmd);
2280 2951
2281 rc = mwl8k_post_cmd(hw, &cmd->header); 2952 return rc;
2953}
2954
2955static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw,
2956 struct ieee80211_vif *vif, u8 *addr)
2957{
2958 struct mwl8k_cmd_set_new_stn *cmd;
2959 int rc;
2960
2961 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2962 if (cmd == NULL)
2963 return -ENOMEM;
2964
2965 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2966 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2967 memcpy(cmd->mac_addr, addr, ETH_ALEN);
2968 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE);
2969
2970 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2282 kfree(cmd); 2971 kfree(cmd);
2283 2972
2284 return rc; 2973 return rc;
2285} 2974}
2286 2975
2287/* 2976/*
2288 * CMD_USE_FIXED_RATE. 2977 * CMD_UPDATE_STADB.
2289 */ 2978 */
2290#define MWL8K_RATE_TABLE_SIZE 8 2979struct ewc_ht_info {
2291#define MWL8K_UCAST_RATE 0 2980 __le16 control1;
2292#define MWL8K_USE_AUTO_RATE 0x0002 2981 __le16 control2;
2982 __le16 control3;
2983} __attribute__((packed));
2984
2985struct peer_capability_info {
2986 /* Peer type - AP vs. STA. */
2987 __u8 peer_type;
2293 2988
2294struct mwl8k_rate_entry { 2989 /* Basic 802.11 capabilities from assoc resp. */
2295 /* Set to 1 if HT rate, 0 if legacy. */ 2990 __le16 basic_caps;
2296 __le32 is_ht_rate;
2297 2991
2298 /* Set to 1 to use retry_count field. */ 2992 /* Set if peer supports 802.11n high throughput (HT). */
2299 __le32 enable_retry; 2993 __u8 ht_support;
2300 2994
2301 /* Specified legacy rate or MCS. */ 2995 /* Valid if HT is supported. */
2302 __le32 rate; 2996 __le16 ht_caps;
2997 __u8 extended_ht_caps;
2998 struct ewc_ht_info ewc_info;
2303 2999
2304 /* Number of allowed retries. */ 3000 /* Legacy rate table. Intersection of our rates and peer rates. */
2305 __le32 retry_count; 3001 __u8 legacy_rates[12];
2306} __attribute__((packed));
2307 3002
2308struct mwl8k_rate_table { 3003 /* HT rate table. Intersection of our rates and peer rates. */
2309 /* 1 to allow specified rate and below */ 3004 __u8 ht_rates[16];
2310 __le32 allow_rate_drop; 3005 __u8 pad[16];
2311 __le32 num_rates; 3006
2312 struct mwl8k_rate_entry rate_entry[MWL8K_RATE_TABLE_SIZE]; 3007 /* If set, interoperability mode, no proprietary extensions. */
3008 __u8 interop;
3009 __u8 pad2;
3010 __u8 station_id;
3011 __le16 amsdu_enabled;
2313} __attribute__((packed)); 3012} __attribute__((packed));
2314 3013
2315struct mwl8k_cmd_use_fixed_rate { 3014struct mwl8k_cmd_update_stadb {
2316 struct mwl8k_cmd_pkt header; 3015 struct mwl8k_cmd_pkt header;
3016
3017 /* See STADB_ACTION_TYPE */
2317 __le32 action; 3018 __le32 action;
2318 struct mwl8k_rate_table rate_table;
2319 3019
2320 /* Unicast, Broadcast or Multicast */ 3020 /* Peer MAC address */
2321 __le32 rate_type; 3021 __u8 peer_addr[ETH_ALEN];
2322 __le32 reserved1; 3022
2323 __le32 reserved2; 3023 __le32 reserved;
3024
3025 /* Peer info - valid during add/update. */
3026 struct peer_capability_info peer_info;
2324} __attribute__((packed)); 3027} __attribute__((packed));
2325 3028
2326static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw, 3029#define MWL8K_STA_DB_MODIFY_ENTRY 1
2327 u32 action, u32 rate_type, struct mwl8k_rate_table *rate_table) 3030#define MWL8K_STA_DB_DEL_ENTRY 2
3031
3032/* Peer Entry flags - used to define the type of the peer node */
3033#define MWL8K_PEER_TYPE_ACCESSPOINT 2
3034
3035static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
3036 struct ieee80211_vif *vif,
3037 struct ieee80211_sta *sta)
2328{ 3038{
2329 struct mwl8k_cmd_use_fixed_rate *cmd; 3039 struct mwl8k_cmd_update_stadb *cmd;
2330 int count; 3040 struct peer_capability_info *p;
3041 u32 rates;
2331 int rc; 3042 int rc;
2332 3043
2333 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 3044 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2334 if (cmd == NULL) 3045 if (cmd == NULL)
2335 return -ENOMEM; 3046 return -ENOMEM;
2336 3047
2337 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); 3048 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
2338 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 3049 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3050 cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY);
3051 memcpy(cmd->peer_addr, sta->addr, ETH_ALEN);
3052
3053 p = &cmd->peer_info;
3054 p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
3055 p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability);
3056 p->ht_support = sta->ht_cap.ht_supported;
3057 p->ht_caps = sta->ht_cap.cap;
3058 p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) |
3059 ((sta->ht_cap.ampdu_density & 7) << 2);
3060 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3061 rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
3062 else
3063 rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3064 legacy_rate_mask_to_array(p->legacy_rates, rates);
3065 memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16);
3066 p->interop = 1;
3067 p->amsdu_enabled = 0;
2339 3068
2340 cmd->action = cpu_to_le32(action); 3069 rc = mwl8k_post_cmd(hw, &cmd->header);
2341 cmd->rate_type = cpu_to_le32(rate_type); 3070 kfree(cmd);
2342 3071
2343 if (rate_table != NULL) { 3072 return rc ? rc : p->station_id;
2344 /* Copy over each field manually so 3073}
2345 * that bitflipping can be done 3074
2346 */ 3075static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw,
2347 cmd->rate_table.allow_rate_drop = 3076 struct ieee80211_vif *vif, u8 *addr)
2348 cpu_to_le32(rate_table->allow_rate_drop); 3077{
2349 cmd->rate_table.num_rates = 3078 struct mwl8k_cmd_update_stadb *cmd;
2350 cpu_to_le32(rate_table->num_rates); 3079 int rc;
2351 3080
2352 for (count = 0; count < rate_table->num_rates; count++) { 3081 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2353 struct mwl8k_rate_entry *dst = 3082 if (cmd == NULL)
2354 &cmd->rate_table.rate_entry[count]; 3083 return -ENOMEM;
2355 struct mwl8k_rate_entry *src = 3084
2356 &rate_table->rate_entry[count]; 3085 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
2357 3086 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2358 dst->is_ht_rate = cpu_to_le32(src->is_ht_rate); 3087 cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY);
2359 dst->enable_retry = cpu_to_le32(src->enable_retry); 3088 memcpy(cmd->peer_addr, addr, ETH_ALEN);
2360 dst->rate = cpu_to_le32(src->rate);
2361 dst->retry_count = cpu_to_le32(src->retry_count);
2362 }
2363 }
2364 3089
2365 rc = mwl8k_post_cmd(hw, &cmd->header); 3090 rc = mwl8k_post_cmd(hw, &cmd->header);
2366 kfree(cmd); 3091 kfree(cmd);
@@ -2379,19 +3104,22 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2379 u32 status; 3104 u32 status;
2380 3105
2381 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 3106 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2382 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2383
2384 if (!status) 3107 if (!status)
2385 return IRQ_NONE; 3108 return IRQ_NONE;
2386 3109
2387 if (status & MWL8K_A2H_INT_TX_DONE) 3110 if (status & MWL8K_A2H_INT_TX_DONE) {
2388 tasklet_schedule(&priv->tx_reclaim_task); 3111 status &= ~MWL8K_A2H_INT_TX_DONE;
3112 tasklet_schedule(&priv->poll_tx_task);
3113 }
2389 3114
2390 if (status & MWL8K_A2H_INT_RX_READY) { 3115 if (status & MWL8K_A2H_INT_RX_READY) {
2391 while (rxq_process(hw, 0, 1)) 3116 status &= ~MWL8K_A2H_INT_RX_READY;
2392 rxq_refill(hw, 0, 1); 3117 tasklet_schedule(&priv->poll_rx_task);
2393 } 3118 }
2394 3119
3120 if (status)
3121 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3122
2395 if (status & MWL8K_A2H_INT_OPC_DONE) { 3123 if (status & MWL8K_A2H_INT_OPC_DONE) {
2396 if (priv->hostcmd_wait != NULL) 3124 if (priv->hostcmd_wait != NULL)
2397 complete(priv->hostcmd_wait); 3125 complete(priv->hostcmd_wait);
@@ -2399,13 +3127,60 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2399 3127
2400 if (status & MWL8K_A2H_INT_QUEUE_EMPTY) { 3128 if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
2401 if (!mutex_is_locked(&priv->fw_mutex) && 3129 if (!mutex_is_locked(&priv->fw_mutex) &&
2402 priv->radio_on && mwl8k_txq_busy(priv)) 3130 priv->radio_on && priv->pending_tx_pkts)
2403 mwl8k_tx_start(priv); 3131 mwl8k_tx_start(priv);
2404 } 3132 }
2405 3133
2406 return IRQ_HANDLED; 3134 return IRQ_HANDLED;
2407} 3135}
2408 3136
3137static void mwl8k_tx_poll(unsigned long data)
3138{
3139 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
3140 struct mwl8k_priv *priv = hw->priv;
3141 int limit;
3142 int i;
3143
3144 limit = 32;
3145
3146 spin_lock_bh(&priv->tx_lock);
3147
3148 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3149 limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
3150
3151 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
3152 complete(priv->tx_wait);
3153 priv->tx_wait = NULL;
3154 }
3155
3156 spin_unlock_bh(&priv->tx_lock);
3157
3158 if (limit) {
3159 writel(~MWL8K_A2H_INT_TX_DONE,
3160 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3161 } else {
3162 tasklet_schedule(&priv->poll_tx_task);
3163 }
3164}
3165
3166static void mwl8k_rx_poll(unsigned long data)
3167{
3168 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
3169 struct mwl8k_priv *priv = hw->priv;
3170 int limit;
3171
3172 limit = 32;
3173 limit -= rxq_process(hw, 0, limit);
3174 limit -= rxq_refill(hw, 0, limit);
3175
3176 if (limit) {
3177 writel(~MWL8K_A2H_INT_RX_READY,
3178 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3179 } else {
3180 tasklet_schedule(&priv->poll_rx_task);
3181 }
3182}
3183
2409 3184
2410/* 3185/*
2411 * Core driver operations. 3186 * Core driver operations.
@@ -2416,9 +3191,9 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2416 int index = skb_get_queue_mapping(skb); 3191 int index = skb_get_queue_mapping(skb);
2417 int rc; 3192 int rc;
2418 3193
2419 if (priv->current_channel == NULL) { 3194 if (!priv->radio_on) {
2420 printk(KERN_DEBUG "%s: dropped TX frame since radio " 3195 printk(KERN_DEBUG "%s: dropped TX frame since radio "
2421 "disabled\n", priv->name); 3196 "disabled\n", wiphy_name(hw->wiphy));
2422 dev_kfree_skb(skb); 3197 dev_kfree_skb(skb);
2423 return NETDEV_TX_OK; 3198 return NETDEV_TX_OK;
2424 } 3199 }
@@ -2433,39 +3208,42 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2433 struct mwl8k_priv *priv = hw->priv; 3208 struct mwl8k_priv *priv = hw->priv;
2434 int rc; 3209 int rc;
2435 3210
2436 rc = request_irq(priv->pdev->irq, &mwl8k_interrupt, 3211 rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
2437 IRQF_SHARED, MWL8K_NAME, hw); 3212 IRQF_SHARED, MWL8K_NAME, hw);
2438 if (rc) { 3213 if (rc) {
2439 printk(KERN_ERR "%s: failed to register IRQ handler\n", 3214 printk(KERN_ERR "%s: failed to register IRQ handler\n",
2440 priv->name); 3215 wiphy_name(hw->wiphy));
2441 return -EIO; 3216 return -EIO;
2442 } 3217 }
2443 3218
2444 /* Enable tx reclaim tasklet */ 3219 /* Enable TX reclaim and RX tasklets. */
2445 tasklet_enable(&priv->tx_reclaim_task); 3220 tasklet_enable(&priv->poll_tx_task);
3221 tasklet_enable(&priv->poll_rx_task);
2446 3222
2447 /* Enable interrupts */ 3223 /* Enable interrupts */
2448 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3224 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2449 3225
2450 rc = mwl8k_fw_lock(hw); 3226 rc = mwl8k_fw_lock(hw);
2451 if (!rc) { 3227 if (!rc) {
2452 rc = mwl8k_cmd_802_11_radio_enable(hw); 3228 rc = mwl8k_cmd_radio_enable(hw);
2453 3229
2454 if (!rc) 3230 if (!priv->ap_fw) {
2455 rc = mwl8k_cmd_set_pre_scan(hw); 3231 if (!rc)
3232 rc = mwl8k_cmd_enable_sniffer(hw, 0);
2456 3233
2457 if (!rc) 3234 if (!rc)
2458 rc = mwl8k_cmd_set_post_scan(hw, 3235 rc = mwl8k_cmd_set_pre_scan(hw);
2459 "\x00\x00\x00\x00\x00\x00");
2460 3236
2461 if (!rc) 3237 if (!rc)
2462 rc = mwl8k_cmd_setrateadaptmode(hw, 0); 3238 rc = mwl8k_cmd_set_post_scan(hw,
3239 "\x00\x00\x00\x00\x00\x00");
3240 }
2463 3241
2464 if (!rc) 3242 if (!rc)
2465 rc = mwl8k_set_wmm(hw, 0); 3243 rc = mwl8k_cmd_set_rateadapt_mode(hw, 0);
2466 3244
2467 if (!rc) 3245 if (!rc)
2468 rc = mwl8k_enable_sniffer(hw, 0); 3246 rc = mwl8k_cmd_set_wmm_mode(hw, 0);
2469 3247
2470 mwl8k_fw_unlock(hw); 3248 mwl8k_fw_unlock(hw);
2471 } 3249 }
@@ -2473,7 +3251,8 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2473 if (rc) { 3251 if (rc) {
2474 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3252 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2475 free_irq(priv->pdev->irq, hw); 3253 free_irq(priv->pdev->irq, hw);
2476 tasklet_disable(&priv->tx_reclaim_task); 3254 tasklet_disable(&priv->poll_tx_task);
3255 tasklet_disable(&priv->poll_rx_task);
2477 } 3256 }
2478 3257
2479 return rc; 3258 return rc;
@@ -2484,7 +3263,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
2484 struct mwl8k_priv *priv = hw->priv; 3263 struct mwl8k_priv *priv = hw->priv;
2485 int i; 3264 int i;
2486 3265
2487 mwl8k_cmd_802_11_radio_disable(hw); 3266 mwl8k_cmd_radio_disable(hw);
2488 3267
2489 ieee80211_stop_queues(hw); 3268 ieee80211_stop_queues(hw);
2490 3269
@@ -2497,68 +3276,83 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
2497 if (priv->beacon_skb != NULL) 3276 if (priv->beacon_skb != NULL)
2498 dev_kfree_skb(priv->beacon_skb); 3277 dev_kfree_skb(priv->beacon_skb);
2499 3278
2500 /* Stop tx reclaim tasklet */ 3279 /* Stop TX reclaim and RX tasklets. */
2501 tasklet_disable(&priv->tx_reclaim_task); 3280 tasklet_disable(&priv->poll_tx_task);
2502 3281 tasklet_disable(&priv->poll_rx_task);
2503 /* Stop config thread */
2504 flush_workqueue(priv->config_wq);
2505 3282
2506 /* Return all skbs to mac80211 */ 3283 /* Return all skbs to mac80211 */
2507 for (i = 0; i < MWL8K_TX_QUEUES; i++) 3284 for (i = 0; i < MWL8K_TX_QUEUES; i++)
2508 mwl8k_txq_reclaim(hw, i, 1); 3285 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
2509} 3286}
2510 3287
2511static int mwl8k_add_interface(struct ieee80211_hw *hw, 3288static int mwl8k_add_interface(struct ieee80211_hw *hw,
2512 struct ieee80211_if_init_conf *conf) 3289 struct ieee80211_vif *vif)
2513{ 3290{
2514 struct mwl8k_priv *priv = hw->priv; 3291 struct mwl8k_priv *priv = hw->priv;
2515 struct mwl8k_vif *mwl8k_vif; 3292 struct mwl8k_vif *mwl8k_vif;
3293 u32 macids_supported;
3294 int macid;
2516 3295
2517 /* 3296 /*
2518 * We only support one active interface at a time. 3297 * Reject interface creation if sniffer mode is active, as
3298 * STA operation is mutually exclusive with hardware sniffer
3299 * mode. (Sniffer mode is only used on STA firmware.)
2519 */ 3300 */
2520 if (priv->vif != NULL) 3301 if (priv->sniffer_enabled) {
2521 return -EBUSY; 3302 printk(KERN_INFO "%s: unable to create STA "
2522 3303 "interface due to sniffer mode being enabled\n",
2523 /* 3304 wiphy_name(hw->wiphy));
2524 * We only support managed interfaces for now.
2525 */
2526 if (conf->type != NL80211_IFTYPE_STATION)
2527 return -EINVAL; 3305 return -EINVAL;
3306 }
2528 3307
2529 /* Clean out driver private area */
2530 mwl8k_vif = MWL8K_VIF(conf->vif);
2531 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
2532
2533 /* Save the mac address */
2534 memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN);
2535 3308
2536 /* Back pointer to parent config block */ 3309 switch (vif->type) {
2537 mwl8k_vif->priv = priv; 3310 case NL80211_IFTYPE_AP:
3311 macids_supported = priv->ap_macids_supported;
3312 break;
3313 case NL80211_IFTYPE_STATION:
3314 macids_supported = priv->sta_macids_supported;
3315 break;
3316 default:
3317 return -EINVAL;
3318 }
2538 3319
2539 /* Setup initial PHY parameters */ 3320 macid = ffs(macids_supported & ~priv->macids_used);
2540 memcpy(mwl8k_vif->legacy_rates, 3321 if (!macid--)
2541 priv->rates, sizeof(mwl8k_vif->legacy_rates)); 3322 return -EBUSY;
2542 mwl8k_vif->legacy_nrates = ARRAY_SIZE(priv->rates);
2543 3323
2544 /* Set Initial sequence number to zero */ 3324 /* Setup driver private area. */
3325 mwl8k_vif = MWL8K_VIF(vif);
3326 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
3327 mwl8k_vif->vif = vif;
3328 mwl8k_vif->macid = macid;
2545 mwl8k_vif->seqno = 0; 3329 mwl8k_vif->seqno = 0;
2546 3330
2547 priv->vif = conf->vif; 3331 /* Set the mac address. */
2548 priv->current_channel = NULL; 3332 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
3333
3334 if (priv->ap_fw)
3335 mwl8k_cmd_set_new_stn_add_self(hw, vif);
3336
3337 priv->macids_used |= 1 << mwl8k_vif->macid;
3338 list_add_tail(&mwl8k_vif->list, &priv->vif_list);
2549 3339
2550 return 0; 3340 return 0;
2551} 3341}
2552 3342
2553static void mwl8k_remove_interface(struct ieee80211_hw *hw, 3343static void mwl8k_remove_interface(struct ieee80211_hw *hw,
2554 struct ieee80211_if_init_conf *conf) 3344 struct ieee80211_vif *vif)
2555{ 3345{
2556 struct mwl8k_priv *priv = hw->priv; 3346 struct mwl8k_priv *priv = hw->priv;
3347 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
2557 3348
2558 if (priv->vif == NULL) 3349 if (priv->ap_fw)
2559 return; 3350 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
3351
3352 mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");
2560 3353
2561 priv->vif = NULL; 3354 priv->macids_used &= ~(1 << mwl8k_vif->macid);
3355 list_del(&mwl8k_vif->list);
2562} 3356}
2563 3357
2564static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) 3358static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
@@ -2568,8 +3362,7 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2568 int rc; 3362 int rc;
2569 3363
2570 if (conf->flags & IEEE80211_CONF_IDLE) { 3364 if (conf->flags & IEEE80211_CONF_IDLE) {
2571 mwl8k_cmd_802_11_radio_disable(hw); 3365 mwl8k_cmd_radio_disable(hw);
2572 priv->current_channel = NULL;
2573 return 0; 3366 return 0;
2574 } 3367 }
2575 3368
@@ -2577,24 +3370,27 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2577 if (rc) 3370 if (rc)
2578 return rc; 3371 return rc;
2579 3372
2580 rc = mwl8k_cmd_802_11_radio_enable(hw); 3373 rc = mwl8k_cmd_radio_enable(hw);
2581 if (rc) 3374 if (rc)
2582 goto out; 3375 goto out;
2583 3376
2584 rc = mwl8k_cmd_set_rf_channel(hw, conf->channel); 3377 rc = mwl8k_cmd_set_rf_channel(hw, conf);
2585 if (rc) 3378 if (rc)
2586 goto out; 3379 goto out;
2587 3380
2588 priv->current_channel = conf->channel;
2589
2590 if (conf->power_level > 18) 3381 if (conf->power_level > 18)
2591 conf->power_level = 18; 3382 conf->power_level = 18;
2592 rc = mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level); 3383 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
2593 if (rc) 3384 if (rc)
2594 goto out; 3385 goto out;
2595 3386
2596 if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7)) 3387 if (priv->ap_fw) {
2597 rc = -EINVAL; 3388 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7);
3389 if (!rc)
3390 rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
3391 } else {
3392 rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7);
3393 }
2598 3394
2599out: 3395out:
2600 mwl8k_fw_unlock(hw); 3396 mwl8k_fw_unlock(hw);
@@ -2602,122 +3398,301 @@ out:
2602 return rc; 3398 return rc;
2603} 3399}
2604 3400
2605static void mwl8k_bss_info_changed(struct ieee80211_hw *hw, 3401static void
2606 struct ieee80211_vif *vif, 3402mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2607 struct ieee80211_bss_conf *info, 3403 struct ieee80211_bss_conf *info, u32 changed)
2608 u32 changed)
2609{ 3404{
2610 struct mwl8k_priv *priv = hw->priv; 3405 struct mwl8k_priv *priv = hw->priv;
2611 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 3406 u32 ap_legacy_rates;
3407 u8 ap_mcs_rates[16];
2612 int rc; 3408 int rc;
2613 3409
2614 if (changed & BSS_CHANGED_BSSID) 3410 if (mwl8k_fw_lock(hw))
2615 memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN);
2616
2617 if ((changed & BSS_CHANGED_ASSOC) == 0)
2618 return; 3411 return;
2619 3412
2620 priv->capture_beacon = false; 3413 /*
3414 * No need to capture a beacon if we're no longer associated.
3415 */
3416 if ((changed & BSS_CHANGED_ASSOC) && !vif->bss_conf.assoc)
3417 priv->capture_beacon = false;
2621 3418
2622 rc = mwl8k_fw_lock(hw); 3419 /*
2623 if (rc) 3420 * Get the AP's legacy and MCS rates.
2624 return; 3421 */
3422 if (vif->bss_conf.assoc) {
3423 struct ieee80211_sta *ap;
2625 3424
2626 if (info->assoc) { 3425 rcu_read_lock();
2627 memcpy(&mwl8k_vif->bss_info, info,
2628 sizeof(struct ieee80211_bss_conf));
2629 3426
2630 /* Install rates */ 3427 ap = ieee80211_find_sta(vif, vif->bss_conf.bssid);
2631 rc = mwl8k_update_rateset(hw, vif); 3428 if (ap == NULL) {
2632 if (rc) 3429 rcu_read_unlock();
2633 goto out; 3430 goto out;
3431 }
2634 3432
2635 /* Turn on rate adaptation */ 3433 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
2636 rc = mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE, 3434 ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ];
2637 MWL8K_UCAST_RATE, NULL); 3435 } else {
3436 ap_legacy_rates =
3437 ap->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3438 }
3439 memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16);
3440
3441 rcu_read_unlock();
3442 }
3443
3444 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) {
3445 rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates);
2638 if (rc) 3446 if (rc)
2639 goto out; 3447 goto out;
2640 3448
2641 /* Set radio preamble */ 3449 rc = mwl8k_cmd_use_fixed_rate_sta(hw);
2642 rc = mwl8k_set_radio_preamble(hw, info->use_short_preamble);
2643 if (rc) 3450 if (rc)
2644 goto out; 3451 goto out;
3452 }
2645 3453
2646 /* Set slot time */ 3454 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
2647 rc = mwl8k_cmd_set_slot(hw, info->use_short_slot); 3455 rc = mwl8k_set_radio_preamble(hw,
3456 vif->bss_conf.use_short_preamble);
2648 if (rc) 3457 if (rc)
2649 goto out; 3458 goto out;
3459 }
2650 3460
2651 /* Update peer rate info */ 3461 if (changed & BSS_CHANGED_ERP_SLOT) {
2652 rc = mwl8k_cmd_update_sta_db(hw, vif, 3462 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot);
2653 MWL8K_STA_DB_MODIFY_ENTRY);
2654 if (rc) 3463 if (rc)
2655 goto out; 3464 goto out;
3465 }
2656 3466
2657 /* Set AID */ 3467 if (vif->bss_conf.assoc &&
2658 rc = mwl8k_cmd_set_aid(hw, vif); 3468 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT |
3469 BSS_CHANGED_HT))) {
3470 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
2659 if (rc) 3471 if (rc)
2660 goto out; 3472 goto out;
3473 }
2661 3474
3475 if (vif->bss_conf.assoc &&
3476 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INT))) {
2662 /* 3477 /*
2663 * Finalize the join. Tell rx handler to process 3478 * Finalize the join. Tell rx handler to process
2664 * next beacon from our BSSID. 3479 * next beacon from our BSSID.
2665 */ 3480 */
2666 memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN); 3481 memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN);
2667 priv->capture_beacon = true; 3482 priv->capture_beacon = true;
2668 } else {
2669 rc = mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
2670 memset(&mwl8k_vif->bss_info, 0,
2671 sizeof(struct ieee80211_bss_conf));
2672 memset(mwl8k_vif->bssid, 0, ETH_ALEN);
2673 } 3483 }
2674 3484
2675out: 3485out:
2676 mwl8k_fw_unlock(hw); 3486 mwl8k_fw_unlock(hw);
2677} 3487}
2678 3488
3489static void
3490mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3491 struct ieee80211_bss_conf *info, u32 changed)
3492{
3493 int rc;
3494
3495 if (mwl8k_fw_lock(hw))
3496 return;
3497
3498 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
3499 rc = mwl8k_set_radio_preamble(hw,
3500 vif->bss_conf.use_short_preamble);
3501 if (rc)
3502 goto out;
3503 }
3504
3505 if (changed & BSS_CHANGED_BASIC_RATES) {
3506 int idx;
3507 int rate;
3508
3509 /*
3510 * Use lowest supported basic rate for multicasts
3511 * and management frames (such as probe responses --
3512 * beacons will always go out at 1 Mb/s).
3513 */
3514 idx = ffs(vif->bss_conf.basic_rates);
3515 if (idx)
3516 idx--;
3517
3518 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3519 rate = mwl8k_rates_24[idx].hw_value;
3520 else
3521 rate = mwl8k_rates_50[idx].hw_value;
3522
3523 mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
3524 }
3525
3526 if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
3527 struct sk_buff *skb;
3528
3529 skb = ieee80211_beacon_get(hw, vif);
3530 if (skb != NULL) {
3531 mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len);
3532 kfree_skb(skb);
3533 }
3534 }
3535
3536 if (changed & BSS_CHANGED_BEACON_ENABLED)
3537 mwl8k_cmd_bss_start(hw, vif, info->enable_beacon);
3538
3539out:
3540 mwl8k_fw_unlock(hw);
3541}
3542
3543static void
3544mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3545 struct ieee80211_bss_conf *info, u32 changed)
3546{
3547 struct mwl8k_priv *priv = hw->priv;
3548
3549 if (!priv->ap_fw)
3550 mwl8k_bss_info_changed_sta(hw, vif, info, changed);
3551 else
3552 mwl8k_bss_info_changed_ap(hw, vif, info, changed);
3553}
3554
2679static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw, 3555static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
2680 int mc_count, struct dev_addr_list *mclist) 3556 int mc_count, struct dev_addr_list *mclist)
2681{ 3557{
2682 struct mwl8k_cmd_pkt *cmd; 3558 struct mwl8k_cmd_pkt *cmd;
2683 3559
2684 cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist); 3560 /*
3561 * Synthesize and return a command packet that programs the
3562 * hardware multicast address filter. At this point we don't
3563 * know whether FIF_ALLMULTI is being requested, but if it is,
3564 * we'll end up throwing this packet away and creating a new
3565 * one in mwl8k_configure_filter().
3566 */
3567 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_count, mclist);
2685 3568
2686 return (unsigned long)cmd; 3569 return (unsigned long)cmd;
2687} 3570}
2688 3571
3572static int
3573mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
3574 unsigned int changed_flags,
3575 unsigned int *total_flags)
3576{
3577 struct mwl8k_priv *priv = hw->priv;
3578
3579 /*
3580 * Hardware sniffer mode is mutually exclusive with STA
3581 * operation, so refuse to enable sniffer mode if a STA
3582 * interface is active.
3583 */
3584 if (!list_empty(&priv->vif_list)) {
3585 if (net_ratelimit())
3586 printk(KERN_INFO "%s: not enabling sniffer "
3587 "mode because STA interface is active\n",
3588 wiphy_name(hw->wiphy));
3589 return 0;
3590 }
3591
3592 if (!priv->sniffer_enabled) {
3593 if (mwl8k_cmd_enable_sniffer(hw, 1))
3594 return 0;
3595 priv->sniffer_enabled = true;
3596 }
3597
3598 *total_flags &= FIF_PROMISC_IN_BSS | FIF_ALLMULTI |
3599 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL |
3600 FIF_OTHER_BSS;
3601
3602 return 1;
3603}
3604
3605static struct mwl8k_vif *mwl8k_first_vif(struct mwl8k_priv *priv)
3606{
3607 if (!list_empty(&priv->vif_list))
3608 return list_entry(priv->vif_list.next, struct mwl8k_vif, list);
3609
3610 return NULL;
3611}
3612
2689static void mwl8k_configure_filter(struct ieee80211_hw *hw, 3613static void mwl8k_configure_filter(struct ieee80211_hw *hw,
2690 unsigned int changed_flags, 3614 unsigned int changed_flags,
2691 unsigned int *total_flags, 3615 unsigned int *total_flags,
2692 u64 multicast) 3616 u64 multicast)
2693{ 3617{
2694 struct mwl8k_priv *priv = hw->priv; 3618 struct mwl8k_priv *priv = hw->priv;
2695 struct mwl8k_cmd_pkt *multicast_adr_cmd; 3619 struct mwl8k_cmd_pkt *cmd = (void *)(unsigned long)multicast;
3620
3621 /*
3622 * AP firmware doesn't allow fine-grained control over
3623 * the receive filter.
3624 */
3625 if (priv->ap_fw) {
3626 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
3627 kfree(cmd);
3628 return;
3629 }
3630
3631 /*
3632 * Enable hardware sniffer mode if FIF_CONTROL or
3633 * FIF_OTHER_BSS is requested.
3634 */
3635 if (*total_flags & (FIF_CONTROL | FIF_OTHER_BSS) &&
3636 mwl8k_configure_filter_sniffer(hw, changed_flags, total_flags)) {
3637 kfree(cmd);
3638 return;
3639 }
2696 3640
2697 /* Clear unsupported feature flags */ 3641 /* Clear unsupported feature flags */
2698 *total_flags &= FIF_BCN_PRBRESP_PROMISC; 3642 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
2699 3643
2700 if (mwl8k_fw_lock(hw)) 3644 if (mwl8k_fw_lock(hw)) {
3645 kfree(cmd);
2701 return; 3646 return;
3647 }
3648
3649 if (priv->sniffer_enabled) {
3650 mwl8k_cmd_enable_sniffer(hw, 0);
3651 priv->sniffer_enabled = false;
3652 }
2702 3653
2703 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { 3654 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
2704 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) 3655 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
3656 /*
3657 * Disable the BSS filter.
3658 */
2705 mwl8k_cmd_set_pre_scan(hw); 3659 mwl8k_cmd_set_pre_scan(hw);
2706 else { 3660 } else {
2707 u8 *bssid; 3661 struct mwl8k_vif *mwl8k_vif;
2708 3662 const u8 *bssid;
2709 bssid = "\x00\x00\x00\x00\x00\x00"; 3663
2710 if (priv->vif != NULL) 3664 /*
2711 bssid = MWL8K_VIF(priv->vif)->bssid; 3665 * Enable the BSS filter.
3666 *
3667 * If there is an active STA interface, use that
3668 * interface's BSSID, otherwise use a dummy one
3669 * (where the OUI part needs to be nonzero for
3670 * the BSSID to be accepted by POST_SCAN).
3671 */
3672 mwl8k_vif = mwl8k_first_vif(priv);
3673 if (mwl8k_vif != NULL)
3674 bssid = mwl8k_vif->vif->bss_conf.bssid;
3675 else
3676 bssid = "\x01\x00\x00\x00\x00\x00";
2712 3677
2713 mwl8k_cmd_set_post_scan(hw, bssid); 3678 mwl8k_cmd_set_post_scan(hw, bssid);
2714 } 3679 }
2715 } 3680 }
2716 3681
2717 multicast_adr_cmd = (void *)(unsigned long)multicast; 3682 /*
2718 if (multicast_adr_cmd != NULL) { 3683 * If FIF_ALLMULTI is being requested, throw away the command
2719 mwl8k_post_cmd(hw, multicast_adr_cmd); 3684 * packet that ->prepare_multicast() built and replace it with
2720 kfree(multicast_adr_cmd); 3685 * a command packet that enables reception of all multicast
3686 * packets.
3687 */
3688 if (*total_flags & FIF_ALLMULTI) {
3689 kfree(cmd);
3690 cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, 0, NULL);
3691 }
3692
3693 if (cmd != NULL) {
3694 mwl8k_post_cmd(hw, cmd);
3695 kfree(cmd);
2721 } 3696 }
2722 3697
2723 mwl8k_fw_unlock(hw); 3698 mwl8k_fw_unlock(hw);
@@ -2725,7 +3700,39 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
2725 3700
2726static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 3701static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
2727{ 3702{
2728 return mwl8k_rts_threshold(hw, MWL8K_CMD_SET, value); 3703 return mwl8k_cmd_set_rts_threshold(hw, value);
3704}
3705
3706static int mwl8k_sta_remove(struct ieee80211_hw *hw,
3707 struct ieee80211_vif *vif,
3708 struct ieee80211_sta *sta)
3709{
3710 struct mwl8k_priv *priv = hw->priv;
3711
3712 if (priv->ap_fw)
3713 return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr);
3714 else
3715 return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr);
3716}
3717
3718static int mwl8k_sta_add(struct ieee80211_hw *hw,
3719 struct ieee80211_vif *vif,
3720 struct ieee80211_sta *sta)
3721{
3722 struct mwl8k_priv *priv = hw->priv;
3723 int ret;
3724
3725 if (!priv->ap_fw) {
3726 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
3727 if (ret >= 0) {
3728 MWL8K_STA(sta)->peer_id = ret;
3729 return 0;
3730 }
3731
3732 return ret;
3733 }
3734
3735 return mwl8k_cmd_set_new_stn_add(hw, vif, sta);
2729} 3736}
2730 3737
2731static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, 3738static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -2737,14 +3744,14 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
2737 rc = mwl8k_fw_lock(hw); 3744 rc = mwl8k_fw_lock(hw);
2738 if (!rc) { 3745 if (!rc) {
2739 if (!priv->wmm_enabled) 3746 if (!priv->wmm_enabled)
2740 rc = mwl8k_set_wmm(hw, 1); 3747 rc = mwl8k_cmd_set_wmm_mode(hw, 1);
2741 3748
2742 if (!rc) 3749 if (!rc)
2743 rc = mwl8k_set_edca_params(hw, queue, 3750 rc = mwl8k_cmd_set_edca_params(hw, queue,
2744 params->cw_min, 3751 params->cw_min,
2745 params->cw_max, 3752 params->cw_max,
2746 params->aifs, 3753 params->aifs,
2747 params->txop); 3754 params->txop);
2748 3755
2749 mwl8k_fw_unlock(hw); 3756 mwl8k_fw_unlock(hw);
2750 } 3757 }
@@ -2752,28 +3759,26 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
2752 return rc; 3759 return rc;
2753} 3760}
2754 3761
2755static int mwl8k_get_tx_stats(struct ieee80211_hw *hw, 3762static int mwl8k_get_stats(struct ieee80211_hw *hw,
2756 struct ieee80211_tx_queue_stats *stats) 3763 struct ieee80211_low_level_stats *stats)
2757{ 3764{
2758 struct mwl8k_priv *priv = hw->priv; 3765 return mwl8k_cmd_get_stat(hw, stats);
2759 struct mwl8k_tx_queue *txq;
2760 int index;
2761
2762 spin_lock_bh(&priv->tx_lock);
2763 for (index = 0; index < MWL8K_TX_QUEUES; index++) {
2764 txq = priv->txq + index;
2765 memcpy(&stats[index], &txq->tx_stats,
2766 sizeof(struct ieee80211_tx_queue_stats));
2767 }
2768 spin_unlock_bh(&priv->tx_lock);
2769
2770 return 0;
2771} 3766}
2772 3767
2773static int mwl8k_get_stats(struct ieee80211_hw *hw, 3768static int
2774 struct ieee80211_low_level_stats *stats) 3769mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3770 enum ieee80211_ampdu_mlme_action action,
3771 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2775{ 3772{
2776 return mwl8k_cmd_802_11_get_stat(hw, stats); 3773 switch (action) {
3774 case IEEE80211_AMPDU_RX_START:
3775 case IEEE80211_AMPDU_RX_STOP:
3776 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
3777 return -ENOTSUPP;
3778 return 0;
3779 default:
3780 return -ENOTSUPP;
3781 }
2777} 3782}
2778 3783
2779static const struct ieee80211_ops mwl8k_ops = { 3784static const struct ieee80211_ops mwl8k_ops = {
@@ -2787,41 +3792,77 @@ static const struct ieee80211_ops mwl8k_ops = {
2787 .prepare_multicast = mwl8k_prepare_multicast, 3792 .prepare_multicast = mwl8k_prepare_multicast,
2788 .configure_filter = mwl8k_configure_filter, 3793 .configure_filter = mwl8k_configure_filter,
2789 .set_rts_threshold = mwl8k_set_rts_threshold, 3794 .set_rts_threshold = mwl8k_set_rts_threshold,
3795 .sta_add = mwl8k_sta_add,
3796 .sta_remove = mwl8k_sta_remove,
2790 .conf_tx = mwl8k_conf_tx, 3797 .conf_tx = mwl8k_conf_tx,
2791 .get_tx_stats = mwl8k_get_tx_stats,
2792 .get_stats = mwl8k_get_stats, 3798 .get_stats = mwl8k_get_stats,
3799 .ampdu_action = mwl8k_ampdu_action,
2793}; 3800};
2794 3801
2795static void mwl8k_tx_reclaim_handler(unsigned long data)
2796{
2797 int i;
2798 struct ieee80211_hw *hw = (struct ieee80211_hw *) data;
2799 struct mwl8k_priv *priv = hw->priv;
2800
2801 spin_lock_bh(&priv->tx_lock);
2802 for (i = 0; i < MWL8K_TX_QUEUES; i++)
2803 mwl8k_txq_reclaim(hw, i, 0);
2804
2805 if (priv->tx_wait != NULL && mwl8k_txq_busy(priv) == 0) {
2806 complete(priv->tx_wait);
2807 priv->tx_wait = NULL;
2808 }
2809 spin_unlock_bh(&priv->tx_lock);
2810}
2811
2812static void mwl8k_finalize_join_worker(struct work_struct *work) 3802static void mwl8k_finalize_join_worker(struct work_struct *work)
2813{ 3803{
2814 struct mwl8k_priv *priv = 3804 struct mwl8k_priv *priv =
2815 container_of(work, struct mwl8k_priv, finalize_join_worker); 3805 container_of(work, struct mwl8k_priv, finalize_join_worker);
2816 struct sk_buff *skb = priv->beacon_skb; 3806 struct sk_buff *skb = priv->beacon_skb;
2817 u8 dtim = MWL8K_VIF(priv->vif)->bss_info.dtim_period; 3807 struct ieee80211_mgmt *mgmt = (void *)skb->data;
3808 int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
3809 const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
3810 mgmt->u.beacon.variable, len);
3811 int dtim_period = 1;
2818 3812
2819 mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim); 3813 if (tim && tim[1] >= 2)
2820 dev_kfree_skb(skb); 3814 dtim_period = tim[3];
3815
3816 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
2821 3817
3818 dev_kfree_skb(skb);
2822 priv->beacon_skb = NULL; 3819 priv->beacon_skb = NULL;
2823} 3820}
2824 3821
3822enum {
3823 MWL8363 = 0,
3824 MWL8687,
3825 MWL8366,
3826};
3827
3828static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
3829 [MWL8363] = {
3830 .part_name = "88w8363",
3831 .helper_image = "mwl8k/helper_8363.fw",
3832 .fw_image = "mwl8k/fmimage_8363.fw",
3833 },
3834 [MWL8687] = {
3835 .part_name = "88w8687",
3836 .helper_image = "mwl8k/helper_8687.fw",
3837 .fw_image = "mwl8k/fmimage_8687.fw",
3838 },
3839 [MWL8366] = {
3840 .part_name = "88w8366",
3841 .helper_image = "mwl8k/helper_8366.fw",
3842 .fw_image = "mwl8k/fmimage_8366.fw",
3843 .ap_rxd_ops = &rxd_8366_ap_ops,
3844 },
3845};
3846
3847MODULE_FIRMWARE("mwl8k/helper_8363.fw");
3848MODULE_FIRMWARE("mwl8k/fmimage_8363.fw");
3849MODULE_FIRMWARE("mwl8k/helper_8687.fw");
3850MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
3851MODULE_FIRMWARE("mwl8k/helper_8366.fw");
3852MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
3853
3854static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
3855 { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
3856 { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
3857 { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
3858 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
3859 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
3860 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
3861 { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, },
3862 { },
3863};
3864MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
3865
2825static int __devinit mwl8k_probe(struct pci_dev *pdev, 3866static int __devinit mwl8k_probe(struct pci_dev *pdev,
2826 const struct pci_device_id *id) 3867 const struct pci_device_id *id)
2827{ 3868{
@@ -2836,6 +3877,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2836 printed_version = 1; 3877 printed_version = 1;
2837 } 3878 }
2838 3879
3880
2839 rc = pci_enable_device(pdev); 3881 rc = pci_enable_device(pdev);
2840 if (rc) { 3882 if (rc) {
2841 printk(KERN_ERR "%s: Cannot enable new PCI device\n", 3883 printk(KERN_ERR "%s: Cannot enable new PCI device\n",
@@ -2847,11 +3889,12 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2847 if (rc) { 3889 if (rc) {
2848 printk(KERN_ERR "%s: Cannot obtain PCI resources\n", 3890 printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
2849 MWL8K_NAME); 3891 MWL8K_NAME);
2850 return rc; 3892 goto err_disable_device;
2851 } 3893 }
2852 3894
2853 pci_set_master(pdev); 3895 pci_set_master(pdev);
2854 3896
3897
2855 hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops); 3898 hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
2856 if (hw == NULL) { 3899 if (hw == NULL) {
2857 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME); 3900 printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
@@ -2859,32 +3902,76 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2859 goto err_free_reg; 3902 goto err_free_reg;
2860 } 3903 }
2861 3904
3905 SET_IEEE80211_DEV(hw, &pdev->dev);
3906 pci_set_drvdata(pdev, hw);
3907
2862 priv = hw->priv; 3908 priv = hw->priv;
2863 priv->hw = hw; 3909 priv->hw = hw;
2864 priv->pdev = pdev; 3910 priv->pdev = pdev;
2865 priv->wmm_enabled = false; 3911 priv->device_info = &mwl8k_info_tbl[id->driver_data];
2866 priv->pending_tx_pkts = 0;
2867 strncpy(priv->name, MWL8K_NAME, sizeof(priv->name));
2868 3912
2869 SET_IEEE80211_DEV(hw, &pdev->dev);
2870 pci_set_drvdata(pdev, hw);
2871 3913
3914 priv->sram = pci_iomap(pdev, 0, 0x10000);
3915 if (priv->sram == NULL) {
3916 printk(KERN_ERR "%s: Cannot map device SRAM\n",
3917 wiphy_name(hw->wiphy));
3918 goto err_iounmap;
3919 }
3920
3921 /*
3922 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
3923 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
3924 */
2872 priv->regs = pci_iomap(pdev, 1, 0x10000); 3925 priv->regs = pci_iomap(pdev, 1, 0x10000);
2873 if (priv->regs == NULL) { 3926 if (priv->regs == NULL) {
2874 printk(KERN_ERR "%s: Cannot map device memory\n", priv->name); 3927 priv->regs = pci_iomap(pdev, 2, 0x10000);
2875 goto err_iounmap; 3928 if (priv->regs == NULL) {
3929 printk(KERN_ERR "%s: Cannot map device registers\n",
3930 wiphy_name(hw->wiphy));
3931 goto err_iounmap;
3932 }
3933 }
3934
3935
3936 /* Reset firmware and hardware */
3937 mwl8k_hw_reset(priv);
3938
3939 /* Ask userland hotplug daemon for the device firmware */
3940 rc = mwl8k_request_firmware(priv);
3941 if (rc) {
3942 printk(KERN_ERR "%s: Firmware files not found\n",
3943 wiphy_name(hw->wiphy));
3944 goto err_stop_firmware;
2876 } 3945 }
2877 3946
2878 memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels)); 3947 /* Load firmware into hardware */
2879 priv->band.band = IEEE80211_BAND_2GHZ; 3948 rc = mwl8k_load_firmware(hw);
2880 priv->band.channels = priv->channels; 3949 if (rc) {
2881 priv->band.n_channels = ARRAY_SIZE(mwl8k_channels); 3950 printk(KERN_ERR "%s: Cannot start firmware\n",
2882 priv->band.bitrates = priv->rates; 3951 wiphy_name(hw->wiphy));
2883 priv->band.n_bitrates = ARRAY_SIZE(mwl8k_rates); 3952 goto err_stop_firmware;
2884 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; 3953 }
3954
3955 /* Reclaim memory once firmware is successfully loaded */
3956 mwl8k_release_firmware(priv);
3957
3958
3959 if (priv->ap_fw) {
3960 priv->rxd_ops = priv->device_info->ap_rxd_ops;
3961 if (priv->rxd_ops == NULL) {
3962 printk(KERN_ERR "%s: Driver does not have AP "
3963 "firmware image support for this hardware\n",
3964 wiphy_name(hw->wiphy));
3965 goto err_stop_firmware;
3966 }
3967 } else {
3968 priv->rxd_ops = &rxd_sta_ops;
3969 }
3970
3971 priv->sniffer_enabled = false;
3972 priv->wmm_enabled = false;
3973 priv->pending_tx_pkts = 0;
2885 3974
2886 BUILD_BUG_ON(sizeof(priv->rates) != sizeof(mwl8k_rates));
2887 memcpy(priv->rates, mwl8k_rates, sizeof(mwl8k_rates));
2888 3975
2889 /* 3976 /*
2890 * Extra headroom is the size of the required DMA header 3977 * Extra headroom is the size of the required DMA header
@@ -2897,12 +3984,13 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2897 3984
2898 hw->queues = MWL8K_TX_QUEUES; 3985 hw->queues = MWL8K_TX_QUEUES;
2899 3986
2900 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
2901
2902 /* Set rssi and noise values to dBm */ 3987 /* Set rssi and noise values to dBm */
2903 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; 3988 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM;
2904 hw->vif_data_size = sizeof(struct mwl8k_vif); 3989 hw->vif_data_size = sizeof(struct mwl8k_vif);
2905 priv->vif = NULL; 3990 hw->sta_data_size = sizeof(struct mwl8k_sta);
3991
3992 priv->macids_used = 0;
3993 INIT_LIST_HEAD(&priv->vif_list);
2906 3994
2907 /* Set default radio state and preamble */ 3995 /* Set default radio state and preamble */
2908 priv->radio_on = 0; 3996 priv->radio_on = 0;
@@ -2911,34 +3999,31 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2911 /* Finalize join worker */ 3999 /* Finalize join worker */
2912 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 4000 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
2913 4001
2914 /* TX reclaim tasklet */ 4002 /* TX reclaim and RX tasklets. */
2915 tasklet_init(&priv->tx_reclaim_task, 4003 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
2916 mwl8k_tx_reclaim_handler, (unsigned long)hw); 4004 tasklet_disable(&priv->poll_tx_task);
2917 tasklet_disable(&priv->tx_reclaim_task); 4005 tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
2918 4006 tasklet_disable(&priv->poll_rx_task);
2919 /* Config workthread */
2920 priv->config_wq = create_singlethread_workqueue("mwl8k_config");
2921 if (priv->config_wq == NULL)
2922 goto err_iounmap;
2923 4007
2924 /* Power management cookie */ 4008 /* Power management cookie */
2925 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); 4009 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
2926 if (priv->cookie == NULL) 4010 if (priv->cookie == NULL)
2927 goto err_iounmap; 4011 goto err_stop_firmware;
2928 4012
2929 rc = mwl8k_rxq_init(hw, 0); 4013 rc = mwl8k_rxq_init(hw, 0);
2930 if (rc) 4014 if (rc)
2931 goto err_iounmap; 4015 goto err_free_cookie;
2932 rxq_refill(hw, 0, INT_MAX); 4016 rxq_refill(hw, 0, INT_MAX);
2933 4017
2934 mutex_init(&priv->fw_mutex); 4018 mutex_init(&priv->fw_mutex);
2935 priv->fw_mutex_owner = NULL; 4019 priv->fw_mutex_owner = NULL;
2936 priv->fw_mutex_depth = 0; 4020 priv->fw_mutex_depth = 0;
2937 priv->tx_wait = NULL;
2938 priv->hostcmd_wait = NULL; 4021 priv->hostcmd_wait = NULL;
2939 4022
2940 spin_lock_init(&priv->tx_lock); 4023 spin_lock_init(&priv->tx_lock);
2941 4024
4025 priv->tx_wait = NULL;
4026
2942 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 4027 for (i = 0; i < MWL8K_TX_QUEUES; i++) {
2943 rc = mwl8k_txq_init(hw, i); 4028 rc = mwl8k_txq_init(hw, i);
2944 if (rc) 4029 if (rc)
@@ -2947,56 +4032,59 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
2947 4032
2948 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 4033 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2949 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4034 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2950 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 4035 iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY,
4036 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
2951 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 4037 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
2952 4038
2953 rc = request_irq(priv->pdev->irq, &mwl8k_interrupt, 4039 rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
2954 IRQF_SHARED, MWL8K_NAME, hw); 4040 IRQF_SHARED, MWL8K_NAME, hw);
2955 if (rc) { 4041 if (rc) {
2956 printk(KERN_ERR "%s: failed to register IRQ handler\n", 4042 printk(KERN_ERR "%s: failed to register IRQ handler\n",
2957 priv->name); 4043 wiphy_name(hw->wiphy));
2958 goto err_free_queues; 4044 goto err_free_queues;
2959 } 4045 }
2960 4046
2961 /* Reset firmware and hardware */
2962 mwl8k_hw_reset(priv);
2963
2964 /* Ask userland hotplug daemon for the device firmware */
2965 rc = mwl8k_request_firmware(priv, (u32)id->driver_data);
2966 if (rc) {
2967 printk(KERN_ERR "%s: Firmware files not found\n", priv->name);
2968 goto err_free_irq;
2969 }
2970
2971 /* Load firmware into hardware */
2972 rc = mwl8k_load_firmware(priv);
2973 if (rc) {
2974 printk(KERN_ERR "%s: Cannot start firmware\n", priv->name);
2975 goto err_stop_firmware;
2976 }
2977
2978 /* Reclaim memory once firmware is successfully loaded */
2979 mwl8k_release_firmware(priv);
2980
2981 /* 4047 /*
2982 * Temporarily enable interrupts. Initial firmware host 4048 * Temporarily enable interrupts. Initial firmware host
2983 * commands use interrupts and avoids polling. Disable 4049 * commands use interrupts and avoid polling. Disable
2984 * interrupts when done. 4050 * interrupts when done.
2985 */ 4051 */
2986 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4052 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2987 4053
2988 /* Get config data, mac addrs etc */ 4054 /* Get config data, mac addrs etc */
2989 rc = mwl8k_cmd_get_hw_spec(hw); 4055 if (priv->ap_fw) {
4056 rc = mwl8k_cmd_get_hw_spec_ap(hw);
4057 if (!rc)
4058 rc = mwl8k_cmd_set_hw_spec(hw);
4059 } else {
4060 rc = mwl8k_cmd_get_hw_spec_sta(hw);
4061 }
2990 if (rc) { 4062 if (rc) {
2991 printk(KERN_ERR "%s: Cannot initialise firmware\n", priv->name); 4063 printk(KERN_ERR "%s: Cannot initialise firmware\n",
2992 goto err_stop_firmware; 4064 wiphy_name(hw->wiphy));
4065 goto err_free_irq;
2993 } 4066 }
2994 4067
4068 hw->wiphy->interface_modes = 0;
4069 if (priv->ap_macids_supported)
4070 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
4071 if (priv->sta_macids_supported)
4072 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
4073
4074
2995 /* Turn radio off */ 4075 /* Turn radio off */
2996 rc = mwl8k_cmd_802_11_radio_disable(hw); 4076 rc = mwl8k_cmd_radio_disable(hw);
2997 if (rc) { 4077 if (rc) {
2998 printk(KERN_ERR "%s: Cannot disable\n", priv->name); 4078 printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
2999 goto err_stop_firmware; 4079 goto err_free_irq;
4080 }
4081
4082 /* Clear MAC address */
4083 rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
4084 if (rc) {
4085 printk(KERN_ERR "%s: Cannot clear MAC address\n",
4086 wiphy_name(hw->wiphy));
4087 goto err_free_irq;
3000 } 4088 }
3001 4089
3002 /* Disable interrupts */ 4090 /* Disable interrupts */
@@ -3005,22 +4093,20 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3005 4093
3006 rc = ieee80211_register_hw(hw); 4094 rc = ieee80211_register_hw(hw);
3007 if (rc) { 4095 if (rc) {
3008 printk(KERN_ERR "%s: Cannot register device\n", priv->name); 4096 printk(KERN_ERR "%s: Cannot register device\n",
3009 goto err_stop_firmware; 4097 wiphy_name(hw->wiphy));
4098 goto err_free_queues;
3010 } 4099 }
3011 4100
3012 printk(KERN_INFO "%s: 88w%u v%d, %pM, firmware version %u.%u.%u.%u\n", 4101 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, 4102 wiphy_name(hw->wiphy), priv->device_info->part_name,
3014 hw->wiphy->perm_addr, 4103 priv->hw_rev, hw->wiphy->perm_addr,
4104 priv->ap_fw ? "AP" : "STA",
3015 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff, 4105 (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
3016 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff); 4106 (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
3017 4107
3018 return 0; 4108 return 0;
3019 4109
3020err_stop_firmware:
3021 mwl8k_hw_reset(priv);
3022 mwl8k_release_firmware(priv);
3023
3024err_free_irq: 4110err_free_irq:
3025 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4111 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3026 free_irq(priv->pdev->irq, hw); 4112 free_irq(priv->pdev->irq, hw);
@@ -3030,22 +4116,29 @@ err_free_queues:
3030 mwl8k_txq_deinit(hw, i); 4116 mwl8k_txq_deinit(hw, i);
3031 mwl8k_rxq_deinit(hw, 0); 4117 mwl8k_rxq_deinit(hw, 0);
3032 4118
3033err_iounmap: 4119err_free_cookie:
3034 if (priv->cookie != NULL) 4120 if (priv->cookie != NULL)
3035 pci_free_consistent(priv->pdev, 4, 4121 pci_free_consistent(priv->pdev, 4,
3036 priv->cookie, priv->cookie_dma); 4122 priv->cookie, priv->cookie_dma);
3037 4123
4124err_stop_firmware:
4125 mwl8k_hw_reset(priv);
4126 mwl8k_release_firmware(priv);
4127
4128err_iounmap:
3038 if (priv->regs != NULL) 4129 if (priv->regs != NULL)
3039 pci_iounmap(pdev, priv->regs); 4130 pci_iounmap(pdev, priv->regs);
3040 4131
3041 if (priv->config_wq != NULL) 4132 if (priv->sram != NULL)
3042 destroy_workqueue(priv->config_wq); 4133 pci_iounmap(pdev, priv->sram);
3043 4134
3044 pci_set_drvdata(pdev, NULL); 4135 pci_set_drvdata(pdev, NULL);
3045 ieee80211_free_hw(hw); 4136 ieee80211_free_hw(hw);
3046 4137
3047err_free_reg: 4138err_free_reg:
3048 pci_release_regions(pdev); 4139 pci_release_regions(pdev);
4140
4141err_disable_device:
3049 pci_disable_device(pdev); 4142 pci_disable_device(pdev);
3050 4143
3051 return rc; 4144 return rc;
@@ -3070,28 +4163,26 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
3070 4163
3071 ieee80211_unregister_hw(hw); 4164 ieee80211_unregister_hw(hw);
3072 4165
3073 /* Remove tx reclaim tasklet */ 4166 /* Remove TX reclaim and RX tasklets. */
3074 tasklet_kill(&priv->tx_reclaim_task); 4167 tasklet_kill(&priv->poll_tx_task);
3075 4168 tasklet_kill(&priv->poll_rx_task);
3076 /* Stop config thread */
3077 destroy_workqueue(priv->config_wq);
3078 4169
3079 /* Stop hardware */ 4170 /* Stop hardware */
3080 mwl8k_hw_reset(priv); 4171 mwl8k_hw_reset(priv);
3081 4172
3082 /* Return all skbs to mac80211 */ 4173 /* Return all skbs to mac80211 */
3083 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4174 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3084 mwl8k_txq_reclaim(hw, i, 1); 4175 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
3085 4176
3086 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4177 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3087 mwl8k_txq_deinit(hw, i); 4178 mwl8k_txq_deinit(hw, i);
3088 4179
3089 mwl8k_rxq_deinit(hw, 0); 4180 mwl8k_rxq_deinit(hw, 0);
3090 4181
3091 pci_free_consistent(priv->pdev, 4, 4182 pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma);
3092 priv->cookie, priv->cookie_dma);
3093 4183
3094 pci_iounmap(pdev, priv->regs); 4184 pci_iounmap(pdev, priv->regs);
4185 pci_iounmap(pdev, priv->sram);
3095 pci_set_drvdata(pdev, NULL); 4186 pci_set_drvdata(pdev, NULL);
3096 ieee80211_free_hw(hw); 4187 ieee80211_free_hw(hw);
3097 pci_release_regions(pdev); 4188 pci_release_regions(pdev);
@@ -3100,7 +4191,7 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
3100 4191
3101static struct pci_driver mwl8k_driver = { 4192static struct pci_driver mwl8k_driver = {
3102 .name = MWL8K_NAME, 4193 .name = MWL8K_NAME,
3103 .id_table = mwl8k_table, 4194 .id_table = mwl8k_pci_id_table,
3104 .probe = mwl8k_probe, 4195 .probe = mwl8k_probe,
3105 .remove = __devexit_p(mwl8k_remove), 4196 .remove = __devexit_p(mwl8k_remove),
3106 .shutdown = __devexit_p(mwl8k_shutdown), 4197 .shutdown = __devexit_p(mwl8k_shutdown),
@@ -3118,3 +4209,8 @@ static void __exit mwl8k_exit(void)
3118 4209
3119module_init(mwl8k_init); 4210module_init(mwl8k_init);
3120module_exit(mwl8k_exit); 4211module_exit(mwl8k_exit);
4212
4213MODULE_DESCRIPTION(MWL8K_DESC);
4214MODULE_VERSION(MWL8K_VERSION);
4215MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
4216MODULE_LICENSE("GPL");