xref: /wlan-driver/qcacld-3.0/core/hdd/src/wlan_hdd_eht.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name /**
19*5113495bSYour Name  * DOC: wlan_hdd_eht.c
20*5113495bSYour Name  *
21*5113495bSYour Name  * WLAN Host Device Driver file for 802.11be (Extremely High Throughput)
22*5113495bSYour Name  * support.
23*5113495bSYour Name  *
24*5113495bSYour Name  */
25*5113495bSYour Name 
26*5113495bSYour Name #include "wlan_hdd_main.h"
27*5113495bSYour Name #include "wlan_hdd_eht.h"
28*5113495bSYour Name #include "osif_sync.h"
29*5113495bSYour Name #include "wlan_utility.h"
30*5113495bSYour Name #include "wlan_mlme_ucfg_api.h"
31*5113495bSYour Name #include "qc_sap_ioctl.h"
32*5113495bSYour Name #include "wma_api.h"
33*5113495bSYour Name #include "wlan_osif_features.h"
34*5113495bSYour Name #include "wlan_psoc_mlme_ucfg_api.h"
35*5113495bSYour Name 
36*5113495bSYour Name #if defined(WLAN_FEATURE_11BE) && defined(CFG80211_11BE_BASIC)
37*5113495bSYour Name #define CHAN_WIDTH_SET_40MHZ_IN_2G \
38*5113495bSYour Name 	IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G
39*5113495bSYour Name #define CHAN_WIDTH_SET_40MHZ_80MHZ_IN_5G \
40*5113495bSYour Name 	IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G
41*5113495bSYour Name #define CHAN_WIDTH_SET_160MHZ_IN_5G \
42*5113495bSYour Name 	IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G
43*5113495bSYour Name #define CHAN_WIDTH_SET_80PLUS80_MHZ_IN_5G \
44*5113495bSYour Name 	IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G
45*5113495bSYour Name 
hdd_update_tgt_eht_cap(struct hdd_context * hdd_ctx,struct wma_tgt_cfg * cfg)46*5113495bSYour Name void hdd_update_tgt_eht_cap(struct hdd_context *hdd_ctx,
47*5113495bSYour Name 			    struct wma_tgt_cfg *cfg)
48*5113495bSYour Name {
49*5113495bSYour Name 	tDot11fIEeht_cap eht_cap_ini = {0};
50*5113495bSYour Name 
51*5113495bSYour Name 	ucfg_mlme_update_tgt_eht_cap(hdd_ctx->psoc, cfg);
52*5113495bSYour Name 	sme_update_tgt_eht_cap(hdd_ctx->mac_handle, cfg, &eht_cap_ini);
53*5113495bSYour Name }
54*5113495bSYour Name 
55*5113495bSYour Name /*
56*5113495bSYour Name  * Typical 802.11 Multi-Link element
57*5113495bSYour Name  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58*5113495bSYour Name  * | Elem ID | Elem Len |Elem ID Extn | MLink Ctrl | Common Info | Link Info |
59*5113495bSYour Name  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60*5113495bSYour Name  *      1          1           1           2        Variable Len  Variable Len
61*5113495bSYour Name  */
wlan_hdd_get_mlo_link_id(struct hdd_beacon_data * beacon,uint8_t * link_id,uint8_t * num_link)62*5113495bSYour Name void wlan_hdd_get_mlo_link_id(struct hdd_beacon_data *beacon,
63*5113495bSYour Name 			      uint8_t *link_id, uint8_t *num_link)
64*5113495bSYour Name {
65*5113495bSYour Name 	const uint8_t *mlie, *cmn_info_ie, *link_info_ie;
66*5113495bSYour Name 	uint8_t total_len, cmn_info_len, link_info_len;
67*5113495bSYour Name 	uint8_t link_len;
68*5113495bSYour Name 
69*5113495bSYour Name 	mlie = wlan_get_ext_ie_ptr_from_ext_id(MLO_IE_OUI_TYPE, MLO_IE_OUI_SIZE,
70*5113495bSYour Name 					       beacon->tail, beacon->tail_len);
71*5113495bSYour Name 	if (mlie) {
72*5113495bSYour Name 		hdd_debug("ML IE found in beacon data");
73*5113495bSYour Name 		*num_link = 1;
74*5113495bSYour Name 
75*5113495bSYour Name 		mlie++; /* WLAN_MAC_EID_EXT */
76*5113495bSYour Name 		total_len = *mlie++; /* length */
77*5113495bSYour Name 
78*5113495bSYour Name 		cmn_info_ie = mlie + 3;
79*5113495bSYour Name 		cmn_info_len = *cmn_info_ie;
80*5113495bSYour Name 
81*5113495bSYour Name 		/* 802.11 Common info sub-element in Multi-link element
82*5113495bSYour Name 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83*5113495bSYour Name 		 * |Cmn info Len |MLD MAC| Link ID | .....
84*5113495bSYour Name 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
85*5113495bSYour Name 		 *        1          6        0/1
86*5113495bSYour Name 		 */
87*5113495bSYour Name 
88*5113495bSYour Name 		*link_id = *(cmn_info_ie + 1 + QDF_MAC_ADDR_SIZE);
89*5113495bSYour Name 
90*5113495bSYour Name 		/* Length of link info equal total length minus below:
91*5113495bSYour Name 		 * 1-Byte Extn Ele ID
92*5113495bSYour Name 		 * 2-Byte Multi link control
93*5113495bSYour Name 		 * Length of Common info sub-element
94*5113495bSYour Name 		 */
95*5113495bSYour Name 
96*5113495bSYour Name 		link_info_ie = cmn_info_ie + cmn_info_len;
97*5113495bSYour Name 		link_info_len = total_len - cmn_info_len - 3;
98*5113495bSYour Name 		while (link_info_len > 0) {
99*5113495bSYour Name 			link_info_ie++;
100*5113495bSYour Name 			link_info_len--;
101*5113495bSYour Name 			/* length of sub element ID */
102*5113495bSYour Name 			link_len = *link_info_ie++;
103*5113495bSYour Name 			link_info_len--;
104*5113495bSYour Name 			link_info_ie += link_len;
105*5113495bSYour Name 			link_info_len -= link_len;
106*5113495bSYour Name 			(*num_link)++;
107*5113495bSYour Name 		}
108*5113495bSYour Name 	} else {
109*5113495bSYour Name 		*num_link = 0;
110*5113495bSYour Name 		hdd_debug("ML IE not found in beacon data");
111*5113495bSYour Name 	}
112*5113495bSYour Name }
113*5113495bSYour Name 
wlan_hdd_check_11be_support(struct hdd_beacon_data * beacon,struct sap_config * config)114*5113495bSYour Name void wlan_hdd_check_11be_support(struct hdd_beacon_data *beacon,
115*5113495bSYour Name 				 struct sap_config *config)
116*5113495bSYour Name {
117*5113495bSYour Name 	const uint8_t *ie;
118*5113495bSYour Name 
119*5113495bSYour Name 	ie = wlan_get_ext_ie_ptr_from_ext_id(EHT_CAP_OUI_TYPE, EHT_CAP_OUI_SIZE,
120*5113495bSYour Name 					     beacon->tail, beacon->tail_len);
121*5113495bSYour Name 	if (ie)
122*5113495bSYour Name 		config->SapHw_mode = eCSR_DOT11_MODE_11be;
123*5113495bSYour Name }
124*5113495bSYour Name 
125*5113495bSYour Name static void
hdd_update_wiphy_eht_caps_6ghz(struct hdd_context * hdd_ctx,tDot11fIEeht_cap eht_cap)126*5113495bSYour Name hdd_update_wiphy_eht_caps_6ghz(struct hdd_context *hdd_ctx,
127*5113495bSYour Name 			       tDot11fIEeht_cap eht_cap)
128*5113495bSYour Name {
129*5113495bSYour Name 	struct ieee80211_supported_band *band_6g =
130*5113495bSYour Name 		   hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ];
131*5113495bSYour Name 	uint8_t *phy_info =
132*5113495bSYour Name 		    hdd_ctx->iftype_data_6g->eht_cap.eht_cap_elem.phy_cap_info;
133*5113495bSYour Name 	struct ieee80211_sband_iftype_data *iftype_sta;
134*5113495bSYour Name 	struct ieee80211_sband_iftype_data *iftype_ap;
135*5113495bSYour Name 
136*5113495bSYour Name 	if (!band_6g || !phy_info) {
137*5113495bSYour Name 		hdd_debug("6ghz not supported in wiphy");
138*5113495bSYour Name 		return;
139*5113495bSYour Name 	}
140*5113495bSYour Name 
141*5113495bSYour Name 	hdd_ctx->iftype_data_6g->types_mask =
142*5113495bSYour Name 		(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
143*5113495bSYour Name 	band_6g->n_iftype_data = EHT_OPMODE_SUPPORTED;
144*5113495bSYour Name 	band_6g->iftype_data = hdd_ctx->iftype_data_6g;
145*5113495bSYour Name 	iftype_sta = hdd_ctx->iftype_data_6g;
146*5113495bSYour Name 	iftype_ap = hdd_ctx->iftype_data_6g + 1;
147*5113495bSYour Name 
148*5113495bSYour Name 
149*5113495bSYour Name 	hdd_ctx->iftype_data_6g->eht_cap.has_eht = eht_cap.present;
150*5113495bSYour Name 	if (hdd_ctx->iftype_data_6g->eht_cap.has_eht &&
151*5113495bSYour Name 	    !hdd_ctx->iftype_data_6g->he_cap.has_he) {
152*5113495bSYour Name 		hdd_debug("6 GHz HE caps not present");
153*5113495bSYour Name 		hdd_ctx->iftype_data_6g->eht_cap.has_eht = false;
154*5113495bSYour Name 		band_6g->n_iftype_data = 1;
155*5113495bSYour Name 		return;
156*5113495bSYour Name 	}
157*5113495bSYour Name 
158*5113495bSYour Name 	if (eht_cap.support_320mhz_6ghz)
159*5113495bSYour Name 		phy_info[0] |= IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
160*5113495bSYour Name 
161*5113495bSYour Name 	if (eht_cap.su_beamformer)
162*5113495bSYour Name 		phy_info[0] |= IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER;
163*5113495bSYour Name 
164*5113495bSYour Name 	if (eht_cap.su_beamformee)
165*5113495bSYour Name 		phy_info[0] |= IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
166*5113495bSYour Name 
167*5113495bSYour Name 	qdf_mem_copy(iftype_ap, hdd_ctx->iftype_data_6g,
168*5113495bSYour Name 		     sizeof(struct ieee80211_supported_band));
169*5113495bSYour Name 
170*5113495bSYour Name 	iftype_sta->types_mask = BIT(NL80211_IFTYPE_STATION);
171*5113495bSYour Name 	iftype_ap->types_mask = BIT(NL80211_IFTYPE_AP);
172*5113495bSYour Name }
173*5113495bSYour Name 
hdd_update_wiphy_eht_cap(struct hdd_context * hdd_ctx)174*5113495bSYour Name void hdd_update_wiphy_eht_cap(struct hdd_context *hdd_ctx)
175*5113495bSYour Name {
176*5113495bSYour Name 	tDot11fIEeht_cap eht_cap_cfg;
177*5113495bSYour Name 	struct ieee80211_supported_band *band_2g =
178*5113495bSYour Name 			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ];
179*5113495bSYour Name 	struct ieee80211_supported_band *band_5g =
180*5113495bSYour Name 			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
181*5113495bSYour Name 	QDF_STATUS status;
182*5113495bSYour Name 	uint8_t *phy_info_5g =
183*5113495bSYour Name 		    hdd_ctx->iftype_data_5g->eht_cap.eht_cap_elem.phy_cap_info;
184*5113495bSYour Name 	uint8_t *phy_info_2g =
185*5113495bSYour Name 		    hdd_ctx->iftype_data_2g->eht_cap.eht_cap_elem.phy_cap_info;
186*5113495bSYour Name 	bool eht_capab;
187*5113495bSYour Name 	struct ieee80211_sband_iftype_data *iftype_sta;
188*5113495bSYour Name 	struct ieee80211_sband_iftype_data *iftype_ap;
189*5113495bSYour Name 
190*5113495bSYour Name 	hdd_enter();
191*5113495bSYour Name 
192*5113495bSYour Name 	ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
193*5113495bSYour Name 	if (!eht_capab)
194*5113495bSYour Name 		return;
195*5113495bSYour Name 
196*5113495bSYour Name 	status = ucfg_mlme_cfg_get_eht_caps(hdd_ctx->psoc, &eht_cap_cfg);
197*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
198*5113495bSYour Name 		return;
199*5113495bSYour Name 
200*5113495bSYour Name 	if (band_2g) {
201*5113495bSYour Name 		iftype_sta = hdd_ctx->iftype_data_2g;
202*5113495bSYour Name 		iftype_ap = hdd_ctx->iftype_data_2g + 1;
203*5113495bSYour Name 		hdd_ctx->iftype_data_2g->types_mask =
204*5113495bSYour Name 			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
205*5113495bSYour Name 		band_2g->n_iftype_data = EHT_OPMODE_SUPPORTED;
206*5113495bSYour Name 		band_2g->iftype_data = hdd_ctx->iftype_data_2g;
207*5113495bSYour Name 
208*5113495bSYour Name 		hdd_ctx->iftype_data_2g->eht_cap.has_eht = eht_cap_cfg.present;
209*5113495bSYour Name 		if (hdd_ctx->iftype_data_2g->eht_cap.has_eht &&
210*5113495bSYour Name 		    !hdd_ctx->iftype_data_2g->he_cap.has_he) {
211*5113495bSYour Name 			hdd_debug("2.4 GHz HE caps not present");
212*5113495bSYour Name 			hdd_ctx->iftype_data_2g->eht_cap.has_eht = false;
213*5113495bSYour Name 			band_2g->n_iftype_data = 1;
214*5113495bSYour Name 			goto band_5ghz;
215*5113495bSYour Name 		}
216*5113495bSYour Name 
217*5113495bSYour Name 		if (eht_cap_cfg.su_beamformer)
218*5113495bSYour Name 			phy_info_2g[0] |= IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER;
219*5113495bSYour Name 
220*5113495bSYour Name 		if (eht_cap_cfg.su_beamformee)
221*5113495bSYour Name 			phy_info_2g[0] |= IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
222*5113495bSYour Name 
223*5113495bSYour Name 		qdf_mem_copy(iftype_ap, hdd_ctx->iftype_data_2g,
224*5113495bSYour Name 			     sizeof(struct ieee80211_supported_band));
225*5113495bSYour Name 
226*5113495bSYour Name 		iftype_sta->types_mask = BIT(NL80211_IFTYPE_STATION);
227*5113495bSYour Name 		iftype_ap->types_mask = BIT(NL80211_IFTYPE_AP);
228*5113495bSYour Name 	}
229*5113495bSYour Name 
230*5113495bSYour Name band_5ghz:
231*5113495bSYour Name 	if (band_5g) {
232*5113495bSYour Name 		iftype_sta = hdd_ctx->iftype_data_5g;
233*5113495bSYour Name 		iftype_ap = hdd_ctx->iftype_data_5g + 1;
234*5113495bSYour Name 		hdd_ctx->iftype_data_5g->types_mask =
235*5113495bSYour Name 			(BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
236*5113495bSYour Name 		band_5g->n_iftype_data = EHT_OPMODE_SUPPORTED;
237*5113495bSYour Name 		band_5g->iftype_data = hdd_ctx->iftype_data_5g;
238*5113495bSYour Name 
239*5113495bSYour Name 		hdd_ctx->iftype_data_5g->eht_cap.has_eht = eht_cap_cfg.present;
240*5113495bSYour Name 		if (hdd_ctx->iftype_data_5g->eht_cap.has_eht &&
241*5113495bSYour Name 		    !hdd_ctx->iftype_data_5g->he_cap.has_he) {
242*5113495bSYour Name 			hdd_debug("5 GHz HE caps not present");
243*5113495bSYour Name 			hdd_ctx->iftype_data_5g->eht_cap.has_eht = false;
244*5113495bSYour Name 			band_5g->n_iftype_data = 1;
245*5113495bSYour Name 			goto band_6ghz;
246*5113495bSYour Name 		}
247*5113495bSYour Name 
248*5113495bSYour Name 		if (eht_cap_cfg.su_beamformer)
249*5113495bSYour Name 			phy_info_5g[0] |= IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER;
250*5113495bSYour Name 
251*5113495bSYour Name 		if (eht_cap_cfg.su_beamformee)
252*5113495bSYour Name 			phy_info_5g[0] |= IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
253*5113495bSYour Name 
254*5113495bSYour Name 		qdf_mem_copy(iftype_ap, hdd_ctx->iftype_data_5g,
255*5113495bSYour Name 			     sizeof(struct ieee80211_supported_band));
256*5113495bSYour Name 
257*5113495bSYour Name 		iftype_sta->types_mask = BIT(NL80211_IFTYPE_STATION);
258*5113495bSYour Name 		iftype_ap->types_mask = BIT(NL80211_IFTYPE_AP);
259*5113495bSYour Name 	}
260*5113495bSYour Name 
261*5113495bSYour Name band_6ghz:
262*5113495bSYour Name 	hdd_update_wiphy_eht_caps_6ghz(hdd_ctx, eht_cap_cfg);
263*5113495bSYour Name 
264*5113495bSYour Name 	hdd_exit();
265*5113495bSYour Name }
266*5113495bSYour Name 
hdd_set_11be_rate_code(struct hdd_adapter * adapter,uint16_t rate_code)267*5113495bSYour Name int hdd_set_11be_rate_code(struct hdd_adapter *adapter, uint16_t rate_code)
268*5113495bSYour Name {
269*5113495bSYour Name 	uint8_t preamble = 0, nss = 0, rix = 0;
270*5113495bSYour Name 	int ret;
271*5113495bSYour Name 	struct sap_config *sap_config = NULL;
272*5113495bSYour Name 
273*5113495bSYour Name 	if (adapter->device_mode == QDF_SAP_MODE)
274*5113495bSYour Name 		sap_config = &adapter->deflink->session.ap.sap_config;
275*5113495bSYour Name 
276*5113495bSYour Name 	if (!sap_config) {
277*5113495bSYour Name 		if (!sme_is_feature_supported_by_fw(DOT11BE)) {
278*5113495bSYour Name 			hdd_err_rl("Target does not support 11be");
279*5113495bSYour Name 			return -EIO;
280*5113495bSYour Name 		}
281*5113495bSYour Name 	} else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11be &&
282*5113495bSYour Name 		   sap_config->SapHw_mode != eCSR_DOT11_MODE_11be_ONLY) {
283*5113495bSYour Name 		hdd_err_rl("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d",
284*5113495bSYour Name 			   sap_config->SapHw_mode, sap_config->chan_freq);
285*5113495bSYour Name 		return -EIO;
286*5113495bSYour Name 	}
287*5113495bSYour Name 
288*5113495bSYour Name 	if ((rate_code >> 8) != WMI_RATE_PREAMBLE_EHT) {
289*5113495bSYour Name 		hdd_err_rl("Invalid input: %x", rate_code);
290*5113495bSYour Name 		return -EIO;
291*5113495bSYour Name 	}
292*5113495bSYour Name 
293*5113495bSYour Name 	rix = RC_2_RATE_IDX_11BE(rate_code);
294*5113495bSYour Name 	preamble = rate_code >> 8;
295*5113495bSYour Name 	nss = HT_RC_2_STREAMS_11BE(rate_code) + 1;
296*5113495bSYour Name 
297*5113495bSYour Name 	hdd_debug("SET_11BE_RATE rate_code %d rix %d preamble %x nss %d",
298*5113495bSYour Name 		  rate_code, rix, preamble, nss);
299*5113495bSYour Name 
300*5113495bSYour Name 	ret = wma_cli_set_command(adapter->deflink->vdev_id,
301*5113495bSYour Name 				  wmi_vdev_param_fixed_rate,
302*5113495bSYour Name 				  rate_code, VDEV_CMD);
303*5113495bSYour Name 
304*5113495bSYour Name 	return ret;
305*5113495bSYour Name }
306*5113495bSYour Name 
307*5113495bSYour Name /**
308*5113495bSYour Name  * hdd_map_eht_gi_to_os() - map txrate_gi to os guard interval
309*5113495bSYour Name  * @guard_interval: guard interval get from fw rate
310*5113495bSYour Name  *
311*5113495bSYour Name  * Return: os guard interval value
312*5113495bSYour Name  */
hdd_map_eht_gi_to_os(enum txrate_gi guard_interval)313*5113495bSYour Name static inline uint8_t hdd_map_eht_gi_to_os(enum txrate_gi guard_interval)
314*5113495bSYour Name {
315*5113495bSYour Name 	switch (guard_interval) {
316*5113495bSYour Name 	case TXRATE_GI_0_8_US:
317*5113495bSYour Name 		return NL80211_RATE_INFO_EHT_GI_0_8;
318*5113495bSYour Name 	case TXRATE_GI_1_6_US:
319*5113495bSYour Name 		return NL80211_RATE_INFO_EHT_GI_1_6;
320*5113495bSYour Name 	case TXRATE_GI_3_2_US:
321*5113495bSYour Name 		return NL80211_RATE_INFO_EHT_GI_3_2;
322*5113495bSYour Name 	default:
323*5113495bSYour Name 		return NL80211_RATE_INFO_EHT_GI_0_8;
324*5113495bSYour Name 	}
325*5113495bSYour Name }
326*5113495bSYour Name 
327*5113495bSYour Name /**
328*5113495bSYour Name  * wlan_hdd_fill_os_eht_rateflags() - Fill EHT related rate_info
329*5113495bSYour Name  * @os_rate: rate info for os
330*5113495bSYour Name  * @rate_flags: rate flags
331*5113495bSYour Name  * @dcm: dcm from rate
332*5113495bSYour Name  * @guard_interval: guard interval from rate
333*5113495bSYour Name  *
334*5113495bSYour Name  * Return: none
335*5113495bSYour Name  */
wlan_hdd_fill_os_eht_rateflags(struct rate_info * os_rate,enum tx_rate_info rate_flags,uint8_t dcm,enum txrate_gi guard_interval)336*5113495bSYour Name void wlan_hdd_fill_os_eht_rateflags(struct rate_info *os_rate,
337*5113495bSYour Name 				    enum tx_rate_info rate_flags,
338*5113495bSYour Name 				    uint8_t dcm,
339*5113495bSYour Name 				    enum txrate_gi guard_interval)
340*5113495bSYour Name {
341*5113495bSYour Name 	/* as fw not yet report ofdma to host, so don't
342*5113495bSYour Name 	 * fill RATE_INFO_BW_EHT_RU.
343*5113495bSYour Name 	 */
344*5113495bSYour Name 	if (rate_flags & (TX_RATE_EHT80 | TX_RATE_EHT40 |
345*5113495bSYour Name 	    TX_RATE_EHT20 | TX_RATE_EHT160 | TX_RATE_EHT320)) {
346*5113495bSYour Name 		if (rate_flags & TX_RATE_EHT320)
347*5113495bSYour Name 			hdd_set_rate_bw(os_rate, HDD_RATE_BW_320);
348*5113495bSYour Name 		else if (rate_flags & TX_RATE_EHT160)
349*5113495bSYour Name 			hdd_set_rate_bw(os_rate, HDD_RATE_BW_160);
350*5113495bSYour Name 		else if (rate_flags & TX_RATE_EHT80)
351*5113495bSYour Name 			hdd_set_rate_bw(os_rate, HDD_RATE_BW_80);
352*5113495bSYour Name 		else if (rate_flags & TX_RATE_EHT40)
353*5113495bSYour Name 			hdd_set_rate_bw(os_rate, HDD_RATE_BW_40);
354*5113495bSYour Name 
355*5113495bSYour Name 		os_rate->flags |= RATE_INFO_FLAGS_EHT_MCS;
356*5113495bSYour Name 	}
357*5113495bSYour Name }
358*5113495bSYour Name 
359*5113495bSYour Name #ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
360*5113495bSYour Name void
wlan_hdd_refill_os_eht_rateflags(struct rate_info * os_rate,uint8_t preamble)361*5113495bSYour Name wlan_hdd_refill_os_eht_rateflags(struct rate_info *os_rate, uint8_t preamble)
362*5113495bSYour Name {
363*5113495bSYour Name 	if (preamble == DOT11_BE)
364*5113495bSYour Name 		os_rate->flags |= RATE_INFO_FLAGS_EHT_MCS;
365*5113495bSYour Name }
366*5113495bSYour Name 
367*5113495bSYour Name void
wlan_hdd_refill_os_eht_bw(struct rate_info * os_rate,enum rx_tlv_bw bw)368*5113495bSYour Name wlan_hdd_refill_os_eht_bw(struct rate_info *os_rate, enum rx_tlv_bw bw)
369*5113495bSYour Name {
370*5113495bSYour Name 	if (bw == RX_TLV_BW_320MHZ)
371*5113495bSYour Name 		os_rate->bw = RATE_INFO_BW_320;
372*5113495bSYour Name 	else
373*5113495bSYour Name 		os_rate->bw = RATE_INFO_BW_20; /* Invalid bw: set 20M */
374*5113495bSYour Name }
375*5113495bSYour Name #endif
376*5113495bSYour Name #endif
377