diff --git a/umac/regulatory/core/src/reg_priv.h b/umac/regulatory/core/src/reg_priv.h index a7a3ae6be056..fea3c218304a 100644 --- a/umac/regulatory/core/src/reg_priv.h +++ b/umac/regulatory/core/src/reg_priv.h @@ -46,8 +46,7 @@ reg_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) struct wlan_regulatory_psoc_priv_obj { - struct regulatory_channel master_ch_list[NUM_CHANNELS]; - struct regulatory_channel current_ch_list[NUM_CHANNELS]; + struct regulatory_channel mas_chan_list[NUM_CHANNELS]; bool offload_enabled; enum channel_enum nol_list[NUM_CHANNELS]; char default_country[REG_ALPHA2_LEN + 1]; diff --git a/umac/regulatory/core/src/reg_services.c b/umac/regulatory/core/src/reg_services.c index 58532650b22f..a1db1bfe4275 100644 --- a/umac/regulatory/core/src/reg_services.c +++ b/umac/regulatory/core/src/reg_services.c @@ -130,36 +130,186 @@ const struct chan_map channel_map[NUM_CHANNELS] = { }; + +static struct reg_dmn_supp_op_classes reg_dmn_curr_supp_opp_classes = { 0 }; + +static const struct reg_dmn_op_class_map_t global_op_class[] = { + {81, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {82, 25, BW20, {14} }, + {83, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7, 8, 9} }, + {84, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {115, 20, BW20, {36, 40, 44, 48} }, + {116, 40, BW40_LOW_PRIMARY, {36, 44} }, + {117, 40, BW40_HIGH_PRIMARY, {40, 48} }, + {118, 20, BW20, {52, 56, 60, 64} }, + {119, 40, BW40_LOW_PRIMARY, {52, 60} }, + {120, 40, BW40_HIGH_PRIMARY, {56, 64} }, + {121, 20, BW20, + {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} }, + {122, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} }, + {123, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} }, + {125, 20, BW20, {149, 153, 157, 161, 165, 169} }, + {126, 40, BW40_LOW_PRIMARY, {149, 157} }, + {127, 40, BW40_HIGH_PRIMARY, {153, 161} }, + {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, + 112, 116, 120, 124, 128, 132, 136, 140, 144, + 149, 153, 157, 161} }, + {0, 0, 0, {0} }, +}; + +static const struct reg_dmn_op_class_map_t us_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48} }, + {2, 20, BW20, {52, 56, 60, 64} }, + {4, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, + 144} }, + {5, 20, BW20, {149, 153, 157, 161, 165} }, + {12, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} }, + {22, 40, BW40_LOW_PRIMARY, {36, 44} }, + {23, 40, BW40_LOW_PRIMARY, {52, 60} }, + {24, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} }, + {26, 40, BW40_LOW_PRIMARY, {149, 157} }, + {27, 40, BW40_HIGH_PRIMARY, {40, 48} }, + {28, 40, BW40_HIGH_PRIMARY, {56, 64} }, + {29, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} }, + {31, 40, BW40_HIGH_PRIMARY, {153, 161} }, + {32, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7} }, + {33, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11} }, + {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, + 112, 116, 120, 124, 128, 132, 136, 140, 144, + 149, 153, 157, 161} }, + {0, 0, 0, {0} }, +}; + +static const struct reg_dmn_op_class_map_t euro_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48} }, + {2, 20, BW20, {52, 56, 60, 64} }, + {3, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} }, + {4, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {5, 40, BW40_LOW_PRIMARY, {36, 44} }, + {6, 40, BW40_LOW_PRIMARY, {52, 60} }, + {7, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} }, + {8, 40, BW40_HIGH_PRIMARY, {40, 48} }, + {9, 40, BW40_HIGH_PRIMARY, {56, 64} }, + {10, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} }, + {11, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7, 8, 9} }, + {12, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {17, 20, BW20, {149, 153, 157, 161, 165, 169} }, + {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128} }, + {0, 0, 0, {0} }, +}; + +static const struct reg_dmn_op_class_map_t japan_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48} }, + {30, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} }, + {31, 25, BW20, {14} }, + {32, 20, BW20, {52, 56, 60, 64} }, + {34, 20, BW20, + {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} }, + {36, 40, BW40_LOW_PRIMARY, {36, 44} }, + {37, 40, BW40_LOW_PRIMARY, {52, 60} }, + {39, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} }, + {41, 40, BW40_HIGH_PRIMARY, {40, 48} }, + {42, 40, BW40_HIGH_PRIMARY, {56, 64} }, + {44, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} }, + {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128} }, + {0, 0, 0, {0} }, +}; + + +/** + * reg_get_bw_value() - give bandwidth value + * bw: bandwidth enum + * + * Return: uint16_t + */ +uint16_t reg_get_bw_value(enum phy_ch_width bw) +{ + switch (bw) { + case CH_WIDTH_20MHZ: + return 20; + case CH_WIDTH_40MHZ: + return 40; + case CH_WIDTH_80MHZ: + return 80; + case CH_WIDTH_160MHZ: + return 160; + case CH_WIDTH_80P80MHZ: + return 160; + case CH_WIDTH_INVALID: + return 0; + case CH_WIDTH_5MHZ: + return 10; + case CH_WIDTH_10MHZ: + return 5; + case CH_WIDTH_MAX: + return 160; + default: + return 0; + } +} + + +/** + * reg_set_default_country() - Read the default country for the regdomain + * @country: country code. + * + * Return: QDF_STATUS + */ +void reg_set_default_country(struct wlan_objmgr_psoc *psoc, uint8_t *country) +{ + struct wlan_regulatory_psoc_priv_obj *soc_reg; + + wlan_psoc_obj_lock(psoc); + soc_reg = (struct wlan_regulatory_psoc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_REGULATORY); + wlan_psoc_obj_unlock(psoc); + + if (NULL == soc_reg) { + reg_err("reg soc is NULL"); + return; + } + + qdf_mem_copy(soc_reg->default_country, country, + sizeof(soc_reg->default_country)); +} + + /** * reg_get_channel_list_with_power() - Provides the channel list with power * @ch_list: pointer to the channel list. * * Return: QDF_STATUS */ -QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc, +QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, struct channel_power *ch_list, uint8_t *num_chan) { int i, count; struct regulatory_channel *reg_channels; - struct wlan_regulatory_psoc_priv_obj *soc_reg; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; if (!num_chan || !ch_list) { reg_err("chan_list or num_ch is NULL"); return QDF_STATUS_E_FAILURE; } - soc_reg = (struct wlan_regulatory_psoc_priv_obj *) - wlan_objmgr_psoc_get_comp_private_obj(psoc, + wlan_pdev_obj_lock(pdev); + pdev_priv_obj = (struct wlan_regulatory_pdev_priv_obj *) + wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_REGULATORY); + wlan_pdev_obj_unlock(pdev); - if (NULL == soc_reg) { - reg_err("soc_reg is NULL"); + if (NULL == pdev_priv_obj) { + reg_err("pdev priv obj is NULL"); return QDF_STATUS_E_FAILURE; } /* set the current channel list */ - reg_channels = &soc_reg->current_ch_list[0]; + reg_channels = pdev_priv_obj->cur_chan_list; + for (i = 0, count = 0; i < NUM_CHANNELS; i++) { if (reg_channels[i].state) { ch_list[count].chan_num = @@ -168,6 +318,7 @@ QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc, reg_channels[i].tx_power; } } + *num_chan = count; return QDF_STATUS_SUCCESS; @@ -178,38 +329,42 @@ QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc, * * Return: QDF_STATUS */ -void reg_read_default_country(struct wlan_objmgr_psoc *psoc, uint8_t *country) +QDF_STATUS reg_read_default_country(struct wlan_objmgr_psoc *psoc, + uint8_t *country) { - struct wlan_regulatory_psoc_priv_obj *soc_reg; + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; - soc_reg = (struct wlan_regulatory_psoc_priv_obj *) + wlan_psoc_obj_lock(psoc); + psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_REGULATORY); + wlan_psoc_obj_unlock(psoc); - if (NULL == soc_reg) { - reg_err("soc_reg is NULL"); - return; + if (NULL == psoc_priv_obj) { + reg_err("psoc priv obj is NULL"); + return QDF_STATUS_E_FAILURE; } if (NULL == country) { reg_err("country is NULL"); - return; + return QDF_STATUS_E_FAILURE; } - qdf_mem_copy(country, soc_reg->default_country, - sizeof(soc_reg->default_country)); + qdf_mem_copy(country, psoc_priv_obj->default_country, + sizeof(psoc_priv_obj->default_country)); + + return QDF_STATUS_SUCCESS; } -static enum channel_enum get_reg_ch_idx(uint32_t chan_num) +enum channel_enum reg_get_chan_enum(uint32_t chan_num) { - uint32_t indx; + uint32_t count; - for (indx = 0; indx < NUM_CHANNELS; indx++) - if (channel_map[indx].chan_num == chan_num) - return indx; + for (count = 0; count < NUM_CHANNELS; count++) + if (channel_map[count].chan_num == chan_num) + return count; - QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, - "invalid channel number %d", chan_num); + reg_err("invalid channel number %d", chan_num); return INVALID_CHANNEL; } @@ -219,27 +374,29 @@ static enum channel_enum get_reg_ch_idx(uint32_t chan_num) * * Return: channel state */ -enum channel_state reg_get_channel_state(struct wlan_objmgr_psoc *psoc, +enum channel_state reg_get_channel_state(struct wlan_objmgr_pdev *pdev, uint32_t ch) { enum channel_enum ch_idx; - struct wlan_regulatory_psoc_priv_obj *soc_reg; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; - ch_idx = get_reg_ch_idx(ch); + ch_idx = reg_get_chan_enum(ch); if (INVALID_CHANNEL == ch_idx) return CHANNEL_STATE_INVALID; - soc_reg = (struct wlan_regulatory_psoc_priv_obj *) - wlan_objmgr_psoc_get_comp_private_obj(psoc, + wlan_pdev_obj_lock(pdev); + pdev_priv_obj = (struct wlan_regulatory_pdev_priv_obj *) + wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_REGULATORY); + wlan_pdev_obj_unlock(pdev); - if (NULL == soc_reg) { - reg_err("soc_reg is NULL"); + if (NULL == pdev_priv_obj) { + reg_err("pdev piv obj is NULL"); return CHANNEL_STATE_INVALID; } - return soc_reg->current_ch_list[ch_idx].state; + return pdev_priv_obj->cur_chan_list[ch_idx].state; } /** @@ -251,7 +408,7 @@ enum channel_state reg_get_channel_state(struct wlan_objmgr_psoc *psoc, * Return: bonded channel state */ static enum channel_state reg_get_5g_bonded_chan_array( - struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, uint32_t oper_chan, const struct bonded_channel bonded_chan_ar[], uint16_t array_size, @@ -277,7 +434,7 @@ static enum channel_state reg_get_5g_bonded_chan_array( *bonded_chan_ptr_ptr = bonded_chan_ptr; chan_num = bonded_chan_ptr->start_ch; while (chan_num <= bonded_chan_ptr->end_ch) { - temp_chan_state = reg_get_channel_state(psoc, chan_num); + temp_chan_state = reg_get_channel_state(pdev, chan_num); if (temp_chan_state < chan_state) chan_state = temp_chan_state; chan_num = chan_num + 4; @@ -295,32 +452,32 @@ static enum channel_state reg_get_5g_bonded_chan_array( * Return: channel state */ static enum channel_state reg_get_5g_bonded_channel( - struct wlan_objmgr_psoc *psoc, uint32_t chan_num, + struct wlan_objmgr_pdev *pdev, uint32_t chan_num, enum phy_ch_width ch_width, const struct bonded_channel **bonded_chan_ptr_ptr) { if (CH_WIDTH_80P80MHZ == ch_width) - return reg_get_5g_bonded_chan_array(psoc, chan_num, + return reg_get_5g_bonded_chan_array(pdev, chan_num, bonded_chan_80mhz_list, QDF_ARRAY_SIZE(bonded_chan_80mhz_list), bonded_chan_ptr_ptr); else if (CH_WIDTH_160MHZ == ch_width) - return reg_get_5g_bonded_chan_array(psoc, chan_num, + return reg_get_5g_bonded_chan_array(pdev, chan_num, bonded_chan_160mhz_list, QDF_ARRAY_SIZE(bonded_chan_160mhz_list), bonded_chan_ptr_ptr); else if (CH_WIDTH_80MHZ == ch_width) - return reg_get_5g_bonded_chan_array(psoc, chan_num, + return reg_get_5g_bonded_chan_array(pdev, chan_num, bonded_chan_80mhz_list, QDF_ARRAY_SIZE(bonded_chan_80mhz_list), bonded_chan_ptr_ptr); else if (CH_WIDTH_40MHZ == ch_width) - return reg_get_5g_bonded_chan_array(psoc, chan_num, + return reg_get_5g_bonded_chan_array(pdev, chan_num, bonded_chan_40mhz_list, QDF_ARRAY_SIZE(bonded_chan_40mhz_list), bonded_chan_ptr_ptr); else - return reg_get_channel_state(psoc, chan_num); + return reg_get_channel_state(pdev, chan_num); } /** * reg_get_5g_bonded_channel_state() - Get channel state for 5G bonded channel @@ -330,13 +487,13 @@ static enum channel_state reg_get_5g_bonded_channel( * Return: channel state */ enum channel_state reg_get_5g_bonded_channel_state( - struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, uint8_t ch, enum phy_ch_width bw) { enum channel_enum ch_indx; enum channel_state chan_state; struct regulatory_channel *reg_channels; - struct wlan_regulatory_psoc_priv_obj *soc_reg; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; bool bw_enabled = false; const struct bonded_channel *bonded_chan_ptr = NULL; @@ -345,23 +502,26 @@ enum channel_state reg_get_5g_bonded_channel_state( return CHANNEL_STATE_INVALID; } - chan_state = reg_get_5g_bonded_channel(psoc, ch, bw, &bonded_chan_ptr); + chan_state = reg_get_5g_bonded_channel(pdev, ch, bw, &bonded_chan_ptr); if ((CHANNEL_STATE_INVALID == chan_state) || (CHANNEL_STATE_DISABLE == chan_state)) return chan_state; - soc_reg = (struct wlan_regulatory_psoc_priv_obj *) - wlan_objmgr_psoc_get_comp_private_obj(psoc, + wlan_pdev_obj_lock(pdev); + pdev_priv_obj = (struct wlan_regulatory_pdev_priv_obj *) + wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_REGULATORY); + wlan_pdev_obj_unlock(pdev); - if (NULL == soc_reg) { - reg_err("soc_reg is NULL"); + if (NULL == pdev_priv_obj) { + reg_err("pdev priv obj is NULL"); return CHANNEL_STATE_INVALID; } - reg_channels = &soc_reg->current_ch_list[0]; - ch_indx = get_reg_ch_idx(ch); + reg_channels = pdev_priv_obj->cur_chan_list; + + ch_indx = reg_get_chan_enum(ch); if (CH_WIDTH_5MHZ == bw) bw_enabled = true; else if (CH_WIDTH_10MHZ == bw) @@ -397,14 +557,14 @@ enum channel_state reg_get_5g_bonded_channel_state( * Return: channel state */ enum channel_state reg_get_2g_bonded_channel_state( - struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, uint8_t oper_ch, uint8_t sec_ch, enum phy_ch_width bw) { enum channel_enum chan_idx; enum channel_state chan_state; struct regulatory_channel *reg_channels; - struct wlan_regulatory_psoc_priv_obj *soc_reg; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; bool bw_enabled = false; enum channel_state chan_state2 = CHANNEL_STATE_INVALID; @@ -415,23 +575,25 @@ enum channel_state reg_get_2g_bonded_channel_state( if ((sec_ch + 4 != oper_ch) && (oper_ch + 4 != sec_ch)) return CHANNEL_STATE_INVALID; - chan_state2 = reg_get_channel_state(psoc, sec_ch); + chan_state2 = reg_get_channel_state(pdev, sec_ch); if (CHANNEL_STATE_INVALID == chan_state2) return chan_state2; } - soc_reg = (struct wlan_regulatory_psoc_priv_obj *) - wlan_objmgr_psoc_get_comp_private_obj(psoc, + wlan_pdev_obj_lock(pdev); + pdev_priv_obj = (struct wlan_regulatory_pdev_priv_obj *) + wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_REGULATORY); + wlan_pdev_obj_unlock(pdev); - if (NULL == soc_reg) { - reg_err("soc_reg is NULL"); + if (NULL == pdev_priv_obj) { + reg_err("pdev priv obj is NULL"); return CHANNEL_STATE_INVALID; } - reg_channels = &soc_reg->current_ch_list[0]; + reg_channels = pdev_priv_obj->cur_chan_list; - chan_state = reg_get_channel_state(psoc, oper_ch); + chan_state = reg_get_channel_state(pdev, oper_ch); if (chan_state2 < chan_state) chan_state = chan_state2; @@ -439,7 +601,7 @@ enum channel_state reg_get_2g_bonded_channel_state( (CHANNEL_STATE_DISABLE == chan_state)) return chan_state; - chan_idx = get_reg_ch_idx(oper_ch); + chan_idx = reg_get_chan_enum(oper_ch); if (CH_WIDTH_5MHZ == bw) bw_enabled = true; else if (CH_WIDTH_10MHZ == bw) @@ -470,20 +632,23 @@ static enum channel_state reg_combine_channel_states( else return min(chan_state1, chan_state2); } + /** - * reg_set_channel_params () - Sets channel parameteres for given bandwidth + * reg_set_5g_channel_params () - Sets channel parameteres for given bandwidth * @ch: channel number. * @ch_params: pointer to the channel parameters. * * Return: None */ -void reg_set_channel_params(struct wlan_objmgr_psoc *psoc, - uint8_t ch, struct ch_params_s *ch_params) +static void reg_set_5g_channel_params(struct wlan_objmgr_pdev *pdev, + uint8_t ch, + struct ch_params *ch_params) { /* * Set channel parameters like center frequency for a bonded channel * state. Also return the maximum bandwidth supported by the channel. */ + enum phy_ch_width next_lower_bw; enum channel_state chan_state = CHANNEL_STATE_ENABLE; enum channel_state chan_state2 = CHANNEL_STATE_ENABLE; @@ -502,21 +667,22 @@ void reg_set_channel_params(struct wlan_objmgr_psoc *psoc, ch_params->ch_width = CH_WIDTH_160MHZ; } next_lower_bw = ch_params->ch_width; + while (ch_params->ch_width != CH_WIDTH_INVALID) { ch_params->ch_width = next_lower_bw; next_lower_bw = get_next_lower_bw[ch_params->ch_width]; bonded_chan_ptr = NULL; bonded_chan_ptr2 = NULL; - chan_state = reg_get_5g_bonded_channel(psoc, ch, + chan_state = reg_get_5g_bonded_channel(pdev, ch, ch_params->ch_width, &bonded_chan_ptr); - chan_state = reg_get_5g_bonded_channel_state(psoc, ch, + chan_state = reg_get_5g_bonded_channel_state(pdev, ch, ch_params->ch_width); if (CH_WIDTH_80P80MHZ == ch_params->ch_width) { - chan_state2 = reg_get_5g_bonded_channel_state(psoc, - ch_params->center_freq_seg1 - 2, - CH_WIDTH_80MHZ); + chan_state2 = reg_get_5g_bonded_channel_state(pdev, + ch_params->center_freq_seg1 - 2, + CH_WIDTH_80MHZ); chan_state = reg_combine_channel_states(chan_state, chan_state2); @@ -530,7 +696,7 @@ void reg_set_channel_params(struct wlan_objmgr_psoc *psoc, ch_params->center_freq_seg0 = ch; break; } else if (CH_WIDTH_40MHZ <= ch_params->ch_width) { - reg_get_5g_bonded_chan_array(psoc, ch, + reg_get_5g_bonded_chan_array(pdev, ch, bonded_chan_40mhz_list, QDF_ARRAY_SIZE(bonded_chan_40mhz_list), &bonded_chan_ptr2); @@ -550,8 +716,8 @@ void reg_set_channel_params(struct wlan_objmgr_psoc *psoc, if (CH_WIDTH_160MHZ == ch_params->ch_width) { ch_params->center_freq_seg1 = ch_params->center_freq_seg0; - chan_state = reg_get_5g_bonded_channel(psoc, ch, - CH_WIDTH_80MHZ, &bonded_chan_ptr); + chan_state = reg_get_5g_bonded_channel(pdev, ch, + CH_WIDTH_80MHZ, &bonded_chan_ptr); if (bonded_chan_ptr) ch_params->center_freq_seg0 = (bonded_chan_ptr->start_ch + @@ -563,6 +729,70 @@ void reg_set_channel_params(struct wlan_objmgr_psoc *psoc, ch_params->center_freq_seg1); } +/** + * reg_set_2g_channel_params() - set the 2.4G bonded channel parameters + * @oper_ch: operating channel + * @ch_params: channel parameters + * @sec_ch_2g: 2.4G secondary channel + * + * Return: void + */ +static void reg_set_2g_channel_params(struct wlan_objmgr_pdev *pdev, + uint16_t oper_ch, struct ch_params *ch_params, + uint16_t sec_ch_2g) +{ + enum channel_state chan_state = CHANNEL_STATE_ENABLE; + + if (CH_WIDTH_MAX <= ch_params->ch_width) + ch_params->ch_width = CH_WIDTH_40MHZ; + if ((reg_get_bw_value(ch_params->ch_width) > 20) && !sec_ch_2g) { + if (oper_ch >= 1 && oper_ch <= 5) + sec_ch_2g = oper_ch + 4; + else if (oper_ch >= 6 && oper_ch <= 13) + sec_ch_2g = oper_ch - 4; + } + + while (ch_params->ch_width != CH_WIDTH_INVALID) { + chan_state = reg_get_2g_bonded_channel_state(pdev, oper_ch, + ch_params->ch_width, + sec_ch_2g); + if (CHANNEL_STATE_ENABLE == chan_state) { + if (CH_WIDTH_40MHZ == ch_params->ch_width) { + if (oper_ch < sec_ch_2g) + ch_params->sec_ch_offset = + LOW_PRIMARY_CH; + else + ch_params->sec_ch_offset = + HIGH_PRIMARY_CH; + ch_params->center_freq_seg0 = + (oper_ch + sec_ch_2g)/2; + } else + ch_params->sec_ch_offset = NO_SEC_CH; + break; + } + + ch_params->ch_width = get_next_lower_bw[ch_params->ch_width]; + } +} + +/** + * reg_set_channel_params () - Sets channel parameteres for given bandwidth + * @ch: channel number. + * @ch_params: pointer to the channel parameters. + * + * Return: None + */ +void reg_set_channel_params(struct wlan_objmgr_pdev *pdev, + uint8_t ch, uint8_t sec_ch_2g, + struct ch_params *ch_params) +{ + if (REG_IS_5GHZ_CH(ch)) + reg_set_5g_channel_params(pdev, ch, ch_params); + else if (REG_IS_24GHZ_CH(ch)) + reg_set_2g_channel_params(pdev, ch, ch_params, + sec_ch_2g); +} + /** * reg_get_dfs_region () - Get the current dfs region * @dfs_reg: pointer to dfs region @@ -570,29 +800,282 @@ void reg_set_channel_params(struct wlan_objmgr_psoc *psoc, * Return: None */ void reg_get_dfs_region(struct wlan_objmgr_psoc *psoc, - enum dfs_reg *dfs_reg) + enum dfs_reg *dfs_reg) { - /* - * Get the current dfs region - */ + struct wlan_regulatory_psoc_priv_obj *soc_reg; + + wlan_psoc_obj_lock(psoc); + soc_reg = (struct wlan_regulatory_psoc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_REGULATORY); + wlan_psoc_obj_unlock(psoc); + + if (NULL == soc_reg) { + reg_err("reg soc is NULL"); + return; + } + + *dfs_reg = soc_reg->dfs_region; } +/** + * reg_set_dfs_region () - Set the current dfs region + * @dfs_reg: pointer to dfs region + * + * Return: None + */ +void reg_set_dfs_region(struct wlan_objmgr_psoc *psoc, + enum dfs_reg dfs_reg) +{ + struct wlan_regulatory_psoc_priv_obj *soc_reg; + + wlan_psoc_obj_lock(psoc); + soc_reg = (struct wlan_regulatory_psoc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_REGULATORY); + wlan_psoc_obj_unlock(psoc); + + if (NULL == soc_reg) { + reg_err("reg soc is NULL"); + return; + } + + soc_reg->dfs_region = dfs_reg; +} + + /** * reg_is_dfs_ch () - Checks the channel state for DFS * @ch: channel * * Return: true or false */ -bool reg_is_dfs_ch(struct wlan_objmgr_psoc *psoc, uint8_t ch) +bool reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint8_t ch) { enum channel_state ch_state; - ch_state = reg_get_channel_state(psoc, ch); + ch_state = reg_get_channel_state(pdev, ch); return ch_state == CHANNEL_STATE_DFS; } +/** + * reg_get_domain_from_country_code() - get the regulatory domain + * @reg_domain_ptr: ptr to store regulatory domain + * + * Return: QDF_STATUS + */ +QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, + const uint8_t *country_alpha2, + enum country_src source) +{ + if (NULL == reg_domain_ptr) { + reg_err("Invalid reg domain pointer"); + return QDF_STATUS_E_FAULT; + } + + *reg_domain_ptr = 0; + + if (NULL == country_alpha2) { + reg_err("Country code array is NULL"); + return QDF_STATUS_E_FAULT; + } + + return QDF_STATUS_SUCCESS; +} + +uint32_t reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, + uint32_t chan_num) +{ + enum channel_enum chan_enum; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct regulatory_channel *reg_channels; + + chan_enum = reg_get_chan_enum(chan_num); + + if (chan_enum == INVALID_CHANNEL) { + reg_err("channel is invalid"); + return CHANNEL_STATE_INVALID; + } + + wlan_pdev_obj_lock(pdev); + pdev_priv_obj = (struct wlan_regulatory_pdev_priv_obj *) + wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_REGULATORY); + wlan_pdev_obj_unlock(pdev); + + reg_channels = pdev_priv_obj->cur_chan_list; + + return reg_channels[chan_enum].tx_power; +} + +uint32_t reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, + uint32_t chan_num) +{ + enum channel_enum chan_enum; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct regulatory_channel *reg_channels; + + chan_enum = reg_get_chan_enum(chan_num); + + if (chan_enum == INVALID_CHANNEL) + return CHANNEL_STATE_INVALID; + + wlan_pdev_obj_lock(pdev); + pdev_priv_obj = (struct wlan_regulatory_pdev_priv_obj *) + wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_REGULATORY); + wlan_pdev_obj_unlock(pdev); + + reg_channels = pdev_priv_obj->cur_chan_list; + + return reg_channels[chan_enum].center_freq; +} + +enum band_info reg_chan_to_band(uint32_t chan_num) +{ + if (chan_num <= 14) + return BAND_2G; + + return BAND_5G; + +} + + +/** + * reg_dmn_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 reg_dmn_get_chanwidth_from_opclass(uint8_t *country, + uint8_t channel, + uint8_t opclass) +{ + const struct reg_dmn_op_class_map_t *class; + uint16_t i; + + if (!qdf_mem_cmp(country, "US", 2)) + class = us_op_class; + else if (!qdf_mem_cmp(country, "EU", 2)) + class = euro_op_class; + else if (!qdf_mem_cmp(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 < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + class->channels[i]); + i++) { + if (channel == class->channels[i]) + return class->ch_spacing; + } + } + class++; + } + + return 0; +} + + +/** + * reg_dmn_get_opclass_from_channel() - get operating class from channel + * @country: the complete reg domain + * @channel: channel number + * @offset: the value of offset + * + * Return: operating class + */ +uint16_t reg_dmn_get_opclass_from_channel(uint8_t *country, uint8_t channel, + uint8_t offset) +{ + const struct reg_dmn_op_class_map_t *class = NULL; + uint16_t i = 0; + + if (!qdf_mem_cmp(country, "US", 2)) + class = us_op_class; + else if (!qdf_mem_cmp(country, "EU", 2)) + class = euro_op_class; + else if (!qdf_mem_cmp(country, "JP", 2)) + class = japan_op_class; + else + class = global_op_class; + + while (class->op_class) { + if ((offset == class->offset) || (offset == BWALL)) { + for (i = 0; + (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS && + class->channels[i]); i++) { + if (channel == class->channels[i]) + return class->op_class; + } + } + class++; + } + + return 0; +} + +/** + * reg_dmn_set_curr_opclasses() - set the current operating class + * @num_classes: number of classes + * @class: operating class + * + * Return: error code + */ +uint16_t reg_dmn_set_curr_opclasses(uint8_t num_classes, uint8_t *class) +{ + uint8_t i; + + if (REG_MAX_SUPP_OPER_CLASSES < num_classes) { + reg_err("invalid num classes %d", num_classes); + return 0; + } + + for (i = 0; i < num_classes; i++) + reg_dmn_curr_supp_opp_classes.classes[i] = class[i]; + + reg_dmn_curr_supp_opp_classes.num_classes = num_classes; + + return 0; +} + +/** + * reg_dmn_get_curr_opclasses() - get the current operating class + * @num_classes: number of classes + * @class: operating class + * + * Return: error code + */ +uint16_t reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class) +{ + uint8_t i; + + if (!num_classes || !class) { + reg_err("either num_classes or class is null"); + return 0; + } + + for (i = 0; i < reg_dmn_curr_supp_opp_classes.num_classes; i++) + class[i] = reg_dmn_curr_supp_opp_classes.classes[i]; + + *num_classes = reg_dmn_curr_supp_opp_classes.num_classes; + + return 0; +} + + + static void reg_fill_channel_info(enum channel_enum chan_enum, struct cur_reg_rule *reg_rule, struct regulatory_channel *master_list, @@ -718,13 +1201,15 @@ QDF_STATUS reg_process_master_chan_list(struct cur_regulatory_info uint32_t num_2g_reg_rules, num_5g_reg_rules; struct cur_reg_rule *reg_rule_2g, *reg_rule_5g; uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g; - struct regulatory_channel *mas_chan_list, *cur_chan_list; + struct regulatory_channel *mas_chan_list; reg_debug("process reg master chan list"); + wlan_psoc_obj_lock(regulat_info->psoc); soc_reg = (struct wlan_regulatory_psoc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(regulat_info->psoc, WLAN_UMAC_COMP_REGULATORY); + wlan_psoc_obj_unlock(regulat_info->psoc); if (NULL == soc_reg) { reg_err("soc_reg is NULL"); @@ -740,8 +1225,7 @@ QDF_STATUS reg_process_master_chan_list(struct cur_regulatory_info qdf_mem_copy(soc_reg->current_country, regulat_info->alpha2, REG_ALPHA2_LEN); - mas_chan_list = soc_reg->master_ch_list; - cur_chan_list = soc_reg->current_ch_list; + mas_chan_list = soc_reg->mas_chan_list; min_bw_2g = regulat_info->min_bw_2g; max_bw_2g = regulat_info->max_bw_2g; @@ -768,9 +1252,6 @@ QDF_STATUS reg_process_master_chan_list(struct cur_regulatory_info num_5g_reg_rules, min_bw_5g, mas_chan_list); - qdf_mem_copy((void *)cur_chan_list, (void *)mas_chan_list, - NUM_CHANNELS * sizeof(struct regulatory_channel)); - return QDF_STATUS_SUCCESS; } @@ -807,7 +1288,7 @@ QDF_STATUS wlan_regulatory_psoc_obj_created_notification( soc_reg_obj->indoor_chan_enabled = true; - mas_chan_list = soc_reg_obj->master_ch_list; + mas_chan_list = soc_reg_obj->mas_chan_list; for (chan_enum = CHAN_ENUM_1; chan_enum <= CHAN_ENUM_196; chan_enum++) { @@ -844,9 +1325,12 @@ QDF_STATUS wlan_regulatory_psoc_obj_destroyed_notification( struct wlan_objmgr_psoc *psoc, void *arg_list) { QDF_STATUS status; - struct wlan_regulatory_psoc_priv_obj *soc_reg = - wlan_objmgr_psoc_get_comp_private_obj(psoc, - WLAN_UMAC_COMP_REGULATORY); + struct wlan_regulatory_psoc_priv_obj *soc_reg; + + wlan_psoc_obj_lock(psoc); + soc_reg = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_REGULATORY); + wlan_psoc_obj_unlock(psoc); if (NULL == soc_reg) { reg_err("reg psoc private obj is NULL"); @@ -1037,9 +1521,11 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification( parent_psoc = wlan_pdev_get_psoc(pdev); pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + wlan_psoc_obj_lock(parent_psoc); psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(parent_psoc, WLAN_UMAC_COMP_REGULATORY); + wlan_psoc_obj_unlock(parent_psoc); if (NULL == psoc_priv_obj) { reg_err("reg psoc private obj is NULL"); @@ -1054,7 +1540,7 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification( psoc_priv_obj->indoor_chan_enabled; qdf_mem_copy(pdev_priv_obj->cur_chan_list, - psoc_priv_obj->master_ch_list, + psoc_priv_obj->mas_chan_list, NUM_CHANNELS * sizeof(struct regulatory_channel)); modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list, @@ -1107,8 +1593,10 @@ QDF_STATUS wlan_regulatory_pdev_obj_destroyed_notification( QDF_STATUS status; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + wlan_pdev_obj_lock(pdev); pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_REGULATORY); + wlan_pdev_obj_unlock(pdev); if (NULL == pdev_priv_obj) { reg_err("reg pdev private obj is NULL"); @@ -1136,8 +1624,10 @@ QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev, { struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + wlan_pdev_obj_lock(pdev); pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_REGULATORY); + wlan_pdev_obj_unlock(pdev); if (NULL == pdev_priv_obj) { reg_err("reg pdev private obj is NULL"); diff --git a/umac/regulatory/core/src/reg_services.h b/umac/regulatory/core/src/reg_services.h index 3886cdbda80e..cd3722b47d1a 100644 --- a/umac/regulatory/core/src/reg_services.h +++ b/umac/regulatory/core/src/reg_services.h @@ -35,6 +35,36 @@ #include "reg_db.h" #include +#define REG_MAX_CHANNELS_PER_OPERATING_CLASS 25 +#define REG_MAX_SUPP_OPER_CLASSES 32 + +#define REG_MIN_24GHZ_CH_NUM channel_map[MIN_24GHZ_CHANNEL].chan_num +#define REG_MAX_24GHZ_CH_NUM channel_map[MAX_24GHZ_CHANNEL].chan_num +#define REG_MIN_5GHZ_CH_NUM channel_map[MIN_5GHZ_CHANNEL].chan_num +#define REG_MAX_5GHZ_CH_NUM channel_map[MAX_5GHZ_CHANNEL].chan_num + +#define REG_IS_5GHZ_CH(chan_num) \ + ((chan_num >= REG_MIN_5GHZ_CH_NUM) && \ + (chan_num <= REG_MAX_5GHZ_CH_NUM)) + +#define REG_IS_24GHZ_CH(chan_num) \ + ((chan_num >= REG_MIN_24GHZ_CH_NUM) && \ + (chan_num <= REG_MAX_24GHZ_CH_NUM)) + +#define REG_CH_NUM(ch_enum) channel_map[ch_enum].chan_num +#define REG_CH_TO_FREQ(ch_enum) channel_map[ch_enum].center_freq + +#define REG_SBS_SEPARATION_THRESHOLD 100 + +#define REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ + (curchan > newchan ? \ + REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \ + - REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \ + > REG_SBS_SEPARATION_THRESHOLD : \ + REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \ + - REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \ + > REG_SBS_SEPARATION_THRESHOLD) + /** * enum channel_state - channel state * @CHANNEL_STATE_DISABLE: disabled state @@ -51,15 +81,6 @@ enum channel_state { CHANNEL_STATE_INVALID, }; -typedef enum { - REGDOMAIN_FCC, - REGDOMAIN_ETSI, - REGDOMAIN_JAPAN, - REGDOMAIN_WORLD, - REGDOMAIN_COUNT -} v_REGDOMAIN_t; - - /** * enum phy_ch_width - channel width * @CH_WIDTH_20MHZ: 20 mhz width @@ -91,7 +112,7 @@ enum phy_ch_width { * @center_freq_seg0: center freq for segment 0 * @center_freq_seg1: center freq for segment 1 */ -struct ch_params_s { +struct ch_params { enum phy_ch_width ch_width; uint8_t sec_ch_offset; uint8_t center_freq_seg0; @@ -126,6 +147,79 @@ struct channel_power { uint32_t tx_power; }; +/** + * enum offset_t: channel offset + * @BW20: 20 mhz channel + * @BW40_LOW_PRIMARY: lower channel in 40 mhz + * @BW40_HIGH_PRIMARY: higher channel in 40 mhz + * @BW80: 80 mhz channel + * @BWALL: unknown bandwidth + */ +enum offset_t { + BW20 = 0, + BW40_LOW_PRIMARY = 1, + BW40_HIGH_PRIMARY = 3, + BW80, + BWALL +}; + +/** + * struct reg_dmn_op_class_map_t: operating class + * @op_class: operating class number + * @ch_spacing: channel spacing + * @offset: offset + * @channels: channel set + */ +struct reg_dmn_op_class_map_t { + uint8_t op_class; + uint8_t ch_spacing; + enum offset_t offset; + uint8_t channels[REG_MAX_CHANNELS_PER_OPERATING_CLASS]; +}; + +/** + * struct reg_dmn_supp_op_classes: operating classes + * @num_classes: number of classes + * @classes: classes + */ +struct reg_dmn_supp_op_classes { + uint8_t num_classes; + uint8_t classes[REG_MAX_SUPP_OPER_CLASSES]; +}; + +/** + * enum reg_domain: reg domain + * @REGDOMAIN_FCC: FCC domain + * @REGDOMAIN_ETSI: ETSI domain + * @REGDOMAIN_JAPAN: JAPAN domain + * @REGDOMAIN_WORLD: WORLD domain + * @REGDOMAIN_COUNT: Max domain + */ +typedef enum { + REGDOMAIN_FCC, + REGDOMAIN_ETSI, + REGDOMAIN_JAPAN, + REGDOMAIN_WORLD, + REGDOMAIN_COUNT +} v_REGDOMAIN_t; + +/** + * enum country_src: country source + * @SOURCE_QUERY: source query + * @SOURCE_CORE: source regulatory core + * @SOURCE_DRIVER: source driver + * @SOURCE_USERSPACE: source userspace + * @SOURCE_11D: source 11D + */ +enum country_src { + SOURCE_UNKNOWN, + SOURCE_QUERY, + SOURCE_CORE, + SOURCE_DRIVER, + SOURCE_USERSPACE, + SOURCE_11D +}; + /** * enum channel_enum - channel enumeration * @CHAN_ENUM_1: channel number 1 @@ -245,23 +339,6 @@ enum channel_enum { INVALID_CHANNEL = 0xBAD, }; -/** - * enum country_src: country source - * @SOURCE_QUERY: source query - * @SOURCE_CORE: source regulatory core - * @SOURCE_DRIVER: source driver - * @SOURCE_USERSPACE: source userspace - * @SOURCE_11D: source 11D - */ -enum country_src { - SOURCE_UNKNOWN, - SOURCE_QUERY, - SOURCE_CORE, - SOURCE_DRIVER, - SOURCE_USERSPACE, - SOURCE_11D -}; - /** * struct regulatory: regulatory information * @reg_domain: regulatory domain pair @@ -288,7 +365,6 @@ struct regulatory { uint32_t reg_flags; }; - /** * struct chan_map * @start_ch: center frequency @@ -321,33 +397,74 @@ enum ht_sec_ch_offset { HIGH_PRIMARY_CH = 3, }; - extern const struct chan_map channel_map[NUM_CHANNELS]; -QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc, +enum channel_enum reg_get_chan_enum(uint32_t chan_num); + +QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, struct channel_power *ch_list, uint8_t *num_chan); -void reg_read_default_country(struct wlan_objmgr_psoc *psoc, - uint8_t *country); -enum channel_state reg_get_channel_state(struct wlan_objmgr_psoc *psoc, +QDF_STATUS reg_read_default_country(struct wlan_objmgr_psoc *psoc, + uint8_t *country); + +enum channel_state reg_get_channel_state(struct wlan_objmgr_pdev *pdev, uint32_t ch); -enum channel_state reg_get_5g_bonded_channel_state(struct wlan_objmgr_psoc - *psoc, + +enum channel_state reg_get_5g_bonded_channel_state(struct wlan_objmgr_pdev + *pdev, uint8_t ch, enum phy_ch_width bw); -enum channel_state reg_get_2g_bonded_channel_state(struct wlan_objmgr_psoc - *psoc, + +enum channel_state reg_get_2g_bonded_channel_state(struct wlan_objmgr_pdev + *pdev, uint8_t oper_ch, uint8_t sec_ch, enum phy_ch_width bw); -void reg_set_channel_params(struct wlan_objmgr_psoc *psoc, - uint8_t ch, struct ch_params_s *ch_params); +void reg_set_channel_params(struct wlan_objmgr_pdev *pdev, + uint8_t ch, uint8_t sec_ch_2g, + struct ch_params *ch_params); + void reg_get_dfs_region(struct wlan_objmgr_psoc *psoc, enum dfs_reg *dfs_reg); -bool reg_is_dfs_ch(struct wlan_objmgr_psoc *psoc, uint8_t ch); +bool reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint8_t ch); + +uint32_t reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, + uint32_t chan_num); + +uint32_t reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, + uint32_t chan_num); + +QDF_STATUS reg_read_default_country(struct wlan_objmgr_psoc *psoc, + uint8_t *country); + +void reg_set_default_country(struct wlan_objmgr_psoc *psoc, uint8_t *country); + +uint16_t reg_get_bw_value(enum phy_ch_width bw); + +void reg_set_dfs_region(struct wlan_objmgr_psoc *psoc, + enum dfs_reg dfs_reg); + +QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, + const uint8_t *country_alpha2, + enum country_src source); + +enum band_info reg_chan_to_band(uint32_t chan_num); + +uint16_t reg_dmn_get_chanwidth_from_opclass(uint8_t *country, + uint8_t channel, + uint8_t opclass); + +uint16_t reg_dmn_get_opclass_from_channel(uint8_t *country, + uint8_t channel, + uint8_t offset); + +uint16_t reg_dmn_set_curr_opclasses(uint8_t num_classes, uint8_t *class); + +uint16_t reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class); + QDF_STATUS reg_process_master_chan_list(struct cur_regulatory_info *reg_info); diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index 5fcf2bed2b4e..be4e55610dc9 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -29,6 +29,36 @@ #include "../../core/src/reg_services.h" #include +#define WLAN_REG_MIN_24GHZ_CH_NUM REG_MIN_24GHZ_CH_NUM +#define WLAN_REG_MAX_24GHZ_CH_NUM REG_MAX_24GHZ_CH_NUM +#define WLAN_REG_MIN_5GHZ_CH_NUM REG_MIN_5GHZ_CH_NUM +#define WLAN_REG_MAX_5GHZ_CH_NUM REG_MAX_5GHZ_CH_NUM + +#define WLAN_REG_IS_24GHZ_CH(ch) REG_IS_24GHZ_CH(ch) +#define WLAN_REG_IS_5GHZ_CH(ch) REG_IS_5GHZ_CH(ch) + +#define WLAN_REG_CH_NUM(ch_enum) REG_CH_NUM(ch_enum) +#define WLAN_REG_CH_TO_FREQ(ch_enum) REG_CH_TO_FREQ(ch_enum) + +#define WLAN_REG_IS_SAME_BAND_CHANNELS(chan_num1, chan_num2) \ + (chan_num1 && chan_num2 && \ + (WLAN_REG_IS_5GHZ_CH(chan_num1) == WLAN_REG_IS_5GHZ_CH(chan_num2))) + + +#define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ + (curchan > newchan ? \ + REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \ + - REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \ + > REG_SBS_SEPARATION_THRESHOLD : \ + REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \ + - REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \ + > REG_SBS_SEPARATION_THRESHOLD) + +#define WLAN_REG_INVALID_CHANNEL_ID +#define WLAN_REG_GET_24_END_CHAN_NUM 14 + +#define WLAN_REG_CHAN_TO_BAND(chan_num) reg_chan_to_band(chan_num) + /** * wlan_reg_get_channel_list_with_power() - Provide the channel list with power @@ -36,7 +66,7 @@ * * Return: QDF_STATUS */ -QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc, +QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, struct channel_power *ch_list, uint8_t *num_chan); @@ -44,9 +74,9 @@ QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc, * wlan_reg_read_default_country() - Read the default country for the regdomain * @country: pointer to the country code. * - * Return: None + * Return: QDF_STATUS */ -void wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc, +QDF_STATUS wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc, uint8_t *country); /** @@ -55,7 +85,7 @@ void wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc, * * Return: channel state */ -enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_psoc *psoc, +enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_pdev *pdev, uint32_t ch); /** @@ -65,9 +95,10 @@ enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_psoc *psoc, * * Return: channel state */ -enum channel_state wlan_reg_get_5g_bonded_channel_state( - struct wlan_objmgr_psoc *psoc, uint8_t ch, - enum phy_ch_width bw); +enum channel_state wlan_reg_get_5g_bonded_channel_state(struct wlan_objmgr_pdev + *pdev, + uint8_t ch, + enum phy_ch_width bw); /** * wlan_reg_get_2g_bonded_channel_state() - Get 2G bonded channel state @@ -77,8 +108,10 @@ enum channel_state wlan_reg_get_5g_bonded_channel_state( * Return: channel state */ enum channel_state wlan_reg_get_2g_bonded_channel_state( - struct wlan_objmgr_psoc *psoc, uint8_t ch, uint8_t sec_ch, - enum phy_ch_width bw); + struct wlan_objmgr_pdev + *pdev, uint8_t ch, + uint8_t sec_ch, + enum phy_ch_width bw); /** * wlan_reg_set_channel_params () - Sets channel parameteres for given bandwidth @@ -87,8 +120,9 @@ enum channel_state wlan_reg_get_2g_bonded_channel_state( * * Return: None */ -void wlan_reg_set_channel_params(struct wlan_objmgr_psoc *psoc, uint8_t ch, - struct ch_params_s *ch_params); +void wlan_reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch, + uint8_t sec_ch_2g, + struct ch_params *ch_params); /** * wlan_reg_get_dfs_region () - Get the current dfs region @@ -97,7 +131,7 @@ void wlan_reg_set_channel_params(struct wlan_objmgr_psoc *psoc, uint8_t ch, * Return: None */ void wlan_reg_get_dfs_region(struct wlan_objmgr_psoc *psoc, - enum dfs_reg *dfs_reg); + enum dfs_reg *dfs_reg); /** * wlan_reg_is_dfs_ch () - Checks the channel state for DFS @@ -105,7 +139,123 @@ void wlan_reg_get_dfs_region(struct wlan_objmgr_psoc *psoc, * * Return: true or false */ -bool wlan_reg_is_dfs_ch(struct wlan_objmgr_psoc *psoc, uint8_t ch); +bool wlan_reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint8_t ch); + +/** + * wlan_reg_get_channel_reg_power() - Provide the channel regulatory power + * @chan_num: chennal number + * + * Return: int + */ +uint32_t wlan_reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, + uint32_t chan_num); + +/** + * wlan_reg_get_channel_freq() - provide the channel center freq + * @chan_num: chennal number + * + * Return: int + */ +uint32_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, + uint32_t chan_num); + +/** + * wlan_reg_get_bonded_channel_state() - get bonded channel state + * @pdev: pdev ptr + * @ch: chennal number + * @bw: chennal number + * @sec_ch: secondary channel + * + * Return: enum channel_state + */ +enum channel_state wlan_reg_get_bonded_channel_state( + struct wlan_objmgr_pdev *pdev, uint8_t ch, + enum phy_ch_width bw, uint8_t sec_ch); + +/** + * wlan_reg_set_default_country() - set default country + * @psoc: psoc ptr + * @country: country alpha2 + * + * Return: void + */ +void wlan_reg_set_default_country(struct wlan_objmgr_psoc *psoc, + uint8_t *country); + +/** + * wlan_reg_set_dfs_region() - set the dfs region + * @psoc: psoc ptr + * @dfs_reg: dfs region + * + * Return: void + */ +void wlan_reg_set_dfs_region(struct wlan_objmgr_psoc *psoc, + enum dfs_reg dfs_reg); + +/** + * wlan_reg_get_bw_value() - provide the channel center freq + * @chan_num: chennal number + * + * Return: int + */ +uint16_t wlan_reg_get_bw_value(enum phy_ch_width bw); + +/** + * wlan_reg_get_domain_from_country_code() - provide the channel center freq + * @reg_domain_ptr: regulatory domain ptr + * @country_alpha2: country alpha2 + * @source: alpha2 source + * + * Return: int + */ +QDF_STATUS wlan_reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, + const uint8_t *country_alpha2, + enum country_src source); + +/** + * wlan_reg_dmn_get_opclass_from_channel() - provide the channel center freq + * @country: country alpha2 + * @channel: channel number + * @offset: offset + * + * Return: int + */ +uint16_t wlan_reg_dmn_get_opclass_from_channel(uint8_t *country, + uint8_t channel, + uint8_t offset); + +/** + * wlan_reg_dmn_get_chanwidth_from_opclass() - get channel width from + * operating class + * @country: country alpha2 + * @channel: channel number + * @opclass: operating class + * + * Return: int + */ +uint16_t wlan_reg_dmn_get_chanwidth_from_opclass(uint8_t *country, + uint8_t channel, + uint8_t opclass); +/** + * wlan_reg_dmn_set_curr_opclasses() - set operating class + * @num_classes: number of classes + * @class: operating class + * + * Return: int + */ +uint16_t wlan_reg_dmn_set_curr_opclasses(uint8_t num_classes, + uint8_t *class); + +/** + * wlan_reg_dmn_get_curr_opclasses() - get current oper classes + * @num_classes: number of classes + * @class: operating class + * + * Return: int + */ +uint16_t wlan_reg_dmn_get_curr_opclasses(uint8_t *num_classes, + uint8_t *class); + /** * wlan_regulatory_init() - init regulatory component diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 716bc1b1b5b4..180a77f65cbd 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -35,14 +35,14 @@ * * Return: QDF_STATUS */ -QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc, +QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev, struct channel_power *ch_list, uint8_t *num_chan) { /* * Update the channel list with channel information with power. */ - return reg_get_channel_list_with_power(psoc, ch_list, num_chan); + return reg_get_channel_list_with_power(pdev, ch_list, num_chan); } /** @@ -51,13 +51,13 @@ QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc, * * Return: None */ -void wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc, - uint8_t *country) +QDF_STATUS wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc, + uint8_t *country) { /* * Get the default country information */ - reg_read_default_country(psoc, country); + return reg_read_default_country(psoc, country); } /** @@ -66,13 +66,13 @@ void wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc, * * Return: channel state */ -enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_psoc *psoc, - uint32_t ch) +enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_pdev *pdev, + uint32_t ch) { /* * Get channel state from regulatory */ - return reg_get_channel_state(psoc, ch); + return reg_get_channel_state(pdev, ch); } /** @@ -83,13 +83,13 @@ enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_psoc *psoc, * Return: channel state */ enum channel_state wlan_reg_get_5g_bonded_channel_state( - struct wlan_objmgr_psoc *psoc, uint8_t ch, - enum phy_ch_width bw) + struct wlan_objmgr_pdev *pdev, uint8_t ch, + enum phy_ch_width bw) { /* * Get channel state from regulatory */ - return reg_get_5g_bonded_channel_state(psoc, ch, bw); + return reg_get_5g_bonded_channel_state(pdev, ch, bw); } /** @@ -100,13 +100,13 @@ enum channel_state wlan_reg_get_5g_bonded_channel_state( * Return: channel state */ enum channel_state wlan_reg_get_2g_bonded_channel_state( - struct wlan_objmgr_psoc *psoc, uint8_t ch, uint8_t sec_ch, - enum phy_ch_width bw) + struct wlan_objmgr_pdev *pdev, uint8_t ch, + uint8_t sec_ch, enum phy_ch_width bw) { /* * Get channel state from regulatory */ - return reg_get_2g_bonded_channel_state(psoc, ch, sec_ch, bw); + return reg_get_2g_bonded_channel_state(pdev, ch, sec_ch, bw); } /** @@ -116,14 +116,15 @@ enum channel_state wlan_reg_get_2g_bonded_channel_state( * * Return: None */ -void wlan_reg_set_channel_params(struct wlan_objmgr_psoc *psoc, uint8_t ch, - struct ch_params_s *ch_params) +void wlan_reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch, + uint8_t sec_ch_2g, + struct ch_params *ch_params) { /* * Set channel parameters like center frequency for a bonded channel * state. Also return the maximum bandwidth supported by the channel. */ - reg_set_channel_params(psoc, ch, ch_params); + reg_set_channel_params(pdev, ch, sec_ch_2g, ch_params); } /** @@ -133,7 +134,7 @@ void wlan_reg_set_channel_params(struct wlan_objmgr_psoc *psoc, uint8_t ch, * Return: None */ void wlan_reg_get_dfs_region(struct wlan_objmgr_psoc *psoc, - enum dfs_reg *dfs_reg) + enum dfs_reg *dfs_reg) { /* * Get the current dfs region @@ -147,12 +148,133 @@ void wlan_reg_get_dfs_region(struct wlan_objmgr_psoc *psoc, * * Return: true or false */ -bool wlan_reg_is_dfs_ch(struct wlan_objmgr_psoc *psoc, uint8_t ch) +bool wlan_reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint8_t ch) { /* * Get the current dfs region */ - return reg_is_dfs_ch(psoc, ch); + return reg_is_dfs_ch(pdev, ch); +} + + /** + * wlan_reg_get_channel_reg_power() - get regulatory power for channel + * @chan_num: channel number + * + * Return: int + */ +uint32_t wlan_reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev, + uint32_t chan_num) +{ + return reg_get_channel_reg_power(pdev, chan_num); +} + +/** + * wlan_reg_get_channel_freq() - get regulatory power for channel + * @chan_num: channel number + * + * Return: int + */ +uint32_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev, + uint32_t chan_num) +{ + return reg_get_channel_freq(pdev, chan_num); +} + +/** + * wlan_reg_get_bw_value() - give bandwidth value + * bw: bandwidth enum + * + * Return: uint16_t + */ +uint16_t wlan_reg_get_bw_value(enum phy_ch_width bw) +{ + return reg_get_bw_value(bw); +} + +/** + * wlan_reg_set_default_country() - Set the default country for the regdomain + * @country: pointer to the country code. + * + * Return: None + */ +void wlan_reg_set_default_country(struct wlan_objmgr_psoc *psoc, + uint8_t *country) +{ + reg_set_default_country(psoc, country); +} + +/** + * wlan_reg_get_bonded_channel_state() - Get 2G bonded channel state + * @ch: channel number. + * @bw: channel band width + * + * Return: channel state + */ +enum channel_state wlan_reg_get_bonded_channel_state( + struct wlan_objmgr_pdev *pdev, uint8_t ch, + enum phy_ch_width bw, uint8_t sec_ch) +{ + if (WLAN_REG_IS_24GHZ_CH(ch)) + return reg_get_2g_bonded_channel_state(pdev, ch, + sec_ch, bw); + else + return reg_get_5g_bonded_channel_state(pdev, ch, + bw); +} + +/** + * wlan_reg_set_dfs_region () - Get the current dfs region + * @dfs_reg: pointer to dfs region + * + * Return: None + */ +void wlan_reg_set_dfs_region(struct wlan_objmgr_psoc *psoc, + enum dfs_reg dfs_reg) +{ + reg_set_dfs_region(psoc, dfs_reg); +} + +/** + * wlan_reg_get_domain_from_country_code() - get the regulatory domain + * @reg_domain_ptr: ptr to store regulatory domain + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, + const uint8_t *country_alpha2, enum country_src source) +{ + + return reg_get_domain_from_country_code(reg_domain_ptr, + country_alpha2, source); +} + + +uint16_t wlan_reg_dmn_get_opclass_from_channel(uint8_t *country, + uint8_t channel, + uint8_t offset) +{ + return reg_dmn_get_opclass_from_channel(country, channel, + offset); +} + +uint16_t wlan_reg_dmn_get_chanwidth_from_opclass(uint8_t *country, + uint8_t channel, + uint8_t opclass) +{ + return reg_dmn_get_chanwidth_from_opclass(country, channel, + opclass); +} + +uint16_t wlan_reg_dmn_set_curr_opclasses(uint8_t num_classes, + uint8_t *class) +{ + return reg_dmn_set_curr_opclasses(num_classes, class); +} + +uint16_t wlan_reg_dmn_get_curr_opclasses(uint8_t *num_classes, + uint8_t *class) +{ + return reg_dmn_get_curr_opclasses(num_classes, class); } /**