qcacld-3.0: SAP DFS-3 channel selection suppport for 80+80MHz/160MHz

Add support for setting channel width for CSA and modify the
SAP DFS channel width fallback algoritham to support DFS for
80+80Mhz and 160Mhz bandwidth. Also, compile out channel matrix
restriction from channel selection process after radar
indication is received for newer platforms and only compile
for older platforms

Change-Id: I771fc162b18aa1e485c513046a265b2d94612972
CRs-Fixed: 964262
This commit is contained in:
Sandeep Puligilla
2016-02-03 01:46:15 -08:00
committed by Vishwajith Upendra
父節點 949eaa7aab
當前提交 2111d3c9b6
共有 8 個文件被更改,包括 262 次插入69 次删除

查看文件

@@ -430,6 +430,7 @@ wlansap_roam_process_ch_change_success(tpAniSirGlobal mac_ctx,
{
tWLAN_SAPEvent sap_event;
QDF_STATUS qdf_status;
bool is_ch_dfs = false;
/*
* Channel change is successful. If the new channel is a DFS channel,
* then we will to perform channel availability check for 60 seconds
@@ -442,8 +443,23 @@ wlansap_roam_process_ch_change_success(tpAniSirGlobal mac_ctx,
if (eSAP_DISCONNECTING != sap_ctx->sapsMachine)
return;
if (sap_ctx->ch_params.ch_width == CH_WIDTH_160MHZ) {
is_ch_dfs = true;
} else if (sap_ctx->ch_params.ch_width == CH_WIDTH_80P80MHZ) {
if (cds_get_channel_state(sap_ctx->channel) ==
CHANNEL_STATE_DFS ||
cds_get_channel_state(sap_ctx->ch_params.center_freq_seg1 -
SIR_80MHZ_START_CENTER_CH_DIFF) ==
CHANNEL_STATE_DFS)
is_ch_dfs = true;
} else {
if (cds_get_channel_state(sap_ctx->channel) ==
CHANNEL_STATE_DFS)
is_ch_dfs = true;
}
/* check if currently selected channel is a DFS channel */
if (CHANNEL_STATE_DFS == cds_get_channel_state(sap_ctx->channel)) {
if (is_ch_dfs) {
if ((false == mac_ctx->sap.SapDfsInfo.ignore_cac)
&& (eSAP_DFS_DO_NOT_SKIP_CAC ==
mac_ctx->sap.SapDfsInfo.cac_state)) {

查看文件

@@ -1078,6 +1078,8 @@ static uint8_t sap_populate_available_channels(chan_bonding_bitmap *bitmap,
switch (ch_width) {
/* VHT80 */
case CH_WIDTH_160MHZ:
case CH_WIDTH_80P80MHZ:
case CH_WIDTH_80MHZ:
for (i = 0; i < MAX_80MHZ_BANDS; i++) {
start_channel = bitmap->chanBondingSet[i].startChannel;
@@ -1499,28 +1501,28 @@ static uint8_t sap_random_channel_sel(ptSapContext sapContext)
* channel list from bitmap
*/
if (ch_width != CH_WIDTH_20MHZ) {
bool flag = false;
uint8_t count = 0, new_160_startchannel = 0;
uint8_t index = 0, sec_seg_ch = 0;
uint8_t primary_seg_start_ch = 0;
available_ch_cnt =
sap_populate_available_channels(&channelBitmap,
ch_width,
availableChannels);
/*
* if no valid channel bonding found,
* If no valid channel bonding found,
* fallback to lower bandwidth
*/
if (available_ch_cnt == 0) {
if (ch_width == CH_WIDTH_80MHZ) {
if ((ch_width == CH_WIDTH_160MHZ) ||
(ch_width == CH_WIDTH_80P80MHZ) ||
(ch_width == CH_WIDTH_80MHZ)) {
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_WARN,
FL
("sapdfs:No 80MHz cb found, falling to 40MHz"));
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_WARN,
FL
("sapdfs:Changing chanWidth from [%d] to [%d]"),
ch_width,
CH_WIDTH_40MHZ);
FL("sapdfs:Changing chanWidth from [%d] to 40Mhz"),
ch_width);
ch_width = CH_WIDTH_40MHZ;
/* continue to start of do loop */
continue;
} else if (ch_width == CH_WIDTH_40MHZ) {
QDF_TRACE(QDF_MODULE_ID_SAP,
@@ -1538,47 +1540,167 @@ static uint8_t sap_random_channel_sel(ptSapContext sapContext)
continue;
}
}
}
/*
* by now, available channels list will be populated or
* no channels are avaialbe
*/
if (available_ch_cnt) {
for (i = 0; i < available_ch_cnt; i++) {
if (CDS_IS_DFS_CH(availableChannels[i])) {
avail_dfs_chan_list[
avail_dfs_chan_count++] =
availableChannels[i];
} else {
avail_non_dfs_chan_list[
avail_non_dfs_chan_count++] =
availableChannels[i];
}
/*
* Number of channel count should be more than 8 to
* switch new channel in 160Mhz band
*/
if (((ch_width == CH_WIDTH_160MHZ) ||
(ch_width == CH_WIDTH_80P80MHZ)) &&
(available_ch_cnt < SIR_DFS_MAX_20M_SUB_CH)) {
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_WARN,
FL("sapdfs:Changing chanWidth from [%d] to [%d]"),
ch_width, CH_WIDTH_80MHZ);
ch_width = CH_WIDTH_80MHZ;
continue;
}
} else {
QDF_TRACE(QDF_MODULE_ID_SAP,
if (ch_width == CH_WIDTH_160MHZ) {
/*
* NA supports only 2 blocks for 160Mhz
* bandwidth i.e 36-64 & 100-128 and
* all the channels in these blocks are
* continuous and seperated by 4Mhz.
*/
for (i = 1; ((i < available_ch_cnt)); i++) {
if ((availableChannels[i] -
availableChannels[i-1]) == 4)
count++;
else
count = 0;
if (count ==
SIR_DFS_MAX_20M_SUB_CH - 1) {
flag = true;
new_160_startchannel =
availableChannels[i-7];
break;
}
}
} else if (ch_width == CH_WIDTH_80P80MHZ) {
flag = true;
}
if ((flag == false) && (ch_width > CH_WIDTH_80MHZ)) {
ch_width = CH_WIDTH_80MHZ;
continue;
}
if (ch_width == CH_WIDTH_160MHZ) {
cds_rand_get_bytes(0, (uint8_t *)&random_byte,
1);
random_byte = (random_byte +
qdf_mc_timer_get_system_ticks())
% SIR_DFS_MAX_20M_SUB_CH;
pMac->sap.SapDfsInfo.new_chanWidth = ch_width;
target_channel = new_160_startchannel +
(random_byte * 4);
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_INFO_LOW,
FL("No target channel found"));
FL("sapdfs: New Channel width = %d"),
pMac->sap.SapDfsInfo.new_chanWidth);
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_INFO_LOW,
FL("sapdfs: target_channel = %d"),
target_channel);
qdf_mem_free(tmp_ch_lst);
return target_channel;
} else if (ch_width == CH_WIDTH_80P80MHZ) {
cds_rand_get_bytes(0,
(uint8_t *)&random_byte, 1);
index = (random_byte +
qdf_mc_timer_get_system_ticks()) %
available_ch_cnt;
target_channel = availableChannels[index];
index -= (index % 4);
primary_seg_start_ch = availableChannels[index];
/* reset channels associate with primary 80Mhz */
for (i = 0; i < 4; i++)
availableChannels[i + index] = 0;
/*
* select and calculate center frequency for
* secondary segement
*/
for (i = 0; i < available_ch_cnt / 4; i++) {
if (availableChannels[i * 4] &&
(abs(primary_seg_start_ch -
availableChannels[i * 4]) >
(SIR_DFS_MAX_20M_SUB_CH * 2))) {
sec_seg_ch =
availableChannels[i * 4] +
SIR_80MHZ_START_CENTER_CH_DIFF;
break;
}
}
if (!sec_seg_ch &&
(available_ch_cnt ==
SIR_DFS_MAX_20M_SUB_CH))
ch_width = CH_WIDTH_160MHZ;
else if (!sec_seg_ch)
ch_width = CH_WIDTH_80MHZ;
pMac->sap.SapDfsInfo.new_ch_params.center_freq_seg1
= sec_seg_ch;
pMac->sap.SapDfsInfo.new_chanWidth = ch_width;
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_INFO_LOW,
FL("sapdfs: New Channel width = %d"),
pMac->sap.SapDfsInfo.new_chanWidth);
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_INFO_LOW,
FL("sapdfs: New Center Freq Seg1 = %d"),
sec_seg_ch);
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_INFO_LOW,
FL("sapdfs: target_channel = %d"),
target_channel);
qdf_mem_free(tmp_ch_lst);
return target_channel;
}
/*
* by now, available channels list will be populated or
* no channels are avaialbe
*/
if (available_ch_cnt) {
for (i = 0; i < available_ch_cnt; i++) {
if (CDS_IS_DFS_CH(availableChannels[i])) {
avail_dfs_chan_list[
avail_dfs_chan_count++] =
availableChannels[i];
} else {
avail_non_dfs_chan_list[
avail_non_dfs_chan_count++] =
availableChannels[i];
}
}
} else {
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_INFO_LOW,
FL("No target channel found"));
}
cds_rand_get_bytes(0, (uint8_t *)&random_byte, 1);
/* Give preference to non-DFS channel */
if (!pMac->f_prefer_non_dfs_on_radar) {
i = (random_byte + qdf_mc_timer_get_system_ticks()) %
available_ch_cnt;
target_channel = availableChannels[i];
} else if (avail_non_dfs_chan_count) {
i = (random_byte + qdf_mc_timer_get_system_ticks()) %
avail_non_dfs_chan_count;
target_channel = avail_non_dfs_chan_list[i];
} else {
i = (random_byte + qdf_mc_timer_get_system_ticks()) %
avail_dfs_chan_count;
target_channel = avail_dfs_chan_list[i];
}
}
cds_rand_get_bytes(0, (uint8_t *)&random_byte, 1);
/* Give preference to non-DFS channel */
if (!pMac->f_prefer_non_dfs_on_radar) {
i = (random_byte + qdf_mc_timer_get_system_ticks()) %
available_ch_cnt;
target_channel = availableChannels[i];
} else if (avail_non_dfs_chan_count) {
i = (random_byte + qdf_mc_timer_get_system_ticks()) %
avail_non_dfs_chan_count;
target_channel = avail_non_dfs_chan_list[i];
} else {
i = (random_byte + qdf_mc_timer_get_system_ticks()) %
avail_dfs_chan_count;
target_channel = avail_dfs_chan_list[i];
}
pMac->sap.SapDfsInfo.new_chanWidth = ch_width;
QDF_TRACE(QDF_MODULE_ID_SAP,
QDF_TRACE_LEVEL_INFO_LOW,

查看文件

@@ -2279,7 +2279,7 @@ wlansap_channel_change_request(void *pSapCtx, uint8_t target_channel)
void *hHal = NULL;
tpAniSirGlobal mac_ctx = NULL;
eCsrPhyMode phy_mode;
struct ch_params_s ch_params;
struct ch_params_s *ch_params;
sapContext = (ptSapContext) pSapCtx;
if (NULL == sapContext) {
@@ -2302,16 +2302,16 @@ wlansap_channel_change_request(void *pSapCtx, uint8_t target_channel)
* because we've implemented channel width fallback mechanism for DFS
* which will result in channel width changing dynamically.
*/
ch_params.ch_width = mac_ctx->sap.SapDfsInfo.new_chanWidth;
sme_set_ch_params(hHal, phy_mode, target_channel, 0, &ch_params);
sapContext->ch_params.ch_width = ch_params.ch_width;
ch_params = &mac_ctx->sap.SapDfsInfo.new_ch_params;
sme_set_ch_params(hHal, phy_mode, target_channel, 0, ch_params);
sapContext->ch_params.ch_width = ch_params->ch_width;
/* Update the channel as this will be used to
* send event to supplicant
*/
sapContext->channel = target_channel;
sapContext->csr_roamProfile.ch_params.ch_width = ch_params.ch_width;
sapContext->csr_roamProfile.ch_params.ch_width = ch_params->ch_width;
qdf_ret_status = sme_roam_channel_change_req(hHal, sapContext->bssid,
&ch_params, &sapContext->csr_roamProfile);
ch_params, &sapContext->csr_roamProfile);
if (qdf_ret_status == QDF_STATUS_SUCCESS) {
sap_signal_hdd_event(sapContext, NULL,
@@ -2430,6 +2430,13 @@ QDF_STATUS wlansap_dfs_send_csa_ie_request(void *pSapCtx)
}
pMac = PMAC_STRUCT(hHal);
pMac->sap.SapDfsInfo.new_ch_params.ch_width =
pMac->sap.SapDfsInfo.new_chanWidth;
sme_set_ch_params(hHal, sapContext->csr_roamProfile.phyMode,
pMac->sap.SapDfsInfo.target_channel, 0,
&pMac->sap.SapDfsInfo.new_ch_params);
qdf_ret_status = sme_roam_csa_ie_request(hHal,
sapContext->bssid,
pMac->sap.SapDfsInfo.target_channel,