|
@@ -722,6 +722,10 @@ static void populate_dot11f_tdls_ht_vht_cap(struct mac_context *mac,
|
|
|
uint8_t nss;
|
|
|
qdf_size_t val_len;
|
|
|
struct mlme_vht_capabilities_info *vht_cap_info;
|
|
|
+ bool is_wideband;
|
|
|
+
|
|
|
+ is_wideband =
|
|
|
+ wlan_cfg80211_tdls_is_fw_wideband_capable(pe_session->vdev);
|
|
|
|
|
|
vht_cap_info = &mac->mlme_cfg->vht_caps.vht_cap_info;
|
|
|
|
|
@@ -734,11 +738,17 @@ static void populate_dot11f_tdls_ht_vht_cap(struct mac_context *mac,
|
|
|
if (IS_DOT11_MODE_HT(selfDot11Mode) &&
|
|
|
!lim_is_he_6ghz_band(pe_session)) {
|
|
|
/* Include HT Capability IE */
|
|
|
- populate_dot11f_ht_caps(mac, NULL, htCap);
|
|
|
+ populate_dot11f_ht_caps(mac, pe_session, htCap);
|
|
|
val_len = SIZE_OF_SUPPORTED_MCS_SET;
|
|
|
wlan_mlme_get_cfg_str(&htCap->supportedMCSSet[0],
|
|
|
&mac->mlme_cfg->rates.supported_mcs_set,
|
|
|
&val_len);
|
|
|
+ if (WLAN_REG_IS_5GHZ_CH_FREQ(pe_session->curr_op_freq) &&
|
|
|
+ !wlan_reg_is_dfs_for_freq(mac->pdev,
|
|
|
+ pe_session->curr_op_freq) &&
|
|
|
+ is_wideband)
|
|
|
+ htCap->supportedChannelWidthSet = 1;
|
|
|
+
|
|
|
if (NSS_1x1_MODE == nss)
|
|
|
htCap->supportedMCSSet[1] = 0;
|
|
|
/*
|
|
@@ -770,25 +780,24 @@ static void populate_dot11f_tdls_ht_vht_cap(struct mac_context *mac,
|
|
|
WLAN_REG_IS_5GHZ_CH_FREQ(pe_session->curr_op_freq)) {
|
|
|
if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
|
|
|
IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
|
|
|
- /* Include VHT Capability IE */
|
|
|
- populate_dot11f_vht_caps(mac, NULL, vhtCap);
|
|
|
-
|
|
|
/*
|
|
|
- * Set to 0 if the TDLS STA does not support either 160
|
|
|
- * or 80+80 MHz.
|
|
|
- * Set to 1 if the TDLS STA supports 160 MHz.
|
|
|
- * Set to 2 if the TDLS STA supports 160 MHz and
|
|
|
- * 80+80 MHz.
|
|
|
- * The value 3 is reserved
|
|
|
+ * Include VHT Capability IE
|
|
|
+ *
|
|
|
+ * VHT supportedChannelWidthSet should be set such as
|
|
|
+ * 1. Set to 0 if AP does not support either
|
|
|
+ * 160 or 80+80 MHz. With 0, it means 20/40/80 Mhz.
|
|
|
+ * Since for TDLS wideband we need to restrict the BW
|
|
|
+ * to 80 MHz for AP supporting BW less than 80 Mhz.
|
|
|
+ * So, set it to 0 for such cases so that TDLS STA
|
|
|
+ * can connect with 80 MHz width.
|
|
|
+ * 2. Set to 1 if AP supports 160 MHz, thus TDLS STA can
|
|
|
+ * connect with 160 MHz BW
|
|
|
+ * 3. Set to 2 if AP supports 160 MHz and
|
|
|
+ * 80+80 MHz. Not possible in case of 5 GHz
|
|
|
+ *
|
|
|
+ * The value 3 is reserved
|
|
|
*/
|
|
|
- if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq))
|
|
|
- {
|
|
|
- vhtCap->supportedChannelWidthSet = 0;
|
|
|
- } else if (wlan_reg_is_dfs_for_freq(mac->pdev,
|
|
|
- pe_session->curr_op_freq)) {
|
|
|
- if (pe_session->ch_width <= CH_WIDTH_80MHZ)
|
|
|
- vhtCap->supportedChannelWidthSet = 0;
|
|
|
- }
|
|
|
+ populate_dot11f_vht_caps(mac, pe_session, vhtCap);
|
|
|
vhtCap->suBeamformeeCap = 0;
|
|
|
vhtCap->suBeamFormerCap = 0;
|
|
|
vhtCap->muBeamformeeCap = 0;
|
|
@@ -879,43 +888,44 @@ static void lim_populate_tdls_setup_6g_cap(struct mac_context *mac,
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+static void lim_fill_session_he_width(struct pe_session *session,
|
|
|
+ tDot11fIEhe_cap *heCap)
|
|
|
+{
|
|
|
+ if (session->ch_width >= CH_WIDTH_40MHZ)
|
|
|
+ heCap->chan_width_0 = 1;
|
|
|
+ if (session->ch_width >= CH_WIDTH_80MHZ)
|
|
|
+ heCap->chan_width_1 = 1;
|
|
|
+ if (session->ch_width >= CH_WIDTH_160MHZ)
|
|
|
+ heCap->chan_width_2 = 1;
|
|
|
+ if (session->ch_width >= CH_WIDTH_80P80MHZ)
|
|
|
+ heCap->chan_width_3 = 1;
|
|
|
+}
|
|
|
+
|
|
|
static void lim_tdls_set_he_chan_width(struct mac_context *mac,
|
|
|
tDot11fIEhe_cap *heCap,
|
|
|
struct pe_session *session,
|
|
|
bool wideband_sta)
|
|
|
{
|
|
|
- tDot11fIEhe_cap *ap_he_cap = &session->he_config;
|
|
|
-
|
|
|
- if (lim_is_session_he_capable(session)) {
|
|
|
- if (wlan_reg_is_5ghz_ch_freq(session->curr_op_freq)) {
|
|
|
- if (!wideband_sta ||
|
|
|
- wlan_reg_is_dfs_for_freq(mac->pdev,
|
|
|
- session->curr_op_freq)) {
|
|
|
- heCap->chan_width_0 = ap_he_cap->chan_width_0 &
|
|
|
- heCap->chan_width_0;
|
|
|
- heCap->chan_width_1 = ap_he_cap->chan_width_1 &
|
|
|
- heCap->chan_width_1;
|
|
|
- }
|
|
|
- /* Restrict BW till 80 Mhz for 5ghz */
|
|
|
- heCap->chan_width_2 = ap_he_cap->chan_width_2 &
|
|
|
- heCap->chan_width_2;
|
|
|
- heCap->chan_width_3 = ap_he_cap->chan_width_3 &
|
|
|
- heCap->chan_width_3;
|
|
|
- heCap->chan_width_4 = ap_he_cap->chan_width_4 &
|
|
|
- heCap->chan_width_4;
|
|
|
- heCap->chan_width_5 = ap_he_cap->chan_width_5 &
|
|
|
- heCap->chan_width_5;
|
|
|
- heCap->chan_width_6 = ap_he_cap->chan_width_6 &
|
|
|
- heCap->chan_width_6;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (session->ch_width == CH_WIDTH_20MHZ) {
|
|
|
- heCap->chan_width_0 = 0;
|
|
|
- heCap->chan_width_1 = 0;
|
|
|
- }
|
|
|
- /* Right now, no support for ch_width 160 Mhz or 80P80 Mhz in 5 Ghz*/
|
|
|
- heCap->chan_width_2 = 0;
|
|
|
+ if (!wideband_sta) {
|
|
|
+ lim_fill_session_he_width(session, heCap);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (wlan_reg_is_5ghz_ch_freq(session->curr_op_freq)) {
|
|
|
+ /*
|
|
|
+ * Right now, no support for ch_width 160 Mhz or 80P80 Mhz in 5 Ghz
|
|
|
+ * Also, restricting bw to 80 Mhz in case ap on 5 ghz is operating in
|
|
|
+ * less than 80 Mhz bw.
|
|
|
+ */
|
|
|
+ if (session->ch_width <= CH_WIDTH_80MHZ)
|
|
|
+ heCap->chan_width_2 = 0;
|
|
|
heCap->chan_width_3 = 0;
|
|
|
+ heCap->chan_width_4 = 0;
|
|
|
+ heCap->chan_width_5 = 0;
|
|
|
+ heCap->chan_width_6 = 0;
|
|
|
+ if (wlan_reg_is_dfs_for_freq(mac->pdev,
|
|
|
+ session->curr_op_freq))
|
|
|
+ lim_fill_session_he_width(session, heCap);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2993,6 +3003,17 @@ lim_tdls_populate_matching_rate_set(struct mac_context *mac_ctx,
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
|
+static void lim_tdls_fill_session_vht_width(struct pe_session *pe_session,
|
|
|
+ tDphHashNode *sta)
|
|
|
+{
|
|
|
+ if (pe_session->ch_width)
|
|
|
+ sta->vhtSupportedChannelWidthSet =
|
|
|
+ pe_session->ch_width - 1;
|
|
|
+ else
|
|
|
+ sta->vhtSupportedChannelWidthSet =
|
|
|
+ pe_session->ch_width;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* update HASH node entry info
|
|
|
*/
|
|
@@ -3076,21 +3097,38 @@ static void lim_tdls_update_hash_node_info(struct mac_context *mac,
|
|
|
* 11.21.1 General: The channel width of the TDLS direct
|
|
|
* link on the base channel shall not exceed the channel
|
|
|
* width of the BSS to which the TDLS peer STAs are
|
|
|
- * associated, if the base channel is dfs channel
|
|
|
+ * associated, if the base channel is dfs channel and peer is
|
|
|
+ * not wide band supported
|
|
|
*/
|
|
|
- if (!wide_band_peer ||
|
|
|
- wlan_reg_is_dfs_for_freq(mac->pdev,
|
|
|
- pe_session->curr_op_freq)) {
|
|
|
- if (pe_session->ch_width)
|
|
|
+ if (!wide_band_peer) {
|
|
|
+ lim_tdls_fill_session_vht_width(pe_session, sta);
|
|
|
+ } else {
|
|
|
+ if (pVhtCaps->supportedChannelWidthSet >=
|
|
|
+ VHT_CAP_NO_160M_SUPP)
|
|
|
sta->vhtSupportedChannelWidthSet =
|
|
|
- pe_session->ch_width - 1;
|
|
|
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
|
|
|
+ if (wlan_reg_is_dfs_for_freq(mac->pdev,
|
|
|
+ pe_session->curr_op_freq)) {
|
|
|
+ lim_tdls_fill_session_vht_width(pe_session,
|
|
|
+ sta);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sta->htSupportedChannelWidthSet) {
|
|
|
+ if (sta->vhtSupportedChannelWidthSet >
|
|
|
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
|
|
|
+ sta->ch_width = CH_WIDTH_160MHZ;
|
|
|
else
|
|
|
- sta->vhtSupportedChannelWidthSet =
|
|
|
- pe_session->ch_width;
|
|
|
+ sta->ch_width =
|
|
|
+ sta->vhtSupportedChannelWidthSet + 1;
|
|
|
+ } else {
|
|
|
+ sta->ch_width = CH_WIDTH_20MHZ;
|
|
|
}
|
|
|
- pe_debug("vhtSupportedChannelWidthSet: %hu htSupportedChannelWidthSet: %hu",
|
|
|
- sta->vhtSupportedChannelWidthSet,
|
|
|
- sta->htSupportedChannelWidthSet);
|
|
|
+
|
|
|
+ pe_debug("vhtSupportedChannelWidthSet: %hu htSupportedChannelWidthSet: %hu sta_ch_width %d",
|
|
|
+ sta->vhtSupportedChannelWidthSet,
|
|
|
+ sta->htSupportedChannelWidthSet,
|
|
|
+ sta->ch_width);
|
|
|
|
|
|
sta->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
|
|
|
sta->vhtBeamFormerCapable = 0;
|