From d0b2f91bede3bd5e3d24dd6803e56eee959c1797 Mon Sep 17 00:00:00 2001 From: AndrĂ© Fabian Silva Delgado Date: Thu, 20 Oct 2016 00:10:27 -0300 Subject: Linux-libre 4.8.2-gnu --- drivers/net/wireless/marvell/mwifiex/11n_aggr.c | 5 +- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 105 ++++++++++++++++----- drivers/net/wireless/marvell/mwifiex/cmdevt.c | 40 +------- drivers/net/wireless/marvell/mwifiex/fw.h | 7 +- drivers/net/wireless/marvell/mwifiex/init.c | 5 +- drivers/net/wireless/marvell/mwifiex/ioctl.h | 12 ++- drivers/net/wireless/marvell/mwifiex/join.c | 14 ++- drivers/net/wireless/marvell/mwifiex/main.c | 12 ++- drivers/net/wireless/marvell/mwifiex/main.h | 6 +- drivers/net/wireless/marvell/mwifiex/pcie.c | 86 +++++++++++++---- drivers/net/wireless/marvell/mwifiex/pcie.h | 4 +- drivers/net/wireless/marvell/mwifiex/scan.c | 48 +++++++++- drivers/net/wireless/marvell/mwifiex/sdio.c | 64 +++++++++---- drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 78 ++++++++------- drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 52 +++++----- drivers/net/wireless/marvell/mwifiex/sta_event.c | 18 ++-- drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 25 +++-- drivers/net/wireless/marvell/mwifiex/uap_cmd.c | 30 +++++- drivers/net/wireless/marvell/mwifiex/uap_txrx.c | 2 +- 19 files changed, 420 insertions(+), 193 deletions(-) (limited to 'drivers/net/wireless/marvell/mwifiex') diff --git a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c index 1efef3b82..c47d63668 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c @@ -184,7 +184,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, tx_info_src = MWIFIEX_SKB_TXCB(skb_src); skb_aggr = mwifiex_alloc_dma_align_buf(adapter->tx_buf_size, - GFP_ATOMIC | GFP_DMA); + GFP_ATOMIC); if (!skb_aggr) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); @@ -205,7 +205,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, do { /* Check if AMSDU can accommodate this MSDU */ - if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN)) + if ((skb_aggr->len + skb_src->len + LLC_SNAP_LEN) > + adapter->tx_buf_size) break; skb_src = skb_dequeue(&pra_list->skb_head); diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index ff948a922..a8ff969c9 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -376,6 +376,29 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, return mwifiex_set_tx_power(priv, &power_cfg); } +/* + * CFG802.11 operation handler to get Tx power. + */ +static int +mwifiex_cfg80211_get_tx_power(struct wiphy *wiphy, + struct wireless_dev *wdev, + int *dbm) +{ + struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); + struct mwifiex_private *priv = mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY); + int ret = mwifiex_send_cmd(priv, HostCmd_CMD_RF_TX_PWR, + HostCmd_ACT_GEN_GET, 0, NULL, true); + + if (ret < 0) + return ret; + + /* tx_power_level is set in HostCmd_CMD_RF_TX_PWR command handler */ + *dbm = priv->tx_power_level; + + return 0; +} + /* * CFG802.11 operation handler to set Power Save option. * @@ -1672,6 +1695,9 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy, struct cfg80211_beacon_data *data) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + struct mwifiex_adapter *adapter = priv->adapter; + + mwifiex_cancel_scan(adapter); if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) { mwifiex_dbg(priv->adapter, ERROR, @@ -1804,6 +1830,21 @@ mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) HostCmd_ACT_GEN_SET, 0, &ant_cfg, true); } +static int +mwifiex_cfg80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant) +{ + struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); + struct mwifiex_private *priv = mwifiex_get_priv(adapter, + MWIFIEX_BSS_ROLE_ANY); + mwifiex_send_cmd(priv, HostCmd_CMD_RF_ANTENNA, + HostCmd_ACT_GEN_GET, 0, NULL, true); + + *tx_ant = priv->tx_ant; + *rx_ant = priv->rx_ant; + + return 0; +} + /* cfg80211 operation handler for stop ap. * Function stops BSS running at uAP interface. */ @@ -1895,10 +1936,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, mwifiex_set_uap_rates(bss_cfg, params); if (mwifiex_set_secure_params(priv, bss_cfg, params)) { - kfree(bss_cfg); mwifiex_dbg(priv->adapter, ERROR, "Failed to parse secuirty parameters!\n"); - return -1; + goto out; } mwifiex_set_ht_params(priv, bss_cfg, params); @@ -1927,7 +1967,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, if (mwifiex_11h_activate(priv, false)) { mwifiex_dbg(priv->adapter, ERROR, "Failed to disable 11h extensions!!"); - return -1; + goto out; } priv->state_11h.is_11h_active = false; } @@ -1935,12 +1975,11 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, if (mwifiex_config_start_uap(priv, bss_cfg)) { mwifiex_dbg(priv->adapter, ERROR, "Failed to start AP\n"); - kfree(bss_cfg); - return -1; + goto out; } if (mwifiex_set_mgmt_ies(priv, ¶ms->beacon)) - return -1; + goto out; if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); @@ -1949,6 +1988,10 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, memcpy(&priv->bss_cfg, bss_cfg, sizeof(priv->bss_cfg)); kfree(bss_cfg); return 0; + +out: + kfree(bss_cfg); + return -1; } /* @@ -2209,6 +2252,9 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return -EALREADY; } + if (priv->scan_block) + priv->scan_block = false; + if (adapter->surprise_removed || adapter->is_cmd_timedout) { mwifiex_dbg(adapter, ERROR, "%s: Ignore connection.\t" @@ -2427,6 +2473,9 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, return -EBUSY; } + if (!priv->wdev.current_bss && priv->scan_block) + priv->scan_block = false; + if (!mwifiex_stop_bg_scan(priv)) cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy); @@ -2734,6 +2783,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, struct mwifiex_private *priv; struct net_device *dev; void *mdev_priv; + int ret; if (!adapter) return ERR_PTR(-EFAULT); @@ -2859,6 +2909,15 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, mwifiex_init_priv_params(priv, dev); priv->netdev = dev; + ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE, + HostCmd_ACT_GEN_SET, 0, NULL, true); + if (ret) + return ERR_PTR(ret); + + ret = mwifiex_sta_init_cmd(priv, false, false); + if (ret) + return ERR_PTR(ret); + mwifiex_setup_ht_caps(&wiphy->bands[NL80211_BAND_2GHZ]->ht_cap, priv); if (adapter->is_hw_11ac_capable) mwifiex_setup_vht_caps( @@ -3262,7 +3321,10 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, struct mwifiex_ds_hs_cfg hs_cfg; int i, ret = 0, retry_num = 10; struct mwifiex_private *priv; + struct mwifiex_private *sta_priv = + mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); + sta_priv->scan_aborting = true; for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; mwifiex_abort_cac(priv); @@ -3291,21 +3353,21 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, if (!wowlan) { mwifiex_dbg(adapter, ERROR, "None of the WOWLAN triggers enabled\n"); - return 0; + ret = 0; + goto done; } - priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); - - if (!priv->media_connected && !wowlan->nd_config) { + if (!sta_priv->media_connected && !wowlan->nd_config) { mwifiex_dbg(adapter, ERROR, "Can not configure WOWLAN in disconnected state\n"); - return 0; + ret = 0; + goto done; } - ret = mwifiex_set_mef_filter(priv, wowlan); + ret = mwifiex_set_mef_filter(sta_priv, wowlan); if (ret) { mwifiex_dbg(adapter, ERROR, "Failed to set MEF filter\n"); - return ret; + goto done; } memset(&hs_cfg, 0, sizeof(hs_cfg)); @@ -3314,26 +3376,25 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, if (wowlan->nd_config) { mwifiex_dbg(adapter, INFO, "Wake on net detect\n"); hs_cfg.conditions |= HS_CFG_COND_MAC_EVENT; - mwifiex_cfg80211_sched_scan_start(wiphy, priv->netdev, + mwifiex_cfg80211_sched_scan_start(wiphy, sta_priv->netdev, wowlan->nd_config); } if (wowlan->disconnect) { hs_cfg.conditions |= HS_CFG_COND_MAC_EVENT; - mwifiex_dbg(priv->adapter, INFO, "Wake on device disconnect\n"); + mwifiex_dbg(sta_priv->adapter, INFO, "Wake on device disconnect\n"); } hs_cfg.is_invoke_hostcmd = false; hs_cfg.gpio = adapter->hs_cfg.gpio; hs_cfg.gap = adapter->hs_cfg.gap; - ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET, + ret = mwifiex_set_hs_params(sta_priv, HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, &hs_cfg); - if (ret) { - mwifiex_dbg(adapter, ERROR, - "Failed to set HS params\n"); - return ret; - } + if (ret) + mwifiex_dbg(adapter, ERROR, "Failed to set HS params\n"); +done: + sta_priv->scan_aborting = false; return ret; } @@ -3940,12 +4001,14 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .set_default_key = mwifiex_cfg80211_set_default_key, .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, .set_tx_power = mwifiex_cfg80211_set_tx_power, + .get_tx_power = mwifiex_cfg80211_get_tx_power, .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, .start_ap = mwifiex_cfg80211_start_ap, .stop_ap = mwifiex_cfg80211_stop_ap, .change_beacon = mwifiex_cfg80211_change_beacon, .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, .set_antenna = mwifiex_cfg80211_set_antenna, + .get_antenna = mwifiex_cfg80211_get_antenna, .del_station = mwifiex_cfg80211_del_station, .sched_scan_start = mwifiex_cfg80211_sched_scan_start, .sched_scan_stop = mwifiex_cfg80211_sched_scan_stop, diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c index 6bc2011d8..c29f26d8b 100644 --- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c +++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c @@ -1020,8 +1020,6 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL, *tmp_node; unsigned long flags, cmd_flags; - struct mwifiex_private *priv; - int i; spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); /* Cancel current cmd */ @@ -1046,23 +1044,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags); spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); - mwifiex_cancel_pending_scan_cmd(adapter); - - if (adapter->scan_processing) { - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); - adapter->scan_processing = false; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); - for (i = 0; i < adapter->priv_num; i++) { - priv = adapter->priv[i]; - if (!priv) - continue; - if (priv->scan_request) { - mwifiex_dbg(adapter, WARN, "info: aborting scan\n"); - cfg80211_scan_done(priv->scan_request, 1); - priv->scan_request = NULL; - } - } - } + mwifiex_cancel_scan(adapter); } /* @@ -1080,8 +1062,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) { struct cmd_ctrl_node *cmd_node = NULL; unsigned long cmd_flags; - struct mwifiex_private *priv; - int i; if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { @@ -1101,23 +1081,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) mwifiex_recycle_cmd_node(adapter, cmd_node); } - mwifiex_cancel_pending_scan_cmd(adapter); - - if (adapter->scan_processing) { - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); - adapter->scan_processing = false; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); - for (i = 0; i < adapter->priv_num; i++) { - priv = adapter->priv[i]; - if (!priv) - continue; - if (priv->scan_request) { - mwifiex_dbg(adapter, WARN, "info: aborting scan\n"); - cfg80211_scan_done(priv->scan_request, 1); - priv->scan_request = NULL; - } - } - } + mwifiex_cancel_scan(adapter); } /* diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h index 8e4145abd..5596b6be1 100644 --- a/drivers/net/wireless/marvell/mwifiex/fw.h +++ b/drivers/net/wireless/marvell/mwifiex/fw.h @@ -462,6 +462,9 @@ enum P2P_MODES { #define HostCmd_ACT_SET_RX 0x0001 #define HostCmd_ACT_SET_TX 0x0002 #define HostCmd_ACT_SET_BOTH 0x0003 +#define HostCmd_ACT_GET_RX 0x0004 +#define HostCmd_ACT_GET_TX 0x0008 +#define HostCmd_ACT_GET_BOTH 0x000c #define RF_ANTENNA_AUTO 0xFFFF @@ -1958,8 +1961,8 @@ struct mwifiex_ie_types_btcoex_scan_time { struct mwifiex_ie_types_header header; u8 coex_scan; u8 reserved; - u16 min_scan_time; - u16 max_scan_time; + __le16 min_scan_time; + __le16 max_scan_time; } __packed; struct mwifiex_ie_types_btcoex_aggr_win_size { diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c index 78c532f0d..1489c9019 100644 --- a/drivers/net/wireless/marvell/mwifiex/init.c +++ b/drivers/net/wireless/marvell/mwifiex/init.c @@ -60,7 +60,7 @@ static void wakeup_timer_fn(unsigned long data) adapter->hw_status = MWIFIEX_HW_STATUS_RESET; mwifiex_cancel_all_pending_cmd(adapter); - if (adapter->if_ops.card_reset) + if (adapter->if_ops.card_reset && !adapter->hs_activated) adapter->if_ops.card_reset(adapter); } @@ -110,6 +110,8 @@ int mwifiex_init_priv(struct mwifiex_private *priv) priv->tx_power_level = 0; priv->max_tx_power_level = 0; priv->min_tx_power_level = 0; + priv->tx_ant = 0; + priv->rx_ant = 0; priv->tx_rate = 0; priv->rxpd_htinfo = 0; priv->rxpd_rate = 0; @@ -788,3 +790,4 @@ poll_fw: return ret; } +EXPORT_SYMBOL_GPL(mwifiex_dnld_fw); diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h index a5a48c183..70429815f 100644 --- a/drivers/net/wireless/marvell/mwifiex/ioctl.h +++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h @@ -83,6 +83,8 @@ struct wep_key { #define MWIFIEX_AUTH_MODE_AUTO 0xFF #define BAND_CONFIG_BG 0x00 #define BAND_CONFIG_A 0x01 +#define MWIFIEX_SEC_CHAN_BELOW 0x30 +#define MWIFIEX_SEC_CHAN_ABOVE 0x10 #define MWIFIEX_SUPPORTED_RATES 14 #define MWIFIEX_SUPPORTED_RATES_EXT 32 #define MWIFIEX_TDLS_SUPPORTED_RATES 8 @@ -341,16 +343,16 @@ enum { }; struct mwifiex_ds_reg_rw { - __le32 type; - __le32 offset; - __le32 value; + u32 type; + u32 offset; + u32 value; }; #define MAX_EEPROM_DATA 256 struct mwifiex_ds_read_eeprom { - __le16 offset; - __le16 byte_count; + u16 offset; + u16 byte_count; u8 value[MAX_EEPROM_DATA]; }; diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c index 62211fca9..1c7b00630 100644 --- a/drivers/net/wireless/marvell/mwifiex/join.c +++ b/drivers/net/wireless/marvell/mwifiex/join.c @@ -647,6 +647,12 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, const u8 *ie_ptr; struct ieee80211_ht_operation *assoc_resp_ht_oper; + if (!priv->attempted_bss_desc) { + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: failed, association terminated by host\n"); + goto done; + } + assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; cap_info = le16_to_cpu(assoc_rsp->cap_info_bitmap); @@ -1270,6 +1276,12 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, u16 cmd = le16_to_cpu(resp->command); u8 result; + if (!priv->attempted_bss_desc) { + mwifiex_dbg(priv->adapter, ERROR, + "ADHOC_RESP: failed, association terminated by host\n"); + goto done; + } + if (cmd == HostCmd_CMD_802_11_AD_HOC_START) result = start_result->result; else @@ -1281,7 +1293,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, if (result) { mwifiex_dbg(priv->adapter, ERROR, "ADHOC_RESP: failed\n"); if (priv->media_connected) - mwifiex_reset_connect_state(priv, result); + mwifiex_reset_connect_state(priv, result, true); memset(&priv->curr_bss_params.bss_descriptor, 0x00, sizeof(struct mwifiex_bssdescriptor)); diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index 4dde1ae35..1afd6a94c 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -526,10 +526,12 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) fw.fw_buf = (u8 *) adapter->firmware->data; fw.fw_len = adapter->firmware->size; - if (adapter->if_ops.dnld_fw) + if (adapter->if_ops.dnld_fw) { ret = adapter->if_ops.dnld_fw(adapter, &fw); - else + } else { ret = mwifiex_dnld_fw(adapter, &fw); + } + if (ret == -1) goto err_dnld_fw; @@ -695,9 +697,13 @@ mwifiex_close(struct net_device *dev) struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); if (priv->scan_request) { + struct cfg80211_scan_info info = { + .aborted = true, + }; + mwifiex_dbg(priv->adapter, INFO, "aborting scan on ndo_stop\n"); - cfg80211_scan_done(priv->scan_request, 1); + cfg80211_scan_done(priv->scan_request, &info); priv->scan_request = NULL; priv->scan_aborting = true; } diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 0207af00b..9f6bb400b 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -533,6 +533,8 @@ struct mwifiex_private { u16 tx_power_level; u8 max_tx_power_level; u8 min_tx_power_level; + u32 tx_ant; + u32 rx_ant; u8 tx_rate; u8 tx_htinfo; u8 rxpd_htinfo; @@ -1054,6 +1056,7 @@ int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter); void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter); void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter); +void mwifiex_cancel_scan(struct mwifiex_adapter *adapter); void mwifiex_recycle_cmd_node(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node); @@ -1128,7 +1131,8 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason); +void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason, + bool from_ap); u8 mwifiex_band_to_radio_type(u8 band); int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); void mwifiex_deauthenticate_all(struct mwifiex_adapter *adapter); diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 0c7937eb6..453ab6ad4 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -202,7 +202,6 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, MWIFIEX_PCIE)) { pr_err("%s failed\n", __func__); - kfree(card); return -1; } @@ -440,6 +439,11 @@ static int mwifiex_pcie_disable_host_int(struct mwifiex_adapter *adapter) return 0; } +static void mwifiex_pcie_disable_host_int_noerr(struct mwifiex_adapter *adapter) +{ + WARN_ON(mwifiex_pcie_disable_host_int(adapter)); +} + /* * This function enables the host interrupt. * @@ -507,7 +511,7 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { /* Allocate skb here so that firmware can DMA data from it */ skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE, - GFP_KERNEL | GFP_DMA); + GFP_KERNEL); if (!skb) { mwifiex_dbg(adapter, ERROR, "Unable to allocate skb for RX ring.\n"); @@ -1319,7 +1323,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) } skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE, - GFP_KERNEL | GFP_DMA); + GFP_KERNEL); if (!skb_tmp) { mwifiex_dbg(adapter, ERROR, "Unable to allocate skb.\n"); @@ -1612,6 +1616,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) pkt_len = *((__le16 *)skb->data); rx_len = le16_to_cpu(pkt_len); + skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len); skb_trim(skb, rx_len); skb_pull(skb, INTF_HEADER_LEN); @@ -2086,6 +2091,13 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter, unsigned long flags; struct pcie_service_card *card = adapter->card; + if (card->msi_enable) { + spin_lock_irqsave(&adapter->int_lock, flags); + adapter->int_status = 1; + spin_unlock_irqrestore(&adapter->int_lock, flags); + return; + } + if (!mwifiex_pcie_ok_to_access_hw(adapter)) return; @@ -2187,15 +2199,44 @@ exit: static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) { int ret; - u32 pcie_ireg; + u32 pcie_ireg = 0; unsigned long flags; + struct pcie_service_card *card = adapter->card; spin_lock_irqsave(&adapter->int_lock, flags); - /* Clear out unused interrupts */ - pcie_ireg = adapter->int_status; + if (!card->msi_enable) { + /* Clear out unused interrupts */ + pcie_ireg = adapter->int_status; + } adapter->int_status = 0; spin_unlock_irqrestore(&adapter->int_lock, flags); + if (card->msi_enable) { + if (mwifiex_pcie_ok_to_access_hw(adapter)) { + if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, + &pcie_ireg)) { + mwifiex_dbg(adapter, ERROR, + "Read register failed\n"); + return -1; + } + + if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { + if (mwifiex_write_reg(adapter, + PCIE_HOST_INT_STATUS, + ~pcie_ireg)) { + mwifiex_dbg(adapter, ERROR, + "Write register failed\n"); + return -1; + } + if (!adapter->pps_uapsd_mode && + adapter->ps_state == PS_STATE_SLEEP) { + adapter->ps_state = PS_STATE_AWAKE; + adapter->pm_wakeup_fw_try = false; + del_timer(&adapter->wakeup_timer); + } + } + } + } while (pcie_ireg & HOST_INTR_MASK) { if (pcie_ireg & HOST_INTR_DNLD_DONE) { pcie_ireg &= ~HOST_INTR_DNLD_DONE; @@ -2235,6 +2276,12 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) return ret; } + if (card->msi_enable) { + spin_lock_irqsave(&adapter->int_lock, flags); + adapter->int_status = 0; + spin_unlock_irqrestore(&adapter->int_lock, flags); + } + if (mwifiex_pcie_ok_to_access_hw(adapter)) { if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) { @@ -2254,11 +2301,17 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) } } + if (!card->msi_enable) { + spin_lock_irqsave(&adapter->int_lock, flags); + pcie_ireg |= adapter->int_status; + adapter->int_status = 0; + spin_unlock_irqrestore(&adapter->int_lock, flags); + } } mwifiex_dbg(adapter, INTR, "info: cmd_sent=%d data_sent=%d\n", adapter->cmd_sent, adapter->data_sent); - if (adapter->ps_state != PS_STATE_SLEEP) + if (!card->msi_enable && adapter->ps_state != PS_STATE_SLEEP) mwifiex_pcie_enable_host_int(adapter); return 0; @@ -2796,7 +2849,6 @@ static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter) "MRVL_PCIE", &card->share_irq_ctx); if (ret) { pr_err("request_irq failed: ret=%d\n", ret); - adapter->card = NULL; return -1; } @@ -2804,7 +2856,7 @@ static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter) } /* - * This function get firmare name for downloading by revision id + * This function gets the firmware name for downloading by revision id * * Read revision id register to get revision id */ @@ -2841,20 +2893,20 @@ static void mwifiex_pcie_get_fw_name(struct mwifiex_adapter *adapter) version &= 0x7; switch (revision_id) { case PCIE8997_V2: - if (version == CHIP_VER_PCIEUSB) + if (version == CHIP_VER_PCIEUART) strcpy(adapter->fw_name, - PCIEUSB8997_FW_NAME_V2); + PCIEUART8997_FW_NAME_V2); else strcpy(adapter->fw_name, - PCIEUART8997_FW_NAME_V2); + PCIEUSB8997_FW_NAME_V2); break; case PCIE8997_Z: - if (version == CHIP_VER_PCIEUSB) + if (version == CHIP_VER_PCIEUART) strcpy(adapter->fw_name, - PCIEUSB8997_FW_NAME_Z); + PCIEUART8997_FW_NAME_Z); else strcpy(adapter->fw_name, - PCIEUART8997_FW_NAME_Z); + PCIEUSB8997_FW_NAME_Z); break; default: strcpy(adapter->fw_name, PCIE8997_DEFAULT_FW_NAME); @@ -2901,10 +2953,11 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg; - struct pci_dev *pdev = card->dev; + struct pci_dev *pdev; int i; if (card) { + pdev = card->dev; if (card->msix_enable) { for (i = 0; i < MWIFIEX_NUM_MSIX_VECTORS; i++) synchronize_irq(card->msix_entries[i].vector); @@ -2945,6 +2998,7 @@ static struct mwifiex_if_ops pcie_ops = { .register_dev = mwifiex_register_dev, .unregister_dev = mwifiex_unregister_dev, .enable_int = mwifiex_pcie_enable_host_int, + .disable_int = mwifiex_pcie_disable_host_int_noerr, .process_int_status = mwifiex_process_int_status, .host_to_card = mwifiex_pcie_host_to_card, .wakeup = mwifiex_pm_wakeup_card, diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h index db18ac6f5..609588400 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.h +++ b/drivers/net/wireless/marvell/mwifiex/pcie.h @@ -48,7 +48,7 @@ #define PCIE8897_B0 0x1200 #define PCIE8997_Z 0x0 #define PCIE8997_V2 0x471 -#define CHIP_VER_PCIEUSB 0x2 +#define CHIP_VER_PCIEUART 0x3 /* Constants for Buffer Descriptor (BD) rings */ #define MWIFIEX_MAX_TXRX_BD 0x20 @@ -258,7 +258,7 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8997 = { .fw_dump_end = 0xcff, .fw_dump_host_ready = 0xcc, .fw_dump_read_done = 0xdd, - .msix_support = 1, + .msix_support = 0, }; static struct memory_type_mapping mem_type_mapping_tbl_w8897[] = { diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c index bc5e52ceb..21ec84794 100644 --- a/drivers/net/wireless/marvell/mwifiex/scan.c +++ b/drivers/net/wireless/marvell/mwifiex/scan.c @@ -1896,7 +1896,8 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv) u8 id = 0; struct mwifiex_user_scan_cfg *user_scan_cfg; - if (adapter->active_scan_triggered || !priv->scan_request) { + if (adapter->active_scan_triggered || !priv->scan_request || + priv->scan_aborting) { adapter->active_scan_triggered = false; return 0; } @@ -1956,10 +1957,15 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) mwifiex_complete_scan(priv); if (priv->scan_request) { + struct cfg80211_scan_info info = { + .aborted = false, + }; + mwifiex_dbg(adapter, INFO, "info: notifying scan done\n"); - cfg80211_scan_done(priv->scan_request, 0); + cfg80211_scan_done(priv->scan_request, &info); priv->scan_request = NULL; + priv->scan_aborting = false; } else { priv->scan_aborting = false; mwifiex_dbg(adapter, INFO, @@ -1977,10 +1983,15 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) if (!adapter->active_scan_triggered) { if (priv->scan_request) { + struct cfg80211_scan_info info = { + .aborted = true, + }; + mwifiex_dbg(adapter, INFO, "info: aborting scan\n"); - cfg80211_scan_done(priv->scan_request, 1); + cfg80211_scan_done(priv->scan_request, &info); priv->scan_request = NULL; + priv->scan_aborting = false; } else { priv->scan_aborting = false; mwifiex_dbg(adapter, INFO, @@ -2001,6 +2012,37 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) return; } +void mwifiex_cancel_scan(struct mwifiex_adapter *adapter) +{ + struct mwifiex_private *priv; + unsigned long cmd_flags; + int i; + + mwifiex_cancel_pending_scan_cmd(adapter); + + if (adapter->scan_processing) { + spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); + adapter->scan_processing = false; + spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + for (i = 0; i < adapter->priv_num; i++) { + priv = adapter->priv[i]; + if (!priv) + continue; + if (priv->scan_request) { + struct cfg80211_scan_info info = { + .aborted = true, + }; + + mwifiex_dbg(adapter, INFO, + "info: aborting scan\n"); + cfg80211_scan_done(priv->scan_request, &info); + priv->scan_request = NULL; + priv->scan_aborting = false; + } + } + } +} + /* * This function handles the command response of scan. * diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index e757dfc51..f49bfdb7f 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -102,10 +102,9 @@ static int mwifiex_sdio_probe_of(struct device *dev, struct sdio_mmc_card *card) struct mwifiex_plt_wake_cfg *cfg; int ret; - if (!dev->of_node || - !of_match_node(mwifiex_sdio_of_match_table, dev->of_node)) { - dev_err(dev, "sdio platform data not available\n"); - return -1; + if (!of_match_node(mwifiex_sdio_of_match_table, dev->of_node)) { + dev_err(dev, "required compatible string missing\n"); + return -EINVAL; } card->plt_of_node = dev->of_node; @@ -115,7 +114,7 @@ static int mwifiex_sdio_probe_of(struct device *dev, struct sdio_mmc_card *card) if (cfg && card->plt_of_node) { cfg->irq_wifi = irq_of_parse_and_map(card->plt_of_node, 0); if (!cfg->irq_wifi) { - dev_err(dev, + dev_dbg(dev, "fail to parse irq_wifi from device tree\n"); } else { ret = devm_request_irq(dev, cfg->irq_wifi, @@ -183,24 +182,35 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) sdio_release_host(func); if (ret) { - pr_err("%s: failed to enable function\n", __func__); - kfree(card); - return -EIO; + dev_err(&func->dev, "failed to enable function\n"); + goto err_free; } /* device tree node parsing and platform specific configuration*/ - mwifiex_sdio_probe_of(&func->dev, card); - - if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops, - MWIFIEX_SDIO)) { - pr_err("%s: add card failed\n", __func__); - kfree(card); - sdio_claim_host(func); - ret = sdio_disable_func(func); - sdio_release_host(func); - ret = -1; + if (func->dev.of_node) { + ret = mwifiex_sdio_probe_of(&func->dev, card); + if (ret) { + dev_err(&func->dev, "SDIO dt node parse failed\n"); + goto err_disable; + } + } + + ret = mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops, + MWIFIEX_SDIO); + if (ret) { + dev_err(&func->dev, "add card failed\n"); + goto err_disable; } + return 0; + +err_disable: + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); +err_free: + kfree(card); + return ret; } @@ -544,6 +554,19 @@ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter) return mwifiex_write_reg(adapter, CONFIGURATION_REG, 0); } +static int mwifiex_sdio_dnld_fw(struct mwifiex_adapter *adapter, + struct mwifiex_fw_image *fw) +{ + struct sdio_mmc_card *card = adapter->card; + int ret; + + sdio_claim_host(card->func); + ret = mwifiex_dnld_fw(adapter, fw); + sdio_release_host(card->func); + + return ret; +} + /* * This function is used to initialize IO ports for the * chipsets supporting SDIO new mode eg SD8897. @@ -1492,7 +1515,7 @@ rx_curr_single: mwifiex_dbg(adapter, INFO, "info: RX: port: %d, rx_len: %d\n", port, rx_len); - skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA); + skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL); if (!skb) { mwifiex_dbg(adapter, ERROR, "single skb allocated fail,\t" @@ -1597,7 +1620,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); mwifiex_dbg(adapter, INFO, "info: rx_len = %d\n", rx_len); - skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA); + skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL); if (!skb) return -1; @@ -2732,6 +2755,7 @@ static struct mwifiex_if_ops sdio_ops = { .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, .event_complete = mwifiex_sdio_event_complete, + .dnld_fw = mwifiex_sdio_dnld_fw, .card_reset = mwifiex_sdio_card_reset, .reg_dump = mwifiex_sdio_reg_dump, .device_dump = mwifiex_sdio_device_dump, diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c index e436574b1..7897037b0 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c @@ -313,23 +313,41 @@ static int mwifiex_cmd_rf_antenna(struct mwifiex_private *priv, cmd->command = cpu_to_le16(HostCmd_CMD_RF_ANTENNA); - if (cmd_action != HostCmd_ACT_GEN_SET) - return 0; - - if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) { - cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_ant_mimo) + - S_DS_GEN); - ant_mimo->action_tx = cpu_to_le16(HostCmd_ACT_SET_TX); - ant_mimo->tx_ant_mode = cpu_to_le16((u16)ant_cfg->tx_ant); - ant_mimo->action_rx = cpu_to_le16(HostCmd_ACT_SET_RX); - ant_mimo->rx_ant_mode = cpu_to_le16((u16)ant_cfg->rx_ant); - } else { - cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_ant_siso) + - S_DS_GEN); - ant_siso->action = cpu_to_le16(HostCmd_ACT_SET_BOTH); - ant_siso->ant_mode = cpu_to_le16((u16)ant_cfg->tx_ant); + switch (cmd_action) { + case HostCmd_ACT_GEN_SET: + if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) { + cmd->size = cpu_to_le16(sizeof(struct + host_cmd_ds_rf_ant_mimo) + + S_DS_GEN); + ant_mimo->action_tx = cpu_to_le16(HostCmd_ACT_SET_TX); + ant_mimo->tx_ant_mode = cpu_to_le16((u16)ant_cfg-> + tx_ant); + ant_mimo->action_rx = cpu_to_le16(HostCmd_ACT_SET_RX); + ant_mimo->rx_ant_mode = cpu_to_le16((u16)ant_cfg-> + rx_ant); + } else { + cmd->size = cpu_to_le16(sizeof(struct + host_cmd_ds_rf_ant_siso) + + S_DS_GEN); + ant_siso->action = cpu_to_le16(HostCmd_ACT_SET_BOTH); + ant_siso->ant_mode = cpu_to_le16((u16)ant_cfg->tx_ant); + } + break; + case HostCmd_ACT_GEN_GET: + if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) { + cmd->size = cpu_to_le16(sizeof(struct + host_cmd_ds_rf_ant_mimo) + + S_DS_GEN); + ant_mimo->action_tx = cpu_to_le16(HostCmd_ACT_GET_TX); + ant_mimo->action_rx = cpu_to_le16(HostCmd_ACT_GET_RX); + } else { + cmd->size = cpu_to_le16(sizeof(struct + host_cmd_ds_rf_ant_siso) + + S_DS_GEN); + ant_siso->action = cpu_to_le16(HostCmd_ACT_GET_BOTH); + } + break; } - return 0; } @@ -1130,9 +1148,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); mac_reg = &cmd->params.mac_reg; mac_reg->action = cpu_to_le16(cmd_action); - mac_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); - mac_reg->value = reg_rw->value; + mac_reg->offset = cpu_to_le16((u16) reg_rw->offset); + mac_reg->value = cpu_to_le32(reg_rw->value); break; } case HostCmd_CMD_BBP_REG_ACCESS: @@ -1142,9 +1159,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); bbp_reg = &cmd->params.bbp_reg; bbp_reg->action = cpu_to_le16(cmd_action); - bbp_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); - bbp_reg->value = (u8) le32_to_cpu(reg_rw->value); + bbp_reg->offset = cpu_to_le16((u16) reg_rw->offset); + bbp_reg->value = (u8) reg_rw->value; break; } case HostCmd_CMD_RF_REG_ACCESS: @@ -1154,8 +1170,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); rf_reg = &cmd->params.rf_reg; rf_reg->action = cpu_to_le16(cmd_action); - rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); - rf_reg->value = (u8) le32_to_cpu(reg_rw->value); + rf_reg->offset = cpu_to_le16((u16) reg_rw->offset); + rf_reg->value = (u8) reg_rw->value; break; } case HostCmd_CMD_PMIC_REG_ACCESS: @@ -1165,9 +1181,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN); pmic_reg = &cmd->params.pmic_reg; pmic_reg->action = cpu_to_le16(cmd_action); - pmic_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); - pmic_reg->value = (u8) le32_to_cpu(reg_rw->value); + pmic_reg->offset = cpu_to_le16((u16) reg_rw->offset); + pmic_reg->value = (u8) reg_rw->value; break; } case HostCmd_CMD_CAU_REG_ACCESS: @@ -1177,9 +1192,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); cau_reg = &cmd->params.rf_reg; cau_reg->action = cpu_to_le16(cmd_action); - cau_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); - cau_reg->value = (u8) le32_to_cpu(reg_rw->value); + cau_reg->offset = cpu_to_le16((u16) reg_rw->offset); + cau_reg->value = (u8) reg_rw->value; break; } case HostCmd_CMD_802_11_EEPROM_ACCESS: @@ -1190,8 +1204,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN); cmd_eeprom->action = cpu_to_le16(cmd_action); - cmd_eeprom->offset = rd_eeprom->offset; - cmd_eeprom->byte_count = rd_eeprom->byte_count; + cmd_eeprom->offset = cpu_to_le16(rd_eeprom->offset); + cmd_eeprom->byte_count = cpu_to_le16(rd_eeprom->byte_count); cmd_eeprom->value = 0; break; } diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c index d18c7979d..ccf54932e 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c @@ -469,7 +469,9 @@ static int mwifiex_ret_rf_antenna(struct mwifiex_private *priv, struct host_cmd_ds_rf_ant_siso *ant_siso = &resp->params.ant_siso; struct mwifiex_adapter *adapter = priv->adapter; - if (adapter->hw_dev_mcs_support == HT_STREAM_2X2) + if (adapter->hw_dev_mcs_support == HT_STREAM_2X2) { + priv->tx_ant = le16_to_cpu(ant_mimo->tx_ant_mode); + priv->rx_ant = le16_to_cpu(ant_mimo->rx_ant_mode); mwifiex_dbg(adapter, INFO, "RF_ANT_RESP: Tx action = 0x%x, Tx Mode = 0x%04x\t" "Rx action = 0x%x, Rx Mode = 0x%04x\n", @@ -477,12 +479,14 @@ static int mwifiex_ret_rf_antenna(struct mwifiex_private *priv, le16_to_cpu(ant_mimo->tx_ant_mode), le16_to_cpu(ant_mimo->action_rx), le16_to_cpu(ant_mimo->rx_ant_mode)); - else + } else { + priv->tx_ant = le16_to_cpu(ant_siso->ant_mode); + priv->rx_ant = le16_to_cpu(ant_siso->ant_mode); mwifiex_dbg(adapter, INFO, "RF_ANT_RESP: action = 0x%x, Mode = 0x%04x\n", le16_to_cpu(ant_siso->action), le16_to_cpu(ant_siso->ant_mode)); - + } return 0; } @@ -553,7 +557,8 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv, if (!memcmp(resp->params.deauth.mac_addr, &priv->curr_bss_params.bss_descriptor.mac_address, sizeof(resp->params.deauth.mac_addr))) - mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING); + mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING, + false); return 0; } @@ -566,7 +571,7 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv, static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { - mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING); + mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING, false); return 0; } @@ -781,45 +786,44 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, switch (type) { case HostCmd_CMD_MAC_REG_ACCESS: r.mac = &resp->params.mac_reg; - reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); - reg_rw->value = r.mac->value; + reg_rw->offset = (u32) le16_to_cpu(r.mac->offset); + reg_rw->value = le32_to_cpu(r.mac->value); break; case HostCmd_CMD_BBP_REG_ACCESS: r.bbp = &resp->params.bbp_reg; - reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); - reg_rw->value = cpu_to_le32((u32) r.bbp->value); + reg_rw->offset = (u32) le16_to_cpu(r.bbp->offset); + reg_rw->value = (u32) r.bbp->value; break; case HostCmd_CMD_RF_REG_ACCESS: r.rf = &resp->params.rf_reg; - reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); - reg_rw->value = cpu_to_le32((u32) r.bbp->value); + reg_rw->offset = (u32) le16_to_cpu(r.rf->offset); + reg_rw->value = (u32) r.bbp->value; break; case HostCmd_CMD_PMIC_REG_ACCESS: r.pmic = &resp->params.pmic_reg; - reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); - reg_rw->value = cpu_to_le32((u32) r.pmic->value); + reg_rw->offset = (u32) le16_to_cpu(r.pmic->offset); + reg_rw->value = (u32) r.pmic->value; break; case HostCmd_CMD_CAU_REG_ACCESS: r.rf = &resp->params.rf_reg; - reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); - reg_rw->value = cpu_to_le32((u32) r.rf->value); + reg_rw->offset = (u32) le16_to_cpu(r.rf->offset); + reg_rw->value = (u32) r.rf->value; break; case HostCmd_CMD_802_11_EEPROM_ACCESS: r.eeprom = &resp->params.eeprom; - pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); - if (le16_to_cpu(eeprom->byte_count) < - le16_to_cpu(r.eeprom->byte_count)) { - eeprom->byte_count = cpu_to_le16(0); + pr_debug("info: EEPROM read len=%x\n", + le16_to_cpu(r.eeprom->byte_count)); + if (eeprom->byte_count < le16_to_cpu(r.eeprom->byte_count)) { + eeprom->byte_count = 0; pr_debug("info: EEPROM read length is too big\n"); return -1; } - eeprom->offset = r.eeprom->offset; - eeprom->byte_count = r.eeprom->byte_count; - if (le16_to_cpu(eeprom->byte_count) > 0) + eeprom->offset = le16_to_cpu(r.eeprom->offset); + eeprom->byte_count = le16_to_cpu(r.eeprom->byte_count); + if (eeprom->byte_count > 0) memcpy(&eeprom->value, &r.eeprom->value, - le16_to_cpu(r.eeprom->byte_count)); - + min((u16)MAX_EEPROM_DATA, eeprom->byte_count)); break; default: return -1; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c index 0104108b4..a422f3306 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -40,8 +40,8 @@ * - Erases current SSID and BSSID information * - Sends a disconnect event to upper layers/applications. */ -void -mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) +void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code, + bool from_ap) { struct mwifiex_adapter *adapter = priv->adapter; @@ -140,7 +140,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) if (priv->bss_mode == NL80211_IFTYPE_STATION || priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) { cfg80211_disconnected(priv->netdev, reason_code, NULL, 0, - false, GFP_KERNEL); + !from_ap, GFP_KERNEL); } eth_zero_addr(priv->cfg_bssid); @@ -474,8 +474,8 @@ void mwifiex_bt_coex_wlan_param_update_event(struct mwifiex_private *priv, scantlv = (struct mwifiex_ie_types_btcoex_scan_time *)tlv; adapter->coex_scan = scantlv->coex_scan; - adapter->coex_min_scan_time = scantlv->min_scan_time; - adapter->coex_max_scan_time = scantlv->max_scan_time; + adapter->coex_min_scan_time = le16_to_cpu(scantlv->min_scan_time); + adapter->coex_max_scan_time = le16_to_cpu(scantlv->max_scan_time); break; default: @@ -574,7 +574,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) if (priv->media_connected) { reason_code = le16_to_cpu(*(__le16 *)adapter->event_body); - mwifiex_reset_connect_state(priv, reason_code); + mwifiex_reset_connect_state(priv, reason_code, true); } break; @@ -589,7 +589,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) if (priv->media_connected) { reason_code = le16_to_cpu(*(__le16 *)adapter->event_body); - mwifiex_reset_connect_state(priv, reason_code); + mwifiex_reset_connect_state(priv, reason_code, true); } break; @@ -599,7 +599,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) if (priv->media_connected) { reason_code = le16_to_cpu(*(__le16 *)adapter->event_body); - mwifiex_reset_connect_state(priv, reason_code); + mwifiex_reset_connect_state(priv, reason_code, true); } break; @@ -708,7 +708,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_EXT_SCAN_REPORT: mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n"); - if (adapter->ext_scan) + if (adapter->ext_scan && !priv->scan_aborting) ret = mwifiex_handle_event_ext_scan_report(priv, adapter->event_skb->data); diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c index 8e0862657..e06647a32 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c @@ -426,6 +426,10 @@ done: if (bss_desc) kfree(bss_desc->beacon_buf); kfree(bss_desc); + + if (ret < 0) + priv->attempted_bss_desc = NULL; + return ret; } @@ -1247,7 +1251,7 @@ static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv, { u16 cmd_no; - switch (le32_to_cpu(reg_rw->type)) { + switch (reg_rw->type) { case MWIFIEX_REG_MAC: cmd_no = HostCmd_CMD_MAC_REG_ACCESS; break; @@ -1282,9 +1286,9 @@ mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type, { struct mwifiex_ds_reg_rw reg_rw; - reg_rw.type = cpu_to_le32(reg_type); - reg_rw.offset = cpu_to_le32(reg_offset); - reg_rw.value = cpu_to_le32(reg_value); + reg_rw.type = reg_type; + reg_rw.offset = reg_offset; + reg_rw.value = reg_value; return mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_SET); } @@ -1302,14 +1306,14 @@ mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, int ret; struct mwifiex_ds_reg_rw reg_rw; - reg_rw.type = cpu_to_le32(reg_type); - reg_rw.offset = cpu_to_le32(reg_offset); + reg_rw.type = reg_type; + reg_rw.offset = reg_offset; ret = mwifiex_reg_mem_ioctl_reg_rw(priv, ®_rw, HostCmd_ACT_GEN_GET); if (ret) goto done; - *value = le32_to_cpu(reg_rw.value); + *value = reg_rw.value; done: return ret; @@ -1328,15 +1332,16 @@ mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, int ret; struct mwifiex_ds_read_eeprom rd_eeprom; - rd_eeprom.offset = cpu_to_le16((u16) offset); - rd_eeprom.byte_count = cpu_to_le16((u16) bytes); + rd_eeprom.offset = offset; + rd_eeprom.byte_count = bytes; /* Send request to firmware */ ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_EEPROM_ACCESS, HostCmd_ACT_GEN_GET, 0, &rd_eeprom, true); if (!ret) - memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA); + memcpy(value, rd_eeprom.value, min((u16)MAX_EEPROM_DATA, + rd_eeprom.byte_count)); return ret; } diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c index f79d00d1e..a7e9f544f 100644 --- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c @@ -19,6 +19,7 @@ #include "main.h" #include "11ac.h" +#include "11n.h" /* This function parses security related parameters from cfg80211_ap_settings * and sets into FW understandable bss_config structure. @@ -521,9 +522,9 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) tlv += sizeof(struct host_cmd_tlv_rates) + i; } if (bss_cfg->channel && - ((bss_cfg->band_cfg == BAND_CONFIG_BG && + (((bss_cfg->band_cfg & BIT(0)) == BAND_CONFIG_BG && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) || - (bss_cfg->band_cfg == BAND_CONFIG_A && + ((bss_cfg->band_cfg & BIT(0)) == BAND_CONFIG_A && bss_cfg->channel <= MAX_CHANNEL_BAND_A))) { chan_band = (struct host_cmd_tlv_channel_band *)tlv; chan_band->header.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST); @@ -833,6 +834,31 @@ void mwifiex_uap_set_channel(struct mwifiex_private *priv, config_bands |= BAND_AAC; } + switch (chandef.width) { + case NL80211_CHAN_WIDTH_5: + case NL80211_CHAN_WIDTH_10: + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + break; + case NL80211_CHAN_WIDTH_40: + if (chandef.center_freq1 < chandef.chan->center_freq) + bss_cfg->band_cfg |= MWIFIEX_SEC_CHAN_BELOW; + else + bss_cfg->band_cfg |= MWIFIEX_SEC_CHAN_ABOVE; + break; + case NL80211_CHAN_WIDTH_80: + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + bss_cfg->band_cfg |= + mwifiex_get_sec_chan_offset(bss_cfg->channel) << 4; + break; + default: + mwifiex_dbg(priv->adapter, + WARN, "Unknown channel width: %d\n", + chandef.width); + break; + } + priv->adapter->config_bands = config_bands; if (old_bands != config_bands) { diff --git a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c index 666e91af5..bf5660eb2 100644 --- a/drivers/net/wireless/marvell/mwifiex/uap_txrx.c +++ b/drivers/net/wireless/marvell/mwifiex/uap_txrx.c @@ -272,7 +272,7 @@ int mwifiex_handle_uap_rx_forward(struct mwifiex_private *priv, int mwifiex_uap_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb) { - struct mwifiex_adapter *adapter = adapter; + struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_sta_node *src_node; struct ethhdr *p_ethhdr; struct sk_buff *skb_uap; -- cgit v1.2.3-54-g00ecf