diff options
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex')
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/cfg80211.c | 91 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/cmdevt.c | 48 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/fw.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/init.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/ioctl.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/join.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/main.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/pcie.c | 68 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/pcie.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/scan.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/sta_event.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/sta_ioctl.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/marvell/mwifiex/uap_cmd.c | 30 |
15 files changed, 275 insertions, 102 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index ff948a922222..867ab815e16a 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -377,6 +377,29 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, } /* + * 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. * * The timeout value, if provided, is currently ignored. @@ -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. */ @@ -2209,6 +2250,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 +2471,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 +2781,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 +2907,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 +3319,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 +3351,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 +3374,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 +3999,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 e7a21443647e..c29f26d8baf2 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,27 +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) { - struct cfg80211_scan_info info = { - .aborted = true, - }; - - mwifiex_dbg(adapter, WARN, "info: aborting scan\n"); - cfg80211_scan_done(priv->scan_request, &info); - priv->scan_request = NULL; - } - } - } + mwifiex_cancel_scan(adapter); } /* @@ -1084,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)) { @@ -1105,27 +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) { - struct cfg80211_scan_info info = { - .aborted = true, - }; - - mwifiex_dbg(adapter, WARN, "info: aborting scan\n"); - cfg80211_scan_done(priv->scan_request, &info); - 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 8e4145abdbfa..5596b6be1898 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 a6d86d4ccd22..1489c90192bd 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; diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h index a5a48c183d37..f5b8fd1fad1b 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 diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c index a4b773d102b3..1c7b00630b90 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 diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index f0cd055c0b2c..9f6bb400bdae 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); diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 1b1e266ce00f..22fe993b7dbb 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -440,6 +440,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. * @@ -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)) { @@ -2258,7 +2305,7 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) 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; @@ -2841,20 +2888,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); @@ -2946,6 +2993,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 2592e63c32cf..f05061cea5cd 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.h +++ b/drivers/net/wireless/marvell/mwifiex/pcie.h @@ -32,7 +32,7 @@ #define PCIE8897_DEFAULT_FW_NAME "mrvl/pcie8897_uapsta.bin" #define PCIE8897_A0_FW_NAME "mrvl/pcie8897_uapsta_a0.bin" #define PCIE8897_B0_FW_NAME "mrvl/pcie8897_uapsta.bin" -#define PCIE8997_DEFAULT_FW_NAME "mrvl/pcieuart8997_combo_v2.bin" +#define PCIE8997_DEFAULT_FW_NAME "mrvl/pcieusb8997_combo_v2.bin" #define PCIEUART8997_FW_NAME_Z "mrvl/pcieuart8997_combo.bin" #define PCIEUART8997_FW_NAME_V2 "mrvl/pcieuart8997_combo_v2.bin" #define PCIEUSB8997_FW_NAME_Z "mrvl/pcieusb8997_combo.bin" @@ -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 fdd749110fcb..21ec84794d0c 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; } @@ -1964,6 +1965,7 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) "info: notifying scan done\n"); cfg80211_scan_done(priv->scan_request, &info); priv->scan_request = NULL; + priv->scan_aborting = false; } else { priv->scan_aborting = false; mwifiex_dbg(adapter, INFO, @@ -1989,6 +1991,7 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) "info: aborting scan\n"); cfg80211_scan_done(priv->scan_request, &info); priv->scan_request = NULL; + priv->scan_aborting = false; } else { priv->scan_aborting = false; mwifiex_dbg(adapter, INFO, @@ -2009,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/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c index e436574b1698..8c658495bf66 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; } diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c index bcfd4b743145..9050d06998e6 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; } diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c index 0cefd40b2762..a422f3306d4d 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -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: @@ -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 8e0862657122..2ba5397272e2 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; } diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c index f79d00d1e294..a7e9f544f219 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) { |