[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