diff options
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex/main.c')
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/main.c | 134 |
1 files changed, 80 insertions, 54 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index d99127dc466e..7b50a88a18e5 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -6,6 +6,7 @@ */ #include <linux/suspend.h> +#include <net/sock.h> #include "main.h" #include "wmm.h" @@ -54,7 +55,7 @@ const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; * proper cleanup before exiting. */ static int mwifiex_register(void *card, struct device *dev, - struct mwifiex_if_ops *if_ops, void **padapter) + const struct mwifiex_if_ops *if_ops, void **padapter) { struct mwifiex_adapter *adapter; int i; @@ -127,10 +128,8 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter) /* Free private structures */ for (i = 0; i < adapter->priv_num; i++) { - if (adapter->priv[i]) { - mwifiex_free_curr_bcn(adapter->priv[i]); - kfree(adapter->priv[i]); - } + mwifiex_free_curr_bcn(adapter->priv[i]); + kfree(adapter->priv[i]); } if (adapter->nd_info) { @@ -309,7 +308,7 @@ process_start: if (IS_CARD_RX_RCVD(adapter)) { adapter->data_received = false; adapter->pm_wakeup_fw_try = false; - del_timer(&adapter->wakeup_timer); + timer_delete(&adapter->wakeup_timer); if (adapter->ps_state == PS_STATE_SLEEP) adapter->ps_state = PS_STATE_AWAKE; } else { @@ -356,13 +355,6 @@ process_start: if (adapter->cmd_resp_received) { adapter->cmd_resp_received = false; mwifiex_process_cmdresp(adapter); - - /* call mwifiex back when init_fw is done */ - if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) { - adapter->hw_status = MWIFIEX_HW_STATUS_READY; - mwifiex_init_fw_complete(adapter); - maybe_quirk_fw_disable_ds(adapter); - } } /* Check if we need to confirm Sleep Request @@ -417,10 +409,7 @@ process_start: if (adapter->hs_activated) { clear_bit(MWIFIEX_IS_HS_CONFIGURED, &adapter->work_flags); - mwifiex_hs_activated_event - (mwifiex_get_priv - (adapter, MWIFIEX_BSS_ROLE_ANY), - false); + mwifiex_hs_activated_event(adapter, false); } } @@ -440,10 +429,7 @@ process_start: if (adapter->hs_activated) { clear_bit(MWIFIEX_IS_HS_CONFIGURED, &adapter->work_flags); - mwifiex_hs_activated_event - (mwifiex_get_priv - (adapter, MWIFIEX_BSS_ROLE_ANY), - false); + mwifiex_hs_activated_event(adapter, false); } } @@ -462,10 +448,7 @@ process_start: if (adapter->hs_activated) { clear_bit(MWIFIEX_IS_HS_CONFIGURED, &adapter->work_flags); - mwifiex_hs_activated_event - (mwifiex_get_priv - (adapter, MWIFIEX_BSS_ROLE_ANY), - false); + mwifiex_hs_activated_event(adapter, false); } } @@ -530,6 +513,11 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter) destroy_workqueue(adapter->rx_workqueue); adapter->rx_workqueue = NULL; } + + if (adapter->host_mlme_workqueue) { + destroy_workqueue(adapter->host_mlme_workqueue); + adapter->host_mlme_workqueue = NULL; + } } /* @@ -584,21 +572,11 @@ static int _mwifiex_fw_dpc(const struct firmware *firmware, void *context) goto err_dnld_fw; } - adapter->init_wait_q_woken = false; ret = mwifiex_init_fw(adapter); - if (ret == -1) { + if (ret == -1) goto err_init_fw; - } else if (!ret) { - adapter->hw_status = MWIFIEX_HW_STATUS_READY; - goto done; - } - /* Wait for mwifiex_init to complete */ - if (!adapter->mfg_mode) { - wait_event_interruptible(adapter->init_wait_q, - adapter->init_wait_q_woken); - if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) - goto err_init_fw; - } + + maybe_quirk_fw_disable_ds(adapter); if (!adapter->wiphy) { if (mwifiex_register_cfg80211(adapter)) { @@ -688,10 +666,6 @@ err_dnld_fw: init_failed = true; done: - if (adapter->cal_data) { - release_firmware(adapter->cal_data); - adapter->cal_data = NULL; - } if (adapter->firmware) { release_firmware(adapter->firmware); adapter->firmware = NULL; @@ -802,6 +776,10 @@ mwifiex_bypass_tx_queue(struct mwifiex_private *priv, "bypass txqueue; eth type %#x, mgmt %d\n", ntohs(eth_hdr->h_proto), mwifiex_is_skb_mgmt_frame(skb)); + if (eth_hdr->h_proto == htons(ETH_P_PAE)) + mwifiex_dbg(priv->adapter, MSG, + "key: send EAPOL to %pM\n", + eth_hdr->h_dest); return true; } @@ -935,8 +913,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) multicast = is_multicast_ether_addr(skb->data); - if (unlikely(!multicast && skb->sk && - skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && + if (unlikely(!multicast && sk_requests_wifi_status(skb->sk) && priv->adapter->fw_api_ver == MWIFIEX_FW_V15)) skb = mwifiex_clone_skb_for_tx_status(priv, skb, @@ -1162,7 +1139,7 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter) } for (i = 0; i < adapter->priv_num; i++) { - if (!adapter->priv[i] || !adapter->priv[i]->netdev) + if (!adapter->priv[i]->netdev) continue; priv = adapter->priv[i]; p += sprintf(p, "\n[interface : \"%s\"]\n", @@ -1201,7 +1178,7 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter) debug_info = kzalloc(sizeof(*debug_info), GFP_KERNEL); if (debug_info) { for (i = 0; i < adapter->priv_num; i++) { - if (!adapter->priv[i] || !adapter->priv[i]->netdev) + if (!adapter->priv[i]->netdev) continue; priv = adapter->priv[i]; mwifiex_get_debug_info(priv, debug_info); @@ -1384,6 +1361,35 @@ int is_command_pending(struct mwifiex_adapter *adapter) return !is_cmd_pend_q_empty; } +/* This is the host mlme work queue function. + * It handles the host mlme operations. + */ +static void mwifiex_host_mlme_work_queue(struct work_struct *work) +{ + struct mwifiex_adapter *adapter = + container_of(work, struct mwifiex_adapter, host_mlme_work); + + if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags)) + return; + + /* Check for host mlme disconnection */ + if (adapter->host_mlme_link_lost) { + if (adapter->priv_link_lost) { + mwifiex_reset_connect_state(adapter->priv_link_lost, + WLAN_REASON_DEAUTH_LEAVING, + true); + adapter->priv_link_lost = NULL; + } + adapter->host_mlme_link_lost = false; + } + + /* Check for host mlme Assoc Resp */ + if (adapter->assoc_resp_received) { + mwifiex_process_assoc_resp(adapter); + adapter->assoc_resp_received = false; + } +} + /* * This is the RX work queue function. * @@ -1434,7 +1440,7 @@ static void mwifiex_uninit_sw(struct mwifiex_adapter *adapter) /* Stop data */ for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; - if (priv && priv->netdev) { + if (priv->netdev) { mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); @@ -1459,8 +1465,6 @@ static void mwifiex_uninit_sw(struct mwifiex_adapter *adapter) for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; - if (!priv) - continue; rtnl_lock(); if (priv->netdev && priv->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED) { @@ -1528,7 +1532,6 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter) adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; clear_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags); - init_waitqueue_head(&adapter->init_wait_q); clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags); adapter->hs_activated = false; clear_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags); @@ -1558,6 +1561,18 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter) INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue); } + if (adapter->host_mlme_enabled) { + adapter->host_mlme_workqueue = + alloc_workqueue("MWIFIEX_HOST_MLME_WORK_QUEUE", + WQ_HIGHPRI | + WQ_MEM_RECLAIM | + WQ_UNBOUND, 0); + if (!adapter->host_mlme_workqueue) + goto err_kmalloc; + INIT_WORK(&adapter->host_mlme_work, + mwifiex_host_mlme_work_queue); + } + /* Register the device. Fill up the private data structure with * relevant information from the card. Some code extracted from * mwifiex_register_dev() @@ -1633,7 +1648,8 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) } ret = devm_request_irq(dev, adapter->irq_wakeup, - mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW, + mwifiex_irq_wakeup_handler, + IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN, "wifi_wake", adapter); if (ret) { dev_err(dev, "Failed to request irq_wakeup %d (%d)\n", @@ -1641,7 +1657,6 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter) goto err_exit; } - disable_irq(adapter->irq_wakeup); if (device_init_wakeup(dev, true)) { dev_err(dev, "fail to init wakeup for mwifiex\n"); goto err_exit; @@ -1667,7 +1682,7 @@ err_exit: */ int mwifiex_add_card(void *card, struct completion *fw_done, - struct mwifiex_if_ops *if_ops, u8 iface_type, + const struct mwifiex_if_ops *if_ops, u8 iface_type, struct device *dev) { struct mwifiex_adapter *adapter; @@ -1684,7 +1699,6 @@ mwifiex_add_card(void *card, struct completion *fw_done, adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; clear_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags); - init_waitqueue_head(&adapter->init_wait_q); clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags); adapter->hs_activated = false; init_waitqueue_head(&adapter->hs_activate_wait_q); @@ -1721,6 +1735,18 @@ mwifiex_add_card(void *card, struct completion *fw_done, goto err_registerdev; } + if (adapter->host_mlme_enabled) { + adapter->host_mlme_workqueue = + alloc_workqueue("MWIFIEX_HOST_MLME_WORK_QUEUE", + WQ_HIGHPRI | + WQ_MEM_RECLAIM | + WQ_UNBOUND, 0); + if (!adapter->host_mlme_workqueue) + goto err_kmalloc; + INIT_WORK(&adapter->host_mlme_work, + mwifiex_host_mlme_work_queue); + } + if (mwifiex_init_hw_fw(adapter, true)) { pr_err("%s: firmware init failed\n", __func__); goto err_init_fw; |