diff options
| author | Naveen Rawat <nrawat@codeaurora.org> | 2016-03-25 15:06:22 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-04-20 22:22:28 -0700 |
| commit | b3264f0358bc8dbedf5fb9f99eb3d16b981688a1 (patch) | |
| tree | 25cd686df8f6d5ca65bbbaf99b28d9d9e2becca4 | |
| parent | d7f7b8d14f05c00aabcdf5482160b234e1a894bb (diff) | |
qcacld-3.0: Re-indent sap_random_channel_sel()
Refactor sap_random_channel_sel() and split it into small
managable functions
Change-Id: Ie0815db84b40901474b109625872c440b1b9cda5
CRs-Fixed: 972906
| -rw-r--r-- | core/sap/src/sap_fsm.c | 800 |
1 files changed, 410 insertions, 390 deletions
diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 815415e67101..fbb94a8b3394 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -939,7 +939,7 @@ sap_find_target_channel_in_channel_matrix(ptSapContext sapContext, } /** - * sap_mark_channels_leaking_into_nol() - to mark channel leaking in to nol + * sap_mark_leaking_ch() - to mark channel leaking in to nol * @sap_ctx: pointer to SAP context * @ch_width: channel width * @nol: nol info @@ -954,7 +954,7 @@ sap_find_target_channel_in_channel_matrix(ptSapContext sapContext, */ QDF_STATUS -sap_mark_channels_leaking_into_nol(ptSapContext sap_ctx, +sap_mark_leaking_ch(ptSapContext sap_ctx, enum phy_ch_width ch_width, tSapDfsNolInfo *nol, uint8_t temp_ch_lst_sz, @@ -994,7 +994,7 @@ sap_mark_channels_leaking_into_nol(ptSapContext sap_ctx, /* * following is based on assumption that both temp_ch_lst * and target channel matrix are in increasing order of - * channelID + * ch_id */ for (j = 0, k = 0; j < temp_ch_lst_sz && k < num_channel;) { if (temp_ch_lst[j] == 0) { @@ -1100,7 +1100,8 @@ static uint8_t sap_populate_available_channels(chan_bonding_bitmap *bitmap, SAP_40MHZ_MASK_L) == SAP_40MHZ_MASK_L) { avail_chnl[chnl_count++] = start_channel; avail_chnl[chnl_count++] = start_channel + 4; - } else if ((bitmap->chanBondingSet[i].channelMap & + } + if ((bitmap->chanBondingSet[i].channelMap & SAP_40MHZ_MASK_H) == SAP_40MHZ_MASK_H) { avail_chnl[chnl_count++] = start_channel + 8; avail_chnl[chnl_count++] = start_channel + 12; @@ -1227,73 +1228,50 @@ bool sap_check_in_avoid_ch_list(ptSapContext sap_ctx, uint8_t channel) } #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ -/* - * This function randomly pick up an AVAILABLE channel +/** + * sap_apply_rules() - validates channels in sap_ctx channel list + * @sap_ctx: sap context pointer + * + * This function takes the channel list in sap_ctx and marks invalid channel + * based on following rules: + * -> invalid due to different reg domain dfs channel list + * -> already present in NOL + * -> outside ACS range or not + * -> not usable due to another SAP operating MCC mode in same channel + * -> preferred location is indoors or outdoors + * + * Return: number of valid channels after applying all the rules */ -static uint8_t sap_random_channel_sel(ptSapContext sapContext) +static uint8_t sap_apply_rules(ptSapContext sap_ctx) { - uint32_t random_byte = 0; - uint8_t available_ch_cnt = 0; - uint8_t avail_dfs_chan_count = 0; - uint8_t avail_non_dfs_chan_count = 0; - uint8_t valid_chnl_count = 0; - uint8_t availableChannels[WNI_CFG_VALID_CHANNEL_LIST_LEN] = { 0, }; - uint8_t avail_dfs_chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0,}; - uint8_t avail_non_dfs_chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0,}; - uint8_t target_channel = 0; - bool isChannelNol = false; - bool isOutOfRange = false; - chan_bonding_bitmap channelBitmap; - uint8_t i = 0; - uint8_t channelID; - tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); - tpAniSirGlobal pMac; - enum phy_ch_width ch_width; - uint8_t *tmp_ch_lst = NULL; - uint8_t dfs_region; + uint8_t num_valid_ch, dfs_region, i = 0, ch_id; + tAll5GChannelList *sap_all_ch = &sap_ctx->SapAllChnlList; + bool is_ch_nol = false; + bool is_out_of_range = false; + tpAniSirGlobal mac_ctx; + tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); + uint8_t preferred_location; - if (NULL == hHal) { + if (NULL == hal) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("invalid hHal")); - return target_channel; + FL("hal pointer NULL")); + return 0; } - pMac = PMAC_STRUCT(hHal); - if (NULL == pMac) { + mac_ctx = PMAC_STRUCT(hal); + if (NULL == mac_ctx) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("invalid pMac")); - return target_channel; - } - - /* - * Retrieve the original one and store it. - * use the stored original value when you call this function next time - * so fall back mechanism always starts with original ini value. - */ - if (pMac->sap.SapDfsInfo.orig_chanWidth == 0) { - pMac->sap.SapDfsInfo.orig_chanWidth = - sapContext->ch_width_orig; - ch_width = pMac->sap.SapDfsInfo.orig_chanWidth; - } else { - ch_width = pMac->sap.SapDfsInfo.orig_chanWidth; - } - - if (sap_get_5ghz_channel_list(sapContext)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, - FL("Getting 5Ghz channel list failed")); - return target_channel; + FL("mac_ctx pointer NULL")); + return 0; } + preferred_location = + mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location; cds_get_dfs_region(&dfs_region); - - /* - * valid_chnl_count will be used to find number of valid channels - * after following for loop ends - */ - valid_chnl_count = sapContext->SapAllChnlList.numChannel; /* loop to check ACS range or NOL channels */ - for (i = 0; i < sapContext->SapAllChnlList.numChannel; i++) { - channelID = sapContext->SapAllChnlList.channelList[i].channel; + num_valid_ch = sap_all_ch->numChannel; + for (i = 0; i < sap_all_ch->numChannel; i++) { + ch_id = sap_all_ch->channelList[i].channel; /* * IN MKK DFS REGION CHECK IF THE FOLLOWING TWO @@ -1316,15 +1294,13 @@ static uint8_t sap_random_channel_sel(ptSapContext sapContext) /* * Check for JAPAN W53 Channel operation capability */ - if (true == sap_dfs_is_w53_invalid(hHal, channelID)) { + if (true == sap_dfs_is_w53_invalid(hal, ch_id)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, - FL - ("index:%d, Channel=%d Invalid,Japan W53 Disabled"), - i, channelID); - sapContext->SapAllChnlList.channelList[i]. - valid = false; - valid_chnl_count--; + FL("index:%d, Channel=%d Invalid,Japan W53 Disabled"), + i, ch_id); + sap_all_ch->channelList[i].valid = false; + num_valid_ch--; continue; } @@ -1336,384 +1312,428 @@ static uint8_t sap_random_channel_sel(ptSapContext sapContext) * domain to Invalid. */ if (false == - sap_dfs_is_channel_in_preferred_location(hHal, - channelID)) { + sap_dfs_is_channel_in_preferred_location(hal, + ch_id)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, - FL - ("CHAN=%d is invalid,preferred Channel Location %d Only"), - channelID, - pMac->sap.SapDfsInfo. - sap_operating_chan_preferred_location); - sapContext->SapAllChnlList.channelList[i]. - valid = false; - valid_chnl_count--; + FL("CHAN=%d is invalid,preferred Channel Location %d Only"), + ch_id, preferred_location); + sap_all_ch->channelList[i].valid = false; + num_valid_ch--; continue; } } - if (cds_get_channel_state(channelID) == - CHANNEL_STATE_DFS) { - isChannelNol = - sap_dfs_is_channel_in_nol_list(sapContext, - channelID, - PHY_SINGLE_CHANNEL_CENTERED); - if (true == isChannelNol) { + if (cds_get_channel_state(ch_id) == CHANNEL_STATE_DFS) { + is_ch_nol = sap_dfs_is_channel_in_nol_list(sap_ctx, + ch_id, PHY_SINGLE_CHANNEL_CENTERED); + if (true == is_ch_nol) { /* * Mark this channel invalid since it is still * in DFS Non-Occupancy-Period which is 30 mins. */ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, - FL - ("index: %d, Channel = %d Present in NOL LIST"), - i, channelID); - sapContext->SapAllChnlList.channelList[i]. - valid = false; - valid_chnl_count--; + FL("index: %d, Channel = %d Present in NOL LIST"), + i, ch_id); + sap_all_ch->channelList[i].valid = false; + num_valid_ch--; continue; } } #ifdef FEATURE_AP_MCC_CH_AVOIDANCE /* avoid ch on which another MDM AP in MCC mode is detected */ - if (pMac->sap.sap_channel_avoidance - && sapContext->sap_detected_avoid_ch_ie.present) { - if (sap_check_in_avoid_ch_list(sapContext, channelID)) { + if (mac_ctx->sap.sap_channel_avoidance + && sap_ctx->sap_detected_avoid_ch_ie.present) { + if (sap_check_in_avoid_ch_list(sap_ctx, ch_id)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, FL("index: %d, Channel = %d, avoided due to presence of another AP+AP MCC device in same channel."), - i, channelID); - sapContext->SapAllChnlList.channelList[i]. - valid = false; + i, ch_id); + sap_all_ch->channelList[i].valid = false; } } #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ /* check if the channel is within ACS channel range */ - isOutOfRange = sap_acs_channel_check(sapContext, channelID); - if (true == isOutOfRange) { + is_out_of_range = sap_acs_channel_check(sap_ctx, ch_id); + if (true == is_out_of_range) { /* * mark this channel invalid since it is out of ACS * channel range */ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, - FL - ("index: %d, Channel = %d out of ACS channel range"), - i, channelID); - sapContext->SapAllChnlList.channelList[i].valid = false; - valid_chnl_count--; + FL("index: %d, Channel = %d out of ACS channel range"), + i, ch_id); + sap_all_ch->channelList[i].valid = false; + num_valid_ch--; continue; } } /* end of check for NOL or ACS channels */ + return num_valid_ch; +} - /* valid_chnl_count now have number of valid channels */ - tmp_ch_lst = qdf_mem_malloc(valid_chnl_count); - if (tmp_ch_lst == NULL) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("sapdfs: memory alloc failed")); - return target_channel; +/** + * select_rand_from_lst() - selects random channel from given list + * @mac_ctx: mac context pointer + * @ch_lst: channel list + * @num_ch: number of channels + * + * Return: new target channel randomly selected + */ +static uint8_t select_rand_from_lst(tpAniSirGlobal mac_ctx, uint8_t *ch_lst, + uint8_t num_ch) +{ + uint32_t rand_byte = 0; + uint8_t i, target_channel, non_dfs_num_ch = 0, dfs_num_ch = 0; + uint8_t dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + uint8_t non_dfs_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + if (num_ch) { + for (i = 0; i < num_ch; i++) { + if (CDS_IS_DFS_CH(ch_lst[i])) + dfs_ch[dfs_num_ch++] = ch_lst[i]; + else + non_dfs_ch[non_dfs_num_ch++] = ch_lst[i]; + } + } else { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, + FL("No target channel found")); + return 0; } - do { - uint8_t j = 0; -#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION - tSapDfsNolInfo *nol = pMac->sap.SapDfsInfo.sapDfsChannelNolList; -#endif + cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); - /* prepare temp list of just the valid channels */ - for (i = 0; i < sapContext->SapAllChnlList.numChannel; i++) { - if (sapContext->SapAllChnlList.channelList[i].valid) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_ERROR, - FL - ("sapdfs: Adding Channel = %d to temp List"), - sapContext->SapAllChnlList. - channelList[i].channel); - tmp_ch_lst[j++] = sapContext->SapAllChnlList. - channelList[i].channel; - } - } + /* Give preference to non-DFS channel */ + if (!mac_ctx->f_prefer_non_dfs_on_radar) { + i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch; + target_channel = ch_lst[i]; + } else if (non_dfs_num_ch) { + i = (rand_byte + qdf_mc_timer_get_system_ticks()) % + non_dfs_num_ch; + target_channel = non_dfs_ch[i]; + } else { + i = (rand_byte + qdf_mc_timer_get_system_ticks()) % dfs_num_ch; + target_channel = dfs_ch[i]; + } -#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_ERROR, - FL - ("sapdfs: Processing temp channel list against NOL.") - ); - if (QDF_STATUS_SUCCESS != - sap_mark_channels_leaking_into_nol(sapContext, - ch_width, - nol, - valid_chnl_count, - tmp_ch_lst)) { - qdf_mem_free(tmp_ch_lst); - return target_channel; - } -#endif - qdf_mem_zero(availableChannels, sizeof(availableChannels)); - qdf_mem_zero(&channelBitmap, sizeof(channelBitmap)); - channelBitmap.chanBondingSet[0].startChannel = 36; - channelBitmap.chanBondingSet[1].startChannel = 52; - channelBitmap.chanBondingSet[2].startChannel = 100; - channelBitmap.chanBondingSet[3].startChannel = 116; - channelBitmap.chanBondingSet[3].startChannel = 132; - channelBitmap.chanBondingSet[4].startChannel = 149; - /* now loop through whatever is left of channel list */ - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_ERROR, - FL("sapdfs: Moving temp channel list to final.")); - for (i = 0; i < valid_chnl_count; i++) { - /* - * add channel from temp channel list to bitmap or fianl - * channel list (in case of 20MHz width) - */ - if (tmp_ch_lst[i] != 0) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_DEBUG, - FL("sapdfs: processing channel: %d "), - tmp_ch_lst[i]); - /* - * for 20MHz, directly create available - * channel list - */ - if (ch_width == CH_WIDTH_20MHZ) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_DEBUG, - FL - ("sapdfs: Channel=%d added to available list"), - tmp_ch_lst[i]); - availableChannels[available_ch_cnt++] = - tmp_ch_lst[i]; - } else { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_DEBUG, - FL("sapdfs: Channel=%d added to bitmap"), - tmp_ch_lst[i]); - sap_set_bitmap(&channelBitmap, - tmp_ch_lst[i]); - } - } + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: New Channel width = %d"), + mac_ctx->sap.SapDfsInfo.new_chanWidth); + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: target_channel = %d"), target_channel); + + return target_channel; +} + +/** + * sap_find_ch_wh_fallback() - find given channel width from given list of + * channels + * @mac_ctx: mac context pointer + * @ch_wd: channel width to find + * @ch_lst: list of channels + * @num_ch: number of channels + * + * This function tries to find given channel width and returns new target ch. + * If not found updates ch_wd to next lower channel width. + * + * Return: new target channel if successful, 0 otherwise + */ +static uint8_t sap_find_ch_wh_fallback(tpAniSirGlobal mac_ctx, + enum phy_ch_width *ch_wd, + uint8_t *ch_lst, + uint8_t num_ch) +{ + bool flag = false; + uint32_t rand_byte = 0; + chan_bonding_bitmap ch_map = { { {0} } }; + uint8_t count = 0, i, index = 0, final_cnt = 0, target_channel = 0; + uint8_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; + uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + + /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ + ch_map.chanBondingSet[0].startChannel = 36; + ch_map.chanBondingSet[1].startChannel = 52; + ch_map.chanBondingSet[2].startChannel = 100; + ch_map.chanBondingSet[3].startChannel = 116; + ch_map.chanBondingSet[4].startChannel = 132; + ch_map.chanBondingSet[5].startChannel = 149; + + /* now loop through leakage free list */ + for (i = 0; i < num_ch; i++) { + /* add tmp ch to bitmap */ + if (ch_lst[i] == 0) + continue; + + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, + FL("sapdfs: Channel=%d added to bitmap"), + ch_lst[i]); + sap_set_bitmap(&ch_map, ch_lst[i]); + } + + /* populate available channel list from bitmap */ + final_cnt = sap_populate_available_channels(&ch_map, *ch_wd, final_lst); + /* If no valid ch bonding found, fallback */ + if (final_cnt == 0) { + if ((*ch_wd == CH_WIDTH_160MHZ) || + (*ch_wd == CH_WIDTH_80P80MHZ) || + (*ch_wd == CH_WIDTH_80MHZ)) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, + FL("sapdfs:Changing chanWidth from [%d] to 40Mhz"), + *ch_wd); + *ch_wd = CH_WIDTH_40MHZ; + } else if (*ch_wd == CH_WIDTH_40MHZ) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, + FL("sapdfs:No 40MHz cb found, falling to 20MHz")); + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_WARN, + FL("sapdfs:Changing chanWidth from [%d] to [%d]"), + *ch_wd, CH_WIDTH_20MHZ); + *ch_wd = CH_WIDTH_20MHZ; } + return 0; + } + /* ch count should be > 8 to switch new channel in 160Mhz band */ + if (((*ch_wd == CH_WIDTH_160MHZ) || (*ch_wd == CH_WIDTH_80P80MHZ)) && + (final_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_wd, CH_WIDTH_80MHZ); + *ch_wd = CH_WIDTH_80MHZ; + return 0; + } + if (*ch_wd == CH_WIDTH_160MHZ) { /* - * if 40 MHz or 80 MHz, populate available - * channel list from bitmap + * 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. */ - 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, - * fallback to lower bandwidth - */ - if (available_ch_cnt == 0) { - 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:Changing chanWidth from [%d] to 40Mhz"), - ch_width); - ch_width = CH_WIDTH_40MHZ; - continue; - } else if (ch_width == CH_WIDTH_40MHZ) { - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_WARN, - FL - ("sapdfs:No 40MHz cb found, falling to 20MHz")); - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_WARN, - FL - ("sapdfs:Changing chanWidth from [%d] to [%d]"), - ch_width, - CH_WIDTH_20MHZ); - ch_width = CH_WIDTH_20MHZ; - /* continue to start of do loop */ - continue; - } + for (i = 1; ((i < final_cnt)); i++) { + if ((final_lst[i] - final_lst[i-1]) == 4) + count++; + else + count = 0; + if (count == SIR_DFS_MAX_20M_SUB_CH - 1) { + flag = true; + new_160_start_ch = final_lst[i-7]; + break; } + } + } else if (*ch_wd == CH_WIDTH_80P80MHZ) { + flag = true; + } + if ((flag == false) && (*ch_wd > CH_WIDTH_80MHZ)) { + *ch_wd = CH_WIDTH_80MHZ; + return 0; + } - /* - * 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; - } - 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_wd == CH_WIDTH_160MHZ) { + cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); + rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) + % SIR_DFS_MAX_20M_SUB_CH; + target_channel = new_160_start_ch + (rand_byte * 4); + } else if (*ch_wd == CH_WIDTH_80P80MHZ) { + cds_rand_get_bytes(0, (uint8_t *)&rand_byte, 1); + index = (rand_byte + qdf_mc_timer_get_system_ticks()) % + final_cnt; + target_channel = final_lst[index]; + index -= (index % 4); + primary_seg_start_ch = final_lst[index]; + + /* reset channels associate with primary 80Mhz */ + for (i = 0; i < 4; i++) + final_lst[i + index] = 0; + /* select and calculate center freq for secondary segement */ + for (i = 0; i < final_cnt / 4; i++) { + if (final_lst[i * 4] && + (abs(primary_seg_start_ch - final_lst[i * 4]) > + (SIR_DFS_MAX_20M_SUB_CH * 2))) { + sec_seg_ch = final_lst[i * 4] + + SIR_80MHZ_START_CENTER_CH_DIFF; + break; } + } + if (!sec_seg_ch && (final_cnt == SIR_DFS_MAX_20M_SUB_CH)) + *ch_wd = CH_WIDTH_160MHZ; + else if (!sec_seg_ch) + *ch_wd = CH_WIDTH_80MHZ; - 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("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; + mac_ctx->sap.SapDfsInfo.new_ch_params.center_freq_seg1 + = sec_seg_ch; - 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 Center Freq Seg1 = %d"), sec_seg_ch); + } else { + target_channel = select_rand_from_lst(mac_ctx, final_lst, + final_cnt); + } + return target_channel; +} - 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); +/** + * sap_random_channel_sel() - This function randomly pick up an available + * channel + * @sap_ctx: sap context. + * + * This function first eliminates invalid channel, then selects random channel + * using following algorithm: + * PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules + * PASS: 2 - now mark channels that will leak into NOL + * PASS: 3 - from leakage_adjusted_lst, either select random channel (for 20MHz) + * or find given channel width possible. if not found fallback to + * lower channel width and try again. once given channel width found + * use random channel from give possibilities. + * Return: channel number picked + */ +static uint8_t sap_random_channel_sel(ptSapContext sap_ctx) +{ + uint8_t j = 0, i = 0, final_cnt = 0, target_channel = 0; + /* count and ch list after applying all rules */ + uint8_t rule_adjusted_cnt, *rule_adjusted_lst; + /* ch list after invalidating channels leaking into NOL */ + uint8_t *leakage_adjusted_lst; + /* final list of channel from which random channel will be selected */ + uint8_t final_lst[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tAll5GChannelList *all_ch = &sap_ctx->SapAllChnlList; + tHalHandle hal = CDS_GET_HAL_CB(sap_ctx->p_cds_gctx); + tpAniSirGlobal mac_ctx; + /* channel width for current iteration */ + enum phy_ch_width ch_wd; +#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION + tSapDfsNolInfo *nol; +#endif - qdf_mem_free(tmp_ch_lst); + if (NULL == hal) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("invalid hal")); + return 0; + } - return target_channel; - } + mac_ctx = PMAC_STRUCT(hal); + if (NULL == mac_ctx) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("invalid mac_ctx")); + return 0; + } + + /* + * Retrieve the original one and store it. + * use the stored original value when you call this function next time + * so fall back mechanism always starts with original ini value. + */ + if (mac_ctx->sap.SapDfsInfo.orig_chanWidth == 0) { + ch_wd = sap_ctx->ch_width_orig; + mac_ctx->sap.SapDfsInfo.orig_chanWidth = ch_wd; + } else { + ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth; + } + + if (sap_get_5ghz_channel_list(sap_ctx)) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, + FL("Getting 5Ghz channel list failed")); + return 0; + } + + /* PASS: 1 - invalidate ch in sap_ctx->all_ch_lst as per rules */ + rule_adjusted_cnt = sap_apply_rules(sap_ctx); + if (0 == rule_adjusted_cnt) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("No channels left after applying rules.")); + return 0; + } + + /* this is list we get after applying all rules */ + rule_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt); + + /* list adjusted after leakage has been marked */ + leakage_adjusted_lst = qdf_mem_malloc(rule_adjusted_cnt); + if (rule_adjusted_lst == NULL || leakage_adjusted_lst == NULL) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("sapdfs: memory alloc failed")); + qdf_mem_free(rule_adjusted_lst); + qdf_mem_free(leakage_adjusted_lst); + return 0; + } + + /* copy valid ch from sap_ctx->all_ch_lst into rule_adjusted_lst */ + for (i = 0, j = 0; i < all_ch->numChannel; i++) { + if (!all_ch->channelList[i].valid) + continue; + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: Adding Channel = %d to temp List"), + all_ch->channelList[i].channel); + rule_adjusted_lst[j++] = all_ch->channelList[i].channel; + } + + /* + * do - while loop for fallback mechanism. at each channel width this + * will try to find channel bonding, if not fall back to lower ch width + */ + do { + /* save rules adjusted lst */ + qdf_mem_copy(leakage_adjusted_lst, rule_adjusted_lst, + rule_adjusted_cnt); +#ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION + nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList; + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("sapdfs: Processing tmp ch list against NOL.")); + /* PASS: 2 - now mark channels that will leak into NOL */ + if (sap_mark_leaking_ch(sap_ctx, ch_wd, nol, rule_adjusted_cnt, + leakage_adjusted_lst) != QDF_STATUS_SUCCESS) { + qdf_mem_free(rule_adjusted_lst); + qdf_mem_free(leakage_adjusted_lst); + return 0; + } +#endif + if (ch_wd == CH_WIDTH_20MHZ) { /* - * by now, available channels list will be populated or - * no channels are avaialbe + * PASS: 3 - from leakage_adjusted_lst, prepare valid + * ch list and use random number from that */ - 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 { + for (i = 0; i < rule_adjusted_cnt; i++) { + if (leakage_adjusted_lst[i] == 0) + continue; 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]; + QDF_TRACE_LEVEL_DEBUG, + FL("sapdfs: Channel=%d added to available list"), + leakage_adjusted_lst[i]); + final_lst[final_cnt] = leakage_adjusted_lst[i]; + final_cnt++; } + target_channel = select_rand_from_lst(mac_ctx, + final_lst, final_cnt); + break; } - 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: target_channel = %d"), - target_channel); - break; - /* this loop will iterate at max 3 times */ - } while (1); - qdf_mem_free(tmp_ch_lst); + + /* + * PASS: 3 - following function will check from valid channels + * left if given ch_wd can be supported. if not reduce ch_wd + * (fallback), then continue with reduced ch_wd + */ + target_channel = sap_find_ch_wh_fallback(mac_ctx, &ch_wd, + leakage_adjusted_lst, + rule_adjusted_cnt); + /* + * if target channel is 0, no channel bonding was found + * ch_wd would have been updated for fallback + */ + if (0 == target_channel) + continue; + else + break; + } while (true); + + if (target_channel) + mac_ctx->sap.SapDfsInfo.new_chanWidth = ch_wd; + + qdf_mem_free(rule_adjusted_lst); + qdf_mem_free(leakage_adjusted_lst); + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: New Channel width = %d"), + mac_ctx->sap.SapDfsInfo.new_chanWidth); + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, + FL("sapdfs: target_channel = %d"), + target_channel); return target_channel; } @@ -3329,7 +3349,7 @@ static QDF_STATUS sap_fsm_state_ch_select(ptSapContext sap_ctx, temp_chan = sap_ctx->channel; p_nol = mac_ctx->sap.SapDfsInfo.sapDfsChannelNolList; - sap_mark_channels_leaking_into_nol(sap_ctx, + sap_mark_leaking_ch(sap_ctx, cbmode, p_nol, 1, &temp_chan); /* |
