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