[PATCH] wifi: ath12k: add keep backward compatibility of PHY mode to avoid firmware crash
Jeff Johnson
quic_jjohnson at quicinc.com
Wed Sep 13 18:53:05 PDT 2023
On 9/13/2023 3:57 AM, Wen Gong wrote:
> In a special WCN7855 firmware release the EHT (IEEE 802.11be) support has
> been disabled for size reduction. Currently ath12k always enables EHT PHY
> mode during vdev start but with the special firmware that will cause a
> firmware crash during vdev start in firmware initialisation. This is
> because the firmware will use the EHT mode to allocate resources but as
> the EHT mode is not available in the firmware, there's an internal
> conflict and the firmware will crash.
>
> To fix the crash check the WMI_TLV_SERVICE_11BE flag to see if the firmware
> supports EHT. If EHT is not supported downgrade the PHY mode to HE
> (IEEE 802.11ax).
>
> This does not impact QCN9274, because WMI_SERVICE_11BE is always enabled
> for QCN9274, then eht_cap->has_eht will always set for it, and the logic
> of this patch will not take effect and the PHY mode will not down grade
> for it.
>
> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4
>
> Signed-off-by: Wen Gong <quic_wgong at quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson at quicinc.com>
> ---
> drivers/net/wireless/ath/ath12k/mac.c | 65 ++++++++++++++++++++++++++-
> drivers/net/wireless/ath/ath12k/wmi.h | 3 ++
> 2 files changed, 66 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index 0f2af2f14ef7..c72a7028b4b3 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -4553,7 +4553,8 @@ 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_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 +4562,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));
> @@ -4626,7 +4631,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++;
> }
> @@ -5789,6 +5794,59 @@ 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,
> @@ -5814,6 +5872,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;
> diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
> index 8c047a9623f9..d7ab8c3ff177 100644
> --- a/drivers/net/wireless/ath/ath12k/wmi.h
> +++ b/drivers/net/wireless/ath/ath12k/wmi.h
> @@ -2158,6 +2158,9 @@ enum wmi_tlv_service {
> WMI_MAX_EXT_SERVICE = 256,
>
> WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281,
> +
> + WMI_TLV_SERVICE_11BE = 289,
> +
> WMI_MAX_EXT2_SERVICE,
> };
>
>
> base-commit: 3f257461ab0ab19806bae2bfde4c3cd88dbf050e
More information about the ath12k
mailing list