diff --git a/components/tdls/core/src/wlan_tdls_ct.c b/components/tdls/core/src/wlan_tdls_ct.c index a0200b7e0cf5..ead717945e24 100644 --- a/components/tdls/core/src/wlan_tdls_ct.c +++ b/components/tdls/core/src/wlan_tdls_ct.c @@ -973,7 +973,7 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, tdls_soc->tdls_channel_offset = BW20; break; case TDLS_SEC_OFFCHAN_OFFSET_40PLUS: - tdls_soc->tdls_channel_offset = BW40_LOW_PRIMARY; + tdls_soc->tdls_channel_offset = BW40_HIGH_PRIMARY; break; case TDLS_SEC_OFFCHAN_OFFSET_40MINUS: tdls_soc->tdls_channel_offset = BW40_LOW_PRIMARY; @@ -1054,6 +1054,23 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, tdls_find_opclass(tdls_soc->soc, chan_switch_params.tdls_off_ch, chan_switch_params.tdls_off_ch_bw_offset); + if (!chan_switch_params.oper_class) { + if (chan_switch_params.tdls_off_ch_bw_offset == + BW40_HIGH_PRIMARY) + chan_switch_params.oper_class = + tdls_find_opclass(tdls_soc->soc, + chan_switch_params.tdls_off_ch, + BW40_LOW_PRIMARY); + else if (chan_switch_params. + tdls_off_ch_bw_offset == + BW40_LOW_PRIMARY) + chan_switch_params.oper_class = + tdls_find_opclass(tdls_soc->soc, + chan_switch_params.tdls_off_ch, + BW40_HIGH_PRIMARY); + tdls_debug("oper_class:%d", + chan_switch_params.oper_class); + } } else { tdls_err("TDLS off-channel parameters are not set yet!!!"); return -EINVAL; diff --git a/components/tdls/core/src/wlan_tdls_main.c b/components/tdls/core/src/wlan_tdls_main.c index aac38365e11c..780563d73320 100644 --- a/components/tdls/core/src/wlan_tdls_main.c +++ b/components/tdls/core/src/wlan_tdls_main.c @@ -1803,3 +1803,28 @@ void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, } +uint8_t tdls_get_opclass_from_bandwidth(struct tdls_soc_priv_obj *soc_obj, + uint8_t channel, uint8_t bw_offset) +{ + uint8_t opclass; + + if (bw_offset & (1 << BW_80_OFFSET_BIT)) { + opclass = tdls_find_opclass(soc_obj->soc, + channel, BW80); + } else if (bw_offset & (1 << BW_40_OFFSET_BIT)) { + opclass = tdls_find_opclass(soc_obj->soc, + channel, BW40_LOW_PRIMARY); + if (!opclass) { + opclass = tdls_find_opclass(soc_obj->soc, + channel, BW40_HIGH_PRIMARY); + } + } else if (bw_offset & (1 << BW_20_OFFSET_BIT)) { + opclass = tdls_find_opclass(soc_obj->soc, + channel, BW20); + } else { + opclass = tdls_find_opclass(soc_obj->soc, + channel, BWALL); + } + + return opclass; +} diff --git a/components/tdls/core/src/wlan_tdls_main.h b/components/tdls/core/src/wlan_tdls_main.h index 057857bb1369..6372d8db8d9d 100644 --- a/components/tdls/core/src/wlan_tdls_main.h +++ b/components/tdls/core/src/wlan_tdls_main.h @@ -743,4 +743,18 @@ QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); + +/** + * tdls_get_opclass_from_bandwidth() - Return opclass for corresponding BW and + * channel. + * @soc_obj: tdls soc object. + * @channel: Channel number. + * @bw_offset: Bandwidth offset. + * + * To return the opclas. + * + * Return: opclass + */ +uint8_t tdls_get_opclass_from_bandwidth(struct tdls_soc_priv_obj *soc_obj, + uint8_t channel, uint8_t bw_offset); #endif diff --git a/components/tdls/core/src/wlan_tdls_peer.c b/components/tdls/core/src/wlan_tdls_peer.c index 6ba81500b547..1d5051de61e9 100644 --- a/components/tdls/core/src/wlan_tdls_peer.c +++ b/components/tdls/core/src/wlan_tdls_peer.c @@ -26,6 +26,7 @@ #include #include #include +#include "wlan_reg_ucfg_api.h" static uint8_t calculate_hash_key(const uint8_t *macaddr) { @@ -144,35 +145,6 @@ uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel, bw_offset); } -static uint8_t -tdls_get_opclass_from_bandwidth(struct tdls_soc_priv_obj *soc_obj, - struct tdls_peer *peer) -{ - uint8_t opclass; - uint8_t bw_offset = soc_obj->tdls_configs.tdls_pre_off_chan_bw; - uint8_t channel = peer->pref_off_chan_num; - - if (bw_offset & (1 << BW_80_OFFSET_BIT)) { - opclass = tdls_find_opclass(soc_obj->soc, - channel, BW80); - } else if (bw_offset & (1 << BW_40_OFFSET_BIT)) { - opclass = tdls_find_opclass(soc_obj->soc, - channel, BW40_LOW_PRIMARY); - if (!opclass) { - opclass = tdls_find_opclass(soc_obj->soc, - channel, BW40_HIGH_PRIMARY); - } - } else if (bw_offset & (1 << BW_20_OFFSET_BIT)) { - opclass = tdls_find_opclass(soc_obj->soc, - channel, BW20); - } else { - opclass = tdls_find_opclass(soc_obj->soc, - channel, BWALL); - } - - return opclass; -} - /** * tdls_add_peer() - add TDLS peer in TDLS vdev object * @vdev_obj: TDLS vdev object @@ -211,7 +183,9 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj, peer->pref_off_chan_num = soc_obj->tdls_configs.tdls_pre_off_chan_num; peer->op_class_for_pref_off_chan = - tdls_get_opclass_from_bandwidth(soc_obj, peer); + tdls_get_opclass_from_bandwidth(soc_obj, + peer->pref_off_chan_num, + soc_obj->tdls_configs.tdls_pre_off_chan_bw); peer->sta_id = INVALID_TDLS_PEER_ID; @@ -498,6 +472,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, enum channel_state ch_state; struct wlan_objmgr_pdev *pdev; uint8_t chan_id; + enum band_info cur_band = BAND_ALL; vdev_obj = peer->vdev_priv; soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); @@ -527,6 +502,16 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, peer_param->peer_cap.opclass_for_prefoffchan = peer->op_class_for_pref_off_chan; + if (QDF_STATUS_SUCCESS != ucfg_reg_get_band(pdev, &cur_band)) { + tdls_err("not able get the current frequency band"); + return; + } + + if (BAND_2G == cur_band) { + tdls_err("sending the offchannel value as 0 as only 2g is supported"); + peer_param->peer_cap.pref_off_channum = 0; + peer_param->peer_cap.opclass_for_prefoffchan = 0; + } if (wlan_reg_is_dfs_ch(pdev, peer_param->peer_cap.pref_off_channum)) { tdls_err("Resetting TDLS off-channel from %d to %d", peer_param->peer_cap.pref_off_channum, @@ -778,7 +763,9 @@ QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj, config = &soc_obj->tdls_configs; curr_peer->pref_off_chan_num = config->tdls_pre_off_chan_num; curr_peer->op_class_for_pref_off_chan = - tdls_get_opclass_from_bandwidth(soc_obj, curr_peer); + tdls_get_opclass_from_bandwidth(soc_obj, + curr_peer->pref_off_chan_num, + soc_obj->tdls_configs.tdls_pre_off_chan_bw); } tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE,