qcacld-3.0: Refine Max chanwidth selection for SAP chanswitch

Remove the calls to wlan_reg_dmn_get_opclass_from_channel API
when SAP is changing channel by ECSA/CSA.
The API accepts channel number and will cause issue when 6GHz
band is supported in target.

Change-Id: Ib6c67417f1a0edae88b5e714e3ed23c589e7eb62
CRs-Fixed: 2676354
This commit is contained in:
Liangwei Dong 2020-04-29 16:48:06 +08:00 • committed by nshrivas
commit 4c11f80dcb
5 changed files with 93 additions and 110 deletions

View file

@ -5352,7 +5352,6 @@ end:
void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx,
uint16_t new_channel_freq,
enum phy_ch_width ch_bandwidth,
enum offset_t offset,
struct pe_session *session_entry)
{
uint8_t op_class = 0;
@ -5361,17 +5360,11 @@ void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx,
uint8_t switch_count;
uint8_t new_channel = 0;
op_class =
lim_op_class_from_bandwidth(mac_ctx, new_channel_freq,
ch_bandwidth,
session_entry->gLimChannelSwitch.sec_ch_offset);
new_channel = wlan_reg_freq_to_chan(mac_ctx->pdev, new_channel_freq);
if (WLAN_REG_IS_6GHZ_CHAN_FREQ(new_channel_freq))
wlan_reg_freq_width_to_chan_op_class
(mac_ctx->pdev, new_channel_freq,
ch_width_in_mhz(ch_bandwidth),
true, BIT(BEHAV_NONE), &op_class,
&new_channel);
else
op_class = wlan_reg_dmn_get_opclass_from_channel
(mac_ctx->scan.countryCodeCurrent, new_channel, offset);
if (LIM_IS_AP_ROLE(session_entry) &&
(mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false))
switch_mode = session_entry->gLimChannelSwitch.switchMode;
@ -5401,7 +5394,6 @@ void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx,
void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx,
uint16_t new_channel_freq,
enum phy_ch_width ch_bandwidth,
enum offset_t offset,
struct pe_session *session_entry)
{
uint8_t op_class = 0, new_channel;
@ -5411,18 +5403,12 @@ void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx,
tpDphHashNode dph_node_array_ptr;
dph_node_array_ptr = session_entry->dph.dphHashTable.pDphNodeArray;
op_class =
lim_op_class_from_bandwidth(mac_ctx, new_channel_freq,
ch_bandwidth,
session_entry->gLimChannelSwitch.sec_ch_offset);
new_channel = wlan_reg_freq_to_chan(mac_ctx->pdev, new_channel_freq);
if (WLAN_REG_IS_6GHZ_CHAN_FREQ(new_channel_freq))
wlan_reg_freq_width_to_chan_op_class
(mac_ctx->pdev, new_channel_freq,
ch_width_in_mhz(ch_bandwidth),
true, BIT(BEHAV_NONE), &op_class,
&new_channel);
else
op_class = wlan_reg_dmn_get_opclass_from_channel
(mac_ctx->scan.countryCodeCurrent,
new_channel, offset);
if (LIM_IS_AP_ROLE(session_entry) &&
(false == mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch))
switch_mode = session_entry->gLimChannelSwitch.switchMode;
@ -5470,7 +5456,6 @@ static void lim_process_sme_dfs_csa_ie_request(struct mac_context *mac_ctx,
struct pe_session *session_entry = NULL;
uint8_t session_id;
tLimWiderBWChannelSwitchInfo *wider_bw_ch_switch;
enum offset_t ch_offset;
QDF_STATUS status;
enum phy_ch_width ch_width;
uint32_t target_ch_freq;
@ -5607,19 +5592,13 @@ skip_vht:
if (QDF_IS_STATUS_ERROR(status))
pe_err("cannot start ap_ecsa_timer");
if (ch_width == CH_WIDTH_80MHZ || ch_width == CH_WIDTH_160MHZ ||
ch_width == CH_WIDTH_80P80MHZ)
ch_offset = BW80;
else
ch_offset = dfs_csa_ie_req->ch_params.sec_ch_offset;
pe_debug("IE count:%d chan:%d freq %d width:%d wrapper:%d ch_offset:%d",
session_entry->gLimChannelSwitch.switchCount,
session_entry->gLimChannelSwitch.primaryChannel,
session_entry->gLimChannelSwitch.sw_target_freq,
session_entry->gLimChannelSwitch.ch_width,
session_entry->dfsIncludeChanWrapperIe,
ch_offset);
session_entry->gLimChannelSwitch.sec_ch_offset);
/* Send ECSA/CSA Action frame after updating the beacon */
if (CHAN_HOP_ALL_BANDS_ENABLE &&
@ -5627,10 +5606,10 @@ skip_vht:
lim_send_chan_switch_action_frame
(mac_ctx,
session_entry->gLimChannelSwitch.primaryChannel,
ch_width, ch_offset, session_entry);
ch_width, session_entry);
else
send_extended_chan_switch_action_frame
(mac_ctx, target_ch_freq, ch_width, ch_offset,
(mac_ctx, target_ch_freq, ch_width,
session_entry);
}
@ -5671,8 +5650,9 @@ static void lim_process_ext_change_channel(struct mac_context *mac_ctx,
new_ext_chan_freq =
wlan_reg_legacy_chan_to_freq(mac_ctx->pdev,
ext_chng_channel->new_channel);
session_entry->gLimChannelSwitch.sec_ch_offset = 0;
send_extended_chan_switch_action_frame(mac_ctx, new_ext_chan_freq, 0,
0, session_entry);
session_entry);
}
/**

View file

@ -5851,6 +5851,33 @@ QDF_STATUS lim_strip_supp_op_class_update_struct(struct mac_context *mac_ctx,
return QDF_STATUS_SUCCESS;
}
uint8_t lim_op_class_from_bandwidth(struct mac_context *mac_ctx,
uint16_t channel_freq,
enum phy_ch_width ch_bandwidth,
enum offset_t offset)
{
uint8_t op_class = 0;
uint16_t ch_behav_limit = BEHAV_NONE;
uint8_t channel;
if (ch_bandwidth == CH_WIDTH_40MHZ &&
wlan_reg_is_24ghz_ch_freq(channel_freq)) {
if (offset == BW40_LOW_PRIMARY)
ch_behav_limit = BEHAV_BW40_LOW_PRIMARY;
else
ch_behav_limit = BEHAV_BW40_HIGH_PRIMARY;
} else if (ch_bandwidth == CH_WIDTH_80P80MHZ) {
ch_behav_limit = BEHAV_BW80_PLUS;
}
wlan_reg_freq_width_to_chan_op_class_auto
(mac_ctx->pdev, channel_freq,
ch_width_in_mhz(ch_bandwidth),
true, BIT(ch_behav_limit), &op_class,
&channel);
return op_class;
}
/**
* lim_update_extcap_struct() - poputlate the dot11f structure
* @mac_ctx: global MAC context
@ -7690,7 +7717,7 @@ void lim_process_ap_ecsa_timeout(void *data)
{
struct pe_session *session = (struct pe_session *)data;
struct mac_context *mac_ctx;
uint8_t bcn_int, ch_width, offset;
uint8_t bcn_int, ch_width;
uint32_t ch_freq;
QDF_STATUS status;
@ -7723,17 +7750,16 @@ void lim_process_ap_ecsa_timeout(void *data)
ch_freq = session->gLimChannelSwitch.sw_target_freq;
ch_width = session->gLimChannelSwitch.ch_width;
offset = session->gLimChannelSwitch.sec_ch_offset;
if (mac_ctx->mlme_cfg->dfs_cfg.dfs_beacon_tx_enhanced) {
if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) {
send_extended_chan_switch_action_frame
(mac_ctx, ch_freq, ch_width,
offset, session);
session);
} else {
/* Send Action frame after updating beacon */
lim_send_chan_switch_action_frame
(mac_ctx, ch_freq, ch_width,
offset, session);
session);
}
}

