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