diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r-- | drivers/net/wireless/mwifiex/11n.c | 102 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/11n.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/cfg80211.c | 61 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/join.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/main.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/scan.c | 32 |
6 files changed, 91 insertions, 112 deletions
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index e22d761f2ef2..1d294cfa6c9b 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -29,95 +29,38 @@ * Fills HT capability information field, AMPDU Parameters field, HT extended * capability field, and supported MCS set fields. * - * Only the following HT capability information fields are used, all other - * fields are always turned off. + * HT capability information field, AMPDU Parameters field, supported MCS set + * fields are retrieved from cfg80211 stack * - * Bit 1 : Supported channel width (0: 20MHz, 1: Both 20 and 40 MHz) - * Bit 4 : Greenfield support (0: Not supported, 1: Supported) - * Bit 5 : Short GI for 20 MHz support (0: Not supported, 1: Supported) - * Bit 6 : Short GI for 40 MHz support (0: Not supported, 1: Supported) - * Bit 7 : Tx STBC (0: Not supported, 1: Supported) - * Bit 8-9 : Rx STBC (0: Not supported, X: Support for up to X spatial streams) - * Bit 10 : Delayed BA support (0: Not supported, 1: Supported) - * Bit 11 : Maximum AMSDU length (0: 3839 octets, 1: 7935 octets) - * Bit 14 : 40-Mhz intolerant support (0: Not supported, 1: Supported) - * - * In addition, the following AMPDU Parameters are set - - * - Maximum AMPDU length exponent (set to 3) - * - Minimum AMPDU start spacing (set to 0 - No restrictions) - * - * MCS is set for 1x1, with MSC32 for infra mode or ad-hoc mode with 40 MHz - * support. - * - * RD responder bit to set to clear in the extended capability header. + * RD responder bit to set to clear in the extended capability header. */ void -mwifiex_fill_cap_info(struct mwifiex_private *priv, +mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, struct mwifiex_ie_types_htcap *ht_cap) { - struct mwifiex_adapter *adapter = priv->adapter; - u8 *mcs; - int rx_mcs_supp; - uint16_t ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info); uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info); + struct ieee80211_supported_band *sband = + priv->wdev->wiphy->bands[radio_type]; - /* Convert dev_cap to IEEE80211_HT_CAP */ - if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) - ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; - else - ht_cap_info &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; - - if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap)) - ht_cap_info |= IEEE80211_HT_CAP_SGI_20; - else - ht_cap_info &= ~IEEE80211_HT_CAP_SGI_20; - - if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap)) - ht_cap_info |= IEEE80211_HT_CAP_SGI_40; - else - ht_cap_info &= ~IEEE80211_HT_CAP_SGI_40; - - if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap)) - ht_cap_info |= IEEE80211_HT_CAP_TX_STBC; - else - ht_cap_info &= ~IEEE80211_HT_CAP_TX_STBC; - - if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap)) - ht_cap_info |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; - else - ht_cap_info &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT); - - if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap)) - ht_cap_info |= IEEE80211_HT_CAP_GRN_FLD; - else - ht_cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; - - ht_cap_info &= ~IEEE80211_HT_CAP_MAX_AMSDU; - ht_cap_info |= IEEE80211_HT_CAP_SM_PS; + ht_cap->ht_cap.ampdu_params_info = + (sband->ht_cap.ampdu_factor & + IEEE80211_HT_AMPDU_PARM_FACTOR)| + ((sband->ht_cap.ampdu_density << + IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) & + IEEE80211_HT_AMPDU_PARM_DENSITY); - ht_cap->ht_cap.ampdu_params_info |= IEEE80211_HT_AMPDU_PARM_FACTOR; - ht_cap->ht_cap.ampdu_params_info &= ~IEEE80211_HT_AMPDU_PARM_DENSITY; - - rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); - - mcs = (u8 *)&ht_cap->ht_cap.mcs; - - /* Set MCS for 1x1 */ - memset(mcs, 0xff, rx_mcs_supp); - - /* Clear all the other values */ - memset(&mcs[rx_mcs_supp], 0, - sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); + memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs, + sizeof(sband->ht_cap.mcs)); if (priv->bss_mode == NL80211_IFTYPE_STATION || - (ht_cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); /* Clear RD responder bit */ ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER; - ht_cap->ht_cap.cap_info = cpu_to_le16(ht_cap_info); + ht_cap->ht_cap.cap_info = cpu_to_le16(sband->ht_cap.cap); ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap); } @@ -391,10 +334,15 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, struct mwifiex_ie_types_2040bssco *bss_co_2040; struct mwifiex_ie_types_extcap *ext_cap; int ret_len = 0; + struct ieee80211_supported_band *sband; + u8 radio_type; if (!buffer || !*buffer) return ret_len; + radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); + sband = priv->wdev->wiphy->bands[radio_type]; + if (bss_desc->bcn_ht_cap) { ht_cap = (struct mwifiex_ie_types_htcap *) *buffer; memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); @@ -406,7 +354,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, sizeof(struct ieee_types_header), le16_to_cpu(ht_cap->header.len)); - mwifiex_fill_cap_info(priv, ht_cap); + mwifiex_fill_cap_info(priv, radio_type, ht_cap); *buffer += sizeof(struct mwifiex_ie_types_htcap); ret_len += sizeof(struct mwifiex_ie_types_htcap); @@ -428,8 +376,8 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, sizeof(struct ieee_types_header), le16_to_cpu(ht_info->header.len)); - if (!ISSUPP_CHANWIDTH40 - (priv->adapter->hw_dot_11n_dev_cap)) + if (!(sband->ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40)) ht_info->ht_info.ht_param &= ~(IEEE80211_HT_PARAM_CHAN_WIDTH_ANY | IEEE80211_HT_PARAM_CHA_SEC_OFFSET); @@ -451,7 +399,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, chan_list->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); - if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) + if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && (bss_desc->bcn_ht_info->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 02602ff30cbf..a4390a1a2a9f 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -38,7 +38,7 @@ int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, u8 **buffer); void mwifiex_cfg_tx_buf(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); -void mwifiex_fill_cap_info(struct mwifiex_private *, +void mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type, struct mwifiex_ie_types_htcap *); int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv, u16 action, int *htcap_cfg); diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index b99ae2677d78..98009e2194c5 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1150,9 +1150,9 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, * * The following default values are set - * - HT Supported = True - * - Maximum AMPDU length factor = 0x3 - * - Minimum AMPDU spacing = 0x6 - * - HT Capabilities map = IEEE80211_HT_CAP_SUP_WIDTH_20_40 (0x0002) + * - Maximum AMPDU length factor = IEEE80211_HT_MAX_AMPDU_64K + * - Minimum AMPDU spacing = IEEE80211_HT_MPDU_DENSITY_NONE + * - HT Capabilities supported by firmware * - MCS information, Rx mask = 0xff * - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01) */ @@ -1166,13 +1166,41 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, struct mwifiex_adapter *adapter = priv->adapter; ht_info->ht_supported = true; - ht_info->ampdu_factor = 0x3; - ht_info->ampdu_density = 0x6; + ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); - ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40; - rx_mcs_supp = GET_RXMCSSUPP(priv->adapter->hw_dev_mcs_support); + /* Fill HT capability information */ + if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) + ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + else + ht_info->cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + + if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap)) + ht_info->cap |= IEEE80211_HT_CAP_SGI_20; + else + ht_info->cap &= ~IEEE80211_HT_CAP_SGI_20; + + if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap)) + ht_info->cap |= IEEE80211_HT_CAP_SGI_40; + else + ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40; + + if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap)) + ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; + else + ht_info->cap &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT); + + if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap)) + ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; + else + ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC; + + ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; + ht_info->cap |= IEEE80211_HT_CAP_SM_PS; + + rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support); /* Set MCS for 1x1 */ memset(mcs, 0xff, rx_mcs_supp); /* Clear all the other values */ @@ -1235,20 +1263,23 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac, wdev->wiphy->max_scan_ssids = 10; wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); + wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; - wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; + mwifiex_setup_ht_caps( + &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); + + if (priv->adapter->config_bands & BAND_A) { + wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; + mwifiex_setup_ht_caps( + &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); + } else { + wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; + } /* Initialize cipher suits */ wdev->wiphy->cipher_suites = mwifiex_cipher_suites; wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); - /* Initialize parameters for 2GHz band */ - - mwifiex_setup_ht_caps(&wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, - priv); - mwifiex_setup_ht_caps(&wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, - priv); - memcpy(wdev->wiphy->perm_addr, mac, 6); wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 23d2d0b9a527..85fca5eb4195 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -100,7 +100,7 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, struct mwifiex_bssdescriptor *bss_desc) { struct mwifiex_ie_types_tsf_timestamp tsf_tlv; - long long tsf_val; + __le64 tsf_val; /* Null Checks */ if (buffer == NULL) @@ -116,6 +116,8 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header)); *buffer += sizeof(tsf_tlv.header); + /* TSF at the time when beacon/probe_response was received */ + tsf_val = cpu_to_le64(bss_desc->network_tsf); memcpy(*buffer, &tsf_val, sizeof(tsf_val)); *buffer += sizeof(tsf_val); diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 1b503038270e..5043fcd22565 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -280,7 +280,7 @@ struct mwifiex_bssdescriptor { * BAND_A(0X04): 'a' band */ u16 bss_band; - long long network_tsf; + u64 network_tsf; u8 time_stamp[8]; union ieee_types_phy_param_set phy_param_set; union ieee_types_ss_param_set ss_param_set; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 68d905d58606..31a529578805 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1007,7 +1007,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); ht_cap->header.len = cpu_to_le16(sizeof(struct ieee80211_ht_cap)); - mwifiex_fill_cap_info(priv, ht_cap); + radio_type = + mwifiex_band_to_radio_type(priv->adapter->config_bands); + mwifiex_fill_cap_info(priv, radio_type, ht_cap); tlv_pos += sizeof(struct mwifiex_ie_types_htcap); } @@ -2988,32 +2990,28 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) struct mwifiex_bssdescriptor *curr_bss = &priv->curr_bss_params.bss_descriptor; - /* save the beacon buffer if it is not saved or updated */ - if ((priv->curr_bcn_buf == NULL) || - (priv->curr_bcn_size != curr_bss->beacon_buf_size) || - (memcmp(priv->curr_bcn_buf, curr_bss->beacon_buf, - curr_bss->beacon_buf_size))) { - - kfree(priv->curr_bcn_buf); - priv->curr_bcn_buf = NULL; + if (!curr_bss->beacon_buf_size) + return; + /* allocate beacon buffer at 1st time; or if it's size has changed */ + if (!priv->curr_bcn_buf || + priv->curr_bcn_size != curr_bss->beacon_buf_size) { priv->curr_bcn_size = curr_bss->beacon_buf_size; - if (!priv->curr_bcn_size) - return; + kfree(priv->curr_bcn_buf); priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size, GFP_KERNEL); if (!priv->curr_bcn_buf) { dev_err(priv->adapter->dev, "failed to alloc curr_bcn_buf\n"); - } else { - memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, - curr_bss->beacon_buf_size); - dev_dbg(priv->adapter->dev, - "info: current beacon saved %d\n", - priv->curr_bcn_size); + return; } } + + memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, + curr_bss->beacon_buf_size); + dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", + priv->curr_bcn_size); } /* |