diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:40:19 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:40:19 +0000 |
commit | 9f0fc191371843c4fc000a226b0a26b6c059aacd (patch) | |
tree | 35f8be3ef04506ac891ad001e8c41e535ae8d01d /drivers/net/wireless/ath/ath12k/mac.c | |
parent | Releasing progress-linux version 6.6.15-2~progress7.99u1. (diff) | |
download | linux-9f0fc191371843c4fc000a226b0a26b6c059aacd.tar.xz linux-9f0fc191371843c4fc000a226b0a26b6c059aacd.zip |
Merging upstream version 6.7.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/net/wireless/ath/ath12k/mac.c')
-rw-r--r-- | drivers/net/wireless/ath/ath12k/mac.c | 315 |
1 files changed, 252 insertions, 63 deletions
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 88346e66bb..b698e55a5b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -523,7 +523,7 @@ static void ath12k_get_arvif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { struct ath12k_vif_iter *arvif_iter = data; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); if (arvif->vdev_id == arvif_iter->vdev_id) arvif_iter->arvif = arvif; @@ -1208,7 +1208,7 @@ static void ath12k_peer_assoc_h_basic(struct ath12k *ar, struct ieee80211_sta *sta, struct ath12k_wmi_peer_assoc_arg *arg) { - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); u32 aid; lockdep_assert_held(&ar->conf_mutex); @@ -1236,7 +1236,7 @@ static void ath12k_peer_assoc_h_crypto(struct ath12k *ar, struct ieee80211_bss_conf *info = &vif->bss_conf; struct cfg80211_chan_def def; struct cfg80211_bss *bss; - struct ath12k_vif *arvif = (struct ath12k_vif *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); const u8 *rsnie = NULL; const u8 *wpaie = NULL; @@ -1294,7 +1294,7 @@ static void ath12k_peer_assoc_h_rates(struct ath12k *ar, struct ieee80211_sta *sta, struct ath12k_wmi_peer_assoc_arg *arg) { - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates; struct cfg80211_chan_def def; const struct ieee80211_supported_band *sband; @@ -1357,7 +1357,7 @@ static void ath12k_peer_assoc_h_ht(struct ath12k *ar, struct ath12k_wmi_peer_assoc_arg *arg) { const struct ieee80211_sta_ht_cap *ht_cap = &sta->deflink.ht_cap; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct cfg80211_chan_def def; enum nl80211_band band; const u8 *ht_mcs_mask; @@ -1518,7 +1518,7 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, struct ath12k_wmi_peer_assoc_arg *arg) { const struct ieee80211_sta_vht_cap *vht_cap = &sta->deflink.vht_cap; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct cfg80211_chan_def def; enum nl80211_band band; const u16 *vht_mcs_mask; @@ -1793,7 +1793,7 @@ static void ath12k_peer_assoc_h_qos(struct ath12k *ar, struct ieee80211_sta *sta, struct ath12k_wmi_peer_assoc_arg *arg) { - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); switch (arvif->vdev_type) { case WMI_VDEV_TYPE_AP: @@ -1991,7 +1991,7 @@ static void ath12k_peer_assoc_h_phymode(struct ath12k *ar, struct ieee80211_sta *sta, struct ath12k_wmi_peer_assoc_arg *arg) { - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct cfg80211_chan_def def; enum nl80211_band band; const u8 *ht_mcs_mask; @@ -2140,7 +2140,7 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar, const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap; const struct ieee80211_eht_mcs_nss_supp_20mhz_only *bw_20; const struct ieee80211_eht_mcs_nss_supp_bw *bw; - struct ath12k_vif *arvif = (struct ath12k_vif *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); u32 *rx_mcs, *tx_mcs; if (!sta->deflink.he_cap.has_he || !eht_cap->has_eht) @@ -2266,7 +2266,7 @@ static void ath12k_bss_assoc(struct ieee80211_hw *hw, struct ieee80211_bss_conf *bss_conf) { struct ath12k *ar = hw->priv; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct ath12k_wmi_peer_assoc_arg peer_arg; struct ieee80211_sta *ap_sta; struct ath12k_peer *peer; @@ -2360,7 +2360,7 @@ static void ath12k_bss_disassoc(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct ath12k *ar = hw->priv; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); int ret; lockdep_assert_held(&ar->conf_mutex); @@ -2407,7 +2407,7 @@ static void ath12k_recalculate_mgmt_rate(struct ath12k *ar, struct ieee80211_vif *vif, struct cfg80211_chan_def *def) { - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); const struct ieee80211_supported_band *sband; u8 basic_rate_idx; int hw_rate_code; @@ -2525,7 +2525,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BEACON) { param_id = WMI_PDEV_PARAM_BEACON_TX_MODE; - param_value = WMI_BEACON_STAGGERED_MODE; + param_value = WMI_BEACON_BURST_MODE; ret = ath12k_wmi_pdev_set_param(ar, param_id, param_value, ar->pdev->pdev_id); if (ret) @@ -2533,7 +2533,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, arvif->vdev_id); else ath12k_dbg(ar->ab, ATH12K_DBG_MAC, - "Set staggered beacon mode for VDEV: %d\n", + "Set burst beacon mode for VDEV: %d\n", arvif->vdev_id); ret = ath12k_mac_setup_bcn_tmpl(arvif); @@ -2761,9 +2761,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & BSS_CHANGED_FILS_DISCOVERY || - changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP) - ath12k_mac_fils_discovery(arvif, info); + ath12k_mac_fils_discovery(arvif, info); if (changed & BSS_CHANGED_EHT_PUNCTURING) arvif->punct_bitmap = info->eht_puncturing; @@ -2780,18 +2778,21 @@ void __ath12k_mac_scan_finish(struct ath12k *ar) break; case ATH12K_SCAN_RUNNING: case ATH12K_SCAN_ABORTING: + if (ar->scan.is_roc && ar->scan.roc_notify) + ieee80211_remain_on_channel_expired(ar->hw); + fallthrough; + case ATH12K_SCAN_STARTING: if (!ar->scan.is_roc) { struct cfg80211_scan_info info = { - .aborted = (ar->scan.state == - ATH12K_SCAN_ABORTING), + .aborted = ((ar->scan.state == + ATH12K_SCAN_ABORTING) || + (ar->scan.state == + ATH12K_SCAN_STARTING)), }; ieee80211_scan_completed(ar->hw, &info); - } else if (ar->scan.roc_notify) { - ieee80211_remain_on_channel_expired(ar->hw); } - fallthrough; - case ATH12K_SCAN_STARTING: + ar->scan.state = ATH12K_SCAN_IDLE; ar->scan_channel = NULL; ar->scan.roc_freq = 0; @@ -3246,7 +3247,7 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ath12k_warn(ab, "peer %pM disappeared!\n", peer_addr); if (sta) { - arsta = (struct ath12k_sta *)sta->drv_priv; + arsta = ath12k_sta_to_arsta(sta); switch (key->cipher) { case WLAN_CIPHER_SUITE_TKIP: @@ -3419,7 +3420,7 @@ static int ath12k_station_disassoc(struct ath12k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); int ret; lockdep_assert_held(&ar->conf_mutex); @@ -3636,7 +3637,7 @@ static int ath12k_mac_station_add(struct ath12k *ar, { struct ath12k_base *ab = ar->ab; struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); - struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; + struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta); struct ath12k_wmi_peer_create_arg peer_param; int ret; @@ -3743,7 +3744,7 @@ static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, { struct ath12k *ar = hw->priv; struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); - struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; + struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta); struct ath12k_peer *peer; int ret = 0; @@ -3855,7 +3856,7 @@ static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, struct ieee80211_sta *sta) { struct ath12k *ar = hw->priv; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); int ret; s16 txpwr; @@ -3891,8 +3892,8 @@ static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw, u32 changed) { struct ath12k *ar = hw->priv; - struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta); + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct ath12k_peer *peer; u32 bw, smps; @@ -4018,7 +4019,7 @@ static int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, const struct ieee80211_tx_queue_params *params) { struct ath12k *ar = hw->priv; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct wmi_wmm_params_arg *p = NULL; int ret; @@ -4553,7 +4554,50 @@ static void ath12k_mac_copy_eht_ppe_thresh(struct ath12k_wmi_ppe_threshold_arg * } } -static void ath12k_mac_copy_eht_cap(struct ath12k_band_cap *band_cap, +static void +ath12k_mac_filter_eht_cap_mesh(struct ieee80211_eht_cap_elem_fixed + *eht_cap_elem) +{ + u8 m; + + m = IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS; + eht_cap_elem->mac_cap_info[0] &= ~m; + + m = IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO; + eht_cap_elem->phy_cap_info[0] &= ~m; + + m = IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK | + IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK | + IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK | + IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK; + eht_cap_elem->phy_cap_info[3] &= ~m; + + m = IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO | + IEEE80211_EHT_PHY_CAP4_PSR_SR_SUPP | + IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP | + IEEE80211_EHT_PHY_CAP4_EHT_MU_PPDU_4_EHT_LTF_08_GI; + eht_cap_elem->phy_cap_info[4] &= ~m; + + m = IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK | + IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP | + IEEE80211_EHT_PHY_CAP5_RX_LESS_242_TONE_RU_SUPP | + IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK; + eht_cap_elem->phy_cap_info[5] &= ~m; + + m = IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK; + eht_cap_elem->phy_cap_info[6] &= ~m; + + m = IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ | + IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ | + IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ | + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ | + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ | + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ; + eht_cap_elem->phy_cap_info[7] &= ~m; +} + +static void ath12k_mac_copy_eht_cap(struct ath12k *ar, + struct ath12k_band_cap *band_cap, struct ieee80211_he_cap_elem *he_cap_elem, int iftype, struct ieee80211_sta_eht_cap *eht_cap) @@ -4561,6 +4605,10 @@ static void ath12k_mac_copy_eht_cap(struct ath12k_band_cap *band_cap, struct ieee80211_eht_cap_elem_fixed *eht_cap_elem = &eht_cap->eht_cap_elem; memset(eht_cap, 0, sizeof(struct ieee80211_sta_eht_cap)); + + if (!(test_bit(WMI_TLV_SERVICE_11BE, ar->ab->wmi_ab.svc_map))) + return; + eht_cap->has_eht = true; memcpy(eht_cap_elem->mac_cap_info, band_cap->eht_cap_mac_info, sizeof(eht_cap_elem->mac_cap_info)); @@ -4586,6 +4634,9 @@ static void ath12k_mac_copy_eht_cap(struct ath12k_band_cap *band_cap, IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ | IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ); break; + case NL80211_IFTYPE_MESH_POINT: + ath12k_mac_filter_eht_cap_mesh(eht_cap_elem); + break; default: break; } @@ -4626,7 +4677,7 @@ static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar, data[idx].he_6ghz_capa.capa = ath12k_mac_setup_he_6ghz_cap(cap, band_cap); } - ath12k_mac_copy_eht_cap(band_cap, &he_cap->he_cap_elem, i, + ath12k_mac_copy_eht_cap(ar, band_cap, &he_cap->he_cap_elem, i, &data[idx].eht_cap); idx++; } @@ -4647,8 +4698,8 @@ static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar, ar->mac.iftype[band], band); sband = &ar->mac.sbands[band]; - sband->iftype_data = ar->mac.iftype[band]; - sband->n_iftype_data = count; + _ieee80211_set_sband_iftype_data(sband, ar->mac.iftype[band], + count); } if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) { @@ -4657,8 +4708,8 @@ static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar, ar->mac.iftype[band], band); sband = &ar->mac.sbands[band]; - sband->iftype_data = ar->mac.iftype[band]; - sband->n_iftype_data = count; + _ieee80211_set_sband_iftype_data(sband, ar->mac.iftype[band], + count); } if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && @@ -4668,8 +4719,8 @@ static void ath12k_mac_setup_sband_iftype_data(struct ath12k *ar, ar->mac.iftype[band], band); sband = &ar->mac.sbands[band]; - sband->iftype_data = ar->mac.iftype[band]; - sband->n_iftype_data = count; + _ieee80211_set_sband_iftype_data(sband, ar->mac.iftype[band], + count); } } @@ -5108,6 +5159,63 @@ err: return ret; } +int ath12k_mac_rfkill_config(struct ath12k *ar) +{ + struct ath12k_base *ab = ar->ab; + u32 param; + int ret; + + if (ab->hw_params->rfkill_pin == 0) + return -EOPNOTSUPP; + + ath12k_dbg(ab, ATH12K_DBG_MAC, + "mac rfkill_pin %d rfkill_cfg %d rfkill_on_level %d", + ab->hw_params->rfkill_pin, ab->hw_params->rfkill_cfg, + ab->hw_params->rfkill_on_level); + + param = u32_encode_bits(ab->hw_params->rfkill_on_level, + WMI_RFKILL_CFG_RADIO_LEVEL) | + u32_encode_bits(ab->hw_params->rfkill_pin, + WMI_RFKILL_CFG_GPIO_PIN_NUM) | + u32_encode_bits(ab->hw_params->rfkill_cfg, + WMI_RFKILL_CFG_PIN_AS_GPIO); + + ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_HW_RFKILL_CONFIG, + param, ar->pdev->pdev_id); + if (ret) { + ath12k_warn(ab, + "failed to set rfkill config 0x%x: %d\n", + param, ret); + return ret; + } + + return 0; +} + +int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable) +{ + enum wmi_rfkill_enable_radio param; + int ret; + + if (enable) + param = WMI_RFKILL_ENABLE_RADIO_ON; + else + param = WMI_RFKILL_ENABLE_RADIO_OFF; + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac %d rfkill enable %d", + ar->pdev_idx, param); + + ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_RFKILL_ENABLE, + param, ar->pdev->pdev_id); + if (ret) { + ath12k_warn(ar->ab, "failed to set rfkill enable param %d: %d\n", + param, ret); + return ret; + } + + return 0; +} + static void ath12k_mac_op_stop(struct ieee80211_hw *hw) { struct ath12k *ar = hw->priv; @@ -5128,6 +5236,7 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&ar->scan.timeout); cancel_work_sync(&ar->regd_update_work); + cancel_work_sync(&ar->ab->rfkill_work); spin_lock_bh(&ar->data_lock); list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { @@ -5788,14 +5897,68 @@ static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, mutex_unlock(&ar->conf_mutex); } +static enum wmi_phy_mode +ath12k_mac_check_down_grade_phy_mode(struct ath12k *ar, + enum wmi_phy_mode mode, + enum nl80211_band band, + enum nl80211_iftype type) +{ + struct ieee80211_sta_eht_cap *eht_cap; + enum wmi_phy_mode down_mode; + + if (mode < MODE_11BE_EHT20) + return mode; + + eht_cap = &ar->mac.iftype[band][type].eht_cap; + if (eht_cap->has_eht) + return mode; + + switch (mode) { + case MODE_11BE_EHT20: + down_mode = MODE_11AX_HE20; + break; + case MODE_11BE_EHT40: + down_mode = MODE_11AX_HE40; + break; + case MODE_11BE_EHT80: + down_mode = MODE_11AX_HE80; + break; + case MODE_11BE_EHT80_80: + down_mode = MODE_11AX_HE80_80; + break; + case MODE_11BE_EHT160: + case MODE_11BE_EHT160_160: + case MODE_11BE_EHT320: + down_mode = MODE_11AX_HE160; + break; + case MODE_11BE_EHT20_2G: + down_mode = MODE_11AX_HE20_2G; + break; + case MODE_11BE_EHT40_2G: + down_mode = MODE_11AX_HE40_2G; + break; + default: + down_mode = mode; + break; + } + + ath12k_dbg(ar->ab, ATH12K_DBG_MAC, + "mac vdev start phymode %s downgrade to %s\n", + ath12k_mac_phymode_str(mode), + ath12k_mac_phymode_str(down_mode)); + + return down_mode; +} + static int ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif, - const struct cfg80211_chan_def *chandef, + struct ieee80211_chanctx_conf *ctx, bool restart) { struct ath12k *ar = arvif->ar; struct ath12k_base *ab = ar->ab; struct wmi_vdev_start_req_arg arg = {}; + const struct cfg80211_chan_def *chandef = &ctx->def; int he_support = arvif->vif->bss_conf.he_support; int ret; @@ -5813,6 +5976,9 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif, arg.band_center_freq2 = chandef->center_freq2; arg.mode = ath12k_phymodes[chandef->chan->band][chandef->width]; + arg.mode = ath12k_mac_check_down_grade_phy_mode(ar, arg.mode, + chandef->chan->band, + arvif->vif->type); arg.min_power = 0; arg.max_power = chandef->chan->max_power * 2; arg.max_reg_power = chandef->chan->max_reg_power * 2; @@ -5829,6 +5995,8 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif, /* For now allow DFS for AP mode */ arg.chan_radar = !!(chandef->chan->flags & IEEE80211_CHAN_RADAR); + arg.freq2_radar = ctx->radar_enabled; + arg.passive = arg.chan_radar; spin_lock_bh(&ab->base_lock); @@ -5936,15 +6104,15 @@ err: } static int ath12k_mac_vdev_start(struct ath12k_vif *arvif, - const struct cfg80211_chan_def *chandef) + struct ieee80211_chanctx_conf *ctx) { - return ath12k_mac_vdev_start_restart(arvif, chandef, false); + return ath12k_mac_vdev_start_restart(arvif, ctx, false); } static int ath12k_mac_vdev_restart(struct ath12k_vif *arvif, - const struct cfg80211_chan_def *chandef) + struct ieee80211_chanctx_conf *ctx) { - return ath12k_mac_vdev_start_restart(arvif, chandef, true); + return ath12k_mac_vdev_start_restart(arvif, ctx, true); } struct ath12k_mac_change_chanctx_arg { @@ -6000,7 +6168,7 @@ ath12k_mac_update_vif_chan(struct ath12k *ar, lockdep_assert_held(&ar->conf_mutex); for (i = 0; i < n_vifs; i++) { - arvif = (void *)vifs[i].vif->drv_priv; + arvif = ath12k_vif_to_arvif(vifs[i].vif); if (vifs[i].vif->type == NL80211_IFTYPE_MONITOR) monitor_vif = true; @@ -6034,18 +6202,33 @@ ath12k_mac_update_vif_chan(struct ath12k *ar, /* TODO: Update ar->rx_channel */ for (i = 0; i < n_vifs; i++) { - arvif = (void *)vifs[i].vif->drv_priv; + arvif = ath12k_vif_to_arvif(vifs[i].vif); if (WARN_ON(!arvif->is_started)) continue; - if (WARN_ON(!arvif->is_up)) - continue; + /* Firmware expect vdev_restart only if vdev is up. + * If vdev is down then it expect vdev_stop->vdev_start. + */ + if (arvif->is_up) { + ret = ath12k_mac_vdev_restart(arvif, vifs[i].new_ctx); + if (ret) { + ath12k_warn(ab, "failed to restart vdev %d: %d\n", + arvif->vdev_id, ret); + continue; + } + } else { + ret = ath12k_mac_vdev_stop(arvif); + if (ret) { + ath12k_warn(ab, "failed to stop vdev %d: %d\n", + arvif->vdev_id, ret); + continue; + } - ret = ath12k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def); - if (ret) { - ath12k_warn(ab, "failed to restart vdev %d: %d\n", - arvif->vdev_id, ret); + ret = ath12k_mac_vdev_start(arvif, vifs[i].new_ctx); + if (ret) + ath12k_warn(ab, "failed to start vdev %d: %d\n", + arvif->vdev_id, ret); continue; } @@ -6118,7 +6301,8 @@ static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL)) goto unlock; - if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) + if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH || + changed & IEEE80211_CHANCTX_CHANGE_RADAR) ath12k_mac_update_active_vif_chan(ar, ctx); /* TODO: Recalc radar detection */ @@ -6132,13 +6316,13 @@ static int ath12k_start_vdev_delay(struct ieee80211_hw *hw, { struct ath12k *ar = hw->priv; struct ath12k_base *ab = ar->ab; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); int ret; if (WARN_ON(arvif->is_started)) return -EBUSY; - ret = ath12k_mac_vdev_start(arvif, &arvif->chanctx.def); + ret = ath12k_mac_vdev_start(arvif, &arvif->chanctx); if (ret) { ath12k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n", arvif->vdev_id, vif->addr, @@ -6168,7 +6352,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, { struct ath12k *ar = hw->priv; struct ath12k_base *ab = ar->ab; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); int ret; struct ath12k_wmi_peer_create_arg param; @@ -6196,8 +6380,8 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, } if (ab->hw_params->vdev_start_delay && - (arvif->vdev_type == WMI_VDEV_TYPE_AP || - arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) { + arvif->vdev_type != WMI_VDEV_TYPE_AP && + arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { param.vdev_id = arvif->vdev_id; param.peer_type = WMI_PEER_TYPE_DEFAULT; param.peer_addr = ar->mac_addr; @@ -6218,7 +6402,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, goto out; } - ret = ath12k_mac_vdev_start(arvif, &ctx->def); + ret = ath12k_mac_vdev_start(arvif, ctx); if (ret) { ath12k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n", arvif->vdev_id, vif->addr, @@ -6247,7 +6431,7 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, { struct ath12k *ar = hw->priv; struct ath12k_base *ab = ar->ab; - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); int ret; mutex_lock(&ar->conf_mutex); @@ -6578,7 +6762,7 @@ static void ath12k_mac_set_bitrate_mask_iter(void *data, struct ieee80211_sta *sta) { struct ath12k_vif *arvif = data; - struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; + struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta); struct ath12k *ar = arvif->ar; spin_lock_bh(&ar->data_lock); @@ -6610,7 +6794,7 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask) { - struct ath12k_vif *arvif = (void *)vif->drv_priv; + struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct cfg80211_chan_def def; struct ath12k *ar = arvif->ar; enum nl80211_band band; @@ -6867,7 +7051,7 @@ static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct station_info *sinfo) { - struct ath12k_sta *arsta = (struct ath12k_sta *)sta->drv_priv; + struct ath12k_sta *arsta = ath12k_sta_to_arsta(sta); sinfo->rx_duration = arsta->rx_duration; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); @@ -7231,6 +7415,11 @@ static int __ath12k_mac_register(struct ath12k *ar) ar->hw->wiphy->interface_modes = ab->hw_params->interface_modes; + if (ar->hw->wiphy->bands[NL80211_BAND_2GHZ] && + ar->hw->wiphy->bands[NL80211_BAND_5GHZ] && + ar->hw->wiphy->bands[NL80211_BAND_6GHZ]) + ieee80211_hw_set(ar->hw, SINGLE_SCAN_ON_ALL_BANDS); + ieee80211_hw_set(ar->hw, SIGNAL_DBM); ieee80211_hw_set(ar->hw, SUPPORTS_PS); ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS); |