diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/init.c')
| -rw-r--r-- | drivers/net/wireless/mwifiex/init.c | 186 |
1 files changed, 48 insertions, 138 deletions
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 39f03ce5a5b..4ecd0b208ac 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -39,16 +39,11 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) unsigned long flags; bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); - if (!bss_prio) { - dev_err(adapter->dev, "%s: failed to alloc bss_prio\n", - __func__); + if (!bss_prio) return -ENOMEM; - } bss_prio->priv = priv; INIT_LIST_HEAD(&bss_prio->list); - if (!tbl[priv->bss_priority].bss_prio_cur) - tbl[priv->bss_priority].bss_prio_cur = bss_prio; spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head); @@ -57,87 +52,6 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) return 0; } -static void scan_delay_timer_fn(unsigned long data) -{ - struct mwifiex_private *priv = (struct mwifiex_private *)data; - struct mwifiex_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *cmd_node, *tmp_node; - unsigned long flags; - - if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { - /* - * Abort scan operation by cancelling all pending scan - * commands - */ - spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); - list_for_each_entry_safe(cmd_node, tmp_node, - &adapter->scan_pending_q, list) { - list_del(&cmd_node->list); - mwifiex_insert_cmd_to_free_q(adapter, cmd_node); - } - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); - - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); - adapter->scan_processing = false; - adapter->scan_delay_cnt = 0; - adapter->empty_tx_q_cnt = 0; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); - - if (priv->user_scan_cfg) { - if (priv->scan_request) { - dev_dbg(priv->adapter->dev, - "info: aborting scan\n"); - cfg80211_scan_done(priv->scan_request, 1); - priv->scan_request = NULL; - } else { - dev_dbg(priv->adapter->dev, - "info: scan already aborted\n"); - } - - kfree(priv->user_scan_cfg); - priv->user_scan_cfg = NULL; - } - goto done; - } - - if (!atomic_read(&priv->adapter->is_tx_received)) { - adapter->empty_tx_q_cnt++; - if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) { - /* - * No Tx traffic for 200msec. Get scan command from - * scan pending queue and put to cmd pending queue to - * resume scan operation - */ - adapter->scan_delay_cnt = 0; - adapter->empty_tx_q_cnt = 0; - spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); - cmd_node = list_first_entry(&adapter->scan_pending_q, - struct cmd_ctrl_node, list); - list_del(&cmd_node->list); - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - flags); - - mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, - true); - queue_work(adapter->workqueue, &adapter->main_work); - goto done; - } - } else { - adapter->empty_tx_q_cnt = 0; - } - - /* Delay scan operation further by 20msec */ - mod_timer(&priv->scan_delay_timer, jiffies + - msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); - adapter->scan_delay_cnt++; - -done: - if (atomic_read(&priv->adapter->is_tx_received)) - atomic_set(&priv->adapter->is_tx_received, false); - - return; -} - /* * This function initializes the private structure and sets default * values to the members. @@ -219,8 +133,11 @@ int mwifiex_init_priv(struct mwifiex_private *priv) priv->scan_block = false; - setup_timer(&priv->scan_delay_timer, scan_delay_timer_fn, - (unsigned long)priv); + priv->csa_chan = 0; + priv->csa_expire_time = 0; + priv->del_list_idx = 0; + priv->hs2_enabled = false; + memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID); return mwifiex_add_bss_prio_tbl(priv); } @@ -317,14 +234,12 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->pm_wakeup_fw_try = false; - adapter->max_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; - adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; adapter->is_hs_configured = false; - adapter->hs_cfg.conditions = cpu_to_le32(HOST_SLEEP_CFG_COND_DEF); - adapter->hs_cfg.gpio = HOST_SLEEP_CFG_GPIO_DEF; - adapter->hs_cfg.gap = HOST_SLEEP_CFG_GAP_DEF; + adapter->hs_cfg.conditions = cpu_to_le32(HS_CFG_COND_DEF); + adapter->hs_cfg.gpio = HS_CFG_GPIO_DEF; + adapter->hs_cfg.gap = HS_CFG_GAP_DEF; adapter->hs_activated = false; memset(adapter->event_body, 0, sizeof(adapter->event_body)); @@ -366,6 +281,9 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->arp_filter_size = 0; adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; adapter->empty_tx_q_cnt = 0; + adapter->ext_scan = true; + adapter->fw_key_api_major_ver = 0; + adapter->fw_key_api_minor_ver = 0; } /* @@ -453,17 +371,16 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) } /* - * This function frees the adapter structure. + * This function performs cleanup for adapter structure. * - * The freeing operation is done recursively, by canceling all - * pending commands, freeing the member buffers previously - * allocated (command buffers, scan table buffer, sleep confirm - * command buffer), stopping the timers and calling the cleanup - * routines for every interface, before the actual adapter - * structure is freed. + * The cleanup is done recursively, by canceling all pending + * commands, freeing the member buffers previously allocated + * (command buffers, scan table buffer, sleep confirm command + * buffer), stopping the timers and calling the cleanup routines + * for every interface. */ static void -mwifiex_free_adapter(struct mwifiex_adapter *adapter) +mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) { if (!adapter) { pr_err("%s: adapter is NULL\n", __func__); @@ -479,13 +396,8 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "info: free cmd buffer\n"); mwifiex_free_cmd_buffer(adapter); - del_timer(&adapter->cmd_timer); - dev_dbg(adapter->dev, "info: free scan table\n"); - if (adapter->if_ops.cleanup_if) - adapter->if_ops.cleanup_if(adapter); - if (adapter->sleep_cfm) dev_kfree_skb_any(adapter->sleep_cfm); } @@ -529,7 +441,6 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) for (i = 0; i < adapter->priv_num; ++i) { INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); - adapter->bss_prio_tbl[i].bss_prio_cur = NULL; spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock); } @@ -537,13 +448,12 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) if (!adapter->priv[i]) continue; priv = adapter->priv[i]; - for (j = 0; j < MAX_NUM_TID; ++j) { + for (j = 0; j < MAX_NUM_TID; ++j) INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list); - spin_lock_init(&priv->wmm.tid_tbl_ptr[j].tid_tbl_lock); - } INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); INIT_LIST_HEAD(&priv->sta_list); + skb_queue_head_init(&priv->tdls_txq); spin_lock_init(&priv->tx_ba_stream_tbl_lock); spin_lock_init(&priv->rx_reorder_tbl_lock); @@ -591,6 +501,12 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter) return -1; } } + + if (adapter->if_ops.init_fw_port) { + if (adapter->if_ops.init_fw_port(adapter)) + return -1; + } + for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta); @@ -625,42 +541,36 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) { int i; struct mwifiex_adapter *adapter = priv->adapter; - struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; + struct mwifiex_bss_prio_node *bssprio_node, *tmp_node; struct list_head *head; spinlock_t *lock; /* bss priority lock */ unsigned long flags; for (i = 0; i < adapter->priv_num; ++i) { head = &adapter->bss_prio_tbl[i].bss_prio_head; - cur = &adapter->bss_prio_tbl[i].bss_prio_cur; lock = &adapter->bss_prio_tbl[i].bss_prio_lock; dev_dbg(adapter->dev, "info: delete BSS priority table," " bss_type = %d, bss_num = %d, i = %d," - " head = %p, cur = %p\n", - priv->bss_type, priv->bss_num, i, head, *cur); - if (*cur) { + " head = %p\n", + priv->bss_type, priv->bss_num, i, head); + + { spin_lock_irqsave(lock, flags); if (list_empty(head)) { spin_unlock_irqrestore(lock, flags); continue; } - bssprio_node = list_first_entry(head, - struct mwifiex_bss_prio_node, list); - spin_unlock_irqrestore(lock, flags); - list_for_each_entry_safe(bssprio_node, tmp_node, head, list) { if (bssprio_node->priv == priv) { dev_dbg(adapter->dev, "info: Delete " "node %p, next = %p\n", bssprio_node, tmp_node); - spin_lock_irqsave(lock, flags); list_del(&bssprio_node->list); - spin_unlock_irqrestore(lock, flags); kfree(bssprio_node); } } - *cur = (struct mwifiex_bss_prio_node *)head; + spin_unlock_irqrestore(lock, flags); } } } @@ -693,7 +603,6 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) int ret = -EINPROGRESS; struct mwifiex_private *priv; s32 i; - unsigned long flags; struct sk_buff *skb; /* mwifiex already shutdown */ @@ -707,6 +616,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) return ret; } + /* cancel current command */ + if (adapter->curr_cmd) { + dev_warn(adapter->dev, "curr_cmd is still in processing\n"); + del_timer_sync(&adapter->cmd_timer); + mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd); + adapter->curr_cmd = NULL; + } + /* shut down mwifiex */ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); @@ -720,7 +637,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) } } - spin_lock_irqsave(&adapter->mwifiex_lock, flags); + spin_lock(&adapter->mwifiex_lock); if (adapter->if_ops.data_complete) { while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) { @@ -730,14 +647,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) if (priv) priv->stats.rx_dropped++; - adapter->if_ops.data_complete(adapter, skb); + dev_kfree_skb_any(skb); + adapter->if_ops.data_complete(adapter); } } - /* Free adapter structure */ - mwifiex_free_adapter(adapter); + mwifiex_adapter_cleanup(adapter); - spin_unlock_irqrestore(&adapter->mwifiex_lock, flags); + spin_unlock(&adapter->mwifiex_lock); /* Notify completion */ ret = mwifiex_shutdown_fw_complete(adapter); @@ -771,7 +688,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, if (!ret) { dev_notice(adapter->dev, "WLAN FW already running! Skip FW dnld\n"); - goto done; + return 0; } poll_num = MAX_FIRMWARE_POLL_TRIES; @@ -780,7 +697,6 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, if (!adapter->winner) { dev_notice(adapter->dev, "FW already running! Skip FW dnld\n"); - poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; goto poll_fw; } } @@ -797,14 +713,8 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, poll_fw: /* Check if the firmware is downloaded successfully or not */ ret = adapter->if_ops.check_fw_status(adapter, poll_num); - if (ret) { + if (ret) dev_err(adapter->dev, "FW failed to be active in time\n"); - return -1; - } -done: - /* re-enable host interrupt for mwifiex after fw dnld is successful */ - if (adapter->if_ops.enable_int) - adapter->if_ops.enable_int(adapter); return ret; } |
