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