0001
0002
0003
0004
0005
0006
0007
0008 #include "decl.h"
0009 #include "ioctl.h"
0010 #include "util.h"
0011 #include "fw.h"
0012 #include "main.h"
0013 #include "wmm.h"
0014 #include "11n.h"
0015
0016
0017
0018
0019
0020
0021
0022 static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
0023 {
0024 struct mwifiex_adapter *adapter = priv->adapter;
0025 struct mwifiex_bss_prio_node *bss_prio;
0026 struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl;
0027
0028 bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
0029 if (!bss_prio)
0030 return -ENOMEM;
0031
0032 bss_prio->priv = priv;
0033 INIT_LIST_HEAD(&bss_prio->list);
0034
0035 spin_lock_bh(&tbl[priv->bss_priority].bss_prio_lock);
0036 list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head);
0037 spin_unlock_bh(&tbl[priv->bss_priority].bss_prio_lock);
0038
0039 return 0;
0040 }
0041
0042 static void wakeup_timer_fn(struct timer_list *t)
0043 {
0044 struct mwifiex_adapter *adapter = from_timer(adapter, t, wakeup_timer);
0045
0046 mwifiex_dbg(adapter, ERROR, "Firmware wakeup failed\n");
0047 adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
0048 mwifiex_cancel_all_pending_cmd(adapter);
0049
0050 if (adapter->if_ops.card_reset)
0051 adapter->if_ops.card_reset(adapter);
0052 }
0053
0054 static void fw_dump_timer_fn(struct timer_list *t)
0055 {
0056 struct mwifiex_adapter *adapter = from_timer(adapter, t, devdump_timer);
0057
0058 mwifiex_upload_device_dump(adapter);
0059 }
0060
0061
0062
0063
0064
0065
0066
0067
0068 int mwifiex_init_priv(struct mwifiex_private *priv)
0069 {
0070 u32 i;
0071
0072 priv->media_connected = false;
0073 eth_broadcast_addr(priv->curr_addr);
0074 priv->port_open = false;
0075 priv->usb_port = MWIFIEX_USB_EP_DATA;
0076 priv->pkt_tx_ctrl = 0;
0077 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
0078 priv->data_rate = 0;
0079 priv->is_data_rate_auto = true;
0080 priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
0081 priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
0082
0083 priv->sec_info.wep_enabled = 0;
0084 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
0085 priv->sec_info.encryption_mode = 0;
0086 for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++)
0087 memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key));
0088 priv->wep_key_curr_index = 0;
0089 priv->curr_pkt_filter = HostCmd_ACT_MAC_DYNAMIC_BW_ENABLE |
0090 HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
0091 HostCmd_ACT_MAC_ETHERNETII_ENABLE;
0092
0093 priv->beacon_period = 100;
0094 priv->attempted_bss_desc = NULL;
0095 memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
0096 priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL;
0097
0098 memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid));
0099 memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid));
0100 memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf));
0101 priv->assoc_rsp_size = 0;
0102 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
0103 priv->atim_window = 0;
0104 priv->adhoc_state = ADHOC_IDLE;
0105 priv->tx_power_level = 0;
0106 priv->max_tx_power_level = 0;
0107 priv->min_tx_power_level = 0;
0108 priv->tx_ant = 0;
0109 priv->rx_ant = 0;
0110 priv->tx_rate = 0;
0111 priv->rxpd_htinfo = 0;
0112 priv->rxpd_rate = 0;
0113 priv->rate_bitmap = 0;
0114 priv->data_rssi_last = 0;
0115 priv->data_rssi_avg = 0;
0116 priv->data_nf_avg = 0;
0117 priv->data_nf_last = 0;
0118 priv->bcn_rssi_last = 0;
0119 priv->bcn_rssi_avg = 0;
0120 priv->bcn_nf_avg = 0;
0121 priv->bcn_nf_last = 0;
0122 memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie));
0123 memset(&priv->aes_key, 0, sizeof(priv->aes_key));
0124 priv->wpa_ie_len = 0;
0125 priv->wpa_is_gtk_set = false;
0126
0127 memset(&priv->assoc_tlv_buf, 0, sizeof(priv->assoc_tlv_buf));
0128 priv->assoc_tlv_buf_len = 0;
0129 memset(&priv->wps, 0, sizeof(priv->wps));
0130 memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf));
0131 priv->gen_ie_buf_len = 0;
0132 memset(priv->vs_ie, 0, sizeof(priv->vs_ie));
0133
0134 priv->wmm_required = true;
0135 priv->wmm_enabled = false;
0136 priv->wmm_qosinfo = 0;
0137 priv->curr_bcn_buf = NULL;
0138 priv->curr_bcn_size = 0;
0139 priv->wps_ie = NULL;
0140 priv->wps_ie_len = 0;
0141 priv->ap_11n_enabled = 0;
0142 memset(&priv->roc_cfg, 0, sizeof(priv->roc_cfg));
0143
0144 priv->scan_block = false;
0145
0146 priv->csa_chan = 0;
0147 priv->csa_expire_time = 0;
0148 priv->del_list_idx = 0;
0149 priv->hs2_enabled = false;
0150 priv->check_tdls_tx = false;
0151 memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID);
0152
0153 mwifiex_init_11h_params(priv);
0154
0155 return mwifiex_add_bss_prio_tbl(priv);
0156 }
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
0167 {
0168 int ret;
0169
0170
0171 ret = mwifiex_alloc_cmd_buffer(adapter);
0172 if (ret) {
0173 mwifiex_dbg(adapter, ERROR,
0174 "%s: failed to alloc cmd buffer\n",
0175 __func__);
0176 return -1;
0177 }
0178
0179 adapter->sleep_cfm =
0180 dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
0181 + INTF_HEADER_LEN);
0182
0183 if (!adapter->sleep_cfm) {
0184 mwifiex_dbg(adapter, ERROR,
0185 "%s: failed to alloc sleep cfm\t"
0186 " cmd buffer\n", __func__);
0187 return -1;
0188 }
0189 skb_reserve(adapter->sleep_cfm, INTF_HEADER_LEN);
0190
0191 return 0;
0192 }
0193
0194
0195
0196
0197
0198
0199
0200
0201 static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
0202 {
0203 struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL;
0204
0205 skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm));
0206
0207 adapter->cmd_sent = false;
0208
0209 if (adapter->iface_type == MWIFIEX_SDIO)
0210 adapter->data_sent = true;
0211 else
0212 adapter->data_sent = false;
0213
0214 if (adapter->iface_type == MWIFIEX_USB)
0215 adapter->intf_hdr_len = 0;
0216 else
0217 adapter->intf_hdr_len = INTF_HEADER_LEN;
0218
0219 adapter->cmd_resp_received = false;
0220 adapter->event_received = false;
0221 adapter->data_received = false;
0222
0223 clear_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags);
0224
0225 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
0226
0227 adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
0228 adapter->ps_state = PS_STATE_AWAKE;
0229 adapter->need_to_wakeup = false;
0230
0231 adapter->scan_mode = HostCmd_BSS_MODE_ANY;
0232 adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME;
0233 adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
0234 adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
0235 adapter->scan_chan_gap_time = MWIFIEX_DEF_SCAN_CHAN_GAP_TIME;
0236
0237 adapter->scan_probes = 1;
0238
0239 adapter->multiple_dtim = 1;
0240
0241 adapter->local_listen_interval = 0;
0242
0243
0244 adapter->is_deep_sleep = false;
0245
0246 adapter->delay_null_pkt = false;
0247 adapter->delay_to_ps = 1000;
0248 adapter->enhanced_ps_mode = PS_MODE_AUTO;
0249
0250 adapter->gen_null_pkt = false;
0251
0252 adapter->pps_uapsd_mode = false;
0253
0254 adapter->pm_wakeup_card_req = false;
0255
0256 adapter->pm_wakeup_fw_try = false;
0257
0258 adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
0259
0260 clear_bit(MWIFIEX_IS_HS_CONFIGURED, &adapter->work_flags);
0261 adapter->hs_cfg.conditions = cpu_to_le32(HS_CFG_COND_DEF);
0262 adapter->hs_cfg.gpio = HS_CFG_GPIO_DEF;
0263 adapter->hs_cfg.gap = HS_CFG_GAP_DEF;
0264 adapter->hs_activated = false;
0265
0266 memset(adapter->event_body, 0, sizeof(adapter->event_body));
0267 adapter->hw_dot_11n_dev_cap = 0;
0268 adapter->hw_dev_mcs_support = 0;
0269 adapter->sec_chan_offset = 0;
0270 adapter->adhoc_11n_enabled = false;
0271
0272 mwifiex_wmm_init(adapter);
0273 atomic_set(&adapter->tx_hw_pending, 0);
0274
0275 sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *)
0276 adapter->sleep_cfm->data;
0277 memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len);
0278 sleep_cfm_buf->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
0279 sleep_cfm_buf->size = cpu_to_le16(adapter->sleep_cfm->len);
0280 sleep_cfm_buf->result = 0;
0281 sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
0282 sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
0283
0284 memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
0285 memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
0286 adapter->tx_lock_flag = false;
0287 adapter->null_pkt_interval = 0;
0288 adapter->fw_bands = 0;
0289 adapter->config_bands = 0;
0290 adapter->adhoc_start_band = 0;
0291 adapter->scan_channels = NULL;
0292 adapter->fw_release_number = 0;
0293 adapter->fw_cap_info = 0;
0294 memset(&adapter->upld_buf, 0, sizeof(adapter->upld_buf));
0295 adapter->event_cause = 0;
0296 adapter->region_code = 0;
0297 adapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
0298 adapter->adhoc_awake_period = 0;
0299 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
0300 adapter->arp_filter_size = 0;
0301 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
0302 adapter->mfg_mode = mfg_mode;
0303 adapter->key_api_major_ver = 0;
0304 adapter->key_api_minor_ver = 0;
0305 eth_broadcast_addr(adapter->perm_addr);
0306 adapter->iface_limit.sta_intf = MWIFIEX_MAX_STA_NUM;
0307 adapter->iface_limit.uap_intf = MWIFIEX_MAX_UAP_NUM;
0308 adapter->iface_limit.p2p_intf = MWIFIEX_MAX_P2P_NUM;
0309 adapter->active_scan_triggered = false;
0310 timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0);
0311 adapter->devdump_len = 0;
0312 timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0);
0313 }
0314
0315
0316
0317
0318 void mwifiex_set_trans_start(struct net_device *dev)
0319 {
0320 int i;
0321
0322 for (i = 0; i < dev->num_tx_queues; i++)
0323 txq_trans_cond_update(netdev_get_tx_queue(dev, i));
0324
0325 netif_trans_update(dev);
0326 }
0327
0328
0329
0330
0331 void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
0332 struct mwifiex_adapter *adapter)
0333 {
0334 spin_lock_bh(&adapter->queue_lock);
0335 netif_tx_wake_all_queues(netdev);
0336 spin_unlock_bh(&adapter->queue_lock);
0337 }
0338
0339
0340
0341
0342 void mwifiex_stop_net_dev_queue(struct net_device *netdev,
0343 struct mwifiex_adapter *adapter)
0344 {
0345 spin_lock_bh(&adapter->queue_lock);
0346 netif_tx_stop_all_queues(netdev);
0347 spin_unlock_bh(&adapter->queue_lock);
0348 }
0349
0350
0351
0352
0353 static void mwifiex_invalidate_lists(struct mwifiex_adapter *adapter)
0354 {
0355 struct mwifiex_private *priv;
0356 s32 i, j;
0357
0358 list_del(&adapter->cmd_free_q);
0359 list_del(&adapter->cmd_pending_q);
0360 list_del(&adapter->scan_pending_q);
0361
0362 for (i = 0; i < adapter->priv_num; i++)
0363 list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
0364
0365 for (i = 0; i < adapter->priv_num; i++) {
0366 if (adapter->priv[i]) {
0367 priv = adapter->priv[i];
0368 for (j = 0; j < MAX_NUM_TID; ++j)
0369 list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
0370 list_del(&priv->tx_ba_stream_tbl_ptr);
0371 list_del(&priv->rx_reorder_tbl_ptr);
0372 list_del(&priv->sta_list);
0373 list_del(&priv->auto_tdls_list);
0374 }
0375 }
0376 }
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387 static void
0388 mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
0389 {
0390 del_timer(&adapter->wakeup_timer);
0391 del_timer_sync(&adapter->devdump_timer);
0392 mwifiex_cancel_all_pending_cmd(adapter);
0393 wake_up_interruptible(&adapter->cmd_wait_q.wait);
0394 wake_up_interruptible(&adapter->hs_activate_wait_q);
0395 }
0396
0397 void mwifiex_free_cmd_buffers(struct mwifiex_adapter *adapter)
0398 {
0399 mwifiex_invalidate_lists(adapter);
0400
0401
0402 mwifiex_dbg(adapter, INFO, "info: free cmd buffer\n");
0403 mwifiex_free_cmd_buffer(adapter);
0404
0405 if (adapter->sleep_cfm)
0406 dev_kfree_skb_any(adapter->sleep_cfm);
0407 }
0408
0409
0410
0411
0412
0413 int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
0414 {
0415 struct mwifiex_private *priv;
0416 s32 i, j;
0417
0418 spin_lock_init(&adapter->int_lock);
0419 spin_lock_init(&adapter->main_proc_lock);
0420 spin_lock_init(&adapter->mwifiex_cmd_lock);
0421 spin_lock_init(&adapter->queue_lock);
0422 for (i = 0; i < adapter->priv_num; i++) {
0423 if (adapter->priv[i]) {
0424 priv = adapter->priv[i];
0425 spin_lock_init(&priv->wmm.ra_list_spinlock);
0426 spin_lock_init(&priv->curr_bcn_buf_lock);
0427 spin_lock_init(&priv->sta_list_spinlock);
0428 spin_lock_init(&priv->auto_tdls_lock);
0429 }
0430 }
0431
0432
0433 INIT_LIST_HEAD(&adapter->cmd_free_q);
0434
0435 INIT_LIST_HEAD(&adapter->cmd_pending_q);
0436
0437 INIT_LIST_HEAD(&adapter->scan_pending_q);
0438
0439 spin_lock_init(&adapter->cmd_free_q_lock);
0440 spin_lock_init(&adapter->cmd_pending_q_lock);
0441 spin_lock_init(&adapter->scan_pending_q_lock);
0442 spin_lock_init(&adapter->rx_proc_lock);
0443
0444 skb_queue_head_init(&adapter->rx_data_q);
0445 skb_queue_head_init(&adapter->tx_data_q);
0446
0447 for (i = 0; i < adapter->priv_num; ++i) {
0448 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
0449 spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
0450 }
0451
0452 for (i = 0; i < adapter->priv_num; i++) {
0453 if (!adapter->priv[i])
0454 continue;
0455 priv = adapter->priv[i];
0456 for (j = 0; j < MAX_NUM_TID; ++j)
0457 INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list);
0458 INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
0459 INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
0460 INIT_LIST_HEAD(&priv->sta_list);
0461 INIT_LIST_HEAD(&priv->auto_tdls_list);
0462 skb_queue_head_init(&priv->tdls_txq);
0463 skb_queue_head_init(&priv->bypass_txq);
0464
0465 spin_lock_init(&priv->tx_ba_stream_tbl_lock);
0466 spin_lock_init(&priv->rx_reorder_tbl_lock);
0467
0468 spin_lock_init(&priv->ack_status_lock);
0469 idr_init(&priv->ack_status_frames);
0470 }
0471
0472 return 0;
0473 }
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486 int mwifiex_init_fw(struct mwifiex_adapter *adapter)
0487 {
0488 int ret;
0489 struct mwifiex_private *priv;
0490 u8 i, first_sta = true;
0491 int is_cmd_pend_q_empty;
0492
0493 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
0494
0495
0496 ret = mwifiex_allocate_adapter(adapter);
0497 if (ret)
0498 return -1;
0499
0500
0501 mwifiex_init_adapter(adapter);
0502
0503 for (i = 0; i < adapter->priv_num; i++) {
0504 if (adapter->priv[i]) {
0505 priv = adapter->priv[i];
0506
0507
0508 ret = mwifiex_init_priv(priv);
0509 if (ret)
0510 return -1;
0511 }
0512 }
0513 if (adapter->mfg_mode) {
0514 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
0515 ret = -EINPROGRESS;
0516 } else {
0517 for (i = 0; i < adapter->priv_num; i++) {
0518 if (adapter->priv[i]) {
0519 ret = mwifiex_sta_init_cmd(adapter->priv[i],
0520 first_sta, true);
0521 if (ret == -1)
0522 return -1;
0523
0524 first_sta = false;
0525 }
0526
0527
0528
0529 }
0530 }
0531
0532 spin_lock_bh(&adapter->cmd_pending_q_lock);
0533 is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
0534 spin_unlock_bh(&adapter->cmd_pending_q_lock);
0535 if (!is_cmd_pend_q_empty) {
0536
0537 if (mwifiex_main_process(adapter) != -1)
0538 ret = -EINPROGRESS;
0539 } else {
0540 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
0541 }
0542
0543 return ret;
0544 }
0545
0546
0547
0548
0549
0550
0551
0552 static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
0553 {
0554 int i;
0555 struct mwifiex_adapter *adapter = priv->adapter;
0556 struct mwifiex_bss_prio_node *bssprio_node, *tmp_node;
0557 struct list_head *head;
0558 spinlock_t *lock;
0559
0560 for (i = 0; i < adapter->priv_num; ++i) {
0561 head = &adapter->bss_prio_tbl[i].bss_prio_head;
0562 lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
0563 mwifiex_dbg(adapter, INFO,
0564 "info: delete BSS priority table,\t"
0565 "bss_type = %d, bss_num = %d, i = %d,\t"
0566 "head = %p\n",
0567 priv->bss_type, priv->bss_num, i, head);
0568
0569 {
0570 spin_lock_bh(lock);
0571 list_for_each_entry_safe(bssprio_node, tmp_node, head,
0572 list) {
0573 if (bssprio_node->priv == priv) {
0574 mwifiex_dbg(adapter, INFO,
0575 "info: Delete\t"
0576 "node %p, next = %p\n",
0577 bssprio_node, tmp_node);
0578 list_del(&bssprio_node->list);
0579 kfree(bssprio_node);
0580 }
0581 }
0582 spin_unlock_bh(lock);
0583 }
0584 }
0585 }
0586
0587
0588
0589
0590
0591 void mwifiex_free_priv(struct mwifiex_private *priv)
0592 {
0593 mwifiex_clean_txrx(priv);
0594 mwifiex_delete_bss_prio_tbl(priv);
0595 mwifiex_free_curr_bcn(priv);
0596 }
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609 void
0610 mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
0611 {
0612 struct mwifiex_private *priv;
0613 s32 i;
0614 struct sk_buff *skb;
0615
0616
0617 if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)
0618 return;
0619
0620
0621 if (adapter->curr_cmd) {
0622 mwifiex_dbg(adapter, WARN,
0623 "curr_cmd is still in processing\n");
0624 del_timer_sync(&adapter->cmd_timer);
0625 mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
0626 adapter->curr_cmd = NULL;
0627 }
0628
0629
0630 mwifiex_dbg(adapter, MSG,
0631 "info: shutdown mwifiex...\n");
0632
0633
0634 for (i = 0; i < adapter->priv_num; i++) {
0635 if (adapter->priv[i]) {
0636 priv = adapter->priv[i];
0637
0638 mwifiex_clean_auto_tdls(priv);
0639 mwifiex_abort_cac(priv);
0640 mwifiex_free_priv(priv);
0641 }
0642 }
0643
0644 atomic_set(&adapter->tx_queued, 0);
0645 while ((skb = skb_dequeue(&adapter->tx_data_q)))
0646 mwifiex_write_data_complete(adapter, skb, 0, 0);
0647
0648 spin_lock_bh(&adapter->rx_proc_lock);
0649
0650 while ((skb = skb_dequeue(&adapter->rx_data_q))) {
0651 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
0652
0653 atomic_dec(&adapter->rx_pending);
0654 priv = adapter->priv[rx_info->bss_num];
0655 if (priv)
0656 priv->stats.rx_dropped++;
0657
0658 dev_kfree_skb_any(skb);
0659 }
0660
0661 spin_unlock_bh(&adapter->rx_proc_lock);
0662
0663 mwifiex_adapter_cleanup(adapter);
0664
0665 adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY;
0666 }
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680 int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
0681 struct mwifiex_fw_image *pmfw)
0682 {
0683 int ret;
0684 u32 poll_num = 1;
0685
0686
0687 ret = adapter->if_ops.check_fw_status(adapter, poll_num);
0688 if (!ret) {
0689 mwifiex_dbg(adapter, MSG,
0690 "WLAN FW already running! Skip FW dnld\n");
0691 return 0;
0692 }
0693
0694
0695 if (adapter->if_ops.check_winner_status) {
0696 adapter->winner = 0;
0697 ret = adapter->if_ops.check_winner_status(adapter);
0698
0699 poll_num = MAX_FIRMWARE_POLL_TRIES;
0700 if (ret) {
0701 mwifiex_dbg(adapter, MSG,
0702 "WLAN read winner status failed!\n");
0703 return ret;
0704 }
0705
0706 if (!adapter->winner) {
0707 mwifiex_dbg(adapter, MSG,
0708 "WLAN is not the winner! Skip FW dnld\n");
0709 goto poll_fw;
0710 }
0711 }
0712
0713 if (pmfw) {
0714
0715 ret = adapter->if_ops.prog_fw(adapter, pmfw);
0716 if (ret) {
0717 mwifiex_dbg(adapter, ERROR,
0718 "prog_fw failed ret=%#x\n", ret);
0719 return ret;
0720 }
0721 }
0722
0723 poll_fw:
0724
0725 ret = adapter->if_ops.check_fw_status(adapter, poll_num);
0726 if (ret)
0727 mwifiex_dbg(adapter, ERROR,
0728 "FW failed to be active in time\n");
0729
0730 return ret;
0731 }
0732 EXPORT_SYMBOL_GPL(mwifiex_dnld_fw);