qcacld-3.0: Support for handling of op class in xcsa action frame
qcacld-2.0 to qcacld-3.0 propagation Add support to parse operating class from xcsa frame and select channel bandwidth on basis of new operating class. Change-Id: I33d794e77220ef82cca793767d459979eb940669 CRs-Fixed: 942104
This commit is contained in:

committed by
Satish Singh

parent
319ae5cd1a
commit
0d766872cb
@@ -2214,5 +2214,7 @@ typedef struct _regdm_supp_op_classes {
|
||||
|
||||
uint16_t cds_regdm_get_opclass_from_channel(uint8_t *country, uint8_t channel,
|
||||
uint8_t offset);
|
||||
uint16_t cds_regdm_get_chanwidth_from_opclass(uint8_t *country, uint8_t channel,
|
||||
uint8_t opclass);
|
||||
uint16_t cds_regdm_set_curr_opclasses(uint8_t num_classes, uint8_t *class);
|
||||
uint16_t cds_regdm_get_curr_opclasses(uint8_t *num_classes, uint8_t *class);
|
||||
|
@@ -622,6 +622,50 @@ uint16_t cds_get_regdmn_5g(uint32_t reg_dmn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cds_regdm_get_chanwidth_from_opclass() - return chan width based on opclass
|
||||
* @country: country name
|
||||
* @channel: operating channel
|
||||
* @opclass: operating class
|
||||
*
|
||||
* Given a value of country, channel and opclass this API will return value of
|
||||
* channel width.
|
||||
*
|
||||
* Return: channel width
|
||||
*
|
||||
*/
|
||||
uint16_t cds_regdm_get_chanwidth_from_opclass(uint8_t *country,
|
||||
uint8_t channel,
|
||||
uint8_t opclass)
|
||||
{
|
||||
regdm_op_class_map_t *class;
|
||||
uint16_t i;
|
||||
|
||||
if (true == cdf_mem_compare(country, "US", 2))
|
||||
class = us_op_class;
|
||||
else if (true == cdf_mem_compare(country, "EU", 2))
|
||||
class = euro_op_class;
|
||||
else if (true == cdf_mem_compare(country, "JP", 2))
|
||||
class = japan_op_class;
|
||||
else
|
||||
class = global_op_class;
|
||||
|
||||
while (class->op_class) {
|
||||
if (opclass == class->op_class) {
|
||||
for (i = 0;
|
||||
(i < MAX_CHANNELS_PER_OPERATING_CLASS &&
|
||||
class->channels[i]);
|
||||
i++) {
|
||||
if (channel == class->channels[i])
|
||||
return class->ch_spacing;
|
||||
}
|
||||
}
|
||||
class++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get operating class for a given channel
|
||||
*/
|
||||
|
@@ -55,6 +55,8 @@
|
||||
#include "lim_session_utils.h"
|
||||
#include "lim_types.h"
|
||||
#include "sir_api.h"
|
||||
#include "cds_regdomain_common.h"
|
||||
#include "lim_send_messages.h"
|
||||
|
||||
static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
|
||||
tpPESession session_entry, tSirResultCodes result_code,
|
||||
@@ -2010,6 +2012,9 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
|
||||
tpDphHashNode sta_ds = NULL;
|
||||
uint8_t session_id;
|
||||
uint16_t aid = 0;
|
||||
uint16_t chan_space = 0;
|
||||
int cb_mode = 0;
|
||||
|
||||
tLimWiderBWChannelSwitchInfo *chnl_switch_info = NULL;
|
||||
|
||||
if (!csa_params) {
|
||||
@@ -2052,10 +2057,13 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
|
||||
eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
|
||||
session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ;
|
||||
|
||||
session_entry->gLimChannelSwitch.ch_center_freq_seg0 = 0;
|
||||
session_entry->gLimChannelSwitch.ch_center_freq_seg1 = 0;
|
||||
chnl_switch_info =
|
||||
&session_entry->gLimWiderBWChannelSwitch;
|
||||
|
||||
if (session_entry->vhtCapability &&
|
||||
session_entry->htSupportedChannelWidthSet) {
|
||||
chnl_switch_info =
|
||||
&session_entry->gLimWiderBWChannelSwitch;
|
||||
if (csa_params->ies_present_flag & lim_wbw_ie_present) {
|
||||
chnl_switch_info->newChanWidth =
|
||||
csa_params->new_ch_width;
|
||||
@@ -2067,8 +2075,103 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
|
||||
eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
|
||||
session_entry->gLimChannelSwitch.ch_width =
|
||||
csa_params->new_ch_width + 1;
|
||||
} else if (csa_params->ies_present_flag
|
||||
& lim_xcsa_ie_present) {
|
||||
chan_space =
|
||||
cds_regdm_get_chanwidth_from_opclass(
|
||||
mac_ctx->scan.countryCodeCurrent,
|
||||
csa_params->channel,
|
||||
csa_params->new_op_class);
|
||||
session_entry->gLimChannelSwitch.state =
|
||||
eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
|
||||
|
||||
if (chan_space == 80) {
|
||||
chnl_switch_info->newChanWidth =
|
||||
CH_WIDTH_80MHZ;
|
||||
} else if (chan_space == 40) {
|
||||
chnl_switch_info->newChanWidth =
|
||||
CH_WIDTH_40MHZ;
|
||||
} else {
|
||||
chnl_switch_info->newChanWidth =
|
||||
CH_WIDTH_20MHZ;
|
||||
session_entry->gLimChannelSwitch.state =
|
||||
eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
|
||||
}
|
||||
|
||||
cb_mode = lim_select_cb_mode_for_sta(
|
||||
session_entry,
|
||||
csa_params->channel,
|
||||
chan_space);
|
||||
|
||||
chnl_switch_info->newCenterChanFreq0 =
|
||||
lim_get_center_channel(mac_ctx,
|
||||
csa_params->channel,
|
||||
cb_mode,
|
||||
chnl_switch_info->newChanWidth);
|
||||
/*
|
||||
* This is not applicable for 20/40/80 MHz.
|
||||
* Only used when we support 80+80 MHz operation.
|
||||
* In case of 80+80 MHz, this parameter indicates
|
||||
* center channel frequency index of 80 MHz
|
||||
* channel offrequency segment 1.
|
||||
*/
|
||||
chnl_switch_info->newCenterChanFreq1 = 0;
|
||||
|
||||
}
|
||||
session_entry->gLimChannelSwitch.ch_center_freq_seg0 =
|
||||
chnl_switch_info->newCenterChanFreq0;
|
||||
session_entry->gLimChannelSwitch.ch_center_freq_seg1 =
|
||||
chnl_switch_info->newCenterChanFreq1;
|
||||
session_entry->gLimChannelSwitch.ch_width =
|
||||
chnl_switch_info->newChanWidth;
|
||||
|
||||
} else if (session_entry->htSupportedChannelWidthSet) {
|
||||
if (csa_params->ies_present_flag
|
||||
& lim_xcsa_ie_present) {
|
||||
chan_space =
|
||||
cds_regdm_get_chanwidth_from_opclass(
|
||||
mac_ctx->scan.countryCodeCurrent,
|
||||
csa_params->channel,
|
||||
csa_params->new_op_class);
|
||||
session_entry->gLimChannelSwitch.state =
|
||||
eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
|
||||
if (chan_space == 40) {
|
||||
session_entry->
|
||||
gLimChannelSwitch.ch_width =
|
||||
CH_WIDTH_40MHZ;
|
||||
chnl_switch_info->newChanWidth =
|
||||
CH_WIDTH_40MHZ;
|
||||
cb_mode = lim_select_cb_mode_for_sta(
|
||||
session_entry,
|
||||
csa_params->channel,
|
||||
chan_space);
|
||||
if (cb_mode ==
|
||||
PHY_DOUBLE_CHANNEL_LOW_PRIMARY) {
|
||||
session_entry->
|
||||
gLimChannelSwitch.
|
||||
ch_center_freq_seg0 =
|
||||
csa_params->channel + 2;
|
||||
} else if (cb_mode ==
|
||||
PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) {
|
||||
session_entry->
|
||||
gLimChannelSwitch.
|
||||
ch_center_freq_seg0 =
|
||||
csa_params->channel - 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
session_entry->
|
||||
gLimChannelSwitch.ch_width =
|
||||
CH_WIDTH_20MHZ;
|
||||
chnl_switch_info->newChanWidth =
|
||||
CH_WIDTH_40MHZ;
|
||||
session_entry->gLimChannelSwitch.state =
|
||||
eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (csa_params->sec_chan_offset) {
|
||||
session_entry->gLimChannelSwitch.ch_width =
|
||||
CH_WIDTH_40MHZ;
|
||||
|
@@ -294,6 +294,59 @@ is_entering_mimo_ps(tSirMacHTMIMOPowerSaveState curState,
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* lim_select_cb_mode_for_sta() - return cb_mode based on current session
|
||||
* @session_entry: Session entry
|
||||
* @channel: channel
|
||||
* @chan_bw: channel bandwidth
|
||||
*
|
||||
* Given a value of channel and bandwidth this API will return the value of
|
||||
* cb_mode on basis of channel, bandwidth ht/vht capabilities
|
||||
*
|
||||
* Return: cb_mode
|
||||
*
|
||||
*/
|
||||
|
||||
static inline int lim_select_cb_mode_for_sta(tpPESession session_entry,
|
||||
uint8_t channel, uint8_t chan_bw)
|
||||
{
|
||||
if (session_entry->vhtCapability && chan_bw) {
|
||||
if (channel == 36 || channel == 52 || channel == 100 ||
|
||||
channel == 116 || channel == 149) {
|
||||
return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
|
||||
} else if (channel == 40 || channel == 56 || channel == 104 ||
|
||||
channel == 120 || channel == 153) {
|
||||
return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
|
||||
} else if (channel == 44 || channel == 60 || channel == 108 ||
|
||||
channel == 124 || channel == 157) {
|
||||
return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH - 1;
|
||||
} else if (channel == 48 || channel == 64 || channel == 112 ||
|
||||
channel == 128 || channel == 161) {
|
||||
return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
|
||||
} else if (channel == 165) {
|
||||
return PHY_SINGLE_CHANNEL_CENTERED;
|
||||
}
|
||||
} else if (session_entry->htSupportedChannelWidthSet) {
|
||||
if (channel == 40 || channel == 48 || channel == 56 ||
|
||||
channel == 64 || channel == 104 || channel == 112 ||
|
||||
channel == 120 || channel == 128 || channel == 136 ||
|
||||
channel == 144 || channel == 153 || channel == 161) {
|
||||
return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
|
||||
} else if (channel == 36 || channel == 44 || channel == 52 ||
|
||||
channel == 60 || channel == 100 ||
|
||||
channel == 108 || channel == 116 ||
|
||||
channel == 124 || channel == 132 ||
|
||||
channel == 140 || channel == 149 ||
|
||||
channel == 157) {
|
||||
return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
|
||||
} else if (channel == 165) {
|
||||
return PHY_SINGLE_CHANNEL_CENTERED;
|
||||
}
|
||||
}
|
||||
return PHY_SINGLE_CHANNEL_CENTERED;
|
||||
}
|
||||
|
||||
|
||||
static inline int lim_select_cb_mode(tDphHashNode *pStaDs,
|
||||
tpPESession psessionEntry, uint8_t channel,
|
||||
uint8_t chan_bw)
|
||||
|
@@ -940,6 +940,7 @@ typedef struct CSAOffloadParams {
|
||||
uint8_t switchmode;
|
||||
uint8_t sec_chan_offset;
|
||||
uint8_t new_ch_width;
|
||||
uint8_t new_op_class;
|
||||
uint8_t new_ch_freq_seg1;
|
||||
uint8_t new_ch_freq_seg2;
|
||||
uint32_t ies_present_flag;
|
||||
|
@@ -1492,6 +1492,7 @@ int wma_csa_offload_handler(void *handle, uint8_t *event, uint32_t len)
|
||||
(&csa_event->xcsa_ie[0]);
|
||||
csa_offload_event->channel = xcsa_ie->newchannel;
|
||||
csa_offload_event->switchmode = xcsa_ie->switchmode;
|
||||
csa_offload_event->new_op_class = xcsa_ie->newClass;
|
||||
} else {
|
||||
WMA_LOGE("CSA Event error: No CSA IE present");
|
||||
cdf_mem_free(csa_offload_event);
|
||||
|
Reference in New Issue
Block a user