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