diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index f77605e9759c..c4762ba8eb34 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1184,6 +1184,7 @@ struct hdd_context_s { struct mutex tdls_lock; uint8_t tdls_off_channel; uint16_t tdls_channel_offset; + int32_t tdls_fw_off_chan_mode; #endif #ifdef IPA_OFFLOAD @@ -1559,4 +1560,7 @@ void wlan_hdd_display_netif_queue_history(hdd_context_t *hdd_ctx); void wlan_hdd_clear_netif_queue_history(hdd_context_t *hdd_ctx); const char *hdd_get_fwpath(void); +uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel, + uint8_t bw_offset); + #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index 285bb7856769..33557fc20901 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -228,6 +228,8 @@ typedef enum { } tdls_state_t; typedef int (*cfg80211_exttdls_callback)(const uint8_t *mac, + uint32_t opclass, + uint32_t channel, uint32_t state, int32_t reason, void *ctx); @@ -531,10 +533,11 @@ int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter, uint32_t op_class, uint32_t min_bandwidth); int wlan_hdd_tdls_get_status(hdd_adapter_t *pAdapter, - const uint8_t *mac, int32_t *state, + const uint8_t *mac, uint32_t *opclass, + uint32_t *channel, uint32_t *state, int32_t *reason); void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, - int32_t *state, int32_t *reason); + uint32_t *state, int32_t *reason); int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer, cfg80211_exttdls_callback callback); void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 88131479cd58..645f0e64fd72 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -86,6 +86,7 @@ #ifdef CONFIG_CNSS #include #endif +#include "cds_regdomain.h" #include "wlan_hdd_ocb.h" @@ -359,6 +360,24 @@ static int con_mode; static int curr_con_mode; #endif +/* wlan_hdd_find_opclass() - Find operating class for a channel + * @hal: handler to HAL + * @channel: channel id + * @bw_offset: bandwidth offset + * + * Function invokes sme api to find the operating class + * + * Return: operating class + */ +uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel, + uint8_t bw_offset) +{ + uint8_t opclass = 0; + + sme_get_opclass(hal, channel, bw_offset, &opclass); + return opclass; +} + /** * hdd_cdf_trace_enable() - configure initial CDF Trace enable * @moduleId: Module whose trace level is being configured diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 19da47f69030..aa0e442bdd5d 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -51,6 +51,40 @@ static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx); int wpa_tdls_is_allowed_force_peer(tdlsCtx_t *pHddTdlsCtx, u8 *mac); static void wlan_hdd_tdls_pre_setup(struct work_struct *work); +/* + * wlan_hdd_tdls_determine_channel_opclass() - determine channel and opclass + * @hddctx: pointer to hdd context + * @adapter: pointer to adapter + * @curr_peer: pointer to current tdls peer + * @channel: pointer to channel + * @opclass: pointer to opclass + * + * Function determines the channel and operating class + * + * Return: None + */ +static void wlan_hdd_tdls_determine_channel_opclass(hdd_context_t *hddctx, + hdd_adapter_t *adapter, hddTdlsPeer_t *curr_peer, + uint32_t *channel, uint32_t *opclass) +{ + hdd_station_ctx_t *hdd_sta_ctx; + + /* + * If tdls offchannel is not enabled then we provide base channel + * and in that case pass opclass as 0 since opclass is mainly needed + * for offchannel cases. + */ + if (!(hddctx->config->fEnableTDLSOffChannel) || + (hddctx->tdls_fw_off_chan_mode != ENABLE_CHANSWITCH)) { + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + *channel = hdd_sta_ctx->conn_info.operationChannel; + *opclass = 0; + } else { + *channel = curr_peer->pref_off_chan_num; + *opclass = curr_peer->op_class_for_pref_off_chan; + } +} + /** * wlan_hdd_tdls_hash_key() - calculate tdls hash key given mac address * @mac: mac address @@ -648,8 +682,12 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) pHddTdlsCtx->threshold_config.rssi_teardown_threshold; tInfo->rssi_delta = pHddTdlsCtx->threshold_config.rssi_delta; tInfo->tdls_options = 0; - if (pHddCtx->config->fEnableTDLSOffChannel) + + if (pHddCtx->config->fEnableTDLSOffChannel) { tInfo->tdls_options |= ENA_TDLS_OFFCHAN; + pHddCtx->tdls_fw_off_chan_mode = ENABLE_CHANSWITCH; + } + if (pHddCtx->config->fEnableTDLSBufferSta) tInfo->tdls_options |= ENA_TDLS_BUFFER_STA; if (pHddCtx->config->fEnableTDLSSleepSta) @@ -862,6 +900,9 @@ hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, const u8 *mac) cdf_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac)); peer->pHddTdlsCtx = pHddTdlsCtx; peer->pref_off_chan_num = pHddCtx->config->fTDLSPrefOffChanNum; + peer->op_class_for_pref_off_chan = + wlan_hdd_find_opclass(pHddCtx->hHal, peer->pref_off_chan_num, + pHddCtx->config->fTDLSPrefOffChanBandwidth); list_add_tail(&peer->node, head); mutex_unlock(&pHddCtx->tdls_lock); @@ -905,7 +946,7 @@ void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, tTDLSLinkStatus status, tTDLSLinkReason reason) { - int32_t state = 0; + uint32_t state = 0; int32_t res = 0; hdd_context_t *pHddCtx; if (curr_peer == NULL) { @@ -941,13 +982,19 @@ void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, mutex_unlock(&pHddCtx->tdls_lock); if (curr_peer->isForcedPeer && curr_peer->state_change_notification) { + uint32_t opclass; + uint32_t channel; + + hdd_adapter_t *adapter = curr_peer->pHddTdlsCtx->pAdapter; curr_peer->reason = reason; + + wlan_hdd_tdls_determine_channel_opclass(pHddCtx, adapter, + curr_peer, &channel, &opclass); + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, &state, &res); (*curr_peer->state_change_notification)(curr_peer->peerMac, - state, - res, - curr_peer-> - pHddTdlsCtx->pAdapter); + opclass, channel, + state, res, adapter); } return; } @@ -966,7 +1013,7 @@ void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter, tTDLSLinkStatus linkStatus, tTDLSLinkReason reason) { - int32_t state = 0; + uint32_t state = 0; int32_t res = 0; hddTdlsPeer_t *curr_peer; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); @@ -994,13 +1041,18 @@ void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter, } mutex_unlock(&pHddCtx->tdls_lock); if (curr_peer->isForcedPeer && curr_peer->state_change_notification) { + uint32_t opclass; + uint32_t channel; + hdd_adapter_t *adapter = curr_peer->pHddTdlsCtx->pAdapter; + curr_peer->reason = reason; + + wlan_hdd_tdls_determine_channel_opclass(pHddCtx, adapter, + curr_peer, &channel, &opclass); + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, &state, &res); - (curr_peer->state_change_notification)(mac, - state, - res, - curr_peer->pHddTdlsCtx-> - pAdapter); + (curr_peer->state_change_notification)(mac, opclass, channel, + state, res, adapter); } return; @@ -1808,11 +1860,6 @@ int wlan_hdd_tdls_set_extctrl_param(hdd_adapter_t *pAdapter, const uint8_t *mac, curr_peer->op_class_for_pref_off_chan = (uint8_t) op_class; curr_peer->pref_off_chan_num = (uint8_t) chan; - if (curr_peer->op_class_for_pref_off_chan) - curr_peer->op_class_for_pref_off_chan_is_set = 1; - else - curr_peer->op_class_for_pref_off_chan_is_set = 0; - mutex_unlock(&pHddCtx->tdls_lock); return 0; } @@ -1960,6 +2007,22 @@ int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, const uint8_t *mac) return -EINVAL; } + /* + * Reset preferred offchannel and opclass for offchannel as + * per INI configuration only if peer is not forced one. For + * forced peer, offchannel and opclass is set in HAL API at the + * time of enabling TDLS for that specific peer and so do not overwrite + * those set by user space. + */ + if (false == curr_peer->isForcedPeer) { + curr_peer->pref_off_chan_num = + pHddCtx->config->fTDLSPrefOffChanNum; + curr_peer->op_class_for_pref_off_chan = + wlan_hdd_find_opclass(WLAN_HDD_GET_HAL_CTX(pAdapter), + curr_peer->pref_off_chan_num, + pHddCtx->config->fTDLSPrefOffChanBandwidth); + } + wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE, eTDLS_LINK_UNSPECIFIED); @@ -2854,9 +2917,24 @@ int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer, * Return: Void */ void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, - int32_t *state, int32_t *reason) + uint32_t *state, int32_t *reason) { + hdd_context_t *hddctx; + hdd_adapter_t *adapter; + + if (!curr_peer) { + hdd_err("curr_peer is NULL"); + return; + } + + adapter = curr_peer->pHddTdlsCtx->pAdapter; + hddctx = WLAN_HDD_GET_CTX(adapter); + + if (0 != (wlan_hdd_validate_context(hddctx))) + return; + *reason = curr_peer->reason; + switch (curr_peer->link_status) { case eTDLS_LINK_IDLE: case eTDLS_LINK_DISCOVERED: @@ -2867,7 +2945,11 @@ void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, *state = QCA_WIFI_HAL_TDLS_ENABLED; break; case eTDLS_LINK_CONNECTED: - *state = QCA_WIFI_HAL_TDLS_ESTABLISHED; + if ((hddctx->config->fEnableTDLSOffChannel) && + (hddctx->tdls_fw_off_chan_mode == ENABLE_CHANSWITCH)) + *state = QCA_WIFI_HAL_TDLS_ESTABLISHED_OFF_CHANNEL; + else + *state = QCA_WIFI_HAL_TDLS_ESTABLISHED; break; case eTDLS_LINK_TEARING: *state = QCA_WIFI_HAL_TDLS_DROPPED; @@ -2885,32 +2967,38 @@ void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, * Return: 0 if success; negative errno otherwise */ int wlan_hdd_tdls_get_status(hdd_adapter_t *pAdapter, - const uint8_t *mac, int32_t *state, + const uint8_t *mac, uint32_t *opclass, + uint32_t *channel, uint32_t *state, int32_t *reason) { hddTdlsPeer_t *curr_peer; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); - curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, true); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return -EINVAL; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, false); if (curr_peer == NULL) { + mutex_unlock(&pHddCtx->tdls_lock); CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR, FL("curr_peer is NULL")); *state = QCA_WIFI_HAL_TDLS_DISABLED; *reason = eTDLS_LINK_UNSPECIFIED; - } else { - if (pHddCtx->config->fTDLSExternalControl && - (false == curr_peer->isForcedPeer)) { - CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR, - FL("curr_peer is not Forced")); - *state = QCA_WIFI_HAL_TDLS_DISABLED; - *reason = eTDLS_LINK_UNSPECIFIED; - } else { - wlan_hdd_tdls_get_wifi_hal_state(curr_peer, - state, reason); - } + return -EINVAL; } + if (pHddCtx->config->fTDLSExternalControl && + (false == curr_peer->isForcedPeer)) { + hdd_err("curr_peer is not Forced"); + *state = QCA_WIFI_HAL_TDLS_DISABLED; + *reason = eTDLS_LINK_UNSPECIFIED; + } else { + wlan_hdd_tdls_determine_channel_opclass(pHddCtx, pAdapter, + curr_peer, channel, opclass); + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, state, reason); + } + mutex_unlock(&pHddCtx->tdls_lock); - wlan_hdd_tdls_get_wifi_hal_state(curr_peer, state, reason); return 0; } @@ -2919,12 +3007,12 @@ static const struct nla_policy wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC}, - [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32}, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_U32}, [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] = {.type = - NLA_S32}, - [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32}, + NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_U32}, [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = - NLA_S32}, + NLA_U32}, }; static const struct nla_policy wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + @@ -3003,7 +3091,8 @@ __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, nla_data(tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]), sizeof(peer)); hddLog(CDF_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peer)); - ret = wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason); + ret = wlan_hdd_tdls_get_status(pAdapter, peer, &global_operating_class, + &channel, &state, &reason); if (0 != ret) { hddLog(CDF_TRACE_LEVEL_ERROR, FL("get status Failed")); return -EINVAL; @@ -3076,14 +3165,14 @@ int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, * Return: 0 for success; negative errno otherwise */ static int wlan_hdd_cfg80211_exttdls_callback(const uint8_t *mac, + uint32_t global_operating_class, + uint32_t channel, uint32_t state, int32_t reason, void *ctx) { hdd_adapter_t *pAdapter = (hdd_adapter_t *) ctx; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); struct sk_buff *skb = NULL; - uint32_t global_operating_class = 0; - uint32_t channel = 0; ENTER(); @@ -4171,21 +4260,15 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, prefOffChanBandwidth = pHddCtx->config-> fTDLSPrefOffChanBandwidth; - if (pTdlsPeer-> - op_class_for_pref_off_chan_is_set) { - smeTdlsPeerStateParams.peerCap. - opClassForPrefOffChanIsSet = - pTdlsPeer-> - op_class_for_pref_off_chan_is_set; - smeTdlsPeerStateParams.peerCap. + smeTdlsPeerStateParams.peerCap. opClassForPrefOffChan = pTdlsPeer-> op_class_for_pref_off_chan; - } + CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_INFO, "%s: Peer " MAC_ADDRESS_STR - "vdevId: %d, peerState: %d, isPeerResponder: %d, uapsdQueues: 0x%x, maxSp: 0x%x, peerBuffStaSupport: %d, peerOffChanSupport: %d, peerCurrOperClass: %d, selfCurrOperClass: %d, peerChanLen: %d, peerOperClassLen: %d, prefOffChanNum: %d, prefOffChanBandwidth: %d, op_class_for_pref_off_chan_is_set: %d, op_class_for_pref_off_chan: %d", + "vdevId: %d, peerState: %d, isPeerResponder: %d, uapsdQueues: 0x%x, maxSp: 0x%x, peerBuffStaSupport: %d, peerOffChanSupport: %d, peerCurrOperClass: %d, selfCurrOperClass: %d, peerChanLen: %d, peerOperClassLen: %d, prefOffChanNum: %d, prefOffChanBandwidth: %d, op_class_for_pref_off_chan: %d", __func__, MAC_ADDR_ARRAY(peer), smeTdlsPeerStateParams.vdevId, @@ -4214,8 +4297,6 @@ static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, smeTdlsPeerStateParams. peerCap.prefOffChanBandwidth, pTdlsPeer-> - op_class_for_pref_off_chan_is_set, - pTdlsPeer-> op_class_for_pref_off_chan); for (i = 0; @@ -4596,6 +4677,7 @@ int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode) hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); sme_tdls_chan_switch_params chan_switch_params; + CDF_STATUS status = CDF_STATUS_E_FAILURE; if (offchanmode < ENABLE_CHANSWITCH || offchanmode > DISABLE_CHANSWITCH) { @@ -4626,46 +4708,24 @@ int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode) FL("TDLS Connection not supported")); return -ENOTSUPP; } + hddLog(LOG1, - FL("TDLS Channel Switch in swmode=%d"), - offchanmode); + FL("TDLS Channel Switch in swmode=%d tdls_off_channel %d offchanoffset %d"), + offchanmode, hdd_ctx->tdls_off_channel, + hdd_ctx->tdls_channel_offset); switch (offchanmode) { case ENABLE_CHANSWITCH: - case DISABLE_CHANSWITCH: - hddLog(LOG1, - FL( - "change tdls off channel mode %d tdls_off_channel %d offchanoffset %d" - ), - offchanmode, hdd_ctx->tdls_off_channel, - hdd_ctx->tdls_channel_offset); - if (hdd_ctx->tdls_off_channel && hdd_ctx->tdls_channel_offset) { - chan_switch_params.vdev_id = adapter->sessionId; + if (hdd_ctx->tdls_off_channel && + hdd_ctx->tdls_channel_offset) { chan_switch_params.tdls_off_channel = hdd_ctx->tdls_off_channel; chan_switch_params.tdls_off_ch_bw_offset = hdd_ctx->tdls_channel_offset; - chan_switch_params.tdls_off_ch_mode = offchanmode; - chan_switch_params.is_responder = - conn_peer->is_responder; - cdf_mem_copy(&chan_switch_params.peer_mac_addr, - &conn_peer->peerMac, - sizeof(tSirMacAddr)); - hddLog(LOG1, - FL("Peer " MAC_ADDRESS_STR - " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d" - ), - MAC_ADDR_ARRAY(chan_switch_params. - peer_mac_addr), - chan_switch_params.vdev_id, - chan_switch_params.tdls_off_channel, - chan_switch_params.tdls_off_ch_bw_offset, - chan_switch_params.tdls_off_ch_mode, - chan_switch_params.is_responder); - - sme_send_tdls_chan_switch_req( - WLAN_HDD_GET_HAL_CTX(adapter), - &chan_switch_params); + chan_switch_params.opclass = + wlan_hdd_find_opclass(WLAN_HDD_GET_HAL_CTX(adapter), + chan_switch_params.tdls_off_channel, + chan_switch_params.tdls_off_ch_bw_offset); } else { hddLog(LOGE, FL( @@ -4674,6 +4734,11 @@ int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode) return -EINVAL; } break; + case DISABLE_CHANSWITCH: + chan_switch_params.tdls_off_channel = 0; + chan_switch_params.tdls_off_ch_bw_offset = 0; + chan_switch_params.opclass = 0; + break; default: hddLog(LOGE, FL( @@ -4681,8 +4746,44 @@ int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode) ), offchanmode, hdd_ctx->tdls_off_channel, hdd_ctx->tdls_channel_offset); - break; + return -EINVAL; } /* end switch */ + + chan_switch_params.vdev_id = adapter->sessionId; + chan_switch_params.tdls_off_ch_mode = offchanmode; + chan_switch_params.is_responder = + conn_peer->is_responder; + cdf_mem_copy(&chan_switch_params.peer_mac_addr, + &conn_peer->peerMac, + sizeof(tSirMacAddr)); + hdd_log(LOG1, + FL("Peer " MAC_ADDRESS_STR + " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d"), + MAC_ADDR_ARRAY(chan_switch_params.peer_mac_addr), + chan_switch_params.vdev_id, + chan_switch_params.tdls_off_channel, + chan_switch_params.tdls_off_ch_bw_offset, + chan_switch_params.tdls_off_ch_mode, + chan_switch_params.is_responder); + + status = sme_send_tdls_chan_switch_req(WLAN_HDD_GET_HAL_CTX(adapter), + &chan_switch_params); + + if (status != CDF_STATUS_SUCCESS) { + hdd_log(LOG1, + FL("Failed to send channel switch request to sme")); + return -EINVAL; + } + + hdd_ctx->tdls_fw_off_chan_mode = offchanmode; + + if (ENABLE_CHANSWITCH == offchanmode) { + conn_peer->pref_off_chan_num = + chan_switch_params.tdls_off_channel; + conn_peer->op_class_for_pref_off_chan = + chan_switch_params.opclass; + } + return 0; } diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index ec368086c3cc..9fb0305989ab 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -155,7 +155,6 @@ typedef struct _smeTdlsPeerCapParams { uint8_t prefOffChanNum; uint8_t prefOffChanBandwidth; uint8_t opClassForPrefOffChan; - uint8_t opClassForPrefOffChanIsSet; } tSmeTdlsPeerCapParams; typedef enum { @@ -184,6 +183,7 @@ typedef struct sme_tdls_chan_switch_params_struct { uint8_t tdls_off_channel; /* Target Off Channel */ uint8_t tdls_off_ch_mode; /* TDLS Off Channel Mode */ uint8_t is_responder; /* is peer responder or initiator */ + uint8_t opclass; /* tdls operating class */ } sme_tdls_chan_switch_params; #endif /* FEATURE_WLAN_TDLS */ @@ -1056,4 +1056,16 @@ void sme_update_tgt_services(tHalHandle hal, struct wma_tgt_services *cfg); bool sme_validate_sap_channel_switch(tHalHandle hal, uint16_t sap_ch, eCsrPhyMode sap_phy_mode, uint8_t cc_switch_mode, uint8_t session_id); + +#ifdef FEATURE_WLAN_TDLS +void sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset, + uint8_t *opclass); +#else +static inline void +sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset, + uint8_t *opclass) +{ +} +#endif + #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 37ff4d100a70..e1651637af84 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -10045,49 +10045,9 @@ CDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal, peerStateParams->peerCap.prefOffChanNum; peer_cap->prefOffChanBandwidth = peerStateParams->peerCap.prefOffChanBandwidth; + peer_cap->opClassForPrefOffChan = + peerStateParams->peerCap.opClassForPrefOffChan; - if (peerStateParams->peerCap.opClassForPrefOffChanIsSet) { - peer_cap->opClassForPrefOffChan = - peerStateParams->peerCap.opClassForPrefOffChan; - } else { - /* - * redgm opclass table contains opclass for 40MHz low - * primary, 40MHz high primary and 20MHz. No support - * for 80MHz yet. So first we will check if bit for - * 40MHz is set and if so find matching opclass either - * with low primary or high primary (a channel would - * never be in both) and then search for opclass - * matching 20MHz, else for any BW. - */ - if (peer_cap->prefOffChanBandwidth & - (1 << BW_40_OFFSET_BIT)) { - peer_cap->opClassForPrefOffChan = - cds_regdm_get_opclass_from_channel( - pMac->scan.countryCodeCurrent, - peer_cap->prefOffChanNum, - BW40_LOW_PRIMARY); - if (!peer_cap->opClassForPrefOffChan) { - peer_cap->opClassForPrefOffChan = - cds_regdm_get_opclass_from_channel( - pMac->scan.countryCodeCurrent, - peer_cap->prefOffChanNum, - BW40_HIGH_PRIMARY); - } - } else if (peer_cap->prefOffChanBandwidth & - (1 << BW_20_OFFSET_BIT)) { - peer_cap->opClassForPrefOffChan = - cds_regdm_get_opclass_from_channel( - pMac->scan.countryCodeCurrent, - peer_cap->prefOffChanNum, - BW20); - } else { - peer_cap->opClassForPrefOffChan = - cds_regdm_get_opclass_from_channel( - pMac->scan.countryCodeCurrent, - peer_cap->prefOffChanNum, - BWALL); - } - } cds_message.type = WMA_UPDATE_TDLS_PEER_STATE; cds_message.reserved = 0; cds_message.bodyptr = pTdlsPeerStateParams; @@ -10159,37 +10119,7 @@ CDF_STATUS sme_send_tdls_chan_switch_req(tHalHandle hal, chan_switch_params->tdls_off_ch_bw_offset = ch_switch_params->tdls_off_ch_bw_offset; chan_switch_params->is_responder = ch_switch_params->is_responder; - - switch (chan_switch_params->tdls_off_ch_bw_offset) { - case (1 << BW_20_OFFSET_BIT): - chan_switch_params->oper_class = - cds_regdm_get_opclass_from_channel( - mac->scan.countryCodeCurrent, - chan_switch_params->tdls_off_ch, - BW20); - break; - case (1 << BW_40_OFFSET_BIT): - chan_switch_params->oper_class = - cds_regdm_get_opclass_from_channel( - mac->scan.countryCodeCurrent, - chan_switch_params->tdls_off_ch, - BW40_LOW_PRIMARY); - if (!chan_switch_params->oper_class) { - chan_switch_params->oper_class = - cds_regdm_get_opclass_from_channel( - mac->scan.countryCodeCurrent, - chan_switch_params->tdls_off_ch, - BW40_HIGH_PRIMARY); - } - break; - default: - chan_switch_params->oper_class = - cds_regdm_get_opclass_from_channel( - mac->scan.countryCodeCurrent, - chan_switch_params->tdls_off_ch, - BWALL); - break; - } /* end switch */ + chan_switch_params->oper_class = ch_switch_params->opclass; CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO, FL("Country Code=%s, Req offset=%d, Selected Operate Class=%d"), @@ -14916,3 +14846,49 @@ void sme_update_tgt_services(tHalHandle hal, struct wma_tgt_services *cfg) return; } + +#ifdef FEATURE_WLAN_TDLS + +/** + * sme_get_opclass() - determine operating class + * @hal: Pointer to HAL + * @channel: channel id + * @bw_offset: bandwidth offset + * @opclass: pointer to operating class + * + * Function will determine operating class from regdm_get_opclass_from_channel + * + * Return: none + */ +void sme_get_opclass(tHalHandle hal, uint8_t channel, uint8_t bw_offset, + uint8_t *opclass) +{ + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + + /* redgm opclass table contains opclass for 40MHz low primary, + * 40MHz high primary and 20MHz. No support for 80MHz yet. So + * first we will check if bit for 40MHz is set and if so find + * matching opclass either with low primary or high primary + * (a channel would never be in both) and then search for opclass + * matching 20MHz, else for any BW. + */ + if (bw_offset & (1 << BW_40_OFFSET_BIT)) { + *opclass = cds_regdm_get_opclass_from_channel( + mac_ctx->scan.countryCodeCurrent, + channel, BW40_LOW_PRIMARY); + if (!(*opclass)) { + *opclass = cds_regdm_get_opclass_from_channel( + mac_ctx->scan.countryCodeCurrent, + channel, BW40_HIGH_PRIMARY); + } + } else if (bw_offset & (1 << BW_20_OFFSET_BIT)) { + *opclass = cds_regdm_get_opclass_from_channel( + mac_ctx->scan.countryCodeCurrent, + channel, BW20); + } else { + *opclass = cds_regdm_get_opclass_from_channel( + mac_ctx->scan.countryCodeCurrent, + channel, BWALL); + } +} +#endif