qcacld-3.0: Allow VHT channel width upgrade

In current design, host driver doesn't allow the
channel width upgrade directly via VHT operation IE.

Allow upgrade of VHT channel width through VHT
operation IE.This will cause VDEV restart to upgrade
the channel width

Change-Id: Ib6a63b72df03b4d4f56cdb0c91d1f5c8ca4612ce
CRs-Fixed: 3537460
Цей коміт міститься в:
Surya Prakash Sivaraj
2023-06-26 09:45:54 +05:30
зафіксовано Rahul Choudhary
джерело 4910df0bb1
коміт 2cb469800b
4 змінених файлів з 104 додано та 116 видалено

Переглянути файл

@@ -249,7 +249,7 @@ static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ct
uint32_t status;
tpDphHashNode sta_ptr;
uint16_t aid;
uint8_t ch_bw = 0;
enum phy_ch_width ch_bw = 0;
mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);

Переглянути файл

@@ -4883,13 +4883,19 @@ bool lim_check_vht_op_mode_change(struct mac_context *mac,
uint8_t chanWidth, uint8_t *peerMac)
{
QDF_STATUS status;
bool update_allow = false;
bool update_allow;
struct ch_params ch_params;
struct csa_offload_params *csa_param;
enum QDF_OPMODE mode = wlan_vdev_mlme_get_opmode(pe_session->vdev);
status = lim_get_update_bw_allow(pe_session, chanWidth, &update_allow);
if (QDF_IS_STATUS_ERROR(status))
return false;
if (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE) {
status = lim_get_update_bw_allow(pe_session, chanWidth,
&update_allow);
if (QDF_IS_STATUS_ERROR(status))
return false;
} else {
update_allow = true;
}
if (update_allow) {
tUpdateVHTOpMode tempParam;
@@ -4904,6 +4910,10 @@ bool lim_check_vht_op_mode_change(struct mac_context *mac,
return true;
}
if (!wlan_cm_is_vdev_connected(pe_session->vdev))
return false;
/* use vdev restart to update STA mode */
qdf_mem_zero(&ch_params, sizeof(ch_params));
ch_params.ch_width = chanWidth;
wlan_reg_set_channel_params_for_pwrmode(mac->pdev,
@@ -11064,10 +11074,12 @@ void lim_update_nss(struct mac_context *mac_ctx, tpDphHashNode sta_ds,
bool lim_update_channel_width(struct mac_context *mac_ctx,
tpDphHashNode sta_ptr,
struct pe_session *session,
uint8_t ch_width, uint8_t *new_ch_width)
enum phy_ch_width ch_width,
enum phy_ch_width *new_ch_width)
{
uint8_t cb_mode, oper_mode;
uint32_t fw_vht_ch_wd;
uint8_t cb_mode;
enum phy_ch_width oper_mode;
enum phy_ch_width fw_vht_ch_wd;
if (wlan_reg_is_24ghz_ch_freq(session->curr_op_freq))
cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz;
@@ -11085,53 +11097,52 @@ bool lim_update_channel_width(struct mac_context *mac_ctx,
if (sta_ptr->htSupportedChannelWidthSet) {
if (sta_ptr->vhtSupportedChannelWidthSet >
WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
oper_mode = eHT_CHANNEL_WIDTH_160MHZ;
oper_mode = CH_WIDTH_160MHZ;
else
oper_mode = sta_ptr->vhtSupportedChannelWidthSet + 1;
} else {
oper_mode = eHT_CHANNEL_WIDTH_20MHZ;
oper_mode = CH_WIDTH_20MHZ;
}
if (((oper_mode == eHT_CHANNEL_WIDTH_80MHZ) &&
(ch_width > eHT_CHANNEL_WIDTH_80MHZ)) ||
(oper_mode == ch_width))
fw_vht_ch_wd = wlan_mlme_get_max_bw();
if (ch_width > fw_vht_ch_wd) {
pe_debug_rl(QDF_MAC_ADDR_FMT ": Downgrade new bw: %d to max %d",
QDF_MAC_ADDR_REF(sta_ptr->staAddr),
ch_width, fw_vht_ch_wd);
ch_width = fw_vht_ch_wd;
}
if (oper_mode == ch_width)
return false;
fw_vht_ch_wd = wma_get_vht_ch_width();
pe_debug(QDF_MAC_ADDR_FMT ": Current : %d, New: %d max %d ",
QDF_MAC_ADDR_REF(sta_ptr->staAddr), oper_mode,
ch_width, fw_vht_ch_wd);
pe_debug("ChannelWidth - Current : %d, New: %d mac : " QDF_MAC_ADDR_FMT,
oper_mode, ch_width, QDF_MAC_ADDR_REF(sta_ptr->staAddr));
if (ch_width >= eHT_CHANNEL_WIDTH_160MHZ &&
(fw_vht_ch_wd >= eHT_CHANNEL_WIDTH_160MHZ)) {
if (ch_width >= CH_WIDTH_160MHZ) {
sta_ptr->vhtSupportedChannelWidthSet =
WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
sta_ptr->htSupportedChannelWidthSet =
eHT_CHANNEL_WIDTH_40MHZ;
*new_ch_width = eHT_CHANNEL_WIDTH_160MHZ;
} else if (ch_width >= eHT_CHANNEL_WIDTH_80MHZ) {
ch_width = CH_WIDTH_160MHZ;
} else if (ch_width == CH_WIDTH_80MHZ) {
sta_ptr->vhtSupportedChannelWidthSet =
WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
sta_ptr->htSupportedChannelWidthSet =
eHT_CHANNEL_WIDTH_40MHZ;
*new_ch_width = eHT_CHANNEL_WIDTH_80MHZ;
} else if (ch_width == eHT_CHANNEL_WIDTH_40MHZ) {
} else if (ch_width == CH_WIDTH_40MHZ) {
sta_ptr->vhtSupportedChannelWidthSet =
WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
sta_ptr->htSupportedChannelWidthSet =
eHT_CHANNEL_WIDTH_40MHZ;
*new_ch_width = eHT_CHANNEL_WIDTH_40MHZ;
} else if (ch_width == eHT_CHANNEL_WIDTH_20MHZ) {
} else if (ch_width == CH_WIDTH_20MHZ) {
sta_ptr->vhtSupportedChannelWidthSet =
WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
sta_ptr->htSupportedChannelWidthSet =
eHT_CHANNEL_WIDTH_20MHZ;
*new_ch_width = eHT_CHANNEL_WIDTH_20MHZ;
} else {
return false;
}
if (ch_width >= CH_WIDTH_40MHZ)
sta_ptr->htSupportedChannelWidthSet = CH_WIDTH_40MHZ;
else
sta_ptr->htSupportedChannelWidthSet = CH_WIDTH_20MHZ;
*new_ch_width = ch_width;
lim_check_vht_op_mode_change(mac_ctx, session, *new_ch_width,
sta_ptr->staAddr);
return true;
return lim_check_vht_op_mode_change(mac_ctx, session, *new_ch_width,
sta_ptr->staAddr);
}
uint8_t lim_get_vht_ch_width(tDot11fIEVHTCaps *vht_cap,
@@ -11484,3 +11495,25 @@ next:
return false;
}
enum phy_ch_width
lim_convert_vht_chwidth_to_phy_chwidth(uint8_t ch_width, bool is_40)
{
switch (ch_width) {
case WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ:
return CH_WIDTH_80P80MHZ;
case WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ:
return CH_WIDTH_160MHZ;
case WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ:
return CH_WIDTH_80MHZ;
case WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ:
if (is_40)
return CH_WIDTH_40MHZ;
else
return CH_WIDTH_20MHZ;
default:
pe_debug("Unknown VHT ch width %d", ch_width);
break;
}
return CH_WIDTH_20MHZ;
}

Переглянути файл

@@ -3115,8 +3115,8 @@ void lim_update_nss(struct mac_context *mac_ctx, tpDphHashNode sta_ds,
bool lim_update_channel_width(struct mac_context *mac_ctx,
tpDphHashNode sta_ptr,
struct pe_session *session,
uint8_t ch_width,
uint8_t *new_ch_width);
enum phy_ch_width ch_width,
enum phy_ch_width *new_ch_width);
/**
* lim_get_vht_ch_width() - Function to get the VHT
@@ -3251,4 +3251,16 @@ bool
lim_is_chan_connected_for_mode(struct wlan_objmgr_psoc *psoc,
enum QDF_OPMODE opmode,
qdf_freq_t freq);
/**
* lim_convert_vht_chwidth_to_phy_chwidth() - Convert VHT operation
* ch width into phy ch width
*
* @ch_width: VHT op channel width
* @is_40: is 40 MHz
*
* Return: phy chwidth
*/
enum phy_ch_width
lim_convert_vht_chwidth_to_phy_chwidth(uint8_t ch_width, bool is_40);
#endif /* __LIM_UTILS_H */

Переглянути файл

@@ -436,13 +436,12 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds,
struct pe_session *session, tpSchBeaconStruct bcn,
tpSirMacMgmtHdr mac_hdr, uint8_t cb_mode)
{
bool skip_opmode_update = false;
uint8_t oper_mode;
uint32_t fw_vht_ch_wd = wma_get_vht_ch_width();
uint8_t ch_width = 0, ch_bw;
enum phy_ch_width ch_bw;
enum phy_ch_width ch_width = CH_WIDTH_20MHZ;
tDot11fIEVHTCaps *vht_caps = NULL;
tDot11fIEVHTOperation *vht_op = NULL;
uint8_t bcn_vht_chwidth = 0;
bool is_40 = false;
/*
* Ignore opmode change during channel change The opmode will be updated
@@ -457,15 +456,6 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds,
return;
}
if (session->vhtCapability && bcn->OperatingMode.present) {
pe_debug("OMN IE is present in the beacon, update NSS/Ch width");
lim_update_nss(mac_ctx, sta_ds, bcn->OperatingMode.rxNSS,
session);
lim_update_channel_width(mac_ctx, sta_ds, session,
bcn->OperatingMode.chanWidth, &ch_bw);
return;
}
if (bcn->VHTCaps.present) {
vht_caps = &bcn->VHTCaps;
vht_op = &bcn->VHTOperation;
@@ -473,74 +463,27 @@ sch_bcn_update_opmode_change(struct mac_context *mac_ctx, tpDphHashNode sta_ds,
vht_caps = &bcn->vendor_vht_ie.VHTCaps;
vht_op = &bcn->vendor_vht_ie.VHTOperation;
}
if (!(session->vhtCapability && (vht_op && vht_op->present)))
if (!session->vhtCapability ||
!(bcn->OperatingMode.present ||
(vht_op && vht_op->present && vht_caps)))
return;
bcn_vht_chwidth = lim_get_vht_ch_width(&bcn->VHTCaps,
&bcn->VHTOperation,
&bcn->HTInfo);
is_40 = bcn->HTCaps.present ?
bcn->HTCaps.supportedChannelWidthSet : false;
oper_mode = sta_ds->vhtSupportedChannelWidthSet;
if ((oper_mode == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) &&
(oper_mode < bcn_vht_chwidth))
skip_opmode_update = true;
if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) {
/*
* if channel bonding is disabled from INI do not
* update the chan width
*/
pe_debug_rl("CB disabled skip bw update: old[%d] new[%d]",
oper_mode, bcn->OperatingMode.chanWidth);
return;
}
if (!skip_opmode_update &&
(oper_mode != bcn_vht_chwidth)) {
pe_debug("received VHTOP CHWidth %d", bcn_vht_chwidth);
pe_debug("MAC - %0x:%0x:%0x:%0x:%0x:%0x",
mac_hdr->sa[0], mac_hdr->sa[1],
mac_hdr->sa[2], mac_hdr->sa[3],
mac_hdr->sa[4], mac_hdr->sa[5]);
if ((bcn_vht_chwidth >=
WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) &&
(fw_vht_ch_wd > eHT_CHANNEL_WIDTH_80MHZ)) {
pe_debug("Updating the CH Width to 160MHz");
sta_ds->vhtSupportedChannelWidthSet =
bcn_vht_chwidth;
sta_ds->htSupportedChannelWidthSet =
eHT_CHANNEL_WIDTH_40MHZ;
ch_width = eHT_CHANNEL_WIDTH_160MHZ;
} else if (bcn_vht_chwidth >=
WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
pe_debug("Updating the CH Width to 80MHz");
sta_ds->vhtSupportedChannelWidthSet =
WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
sta_ds->htSupportedChannelWidthSet =
eHT_CHANNEL_WIDTH_40MHZ;
ch_width = eHT_CHANNEL_WIDTH_80MHZ;
} else if (bcn_vht_chwidth ==
WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) {
sta_ds->vhtSupportedChannelWidthSet =
WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
if (bcn->HTCaps.supportedChannelWidthSet) {
pe_debug("Updating the CH Width to 40MHz");
sta_ds->htSupportedChannelWidthSet =
eHT_CHANNEL_WIDTH_40MHZ;
ch_width = eHT_CHANNEL_WIDTH_40MHZ;
} else {
pe_debug("Updating the CH Width to 20MHz");
sta_ds->htSupportedChannelWidthSet =
eHT_CHANNEL_WIDTH_20MHZ;
ch_width = eHT_CHANNEL_WIDTH_20MHZ;
}
}
lim_check_vht_op_mode_change(mac_ctx, session, ch_width,
mac_hdr->sa);
if (bcn->OperatingMode.present) {
pe_debug("OMN IE is present in the beacon, update NSS/Ch width");
lim_update_nss(mac_ctx, sta_ds, bcn->OperatingMode.rxNSS,
session);
ch_width = bcn->OperatingMode.chanWidth;
} else {
bcn_vht_chwidth = lim_get_vht_ch_width(vht_caps, vht_op,
&bcn->HTInfo);
ch_width =
lim_convert_vht_chwidth_to_phy_chwidth(bcn_vht_chwidth,
is_40);
}
lim_update_channel_width(mac_ctx, sta_ds, session, ch_width, &ch_bw);
}
#ifdef WLAN_FEATURE_SR