View file

@ -627,6 +627,13 @@ struct pe_session *lim_is_ibss_session_active(struct mac_context *mac)
}
#endif
/**
* ch_width_in_mhz() - API to get channel space in MHz
*
* For CH_WIDTH_80P80MHZ, the channel space is max channel space of one
* segment - 80MHz.
*
*/
static inline uint8_t ch_width_in_mhz(enum phy_ch_width ch_width)
{
switch (ch_width) {
@ -637,7 +644,7 @@ static inline uint8_t ch_width_in_mhz(enum phy_ch_width ch_width)
case CH_WIDTH_160MHZ:
return 160;
case CH_WIDTH_80P80MHZ:
return 160;
return 80;
case CH_WIDTH_5MHZ:
return 5;
case CH_WIDTH_10MHZ:
@ -1689,7 +1696,6 @@ void lim_send_start_bss_confirm(struct mac_context *mac_ctx,
* @mac_ctx: pointer to global mac structure
* @new_channel_freq: new channel freq(Mhz) to switch to.
* @ch_bandwidth: ch bw of enum phy_ch_width
* @offset: BW of type enum offset_t
* @session_entry: pe session
*
* Return: void
@ -1697,7 +1703,6 @@ void lim_send_start_bss_confirm(struct mac_context *mac_ctx,
void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx,
uint16_t new_channel_freq,
enum phy_ch_width ch_bandwidth,
enum offset_t offset,
struct pe_session *session_entry);
/**
@ -1707,7 +1712,6 @@ void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx,
* @mac_ctx: pointer to global mac structure
* @new_channel_freq: new channel to switch to.
* @ch_bandwidth: channel bw of type enum phy_ch_width
* @offset: BW of enum offset_t
* @session_entry: pe session
*
* This function is called to send ECSA frame for STA/CLI and SAP/GO.
@ -1717,7 +1721,6 @@ void lim_send_chan_switch_action_frame(struct mac_context *mac_ctx,
void send_extended_chan_switch_action_frame(struct mac_context *mac_ctx,
uint16_t new_channel_freq,
enum phy_ch_width ch_bandwidth,
enum offset_t offset,
struct pe_session *session_entry);
/**
@ -2029,6 +2032,23 @@ QDF_STATUS lim_mon_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
QDF_STATUS lim_get_capability_info(struct mac_context *mac, uint16_t *pCap,
struct pe_session *pe_session);
/**
* lim_op_class_from_bandwidth() - get op class from bandwidth
* @mac_ctx: mac context
* @channel_freq: channel frequency MHz
* @ch_bandwidth: channel bandwidth
* @offset: second channel offfset
*
* This API can get the operating class based on channel freq,
* bandwidth and second channel offset.
*
* Return: op class
*/
uint8_t lim_op_class_from_bandwidth(struct mac_context *mac_ctx,
uint16_t channel_freq,
enum phy_ch_width ch_bandwidth,
enum offset_t offset);
/**
* lim_flush_bssid() - flush bssid from scan cache
* @mac_ctx: pointer to mac data

View file

@ -179,34 +179,19 @@ void populate_dot_11_f_ext_chann_switch_ann(struct mac_context *mac_ptr,
struct pe_session *session_entry)
{
uint8_t ch_offset;
uint8_t op_class = 0;
uint8_t chan_num = 0;
uint32_t sw_target_freq;
uint8_t primary_channel;
enum phy_ch_width ch_width;
ch_width = session_entry->gLimChannelSwitch.ch_width;
if (ch_width == CH_WIDTH_80MHZ)
ch_offset = BW80;
else
ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset;
ch_offset = session_entry->gLimChannelSwitch.sec_ch_offset;
dot_11_ptr->switch_mode = session_entry->gLimChannelSwitch.switchMode;
sw_target_freq = session_entry->gLimChannelSwitch.sw_target_freq;
primary_channel = session_entry->gLimChannelSwitch.primaryChannel;
if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sw_target_freq)) {
wlan_reg_freq_width_to_chan_op_class
(mac_ptr->pdev, sw_target_freq,
ch_width_in_mhz(ch_width),
true, BIT(BEHAV_NONE), &op_class, &chan_num);
dot_11_ptr->new_reg_class = op_class;
} else {
dot_11_ptr->new_reg_class =
wlan_reg_dmn_get_opclass_from_channel
(mac_ptr->scan.countryCodeCurrent,
primary_channel, ch_offset);
}
dot_11_ptr->new_reg_class =
lim_op_class_from_bandwidth(mac_ptr, sw_target_freq, ch_width,
ch_offset);
dot_11_ptr->new_channel =
session_entry->gLimChannelSwitch.primaryChannel;
dot_11_ptr->switch_count =
@ -249,32 +234,31 @@ populate_dot11_supp_operating_classes(struct mac_context *mac_ptr,
tDot11fIESuppOperatingClasses *dot_11_ptr,
struct pe_session *session_entry)
{
uint8_t ch_bandwidth;
uint8_t ch_offset;
if (session_entry->ch_width == CH_WIDTH_80MHZ) {
ch_bandwidth = BW80;
ch_offset = BW80;
} else {
switch (session_entry->htSecondaryChannelOffset) {
case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
ch_bandwidth = BW40_HIGH_PRIMARY;
ch_offset = BW40_HIGH_PRIMARY;
break;
case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
ch_bandwidth = BW40_LOW_PRIMARY;
ch_offset = BW40_LOW_PRIMARY;
break;
default:
ch_bandwidth = BW20;
ch_offset = BW20;
break;
}
}
wlan_reg_dmn_get_curr_opclasses(&dot_11_ptr->num_classes,
&dot_11_ptr->classes[1]);
dot_11_ptr->classes[0] = wlan_reg_dmn_get_opclass_from_channel(
mac_ptr->scan.countryCodeCurrent,
wlan_reg_freq_to_chan(
mac_ptr->pdev,
session_entry->curr_op_freq),
ch_bandwidth);
dot_11_ptr->classes[0] =
lim_op_class_from_bandwidth(mac_ptr,
session_entry->curr_op_freq,
session_entry->ch_width,
ch_offset);
dot_11_ptr->num_classes++;
dot_11_ptr->present = 1;
}

View file

@ -1210,7 +1210,7 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context,
uint32_t chan_freq)
{
struct mac_context *mac_ctx;
uint8_t bw;
uint32_t max_fw_bw;
mac_ctx = sap_get_mac_context();
if (!mac_ctx) {
@ -1224,8 +1224,7 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context,
* SAP coming up in HT40 on channel switch we are
* disabling channel bonding in 2.4Ghz.
*/
mac_ctx->sap.SapDfsInfo.new_chanWidth = 0;
mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_20MHZ;
} else {
if (sap_context->csr_roamProfile.phyMode ==
eCSR_DOT11_MODE_11ac ||
@ -1235,48 +1234,22 @@ wlansap_update_csa_channel_params(struct sap_context *sap_context,
eCSR_DOT11_MODE_11ax ||
sap_context->csr_roamProfile.phyMode ==
eCSR_DOT11_MODE_11ax_ONLY) {
bw = BW80;
max_fw_bw = sme_get_vht_ch_width();
if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
mac_ctx->sap.SapDfsInfo.new_chanWidth =
CH_WIDTH_160MHZ;
else
mac_ctx->sap.SapDfsInfo.new_chanWidth =
CH_WIDTH_80MHZ;
} else if (sap_context->csr_roamProfile.phyMode ==
eCSR_DOT11_MODE_11n ||
sap_context->csr_roamProfile.phyMode ==
eCSR_DOT11_MODE_11n_ONLY) {
bw = BW40_HIGH_PRIMARY;
mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_40MHZ;
} else {
/* For legacy 11a mode return 20MHz */
mac_ctx->sap.SapDfsInfo.new_chanWidth = CH_WIDTH_20MHZ;
return QDF_STATUS_SUCCESS;
}
for (; bw >= BW20; bw--) {
uint16_t op_class;
op_class = wlan_reg_dmn_get_opclass_from_channel(
mac_ctx->scan.countryCodeCurrent,
wlan_reg_freq_to_chan(mac_ctx->pdev, chan_freq),
bw);
/*
* Do not continue if bw is 20. This mean channel is not
* found and thus set BW20 for the channel.
*/
if (!op_class && bw > BW20)
continue;
if (bw == BW80) {
mac_ctx->sap.SapDfsInfo.new_chanWidth =
CH_WIDTH_80MHZ;
} else if (bw == BW40_HIGH_PRIMARY) {
mac_ctx->sap.SapDfsInfo.new_chanWidth =
CH_WIDTH_40MHZ;
} else if (bw == BW40_LOW_PRIMARY) {
mac_ctx->sap.SapDfsInfo.new_chanWidth =
CH_WIDTH_40MHZ;
} else {
mac_ctx->sap.SapDfsInfo.new_chanWidth =
CH_WIDTH_20MHZ;
}
break;
}
}
return QDF_STATUS_SUCCESS;