mwifiex: fix simultaneous assoc and scan issue
[deliverable/linux.git] / drivers / net / wireless / mwifiex / main.c
CommitLineData
5e6e3a92
BZ
1/*
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
29struct mwifiex_adapter *g_adapter;
30EXPORT_SYMBOL_GPL(g_adapter);
31
32static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
33 {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0},
34};
35
36static int drv_mode = DRV_MODE_STA;
37
38static char fw_name[32] = DEFAULT_FW_NAME;
39
40/* Supported drv_mode table */
41static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
42 {
2be7859f
AK
43 .drv_mode = DRV_MODE_STA,
44 .intf_num = ARRAY_SIZE(mwifiex_bss_sta),
45 .bss_attr = mwifiex_bss_sta,
46 },
5e6e3a92
BZ
47};
48
49/*
50 * This function registers the device and performs all the necessary
51 * initializations.
52 *
53 * The following initialization operations are performed -
54 * - Allocate adapter structure
55 * - Save interface specific operations table in adapter
56 * - Call interface specific initialization routine
57 * - Allocate private structures
58 * - Set default adapter structure parameters
59 * - Initialize locks
60 *
61 * In case of any errors during inittialization, this function also ensures
62 * proper cleanup before exiting.
63 */
64static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
2be7859f 65 struct mwifiex_drv_mode *drv_mode_ptr)
5e6e3a92 66{
2be7859f
AK
67 struct mwifiex_adapter *adapter;
68 int i;
5e6e3a92
BZ
69
70 adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL);
5e6e3a92
BZ
71 if (!adapter)
72 return -1;
73
74 g_adapter = adapter;
75 adapter->card = card;
76
77 /* Save interface specific operations in adapter */
78 memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops));
79
80 /* card specific initialization has been deferred until now .. */
636c4598 81 if (adapter->if_ops.init_if(adapter))
5e6e3a92
BZ
82 goto error;
83
84 adapter->priv_num = 0;
2be7859f 85 for (i = 0; i < drv_mode_ptr->intf_num; i++) {
5e6e3a92
BZ
86 adapter->priv[i] = NULL;
87
2be7859f 88 if (!drv_mode_ptr->bss_attr[i].active)
5e6e3a92
BZ
89 continue;
90
2be7859f 91 /* Allocate memory for private structure */
5e6e3a92
BZ
92 adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private),
93 GFP_KERNEL);
94 if (!adapter->priv[i]) {
95 dev_err(adapter->dev, "%s: failed to alloc priv[%d]\n",
96 __func__, i);
97 goto error;
98 }
99
100 adapter->priv_num++;
5e6e3a92
BZ
101 adapter->priv[i]->adapter = adapter;
102 /* Save bss_type, frame_type & bss_priority */
2be7859f 103 adapter->priv[i]->bss_type = drv_mode_ptr->bss_attr[i].bss_type;
5e6e3a92 104 adapter->priv[i]->frame_type =
2be7859f 105 drv_mode_ptr->bss_attr[i].frame_type;
5e6e3a92 106 adapter->priv[i]->bss_priority =
2be7859f
AK
107 drv_mode_ptr->bss_attr[i].bss_priority;
108
109 if (drv_mode_ptr->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA)
5e6e3a92 110 adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA;
2be7859f
AK
111 else if (drv_mode_ptr->bss_attr[i].bss_type ==
112 MWIFIEX_BSS_TYPE_UAP)
5e6e3a92
BZ
113 adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP;
114
115 /* Save bss_index & bss_num */
116 adapter->priv[i]->bss_index = i;
2be7859f 117 adapter->priv[i]->bss_num = drv_mode_ptr->bss_attr[i].bss_num;
5e6e3a92 118 }
2be7859f 119 adapter->drv_mode = drv_mode_ptr;
5e6e3a92 120
5e6e3a92
BZ
121 if (mwifiex_init_lock_list(adapter))
122 goto error;
123
124 init_timer(&adapter->cmd_timer);
125 adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
126 adapter->cmd_timer.data = (unsigned long) adapter;
127
5e6e3a92
BZ
128 return 0;
129
130error:
131 dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
132
5e6e3a92 133 mwifiex_free_lock_list(adapter);
2be7859f 134 for (i = 0; i < drv_mode_ptr->intf_num; i++)
5e6e3a92
BZ
135 kfree(adapter->priv[i]);
136 kfree(adapter);
137
138 return -1;
139}
140
141/*
142 * This function unregisters the device and performs all the necessary
143 * cleanups.
144 *
145 * The following cleanup operations are performed -
146 * - Free the timers
147 * - Free beacon buffers
148 * - Free private structures
149 * - Free adapter structure
150 */
151static int mwifiex_unregister(struct mwifiex_adapter *adapter)
152{
153 s32 i = 0;
154
155 del_timer(&adapter->cmd_timer);
156
157 /* Free private structures */
158 for (i = 0; i < adapter->priv_num; i++) {
159 if (adapter->priv[i]) {
160 mwifiex_free_curr_bcn(adapter->priv[i]);
161 kfree(adapter->priv[i]);
162 }
163 }
164
165 kfree(adapter);
166 return 0;
167}
168
169/*
170 * The main process.
171 *
172 * This function is the main procedure of the driver and handles various driver
173 * operations. It runs in a loop and provides the core functionalities.
174 *
175 * The main responsibilities of this function are -
176 * - Ensure concurrency control
177 * - Handle pending interrupts and call interrupt handlers
178 * - Wake up the card if required
179 * - Handle command responses and call response handlers
180 * - Handle events and call event handlers
181 * - Execute pending commands
182 * - Transmit pending data packets
183 */
184int mwifiex_main_process(struct mwifiex_adapter *adapter)
185{
186 int ret = 0;
187 unsigned long flags;
188
189 spin_lock_irqsave(&adapter->main_proc_lock, flags);
190
191 /* Check if already processing */
192 if (adapter->mwifiex_processing) {
193 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
194 goto exit_main_proc;
195 } else {
196 adapter->mwifiex_processing = true;
197 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
198 }
199process_start:
200 do {
201 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
202 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
203 break;
204
205 /* Handle pending interrupt if any */
206 if (adapter->int_status) {
207 if (adapter->hs_activated)
208 mwifiex_process_hs_config(adapter);
209 adapter->if_ops.process_int_status(adapter);
210 }
211
212 /* Need to wake up the card ? */
213 if ((adapter->ps_state == PS_STATE_SLEEP) &&
214 (adapter->pm_wakeup_card_req &&
215 !adapter->pm_wakeup_fw_try) &&
216 (is_command_pending(adapter)
217 || !mwifiex_wmm_lists_empty(adapter))) {
218 adapter->pm_wakeup_fw_try = true;
219 adapter->if_ops.wakeup(adapter);
220 continue;
221 }
222 if (IS_CARD_RX_RCVD(adapter)) {
223 adapter->pm_wakeup_fw_try = false;
224 if (adapter->ps_state == PS_STATE_SLEEP)
225 adapter->ps_state = PS_STATE_AWAKE;
226 } else {
227 /* We have tried to wakeup the card already */
228 if (adapter->pm_wakeup_fw_try)
229 break;
230 if (adapter->ps_state != PS_STATE_AWAKE ||
231 adapter->tx_lock_flag)
232 break;
233
234 if (adapter->scan_processing || adapter->data_sent
235 || mwifiex_wmm_lists_empty(adapter)) {
236 if (adapter->cmd_sent || adapter->curr_cmd
237 || (!is_command_pending(adapter)))
238 break;
239 }
240 }
241
242 /* Check for Cmd Resp */
243 if (adapter->cmd_resp_received) {
244 adapter->cmd_resp_received = false;
245 mwifiex_process_cmdresp(adapter);
246
247 /* call mwifiex back when init_fw is done */
248 if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
249 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
250 mwifiex_init_fw_complete(adapter);
251 }
252 }
253
254 /* Check for event */
255 if (adapter->event_received) {
256 adapter->event_received = false;
257 mwifiex_process_event(adapter);
258 }
259
260 /* Check if we need to confirm Sleep Request
261 received previously */
262 if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
263 if (!adapter->cmd_sent && !adapter->curr_cmd)
264 mwifiex_check_ps_cond(adapter);
265 }
266
267 /* * The ps_state may have been changed during processing of
268 * Sleep Request event.
269 */
270 if ((adapter->ps_state == PS_STATE_SLEEP)
271 || (adapter->ps_state == PS_STATE_PRE_SLEEP)
272 || (adapter->ps_state == PS_STATE_SLEEP_CFM)
273 || adapter->tx_lock_flag)
274 continue;
275
276 if (!adapter->cmd_sent && !adapter->curr_cmd) {
277 if (mwifiex_exec_next_cmd(adapter) == -1) {
278 ret = -1;
279 break;
280 }
281 }
282
283 if (!adapter->scan_processing && !adapter->data_sent &&
284 !mwifiex_wmm_lists_empty(adapter)) {
285 mwifiex_wmm_process_tx(adapter);
286 if (adapter->hs_activated) {
287 adapter->is_hs_configured = false;
288 mwifiex_hs_activated_event
289 (mwifiex_get_priv
290 (adapter, MWIFIEX_BSS_ROLE_ANY),
291 false);
292 }
293 }
294
295 if (adapter->delay_null_pkt && !adapter->cmd_sent &&
296 !adapter->curr_cmd && !is_command_pending(adapter)
297 && mwifiex_wmm_lists_empty(adapter)) {
298 if (!mwifiex_send_null_packet
299 (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
300 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
301 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) {
302 adapter->delay_null_pkt = false;
303 adapter->ps_state = PS_STATE_SLEEP;
304 }
305 break;
306 }
307 } while (true);
308
309 if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
310 goto process_start;
311
312 spin_lock_irqsave(&adapter->main_proc_lock, flags);
313 adapter->mwifiex_processing = false;
314 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
315
316exit_main_proc:
317 if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
318 mwifiex_shutdown_drv(adapter);
319 return ret;
320}
321
322/*
323 * This function initializes the software.
324 *
325 * The main work includes allocating and initializing the adapter structure
326 * and initializing the private structures.
327 */
328static int
2be7859f 329mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops)
5e6e3a92
BZ
330{
331 int i;
5e6e3a92
BZ
332 struct mwifiex_drv_mode *drv_mode_ptr;
333
334 /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */
335 drv_mode_ptr = NULL;
336 for (i = 0; i < ARRAY_SIZE(mwifiex_drv_mode_tbl); i++) {
337 if (mwifiex_drv_mode_tbl[i].drv_mode == drv_mode) {
338 drv_mode_ptr = &mwifiex_drv_mode_tbl[i];
339 break;
340 }
341 }
342
343 if (!drv_mode_ptr) {
344 pr_err("invalid drv_mode=%d\n", drv_mode);
345 return -1;
346 }
347
2be7859f 348 if (mwifiex_register(card, if_ops, drv_mode_ptr))
5e6e3a92
BZ
349 return -1;
350
351 return 0;
352}
353
354/*
355 * This function frees the adapter structure.
356 *
357 * Additionally, this closes the netlink socket, frees the timers
358 * and private structures.
359 */
360static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
361{
362 if (!adapter) {
363 pr_err("%s: adapter is NULL\n", __func__);
364 return;
365 }
366
367 mwifiex_unregister(adapter);
368 pr_debug("info: %s: free adapter\n", __func__);
369}
370
371/*
372 * This function initializes the hardware and firmware.
373 *
374 * The main initialization steps followed are -
375 * - Download the correct firmware to card
376 * - Allocate and initialize the adapter structure
377 * - Initialize the private structures
378 * - Issue the init commands to firmware
379 */
380static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
381{
382 int ret = 0;
383 int err;
384 struct mwifiex_fw_image fw;
385
386 memset(&fw, 0, sizeof(struct mwifiex_fw_image));
387
388 switch (adapter->revision_id) {
389 case SD8787_W0:
390 case SD8787_W1:
391 strcpy(fw_name, SD8787_W1_FW_NAME);
392 break;
393 case SD8787_A0:
394 case SD8787_A1:
395 strcpy(fw_name, SD8787_AX_FW_NAME);
396 break;
397 default:
398 break;
399 }
400
401 err = request_firmware(&adapter->firmware, fw_name, adapter->dev);
402 if (err < 0) {
403 dev_err(adapter->dev, "request_firmware() returned"
404 " error code %#x\n", err);
405 ret = -1;
406 goto done;
407 }
408 fw.fw_buf = (u8 *) adapter->firmware->data;
409 fw.fw_len = adapter->firmware->size;
410
411 ret = mwifiex_dnld_fw(adapter, &fw);
412 if (ret == -1)
413 goto done;
414
415 dev_notice(adapter->dev, "WLAN FW is active\n");
416
417 adapter->init_wait_q_woken = false;
418 ret = mwifiex_init_fw(adapter);
419 if (ret == -1) {
420 goto done;
421 } else if (!ret) {
422 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
423 goto done;
424 }
425 /* Wait for mwifiex_init to complete */
426 wait_event_interruptible(adapter->init_wait_q,
427 adapter->init_wait_q_woken);
428 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) {
429 ret = -1;
430 goto done;
431 }
432 ret = 0;
433
434done:
435 if (adapter->firmware)
436 release_firmware(adapter->firmware);
437 if (ret)
438 ret = -1;
439 return ret;
440}
441
442/*
443 * This function fills a driver buffer.
444 *
445 * The function associates a given SKB with the provided driver buffer
446 * and also updates some of the SKB parameters, including IP header,
447 * priority and timestamp.
448 */
449static void
450mwifiex_fill_buffer(struct sk_buff *skb)
451{
452 struct ethhdr *eth = NULL;
453 struct iphdr *iph;
454 struct timeval tv;
455 u8 tid = 0;
456
457 eth = (struct ethhdr *) skb->data;
458 switch (eth->h_proto) {
459 case __constant_htons(ETH_P_IP):
460 iph = ip_hdr(skb);
461 tid = IPTOS_PREC(iph->tos);
462 pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
463 eth->h_proto, tid, skb->priority);
464 break;
465 case __constant_htons(ETH_P_ARP):
466 pr_debug("data: ARP packet: %04x\n", eth->h_proto);
467 default:
468 break;
469 }
470/* Offset for TOS field in the IP header */
471#define IPTOS_OFFSET 5
472 tid = (tid >> IPTOS_OFFSET);
473 skb->priority = tid;
474 /* Record the current time the packet was queued; used to
475 determine the amount of time the packet was queued in
476 the driver before it was sent to the firmware.
477 The delay is then sent along with the packet to the
478 firmware for aggregate delay calculation for stats and
479 MSDU lifetime expiry.
480 */
481 do_gettimeofday(&tv);
482 skb->tstamp = timeval_to_ktime(tv);
5e6e3a92
BZ
483}
484
485/*
486 * CFG802.11 network device handler for open.
487 *
488 * Starts the data queue.
489 */
490static int
491mwifiex_open(struct net_device *dev)
492{
493 netif_start_queue(dev);
494 return 0;
495}
496
497/*
498 * CFG802.11 network device handler for close.
499 */
500static int
501mwifiex_close(struct net_device *dev)
502{
503 return 0;
504}
505
506/*
507 * CFG802.11 network device handler for data transmission.
508 */
509static int
510mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
511{
512 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
513 struct sk_buff *new_skb = NULL;
514 struct mwifiex_txinfo *tx_info;
515
516 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
517 jiffies, priv->bss_index);
518
519 if (priv->adapter->surprise_removed) {
520 kfree(skb);
521 priv->stats.tx_dropped++;
522 return 0;
523 }
524 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
525 dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
526 kfree(skb);
527 priv->stats.tx_dropped++;
528 return 0;
529 }
530 if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
531 dev_dbg(priv->adapter->dev,
532 "data: Tx: insufficient skb headroom %d\n",
533 skb_headroom(skb));
534 /* Insufficient skb headroom - allocate a new skb */
535 new_skb =
536 skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
537 if (unlikely(!new_skb)) {
538 dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n");
539 kfree(skb);
540 priv->stats.tx_dropped++;
541 return 0;
542 }
543 kfree_skb(skb);
544 skb = new_skb;
545 dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
546 skb_headroom(skb));
547 }
548
549 tx_info = MWIFIEX_SKB_TXCB(skb);
550 tx_info->bss_index = priv->bss_index;
551 mwifiex_fill_buffer(skb);
552
553 mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
554 atomic_inc(&priv->adapter->tx_pending);
555
556 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
557 netif_stop_queue(priv->netdev);
558 dev->trans_start = jiffies;
559 }
560
561 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
562
563 return 0;
564}
565
566/*
567 * CFG802.11 network device handler for setting MAC address.
568 */
569static int
570mwifiex_set_mac_address(struct net_device *dev, void *addr)
571{
572 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
573 struct sockaddr *hw_addr = (struct sockaddr *) addr;
600f5d90 574 int ret = 0;
5e6e3a92
BZ
575
576 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
577
600f5d90
AK
578 /* Send request to firmware */
579 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
580 HostCmd_ACT_GEN_SET, 0, NULL);
581
582 if (!ret)
583 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
584 else
585 dev_err(priv->adapter->dev, "set mac address failed: ret=%d"
586 "\n", ret);
587
5e6e3a92
BZ
588 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
589
600f5d90 590 return ret;
5e6e3a92
BZ
591}
592
593/*
594 * CFG802.11 network device handler for setting multicast list.
595 */
596static void mwifiex_set_multicast_list(struct net_device *dev)
597{
598 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
600f5d90
AK
599 struct mwifiex_multicast_list mcast_list;
600
601 if (dev->flags & IFF_PROMISC) {
602 mcast_list.mode = MWIFIEX_PROMISC_MODE;
603 } else if (dev->flags & IFF_ALLMULTI ||
604 netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
605 mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
606 } else {
607 mcast_list.mode = MWIFIEX_MULTICAST_MODE;
608 if (netdev_mc_count(dev))
609 mcast_list.num_multicast_addr =
610 mwifiex_copy_mcast_addr(&mcast_list, dev);
611 }
612 mwifiex_request_set_multicast_list(priv, &mcast_list);
5e6e3a92
BZ
613}
614
615/*
616 * CFG802.11 network device handler for transmission timeout.
617 */
618static void
619mwifiex_tx_timeout(struct net_device *dev)
620{
621 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
622
623 dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
624 jiffies, priv->bss_index);
625 dev->trans_start = jiffies;
626 priv->num_tx_timeout++;
627}
628
629/*
630 * CFG802.11 network device handler for statistics retrieval.
631 */
632static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
633{
634 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
635
636 return &priv->stats;
637}
638
639/* Network device handlers */
640static const struct net_device_ops mwifiex_netdev_ops = {
641 .ndo_open = mwifiex_open,
642 .ndo_stop = mwifiex_close,
643 .ndo_start_xmit = mwifiex_hard_start_xmit,
644 .ndo_set_mac_address = mwifiex_set_mac_address,
645 .ndo_tx_timeout = mwifiex_tx_timeout,
646 .ndo_get_stats = mwifiex_get_stats,
647 .ndo_set_multicast_list = mwifiex_set_multicast_list,
648};
649
650/*
651 * This function initializes the private structure parameters.
652 *
653 * The following wait queues are initialized -
654 * - IOCTL wait queue
655 * - Command wait queue
656 * - Statistics wait queue
657 *
658 * ...and the following default parameters are set -
659 * - Current key index : Set to 0
660 * - Rate index : Set to auto
661 * - Media connected : Set to disconnected
662 * - Adhoc link sensed : Set to false
663 * - Nick name : Set to null
664 * - Number of Tx timeout : Set to 0
665 * - Device address : Set to current address
666 *
667 * In addition, the CFG80211 work queue is also created.
668 */
669static void
670mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
671{
672 dev->netdev_ops = &mwifiex_netdev_ops;
673 /* Initialize private structure */
5e6e3a92
BZ
674 priv->current_key_index = 0;
675 priv->media_connected = false;
676 memset(&priv->nick_name, 0, sizeof(priv->nick_name));
677 priv->num_tx_timeout = 0;
678 priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
679 INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results);
680 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
681}
682
683/*
684 * This function adds a new logical interface.
685 *
686 * It allocates, initializes and registers the interface by performing
687 * the following opearations -
688 * - Allocate a new net device structure
689 * - Assign device name
690 * - Register the new device with CFG80211 subsystem
691 * - Initialize semaphore and private structure
692 * - Register the new device with kernel
693 * - Create the complete debug FS structure if configured
694 */
695static struct mwifiex_private *mwifiex_add_interface(
696 struct mwifiex_adapter *adapter,
697 u8 bss_index, u8 bss_type)
698{
699 struct net_device *dev = NULL;
700 struct mwifiex_private *priv = NULL;
701 void *mdev_priv = NULL;
702
703 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d",
704 ether_setup, 1);
705 if (!dev) {
706 dev_err(adapter->dev, "no memory available for netdevice\n");
707 goto error;
708 }
709 if (dev_alloc_name(dev, dev->name)) {
710 dev_err(adapter->dev, "unable to alloc name for netdevice\n");
711 goto error;
712 }
713
714 if (mwifiex_register_cfg80211(dev, adapter->priv[bss_index]->curr_addr,
715 adapter->priv[bss_index]) != 0) {
716 dev_err(adapter->dev, "cannot register netdevice with cfg80211\n");
717 goto error;
718 }
719 /* Save the priv pointer in netdev */
720 priv = adapter->priv[bss_index];
721 mdev_priv = netdev_priv(dev);
722 *((unsigned long *) mdev_priv) = (unsigned long) priv;
723
724 priv->netdev = dev;
725
726 sema_init(&priv->async_sem, 1);
727 priv->scan_pending_on_block = false;
728
729 mwifiex_init_priv_params(priv, dev);
730
731 SET_NETDEV_DEV(dev, adapter->dev);
732
733 /* Register network device */
734 if (register_netdev(dev)) {
735 dev_err(adapter->dev, "cannot register virtual network device\n");
736 goto error;
737 }
738
739 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
740#ifdef CONFIG_DEBUG_FS
741 mwifiex_dev_debugfs_init(priv);
742#endif
743 return priv;
744error:
745 if (dev)
746 free_netdev(dev);
747 return NULL;
748}
749
750/*
751 * This function removes a logical interface.
752 *
753 * It deregisters, resets and frees the interface by performing
754 * the following operations -
755 * - Disconnect the device if connected, send wireless event to
756 * notify applications.
757 * - Remove the debug FS structure if configured
758 * - Unregister the device from kernel
759 * - Free the net device structure
760 * - Cancel all works and destroy work queue
761 * - Unregister and free the wireless device from CFG80211 subsystem
762 */
763static void
764mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
765{
766 struct net_device *dev = NULL;
767 struct mwifiex_private *priv = adapter->priv[bss_index];
768
769 if (!priv)
770 return;
771 dev = priv->netdev;
772
773 if (priv->media_connected)
774 priv->media_connected = false;
775
776#ifdef CONFIG_DEBUG_FS
777 mwifiex_dev_debugfs_remove(priv);
778#endif
779 /* Last reference is our one */
780 dev_dbg(adapter->dev, "info: %s: refcnt = %d\n",
781 dev->name, netdev_refcnt_read(dev));
782
783 if (dev->reg_state == NETREG_REGISTERED)
784 unregister_netdev(dev);
785
786 /* Clear the priv in adapter */
787 priv->netdev = NULL;
788 if (dev)
789 free_netdev(dev);
790
791 cancel_work_sync(&priv->cfg_workqueue);
792 flush_workqueue(priv->workqueue);
793 destroy_workqueue(priv->workqueue);
794 wiphy_unregister(priv->wdev->wiphy);
795 wiphy_free(priv->wdev->wiphy);
796 kfree(priv->wdev);
5e6e3a92
BZ
797}
798
5e6e3a92
BZ
799/*
800 * This function check if command is pending.
801 */
802int is_command_pending(struct mwifiex_adapter *adapter)
803{
804 unsigned long flags;
805 int is_cmd_pend_q_empty;
806
807 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
808 is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
809 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
810
811 return !is_cmd_pend_q_empty;
812}
813
814/*
815 * This function returns the correct private structure pointer based
816 * upon the BSS number.
817 */
818struct mwifiex_private *
819mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
820{
821 if (!adapter || (bss_index >= adapter->priv_num))
822 return NULL;
823 return adapter->priv[bss_index];
824}
825
826/*
827 * This is the main work queue function.
828 *
829 * It handles the main process, which in turn handles the complete
830 * driver operations.
831 */
832static void mwifiex_main_work_queue(struct work_struct *work)
833{
834 struct mwifiex_adapter *adapter =
835 container_of(work, struct mwifiex_adapter, main_work);
836
837 if (adapter->surprise_removed)
838 return;
839 mwifiex_main_process(adapter);
840}
841
842/*
843 * This function cancels all works in the queue and destroys
844 * the main workqueue.
845 */
846static void
847mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
848{
849 flush_workqueue(adapter->workqueue);
850 destroy_workqueue(adapter->workqueue);
851 adapter->workqueue = NULL;
852}
853
854/*
855 * This function adds the card.
856 *
857 * This function follows the following major steps to set up the device -
858 * - Initialize software. This includes probing the card, registering
859 * the interface operations table, and allocating/initializing the
860 * adapter structure
861 * - Set up the netlink socket
862 * - Create and start the main work queue
863 * - Register the device
864 * - Initialize firmware and hardware
865 * - Add logical interfaces
866 */
867int
868mwifiex_add_card(void *card, struct semaphore *sem,
869 struct mwifiex_if_ops *if_ops)
870{
5e6e3a92 871 int i;
2be7859f 872 struct mwifiex_adapter *adapter;
5e6e3a92
BZ
873
874 if (down_interruptible(sem))
875 goto exit_sem_err;
876
2be7859f 877 if (mwifiex_init_sw(card, if_ops)) {
5e6e3a92
BZ
878 pr_err("%s: software init failed\n", __func__);
879 goto err_init_sw;
880 }
881
2be7859f 882 adapter = g_adapter;
5e6e3a92
BZ
883
884 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
5e6e3a92
BZ
885 adapter->surprise_removed = false;
886 init_waitqueue_head(&adapter->init_wait_q);
887 adapter->is_suspended = false;
888 adapter->hs_activated = false;
889 init_waitqueue_head(&adapter->hs_activate_wait_q);
600f5d90
AK
890 adapter->cmd_wait_q_required = false;
891 init_waitqueue_head(&adapter->cmd_wait_q.wait);
892 adapter->cmd_wait_q.condition = false;
893 adapter->cmd_wait_q.status = 0;
5e6e3a92 894
5e6e3a92
BZ
895 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
896 if (!adapter->workqueue)
897 goto err_kmalloc;
898
899 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
900
901 /* Register the device. Fill up the private data structure with relevant
902 information from the card and request for the required IRQ. */
903 if (adapter->if_ops.register_dev(adapter)) {
904 pr_err("%s: failed to register mwifiex device\n", __func__);
905 goto err_registerdev;
906 }
907
5e6e3a92
BZ
908 if (mwifiex_init_hw_fw(adapter)) {
909 pr_err("%s: firmware init failed\n", __func__);
910 goto err_init_fw;
911 }
2be7859f 912
5e6e3a92 913 /* Add interfaces */
2be7859f 914 for (i = 0; i < adapter->drv_mode->intf_num; i++) {
5e6e3a92
BZ
915 if (!mwifiex_add_interface(adapter, i,
916 adapter->drv_mode->bss_attr[i].bss_type)) {
636c4598 917 goto err_add_intf;
5e6e3a92
BZ
918 }
919 }
5e6e3a92
BZ
920
921 up(sem);
922
923 return 0;
924
925err_add_intf:
926 for (i = 0; i < adapter->priv_num; i++)
927 mwifiex_remove_interface(adapter, i);
928err_init_fw:
5e6e3a92
BZ
929 pr_debug("info: %s: unregister device\n", __func__);
930 adapter->if_ops.unregister_dev(adapter);
931err_registerdev:
932 adapter->surprise_removed = true;
933 mwifiex_terminate_workqueue(adapter);
934err_kmalloc:
935 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
936 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
937 pr_debug("info: %s: shutdown mwifiex\n", __func__);
938 adapter->init_wait_q_woken = false;
636c4598
YAP
939
940 if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
5e6e3a92
BZ
941 wait_event_interruptible(adapter->init_wait_q,
942 adapter->init_wait_q_woken);
943 }
944
945 mwifiex_free_adapter(adapter);
946
947err_init_sw:
948 up(sem);
949
950exit_sem_err:
951 return -1;
952}
953EXPORT_SYMBOL_GPL(mwifiex_add_card);
954
955/*
956 * This function removes the card.
957 *
958 * This function follows the following major steps to remove the device -
959 * - Stop data traffic
960 * - Shutdown firmware
961 * - Remove the logical interfaces
962 * - Terminate the work queue
963 * - Unregister the device
964 * - Free the adapter structure
965 */
966int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
967{
968 struct mwifiex_private *priv = NULL;
5e6e3a92
BZ
969 int i;
970
971 if (down_interruptible(sem))
972 goto exit_sem_err;
973
974 if (!adapter)
975 goto exit_remove;
976
977 adapter->surprise_removed = true;
978
979 /* Stop data */
980 for (i = 0; i < adapter->priv_num; i++) {
981 priv = adapter->priv[i];
982 if (priv) {
983 if (!netif_queue_stopped(priv->netdev))
984 netif_stop_queue(priv->netdev);
985 if (netif_carrier_ok(priv->netdev))
986 netif_carrier_off(priv->netdev);
987 }
988 }
989
990 dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n");
991 adapter->init_wait_q_woken = false;
636c4598
YAP
992
993 if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
5e6e3a92
BZ
994 wait_event_interruptible(adapter->init_wait_q,
995 adapter->init_wait_q_woken);
996 dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n");
997 if (atomic_read(&adapter->rx_pending) ||
998 atomic_read(&adapter->tx_pending) ||
600f5d90 999 atomic_read(&adapter->cmd_pending)) {
5e6e3a92 1000 dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, "
600f5d90 1001 "cmd_pending=%d\n",
5e6e3a92
BZ
1002 atomic_read(&adapter->rx_pending),
1003 atomic_read(&adapter->tx_pending),
600f5d90 1004 atomic_read(&adapter->cmd_pending));
5e6e3a92
BZ
1005 }
1006
1007 /* Remove interface */
1008 for (i = 0; i < adapter->priv_num; i++)
1009 mwifiex_remove_interface(adapter, i);
1010
1011 mwifiex_terminate_workqueue(adapter);
1012
1013 /* Unregister device */
1014 dev_dbg(adapter->dev, "info: unregister device\n");
1015 adapter->if_ops.unregister_dev(adapter);
1016 /* Free adapter structure */
1017 dev_dbg(adapter->dev, "info: free adapter\n");
1018 mwifiex_free_adapter(adapter);
1019
1020exit_remove:
1021 up(sem);
1022exit_sem_err:
1023 return 0;
1024}
1025EXPORT_SYMBOL_GPL(mwifiex_remove_card);
1026
1027/*
1028 * This function initializes the module.
1029 *
1030 * The debug FS is also initialized if configured.
1031 */
1032static int
1033mwifiex_init_module(void)
1034{
1035#ifdef CONFIG_DEBUG_FS
1036 mwifiex_debugfs_init();
1037#endif
1038 return 0;
1039}
1040
1041/*
1042 * This function cleans up the module.
1043 *
1044 * The debug FS is removed if available.
1045 */
1046static void
1047mwifiex_cleanup_module(void)
1048{
1049#ifdef CONFIG_DEBUG_FS
1050 mwifiex_debugfs_remove();
1051#endif
1052}
1053
1054module_init(mwifiex_init_module);
1055module_exit(mwifiex_cleanup_module);
1056
1057MODULE_AUTHOR("Marvell International Ltd.");
1058MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION);
1059MODULE_VERSION(VERSION);
1060MODULE_LICENSE("GPL v2");
This page took 0.085266 seconds and 5 git commands to generate.