blob: e5fc53dc6887411152063c4692517aef2fe7e1e1 [file] [log] [blame]
Bing Zhao5e6e3a92011-03-21 18:00:50 -07001/*
2 * Marvell Wireless LAN device driver: major functions
3 *
4 * Copyright (C) 2011, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License"). You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "main.h"
21#include "wmm.h"
22#include "cfg80211.h"
23#include "11n.h"
24
25#define VERSION "1.0"
26
27const char driver_version[] = "mwifiex " VERSION " (%s) ";
28
Bing Zhao5e6e3a92011-03-21 18:00:50 -070029static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
30 {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0},
31};
32
33static int drv_mode = DRV_MODE_STA;
34
Bing Zhao5e6e3a92011-03-21 18:00:50 -070035/* Supported drv_mode table */
36static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
37 {
Amitkumar Karwar2be78592011-04-15 20:50:42 -070038 .drv_mode = DRV_MODE_STA,
39 .intf_num = ARRAY_SIZE(mwifiex_bss_sta),
40 .bss_attr = mwifiex_bss_sta,
41 },
Bing Zhao5e6e3a92011-03-21 18:00:50 -070042};
43
44/*
45 * This function registers the device and performs all the necessary
46 * initializations.
47 *
48 * The following initialization operations are performed -
49 * - Allocate adapter structure
50 * - Save interface specific operations table in adapter
51 * - Call interface specific initialization routine
52 * - Allocate private structures
53 * - Set default adapter structure parameters
54 * - Initialize locks
55 *
56 * In case of any errors during inittialization, this function also ensures
57 * proper cleanup before exiting.
58 */
59static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
Amitkumar Karwar287546d2011-06-08 20:39:20 +053060 struct mwifiex_drv_mode *drv_mode_ptr,
61 void **padapter)
Bing Zhao5e6e3a92011-03-21 18:00:50 -070062{
Amitkumar Karwar2be78592011-04-15 20:50:42 -070063 struct mwifiex_adapter *adapter;
64 int i;
Bing Zhao5e6e3a92011-03-21 18:00:50 -070065
66 adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL);
Bing Zhao5e6e3a92011-03-21 18:00:50 -070067 if (!adapter)
Christoph Fritzb53575e2011-05-08 22:50:09 +020068 return -ENOMEM;
Bing Zhao5e6e3a92011-03-21 18:00:50 -070069
Amitkumar Karwar287546d2011-06-08 20:39:20 +053070 *padapter = adapter;
Bing Zhao5e6e3a92011-03-21 18:00:50 -070071 adapter->card = card;
72
73 /* Save interface specific operations in adapter */
74 memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops));
75
76 /* card specific initialization has been deferred until now .. */
Yogesh Ashok Powar636c4592011-04-15 20:50:40 -070077 if (adapter->if_ops.init_if(adapter))
Bing Zhao5e6e3a92011-03-21 18:00:50 -070078 goto error;
79
80 adapter->priv_num = 0;
Amitkumar Karwar2be78592011-04-15 20:50:42 -070081 for (i = 0; i < drv_mode_ptr->intf_num; i++) {
Bing Zhao5e6e3a92011-03-21 18:00:50 -070082 adapter->priv[i] = NULL;
83
Amitkumar Karwar2be78592011-04-15 20:50:42 -070084 if (!drv_mode_ptr->bss_attr[i].active)
Bing Zhao5e6e3a92011-03-21 18:00:50 -070085 continue;
86
Amitkumar Karwar2be78592011-04-15 20:50:42 -070087 /* Allocate memory for private structure */
Bing Zhao5e6e3a92011-03-21 18:00:50 -070088 adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private),
89 GFP_KERNEL);
90 if (!adapter->priv[i]) {
91 dev_err(adapter->dev, "%s: failed to alloc priv[%d]\n",
92 __func__, i);
93 goto error;
94 }
95
96 adapter->priv_num++;
Bing Zhao5e6e3a92011-03-21 18:00:50 -070097 adapter->priv[i]->adapter = adapter;
98 /* Save bss_type, frame_type & bss_priority */
Amitkumar Karwar2be78592011-04-15 20:50:42 -070099 adapter->priv[i]->bss_type = drv_mode_ptr->bss_attr[i].bss_type;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700100 adapter->priv[i]->frame_type =
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700101 drv_mode_ptr->bss_attr[i].frame_type;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700102 adapter->priv[i]->bss_priority =
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700103 drv_mode_ptr->bss_attr[i].bss_priority;
104
105 if (drv_mode_ptr->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA)
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700106 adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA;
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700107 else if (drv_mode_ptr->bss_attr[i].bss_type ==
108 MWIFIEX_BSS_TYPE_UAP)
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700109 adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP;
110
111 /* Save bss_index & bss_num */
112 adapter->priv[i]->bss_index = i;
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700113 adapter->priv[i]->bss_num = drv_mode_ptr->bss_attr[i].bss_num;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700114 }
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700115 adapter->drv_mode = drv_mode_ptr;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700116
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700117 if (mwifiex_init_lock_list(adapter))
118 goto error;
119
120 init_timer(&adapter->cmd_timer);
121 adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
122 adapter->cmd_timer.data = (unsigned long) adapter;
123
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700124 return 0;
125
126error:
127 dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
128
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700129 mwifiex_free_lock_list(adapter);
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700130 for (i = 0; i < drv_mode_ptr->intf_num; i++)
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700131 kfree(adapter->priv[i]);
132 kfree(adapter);
133
134 return -1;
135}
136
137/*
138 * This function unregisters the device and performs all the necessary
139 * cleanups.
140 *
141 * The following cleanup operations are performed -
142 * - Free the timers
143 * - Free beacon buffers
144 * - Free private structures
145 * - Free adapter structure
146 */
147static int mwifiex_unregister(struct mwifiex_adapter *adapter)
148{
Yogesh Ashok Powar270e58e2011-05-03 20:11:46 -0700149 s32 i;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700150
151 del_timer(&adapter->cmd_timer);
152
153 /* Free private structures */
154 for (i = 0; i < adapter->priv_num; i++) {
155 if (adapter->priv[i]) {
156 mwifiex_free_curr_bcn(adapter->priv[i]);
157 kfree(adapter->priv[i]);
158 }
159 }
160
161 kfree(adapter);
162 return 0;
163}
164
165/*
166 * The main process.
167 *
168 * This function is the main procedure of the driver and handles various driver
169 * operations. It runs in a loop and provides the core functionalities.
170 *
171 * The main responsibilities of this function are -
172 * - Ensure concurrency control
173 * - Handle pending interrupts and call interrupt handlers
174 * - Wake up the card if required
175 * - Handle command responses and call response handlers
176 * - Handle events and call event handlers
177 * - Execute pending commands
178 * - Transmit pending data packets
179 */
180int mwifiex_main_process(struct mwifiex_adapter *adapter)
181{
182 int ret = 0;
183 unsigned long flags;
184
185 spin_lock_irqsave(&adapter->main_proc_lock, flags);
186
187 /* Check if already processing */
188 if (adapter->mwifiex_processing) {
189 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
190 goto exit_main_proc;
191 } else {
192 adapter->mwifiex_processing = true;
193 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
194 }
195process_start:
196 do {
197 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
198 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
199 break;
200
201 /* Handle pending interrupt if any */
202 if (adapter->int_status) {
203 if (adapter->hs_activated)
204 mwifiex_process_hs_config(adapter);
205 adapter->if_ops.process_int_status(adapter);
206 }
207
208 /* Need to wake up the card ? */
209 if ((adapter->ps_state == PS_STATE_SLEEP) &&
210 (adapter->pm_wakeup_card_req &&
211 !adapter->pm_wakeup_fw_try) &&
212 (is_command_pending(adapter)
213 || !mwifiex_wmm_lists_empty(adapter))) {
214 adapter->pm_wakeup_fw_try = true;
215 adapter->if_ops.wakeup(adapter);
216 continue;
217 }
218 if (IS_CARD_RX_RCVD(adapter)) {
219 adapter->pm_wakeup_fw_try = false;
220 if (adapter->ps_state == PS_STATE_SLEEP)
221 adapter->ps_state = PS_STATE_AWAKE;
222 } else {
223 /* We have tried to wakeup the card already */
224 if (adapter->pm_wakeup_fw_try)
225 break;
226 if (adapter->ps_state != PS_STATE_AWAKE ||
227 adapter->tx_lock_flag)
228 break;
229
230 if (adapter->scan_processing || adapter->data_sent
231 || mwifiex_wmm_lists_empty(adapter)) {
232 if (adapter->cmd_sent || adapter->curr_cmd
233 || (!is_command_pending(adapter)))
234 break;
235 }
236 }
237
238 /* Check for Cmd Resp */
239 if (adapter->cmd_resp_received) {
240 adapter->cmd_resp_received = false;
241 mwifiex_process_cmdresp(adapter);
242
243 /* call mwifiex back when init_fw is done */
244 if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
245 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
246 mwifiex_init_fw_complete(adapter);
247 }
248 }
249
250 /* Check for event */
251 if (adapter->event_received) {
252 adapter->event_received = false;
253 mwifiex_process_event(adapter);
254 }
255
256 /* Check if we need to confirm Sleep Request
257 received previously */
258 if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
259 if (!adapter->cmd_sent && !adapter->curr_cmd)
260 mwifiex_check_ps_cond(adapter);
261 }
262
263 /* * The ps_state may have been changed during processing of
264 * Sleep Request event.
265 */
266 if ((adapter->ps_state == PS_STATE_SLEEP)
267 || (adapter->ps_state == PS_STATE_PRE_SLEEP)
268 || (adapter->ps_state == PS_STATE_SLEEP_CFM)
269 || adapter->tx_lock_flag)
270 continue;
271
272 if (!adapter->cmd_sent && !adapter->curr_cmd) {
273 if (mwifiex_exec_next_cmd(adapter) == -1) {
274 ret = -1;
275 break;
276 }
277 }
278
279 if (!adapter->scan_processing && !adapter->data_sent &&
280 !mwifiex_wmm_lists_empty(adapter)) {
281 mwifiex_wmm_process_tx(adapter);
282 if (adapter->hs_activated) {
283 adapter->is_hs_configured = false;
284 mwifiex_hs_activated_event
285 (mwifiex_get_priv
286 (adapter, MWIFIEX_BSS_ROLE_ANY),
287 false);
288 }
289 }
290
291 if (adapter->delay_null_pkt && !adapter->cmd_sent &&
292 !adapter->curr_cmd && !is_command_pending(adapter)
293 && mwifiex_wmm_lists_empty(adapter)) {
294 if (!mwifiex_send_null_packet
295 (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
296 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
297 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) {
298 adapter->delay_null_pkt = false;
299 adapter->ps_state = PS_STATE_SLEEP;
300 }
301 break;
302 }
303 } while (true);
304
305 if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
306 goto process_start;
307
308 spin_lock_irqsave(&adapter->main_proc_lock, flags);
309 adapter->mwifiex_processing = false;
310 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
311
312exit_main_proc:
313 if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
314 mwifiex_shutdown_drv(adapter);
315 return ret;
316}
317
318/*
319 * This function initializes the software.
320 *
321 * The main work includes allocating and initializing the adapter structure
322 * and initializing the private structures.
323 */
324static int
Amitkumar Karwar287546d2011-06-08 20:39:20 +0530325mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter)
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700326{
327 int i;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700328 struct mwifiex_drv_mode *drv_mode_ptr;
329
330 /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */
331 drv_mode_ptr = NULL;
332 for (i = 0; i < ARRAY_SIZE(mwifiex_drv_mode_tbl); i++) {
333 if (mwifiex_drv_mode_tbl[i].drv_mode == drv_mode) {
334 drv_mode_ptr = &mwifiex_drv_mode_tbl[i];
335 break;
336 }
337 }
338
339 if (!drv_mode_ptr) {
340 pr_err("invalid drv_mode=%d\n", drv_mode);
341 return -1;
342 }
343
Amitkumar Karwar287546d2011-06-08 20:39:20 +0530344 if (mwifiex_register(card, if_ops, drv_mode_ptr, padapter))
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700345 return -1;
346
347 return 0;
348}
349
350/*
351 * This function frees the adapter structure.
352 *
353 * Additionally, this closes the netlink socket, frees the timers
354 * and private structures.
355 */
356static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
357{
358 if (!adapter) {
359 pr_err("%s: adapter is NULL\n", __func__);
360 return;
361 }
362
363 mwifiex_unregister(adapter);
364 pr_debug("info: %s: free adapter\n", __func__);
365}
366
367/*
368 * This function initializes the hardware and firmware.
369 *
370 * The main initialization steps followed are -
371 * - Download the correct firmware to card
372 * - Allocate and initialize the adapter structure
373 * - Initialize the private structures
374 * - Issue the init commands to firmware
375 */
376static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
377{
Yogesh Ashok Powar270e58e2011-05-03 20:11:46 -0700378 int ret, err;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700379 struct mwifiex_fw_image fw;
380
381 memset(&fw, 0, sizeof(struct mwifiex_fw_image));
382
Amitkumar Karwar4a7f5db2011-05-23 18:00:17 -0700383 err = request_firmware(&adapter->firmware, adapter->fw_name,
384 adapter->dev);
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700385 if (err < 0) {
386 dev_err(adapter->dev, "request_firmware() returned"
387 " error code %#x\n", err);
388 ret = -1;
389 goto done;
390 }
391 fw.fw_buf = (u8 *) adapter->firmware->data;
392 fw.fw_len = adapter->firmware->size;
393
394 ret = mwifiex_dnld_fw(adapter, &fw);
395 if (ret == -1)
396 goto done;
397
398 dev_notice(adapter->dev, "WLAN FW is active\n");
399
400 adapter->init_wait_q_woken = false;
401 ret = mwifiex_init_fw(adapter);
402 if (ret == -1) {
403 goto done;
404 } else if (!ret) {
405 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
406 goto done;
407 }
408 /* Wait for mwifiex_init to complete */
409 wait_event_interruptible(adapter->init_wait_q,
410 adapter->init_wait_q_woken);
411 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) {
412 ret = -1;
413 goto done;
414 }
415 ret = 0;
416
417done:
418 if (adapter->firmware)
419 release_firmware(adapter->firmware);
420 if (ret)
421 ret = -1;
422 return ret;
423}
424
425/*
426 * This function fills a driver buffer.
427 *
428 * The function associates a given SKB with the provided driver buffer
429 * and also updates some of the SKB parameters, including IP header,
430 * priority and timestamp.
431 */
432static void
433mwifiex_fill_buffer(struct sk_buff *skb)
434{
Yogesh Ashok Powar270e58e2011-05-03 20:11:46 -0700435 struct ethhdr *eth;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700436 struct iphdr *iph;
437 struct timeval tv;
438 u8 tid = 0;
439
440 eth = (struct ethhdr *) skb->data;
441 switch (eth->h_proto) {
442 case __constant_htons(ETH_P_IP):
443 iph = ip_hdr(skb);
444 tid = IPTOS_PREC(iph->tos);
445 pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
446 eth->h_proto, tid, skb->priority);
447 break;
448 case __constant_htons(ETH_P_ARP):
449 pr_debug("data: ARP packet: %04x\n", eth->h_proto);
450 default:
451 break;
452 }
453/* Offset for TOS field in the IP header */
454#define IPTOS_OFFSET 5
455 tid = (tid >> IPTOS_OFFSET);
456 skb->priority = tid;
457 /* Record the current time the packet was queued; used to
458 determine the amount of time the packet was queued in
459 the driver before it was sent to the firmware.
460 The delay is then sent along with the packet to the
461 firmware for aggregate delay calculation for stats and
462 MSDU lifetime expiry.
463 */
464 do_gettimeofday(&tv);
465 skb->tstamp = timeval_to_ktime(tv);
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700466}
467
468/*
469 * CFG802.11 network device handler for open.
470 *
471 * Starts the data queue.
472 */
473static int
474mwifiex_open(struct net_device *dev)
475{
476 netif_start_queue(dev);
477 return 0;
478}
479
480/*
481 * CFG802.11 network device handler for close.
482 */
483static int
484mwifiex_close(struct net_device *dev)
485{
486 return 0;
487}
488
489/*
490 * CFG802.11 network device handler for data transmission.
491 */
492static int
493mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
494{
495 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
Yogesh Ashok Powar270e58e2011-05-03 20:11:46 -0700496 struct sk_buff *new_skb;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700497 struct mwifiex_txinfo *tx_info;
498
499 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
500 jiffies, priv->bss_index);
501
502 if (priv->adapter->surprise_removed) {
Christoph Fritzb53575e2011-05-08 22:50:09 +0200503 kfree_skb(skb);
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700504 priv->stats.tx_dropped++;
505 return 0;
506 }
507 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
508 dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
Christoph Fritzb53575e2011-05-08 22:50:09 +0200509 kfree_skb(skb);
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700510 priv->stats.tx_dropped++;
511 return 0;
512 }
513 if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
514 dev_dbg(priv->adapter->dev,
515 "data: Tx: insufficient skb headroom %d\n",
516 skb_headroom(skb));
517 /* Insufficient skb headroom - allocate a new skb */
518 new_skb =
519 skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
520 if (unlikely(!new_skb)) {
521 dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n");
Christoph Fritzb53575e2011-05-08 22:50:09 +0200522 kfree_skb(skb);
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700523 priv->stats.tx_dropped++;
524 return 0;
525 }
526 kfree_skb(skb);
527 skb = new_skb;
528 dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
529 skb_headroom(skb));
530 }
531
532 tx_info = MWIFIEX_SKB_TXCB(skb);
533 tx_info->bss_index = priv->bss_index;
534 mwifiex_fill_buffer(skb);
535
536 mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
537 atomic_inc(&priv->adapter->tx_pending);
538
539 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
540 netif_stop_queue(priv->netdev);
541 dev->trans_start = jiffies;
542 }
543
544 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
545
546 return 0;
547}
548
549/*
550 * CFG802.11 network device handler for setting MAC address.
551 */
552static int
553mwifiex_set_mac_address(struct net_device *dev, void *addr)
554{
555 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
Amitkumar Karwara5ffddb2011-06-20 15:21:48 -0700556 struct sockaddr *hw_addr = addr;
Yogesh Ashok Powar270e58e2011-05-03 20:11:46 -0700557 int ret;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700558
559 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
560
Amitkumar Karwar600f5d92011-04-13 17:27:06 -0700561 /* Send request to firmware */
562 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
563 HostCmd_ACT_GEN_SET, 0, NULL);
564
565 if (!ret)
566 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
567 else
568 dev_err(priv->adapter->dev, "set mac address failed: ret=%d"
569 "\n", ret);
570
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700571 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
572
Amitkumar Karwar600f5d92011-04-13 17:27:06 -0700573 return ret;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700574}
575
576/*
577 * CFG802.11 network device handler for setting multicast list.
578 */
579static void mwifiex_set_multicast_list(struct net_device *dev)
580{
581 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
Amitkumar Karwar600f5d92011-04-13 17:27:06 -0700582 struct mwifiex_multicast_list mcast_list;
583
584 if (dev->flags & IFF_PROMISC) {
585 mcast_list.mode = MWIFIEX_PROMISC_MODE;
586 } else if (dev->flags & IFF_ALLMULTI ||
587 netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
588 mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
589 } else {
590 mcast_list.mode = MWIFIEX_MULTICAST_MODE;
591 if (netdev_mc_count(dev))
592 mcast_list.num_multicast_addr =
593 mwifiex_copy_mcast_addr(&mcast_list, dev);
594 }
595 mwifiex_request_set_multicast_list(priv, &mcast_list);
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700596}
597
598/*
599 * CFG802.11 network device handler for transmission timeout.
600 */
601static void
602mwifiex_tx_timeout(struct net_device *dev)
603{
604 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
605
606 dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
607 jiffies, priv->bss_index);
608 dev->trans_start = jiffies;
609 priv->num_tx_timeout++;
610}
611
612/*
613 * CFG802.11 network device handler for statistics retrieval.
614 */
615static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
616{
617 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
618
619 return &priv->stats;
620}
621
622/* Network device handlers */
623static const struct net_device_ops mwifiex_netdev_ops = {
624 .ndo_open = mwifiex_open,
625 .ndo_stop = mwifiex_close,
626 .ndo_start_xmit = mwifiex_hard_start_xmit,
627 .ndo_set_mac_address = mwifiex_set_mac_address,
628 .ndo_tx_timeout = mwifiex_tx_timeout,
629 .ndo_get_stats = mwifiex_get_stats,
630 .ndo_set_multicast_list = mwifiex_set_multicast_list,
631};
632
633/*
634 * This function initializes the private structure parameters.
635 *
636 * The following wait queues are initialized -
637 * - IOCTL wait queue
638 * - Command wait queue
639 * - Statistics wait queue
640 *
641 * ...and the following default parameters are set -
642 * - Current key index : Set to 0
643 * - Rate index : Set to auto
644 * - Media connected : Set to disconnected
645 * - Adhoc link sensed : Set to false
646 * - Nick name : Set to null
647 * - Number of Tx timeout : Set to 0
648 * - Device address : Set to current address
649 *
650 * In addition, the CFG80211 work queue is also created.
651 */
652static void
653mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
654{
655 dev->netdev_ops = &mwifiex_netdev_ops;
656 /* Initialize private structure */
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700657 priv->current_key_index = 0;
658 priv->media_connected = false;
659 memset(&priv->nick_name, 0, sizeof(priv->nick_name));
660 priv->num_tx_timeout = 0;
661 priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
662 INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results);
663 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
664}
665
666/*
667 * This function adds a new logical interface.
668 *
669 * It allocates, initializes and registers the interface by performing
670 * the following opearations -
671 * - Allocate a new net device structure
672 * - Assign device name
673 * - Register the new device with CFG80211 subsystem
674 * - Initialize semaphore and private structure
675 * - Register the new device with kernel
676 * - Create the complete debug FS structure if configured
677 */
678static struct mwifiex_private *mwifiex_add_interface(
679 struct mwifiex_adapter *adapter,
680 u8 bss_index, u8 bss_type)
681{
Yogesh Ashok Powar270e58e2011-05-03 20:11:46 -0700682 struct net_device *dev;
683 struct mwifiex_private *priv;
684 void *mdev_priv;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700685
686 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d",
687 ether_setup, 1);
688 if (!dev) {
689 dev_err(adapter->dev, "no memory available for netdevice\n");
690 goto error;
691 }
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700692
693 if (mwifiex_register_cfg80211(dev, adapter->priv[bss_index]->curr_addr,
694 adapter->priv[bss_index]) != 0) {
695 dev_err(adapter->dev, "cannot register netdevice with cfg80211\n");
696 goto error;
697 }
698 /* Save the priv pointer in netdev */
699 priv = adapter->priv[bss_index];
700 mdev_priv = netdev_priv(dev);
701 *((unsigned long *) mdev_priv) = (unsigned long) priv;
702
703 priv->netdev = dev;
704
705 sema_init(&priv->async_sem, 1);
706 priv->scan_pending_on_block = false;
707
708 mwifiex_init_priv_params(priv, dev);
709
710 SET_NETDEV_DEV(dev, adapter->dev);
711
712 /* Register network device */
713 if (register_netdev(dev)) {
714 dev_err(adapter->dev, "cannot register virtual network device\n");
715 goto error;
716 }
717
718 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
719#ifdef CONFIG_DEBUG_FS
720 mwifiex_dev_debugfs_init(priv);
721#endif
722 return priv;
723error:
724 if (dev)
725 free_netdev(dev);
726 return NULL;
727}
728
729/*
730 * This function removes a logical interface.
731 *
732 * It deregisters, resets and frees the interface by performing
733 * the following operations -
734 * - Disconnect the device if connected, send wireless event to
735 * notify applications.
736 * - Remove the debug FS structure if configured
737 * - Unregister the device from kernel
738 * - Free the net device structure
739 * - Cancel all works and destroy work queue
740 * - Unregister and free the wireless device from CFG80211 subsystem
741 */
742static void
743mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
744{
Yogesh Ashok Powar270e58e2011-05-03 20:11:46 -0700745 struct net_device *dev;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700746 struct mwifiex_private *priv = adapter->priv[bss_index];
747
748 if (!priv)
749 return;
750 dev = priv->netdev;
751
752 if (priv->media_connected)
753 priv->media_connected = false;
754
755#ifdef CONFIG_DEBUG_FS
756 mwifiex_dev_debugfs_remove(priv);
757#endif
758 /* Last reference is our one */
759 dev_dbg(adapter->dev, "info: %s: refcnt = %d\n",
760 dev->name, netdev_refcnt_read(dev));
761
762 if (dev->reg_state == NETREG_REGISTERED)
763 unregister_netdev(dev);
764
765 /* Clear the priv in adapter */
766 priv->netdev = NULL;
767 if (dev)
768 free_netdev(dev);
769
770 cancel_work_sync(&priv->cfg_workqueue);
771 flush_workqueue(priv->workqueue);
772 destroy_workqueue(priv->workqueue);
773 wiphy_unregister(priv->wdev->wiphy);
774 wiphy_free(priv->wdev->wiphy);
775 kfree(priv->wdev);
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700776}
777
778/*
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700779 * This function check if command is pending.
780 */
781int is_command_pending(struct mwifiex_adapter *adapter)
782{
783 unsigned long flags;
784 int is_cmd_pend_q_empty;
785
786 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
787 is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
788 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
789
790 return !is_cmd_pend_q_empty;
791}
792
793/*
794 * This function returns the correct private structure pointer based
795 * upon the BSS number.
796 */
797struct mwifiex_private *
798mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
799{
800 if (!adapter || (bss_index >= adapter->priv_num))
801 return NULL;
802 return adapter->priv[bss_index];
803}
804
805/*
806 * This is the main work queue function.
807 *
808 * It handles the main process, which in turn handles the complete
809 * driver operations.
810 */
811static void mwifiex_main_work_queue(struct work_struct *work)
812{
813 struct mwifiex_adapter *adapter =
814 container_of(work, struct mwifiex_adapter, main_work);
815
816 if (adapter->surprise_removed)
817 return;
818 mwifiex_main_process(adapter);
819}
820
821/*
822 * This function cancels all works in the queue and destroys
823 * the main workqueue.
824 */
825static void
826mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
827{
828 flush_workqueue(adapter->workqueue);
829 destroy_workqueue(adapter->workqueue);
830 adapter->workqueue = NULL;
831}
832
833/*
834 * This function adds the card.
835 *
836 * This function follows the following major steps to set up the device -
837 * - Initialize software. This includes probing the card, registering
838 * the interface operations table, and allocating/initializing the
839 * adapter structure
840 * - Set up the netlink socket
841 * - Create and start the main work queue
842 * - Register the device
843 * - Initialize firmware and hardware
844 * - Add logical interfaces
845 */
846int
847mwifiex_add_card(void *card, struct semaphore *sem,
848 struct mwifiex_if_ops *if_ops)
849{
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700850 int i;
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700851 struct mwifiex_adapter *adapter;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700852
853 if (down_interruptible(sem))
854 goto exit_sem_err;
855
Amitkumar Karwar287546d2011-06-08 20:39:20 +0530856 if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) {
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700857 pr_err("%s: software init failed\n", __func__);
858 goto err_init_sw;
859 }
860
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700861 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700862 adapter->surprise_removed = false;
863 init_waitqueue_head(&adapter->init_wait_q);
864 adapter->is_suspended = false;
865 adapter->hs_activated = false;
866 init_waitqueue_head(&adapter->hs_activate_wait_q);
Amitkumar Karwar600f5d92011-04-13 17:27:06 -0700867 adapter->cmd_wait_q_required = false;
868 init_waitqueue_head(&adapter->cmd_wait_q.wait);
869 adapter->cmd_wait_q.condition = false;
870 adapter->cmd_wait_q.status = 0;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700871
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700872 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
873 if (!adapter->workqueue)
874 goto err_kmalloc;
875
876 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
877
878 /* Register the device. Fill up the private data structure with relevant
879 information from the card and request for the required IRQ. */
880 if (adapter->if_ops.register_dev(adapter)) {
881 pr_err("%s: failed to register mwifiex device\n", __func__);
882 goto err_registerdev;
883 }
884
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700885 if (mwifiex_init_hw_fw(adapter)) {
886 pr_err("%s: firmware init failed\n", __func__);
887 goto err_init_fw;
888 }
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700889
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700890 /* Add interfaces */
Amitkumar Karwar2be78592011-04-15 20:50:42 -0700891 for (i = 0; i < adapter->drv_mode->intf_num; i++) {
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700892 if (!mwifiex_add_interface(adapter, i,
893 adapter->drv_mode->bss_attr[i].bss_type)) {
Yogesh Ashok Powar636c4592011-04-15 20:50:40 -0700894 goto err_add_intf;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700895 }
896 }
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700897
898 up(sem);
899
900 return 0;
901
902err_add_intf:
903 for (i = 0; i < adapter->priv_num; i++)
904 mwifiex_remove_interface(adapter, i);
905err_init_fw:
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700906 pr_debug("info: %s: unregister device\n", __func__);
907 adapter->if_ops.unregister_dev(adapter);
908err_registerdev:
909 adapter->surprise_removed = true;
910 mwifiex_terminate_workqueue(adapter);
911err_kmalloc:
912 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
913 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
914 pr_debug("info: %s: shutdown mwifiex\n", __func__);
915 adapter->init_wait_q_woken = false;
Yogesh Ashok Powar636c4592011-04-15 20:50:40 -0700916
917 if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700918 wait_event_interruptible(adapter->init_wait_q,
919 adapter->init_wait_q_woken);
920 }
921
922 mwifiex_free_adapter(adapter);
923
924err_init_sw:
925 up(sem);
926
927exit_sem_err:
928 return -1;
929}
930EXPORT_SYMBOL_GPL(mwifiex_add_card);
931
932/*
933 * This function removes the card.
934 *
935 * This function follows the following major steps to remove the device -
936 * - Stop data traffic
937 * - Shutdown firmware
938 * - Remove the logical interfaces
939 * - Terminate the work queue
940 * - Unregister the device
941 * - Free the adapter structure
942 */
943int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
944{
945 struct mwifiex_private *priv = NULL;
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700946 int i;
947
948 if (down_interruptible(sem))
949 goto exit_sem_err;
950
951 if (!adapter)
952 goto exit_remove;
953
954 adapter->surprise_removed = true;
955
956 /* Stop data */
957 for (i = 0; i < adapter->priv_num; i++) {
958 priv = adapter->priv[i];
959 if (priv) {
960 if (!netif_queue_stopped(priv->netdev))
961 netif_stop_queue(priv->netdev);
962 if (netif_carrier_ok(priv->netdev))
963 netif_carrier_off(priv->netdev);
964 }
965 }
966
967 dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n");
968 adapter->init_wait_q_woken = false;
Yogesh Ashok Powar636c4592011-04-15 20:50:40 -0700969
970 if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700971 wait_event_interruptible(adapter->init_wait_q,
972 adapter->init_wait_q_woken);
973 dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n");
974 if (atomic_read(&adapter->rx_pending) ||
975 atomic_read(&adapter->tx_pending) ||
Amitkumar Karwar600f5d92011-04-13 17:27:06 -0700976 atomic_read(&adapter->cmd_pending)) {
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700977 dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, "
Amitkumar Karwar600f5d92011-04-13 17:27:06 -0700978 "cmd_pending=%d\n",
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700979 atomic_read(&adapter->rx_pending),
980 atomic_read(&adapter->tx_pending),
Amitkumar Karwar600f5d92011-04-13 17:27:06 -0700981 atomic_read(&adapter->cmd_pending));
Bing Zhao5e6e3a92011-03-21 18:00:50 -0700982 }
983
984 /* Remove interface */
985 for (i = 0; i < adapter->priv_num; i++)
986 mwifiex_remove_interface(adapter, i);
987
988 mwifiex_terminate_workqueue(adapter);
989
990 /* Unregister device */
991 dev_dbg(adapter->dev, "info: unregister device\n");
992 adapter->if_ops.unregister_dev(adapter);
993 /* Free adapter structure */
994 dev_dbg(adapter->dev, "info: free adapter\n");
995 mwifiex_free_adapter(adapter);
996
997exit_remove:
998 up(sem);
999exit_sem_err:
1000 return 0;
1001}
1002EXPORT_SYMBOL_GPL(mwifiex_remove_card);
1003
1004/*
1005 * This function initializes the module.
1006 *
1007 * The debug FS is also initialized if configured.
1008 */
1009static int
1010mwifiex_init_module(void)
1011{
1012#ifdef CONFIG_DEBUG_FS
1013 mwifiex_debugfs_init();
1014#endif
1015 return 0;
1016}
1017
1018/*
1019 * This function cleans up the module.
1020 *
1021 * The debug FS is removed if available.
1022 */
1023static void
1024mwifiex_cleanup_module(void)
1025{
1026#ifdef CONFIG_DEBUG_FS
1027 mwifiex_debugfs_remove();
1028#endif
1029}
1030
1031module_init(mwifiex_init_module);
1032module_exit(mwifiex_cleanup_module);
1033
1034MODULE_AUTHOR("Marvell International Ltd.");
1035MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION);
1036MODULE_VERSION(VERSION);
1037MODULE_LICENSE("GPL v2");