X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fath%2Fath10k%2Fmac.c;h=a7411fe90cc43ebcef7590538cb3d6cb73a6a13a;hb=71ccd7bf956da5eab6bf03fb99eaa4dcc5199fb6;hp=484c1a10372f13a9fead3d7c4f4368080ab9f10a;hpb=d59542ddcb547871b1913c34c31a6d207627db02;p=karo-tx-linux.git diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 484c1a10372f..a7411fe90cc4 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3736,13 +3736,8 @@ static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) mutex_lock(&ar->conf_mutex); - if (ar->cfg_tx_chainmask) { - *tx_ant = ar->cfg_tx_chainmask; - *rx_ant = ar->cfg_rx_chainmask; - } else { - *tx_ant = ar->supp_tx_chainmask; - *rx_ant = ar->supp_rx_chainmask; - } + *tx_ant = ar->cfg_tx_chainmask; + *rx_ant = ar->cfg_rx_chainmask; mutex_unlock(&ar->conf_mutex); @@ -3762,6 +3757,169 @@ static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg) dbg, cm); } +static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar) +{ + int nsts = ar->vht_cap_info; + + nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; + nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; + + /* If firmware does not deliver to host number of space-time + * streams supported, assume it support up to 4 BF STS and return + * the value for VHT CAP: nsts-1) + */ + if (nsts == 0) + return 3; + + return nsts; +} + +static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar) +{ + int sound_dim = ar->vht_cap_info; + + sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; + sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; + + /* If the sounding dimension is not advertised by the firmware, + * let's use a default value of 1 + */ + if (sound_dim == 0) + return 1; + + return sound_dim; +} + +static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) +{ + struct ieee80211_sta_vht_cap vht_cap = {0}; + u16 mcs_map; + u32 val; + int i; + + vht_cap.vht_supported = 1; + vht_cap.cap = ar->vht_cap_info; + + if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | + IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) { + val = ath10k_mac_get_vht_cap_bf_sts(ar); + val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; + val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; + + vht_cap.cap |= val; + } + + if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | + IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) { + val = ath10k_mac_get_vht_cap_bf_sound_dim(ar); + val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; + val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; + + vht_cap.cap |= val; + } + + mcs_map = 0; + for (i = 0; i < 8; i++) { + if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i))) + mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); + else + mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); + } + + vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); + vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); + + return vht_cap; +} + +static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar) +{ + int i; + struct ieee80211_sta_ht_cap ht_cap = {0}; + + if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED)) + return ht_cap; + + ht_cap.ht_supported = 1; + ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; + ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; + ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT; + + if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI) + ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; + + if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI) + ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; + + if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) { + u32 smps; + + smps = WLAN_HT_CAP_SM_PS_DYNAMIC; + smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT; + + ht_cap.cap |= smps; + } + + if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC) + ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; + + if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) { + u32 stbc; + + stbc = ar->ht_cap_info; + stbc &= WMI_HT_CAP_RX_STBC; + stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT; + stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT; + stbc &= IEEE80211_HT_CAP_RX_STBC; + + ht_cap.cap |= stbc; + } + + if (ar->ht_cap_info & WMI_HT_CAP_LDPC) + ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; + + if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT) + ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT; + + /* max AMSDU is implicitly taken from vht_cap_info */ + if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK) + ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU; + + for (i = 0; i < ar->num_rf_chains; i++) { + if (ar->cfg_rx_chainmask & BIT(i)) + ht_cap.mcs.rx_mask[i] = 0xFF; + } + + ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; + + return ht_cap; +} + +static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar) +{ + struct ieee80211_supported_band *band; + struct ieee80211_sta_vht_cap vht_cap; + struct ieee80211_sta_ht_cap ht_cap; + + ht_cap = ath10k_get_ht_cap(ar); + vht_cap = ath10k_create_vht_cap(ar); + + if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) { + band = &ar->mac.sbands[IEEE80211_BAND_2GHZ]; + band->ht_cap = ht_cap; + + /* Enable the VHT support at 2.4 GHz */ + band->vht_cap = vht_cap; + } + if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) { + band = &ar->mac.sbands[IEEE80211_BAND_5GHZ]; + band->ht_cap = ht_cap; + band->vht_cap = vht_cap; + } +} + static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant) { int ret; @@ -3794,6 +3952,9 @@ static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant) return ret; } + /* Reload HT/VHT capability */ + ath10k_mac_setup_ht_vht_cap(ar); + return 0; } @@ -3884,9 +4045,7 @@ static int ath10k_start(struct ieee80211_hw *hw) } } - if (ar->cfg_tx_chainmask) - __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, - ar->cfg_rx_chainmask); + __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask); /* * By default FW set ARP frames ac to voice (6). In that case ARP @@ -3905,6 +4064,18 @@ static int ath10k_start(struct ieee80211_hw *hw) goto err_core_stop; } + if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA, + ar->fw_features)) { + ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1, + WMI_CCA_DETECT_LEVEL_AUTO, + WMI_CCA_DETECT_MARGIN_AUTO); + if (ret) { + ath10k_warn(ar, "failed to enable adaptive cca: %d\n", + ret); + goto err_core_stop; + } + } + ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->ani_enable, 1); if (ret) { @@ -4063,39 +4234,6 @@ static u32 get_nss_from_chainmask(u16 chain_mask) return 1; } -static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar) -{ - int nsts = ar->vht_cap_info; - - nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; - nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; - - /* If firmware does not deliver to host number of space-time - * streams supported, assume it support up to 4 BF STS and return - * the value for VHT CAP: nsts-1) - * */ - if (nsts == 0) - return 3; - - return nsts; -} - -static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar) -{ - int sound_dim = ar->vht_cap_info; - - sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; - sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; - - /* If the sounding dimension is not advertised by the firmware, - * let's use a default value of 1 - */ - if (sound_dim == 0) - return 1; - - return sound_dim; -} - static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif) { u32 value = 0; @@ -6949,111 +7087,6 @@ static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = { }, }; -static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar) -{ - struct ieee80211_sta_vht_cap vht_cap = {0}; - u16 mcs_map; - u32 val; - int i; - - vht_cap.vht_supported = 1; - vht_cap.cap = ar->vht_cap_info; - - if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | - IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) { - val = ath10k_mac_get_vht_cap_bf_sts(ar); - val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; - val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; - - vht_cap.cap |= val; - } - - if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | - IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) { - val = ath10k_mac_get_vht_cap_bf_sound_dim(ar); - val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; - val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; - - vht_cap.cap |= val; - } - - mcs_map = 0; - for (i = 0; i < 8; i++) { - if (i < ar->num_rf_chains) - mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2); - else - mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2); - } - - vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); - vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); - - return vht_cap; -} - -static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar) -{ - int i; - struct ieee80211_sta_ht_cap ht_cap = {0}; - - if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED)) - return ht_cap; - - ht_cap.ht_supported = 1; - ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; - ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; - ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; - ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; - ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT; - - if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI) - ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; - - if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI) - ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; - - if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) { - u32 smps; - - smps = WLAN_HT_CAP_SM_PS_DYNAMIC; - smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT; - - ht_cap.cap |= smps; - } - - if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC) - ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; - - if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) { - u32 stbc; - - stbc = ar->ht_cap_info; - stbc &= WMI_HT_CAP_RX_STBC; - stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT; - stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT; - stbc &= IEEE80211_HT_CAP_RX_STBC; - - ht_cap.cap |= stbc; - } - - if (ar->ht_cap_info & WMI_HT_CAP_LDPC) - ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; - - if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT) - ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT; - - /* max AMSDU is implicitly taken from vht_cap_info */ - if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK) - ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU; - - for (i = 0; i < ar->num_rf_chains; i++) - ht_cap.mcs.rx_mask[i] = 0xFF; - - ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; - - return ht_cap; -} - static void ath10k_get_arvif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { @@ -7095,8 +7128,6 @@ int ath10k_mac_register(struct ath10k *ar) WLAN_CIPHER_SUITE_AES_CMAC, }; struct ieee80211_supported_band *band; - struct ieee80211_sta_vht_cap vht_cap; - struct ieee80211_sta_ht_cap ht_cap; void *channels; int ret; @@ -7104,9 +7135,6 @@ int ath10k_mac_register(struct ath10k *ar) SET_IEEE80211_DEV(ar->hw, ar->dev); - ht_cap = ath10k_get_ht_cap(ar); - vht_cap = ath10k_create_vht_cap(ar); - BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) + ARRAY_SIZE(ath10k_5ghz_channels)) != ATH10K_NUM_CHANS); @@ -7125,10 +7153,6 @@ int ath10k_mac_register(struct ath10k *ar) band->channels = channels; band->n_bitrates = ath10k_g_rates_size; band->bitrates = ath10k_g_rates; - band->ht_cap = ht_cap; - - /* Enable the VHT support at 2.4 GHz */ - band->vht_cap = vht_cap; ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band; } @@ -7147,18 +7171,18 @@ int ath10k_mac_register(struct ath10k *ar) band->channels = channels; band->n_bitrates = ath10k_a_rates_size; band->bitrates = ath10k_a_rates; - band->ht_cap = ht_cap; - band->vht_cap = vht_cap; ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band; } + ath10k_mac_setup_ht_vht_cap(ar); + ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MESH_POINT); - ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask; - ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask; + ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask; + ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask; if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) ar->hw->wiphy->interface_modes |=