diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 3abf7ff87fa0..d6c6af0b3130 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -5493,4 +5493,89 @@ struct sir_saved_csa_params { uint32_t session_id; }; +/** + * enum obss_ht40_scancmd_type - obss scan command type + * @HT40_OBSS_SCAN_PARAM_START: OBSS scan start + * @HT40_OBSS_SCAN_PARAM_UPDATE: OBSS scan param update + */ +enum obss_ht40_scancmd_type { + HT40_OBSS_SCAN_PARAM_START, + HT40_OBSS_SCAN_PARAM_UPDATE +}; + +/** + * struct sme_obss_ht40_scanind_msg - sme obss scan params + * @msg_type: message type + * @length: message length + * @mac_addr: mac address + */ +struct sme_obss_ht40_scanind_msg { + uint16_t msg_type; + uint16_t length; + struct qdf_mac_addr mac_addr; +}; + +/** + * struct obss_ht40_scanind - ht40 obss scan request + * @cmd: message type + * @scan_type: message length + * @obss_passive_dwelltime: obss passive dwelltime + * @obss_active_dwelltime: obss active dwelltime + * @obss_width_trigger_interval: scan interval + * @obss_passive_total_per_channel: total passive scan time per channel + * @obss_active_total_per_channel: total active scan time per channel + * @bsswidth_ch_trans_delay: OBSS transition delay time + * @obss_activity_threshold: OBSS activity threshold + * @self_sta_id: self sta identification + * @bss_id: BSS index + * @fortymhz_intolerent: Ht40mhz intolerance + * @channel_count: channel count + * @channels: channel information + * @current_operatingclass: operating class + * @iefield_len: ie's length + * @iefiled: ie's information + */ +struct obss_ht40_scanind { + enum obss_ht40_scancmd_type cmd; + enum eSirScanType scan_type; + /* In TUs */ + uint16_t obss_passive_dwelltime; + uint16_t obss_active_dwelltime; + /* In seconds */ + uint16_t obss_width_trigger_interval; + /* In TU's */ + uint16_t obss_passive_total_per_channel; + uint16_t obss_active_total_per_channel; + uint16_t bsswidth_ch_trans_delay; + uint16_t obss_activity_threshold; + uint8_t self_sta_idx; + uint8_t bss_id; + uint8_t fortymhz_intolerent; + uint8_t channel_count; + uint8_t channels[SIR_ROAM_MAX_CHANNELS]; + uint8_t current_operatingclass; + uint16_t iefield_len; + uint8_t iefield[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE]; +}; + +/** + * struct obss_scanparam - OBSS scan parameters + * @obss_passive_dwelltime: message type + * @obss_active_dwelltime: message length + * @obss_width_trigger_interval: obss passive dwelltime + * @obss_passive_total_per_channel: obss passive total scan time + * @obss_active_total_per_channel: obss active total scan time + * @bsswidth_ch_trans_delay: OBSS transition delay time + * @obss_activity_threshold: OBSS activity threshold + */ +struct obss_scanparam { + uint16_t obss_passive_dwelltime; + uint16_t obss_active_dwelltime; + uint16_t obss_width_trigger_interval; + uint16_t obss_passive_total_per_channel; + uint16_t obss_active_total_per_channel; + uint16_t bsswidth_ch_trans_delay; + uint16_t obss_activity_threshold; +}; + #endif /* __SIR_API_H */ diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 2caf25d702fb..225149cda2d0 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -244,6 +244,7 @@ enum eWniMsgTypes { eWNI_SME_EXT_CHANGE_CHANNEL, eWNI_SME_EXT_CHANGE_CHANNEL_IND, eWNI_SME_REGISTER_MGMT_FRAME_CB, + eWNI_SME_HT40_OBSS_SCAN_IND, /* START and UPDATE OBSS SCAN Indication*/ eWNI_SME_MSG_TYPES_END }; diff --git a/core/mac/inc/wni_cfg.h b/core/mac/inc/wni_cfg.h index adc9e6513d56..2c46e7d2ee35 100644 --- a/core/mac/inc/wni_cfg.h +++ b/core/mac/inc/wni_cfg.h @@ -318,7 +318,14 @@ enum { WNI_CFG_IBSS_ATIM_WIN_SIZE, WNI_CFG_DFS_MASTER_ENABLED, WNI_CFG_VHT_ENABLE_TXBF_20MHZ, - WNI_CFG_TDLS_WMM_MODE_ENABLED + WNI_CFG_TDLS_WMM_MODE_ENABLED, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL, + WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY, + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD }; /* * String parameter lengths @@ -1548,7 +1555,36 @@ enum { #define WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMAX 1 #define WNI_CFG_TDLS_WMM_MODE_ENABLED_STADEF 0 -#define CFG_PARAM_MAX_NUM 286 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMIN 5 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMAX 1000 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STADEF 20 + +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMIN 10 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMAX 1000 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STADEF 10 + +#define WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMIN 10 +#define WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMAX 900 +#define WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STADEF 200 + +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMIN 200 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMAX 10000 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STADEF 200 + +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMIN 20 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMAX 10000 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STADEF 20 + +#define WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STAMIN 5 +#define WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STAMAX 100 +#define WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STADEF 5 + +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMIN 0 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMAX 100 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STADEF 25 + + +#define CFG_PARAM_MAX_NUM 293 #define CFG_STA_MAGIC_DWORD 0xbeefbeef diff --git a/core/mac/src/cfg/cfg_proc_msg.c b/core/mac/src/cfg/cfg_proc_msg.c index 4c9969b84ef3..0105a09a52c8 100644 --- a/core/mac/src/cfg/cfg_proc_msg.c +++ b/core/mac/src/cfg/cfg_proc_msg.c @@ -1524,7 +1524,49 @@ cgstatic cfg_static[CFG_PARAM_MAX_NUM] = { CFG_CTL_NTF_LIM, WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMIN, WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMAX, - WNI_CFG_TDLS_WMM_MODE_ENABLED_STADEF} + WNI_CFG_TDLS_WMM_MODE_ENABLED_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | + CFG_CTL_NTF_LIM, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | + CFG_CTL_NTF_LIM, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | + CFG_CTL_NTF_LIM, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | + CFG_CTL_NTF_LIM, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | + CFG_CTL_NTF_LIM, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STADEF}, + {WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | + CFG_CTL_NTF_LIM, + WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STAMIN, + WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STAMAX, + WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | + CFG_CTL_NTF_LIM, + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STADEF} }; diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h index 27e72b527a69..256967d6599d 100644 --- a/core/mac/src/include/parser_api.h +++ b/core/mac/src/include/parser_api.h @@ -161,6 +161,7 @@ typedef struct sSirProbeRespBeacon { #ifdef FEATURE_WLAN_ESE uint8_t is_ese_ver_ie_present; #endif + tDot11fIEOBSSScanParameters obss_scanparams; } tSirProbeRespBeacon, *tpSirProbeRespBeacon; /* probe Request structure */ @@ -276,6 +277,7 @@ typedef struct sSirAssocRsp { tDot11fIETimeoutInterval TimeoutInterval; #endif tDot11fIEvendor2_ie vendor2_ie; + tDot11fIEOBSSScanParameters obss_scanparams; } tSirAssocRsp, *tpSirAssocRsp; #if defined(FEATURE_WLAN_ESE_UPLOAD) diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 62b8517406e8..0264f898f947 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -600,7 +600,7 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_LRO_CONFIG_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 335) #define SIR_HAL_SET_EGAP_CONF_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 336) - +#define SIR_HAL_HT40_OBSS_SCAN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 337) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) /* CFG message types */ diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 67efbf02a084..27d1f99c383c 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -472,6 +472,8 @@ typedef struct sPESession /* Added to Support BT-AMP */ uint8_t nss; bool add_bss_failed; struct csa_offload_params saved_csa_params; + /* To hold OBSS Scan IE Parameters */ + struct obss_scanparam obss_ht40_scanparam; } tPESession, *tpPESession; /*------------------------------------------------------------------------- diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c index 5f1e54176e04..728fb3846cd3 100644 --- a/core/mac/src/pe/lim/lim_ft.c +++ b/core/mac/src/pe/lim/lim_ft.c @@ -928,6 +928,10 @@ void lim_fill_ft_session(tpAniSirGlobal pMac, #ifdef WLAN_FEATURE_11W pftSessionEntry->limRmfEnabled = psessionEntry->limRmfEnabled; #endif + if ((pftSessionEntry->limRFBand == SIR_BAND_2_4_GHZ) && + (pftSessionEntry->htSupportedChannelWidthSet == + eHT_CHANNEL_WIDTH_40MHZ)) + lim_init_obss_params(pMac, pftSessionEntry); qdf_mem_free(pBeaconStruct); } diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c index 725e996e49de..adeee6ad8045 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c @@ -1067,6 +1067,10 @@ lim_process_assoc_rsp_frame(tpAniSirGlobal mac_ctx, lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_CONNECTED, session_entry, eSIR_SUCCESS, eSIR_SUCCESS); #endif + if (assoc_rsp->obss_scanparams.present) + lim_update_obss_scanparams(session_entry, + &assoc_rsp->obss_scanparams); + if (assoc_rsp->QosMapSet.present) qdf_mem_copy(&session_entry->QosMapSet, &assoc_rsp->QosMapSet, sizeof(tSirQosMapSet)); diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 4064a074ce6f..6866468577df 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1147,6 +1147,38 @@ void lim_process_oem_data_rsp(tpAniSirGlobal pMac, uint32_t *body) #endif +static void lim_process_sme_obss_scan_ind(tpAniSirGlobal mac_ctx, + struct sSirMsgQ *msg) +{ + struct sPESession *session; + uint8_t session_id; + struct sme_obss_ht40_scanind_msg *ht40_scanind; + + ht40_scanind = (struct sme_obss_ht40_scanind_msg *)msg->bodyptr; + session = pe_find_session_by_bssid(mac_ctx, + ht40_scanind->mac_addr.bytes, &session_id); + if (session == NULL) { + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, + "OBSS Scan not started: session id is NULL"); + return; + } + if (session->htSupportedChannelWidthSet == + WNI_CFG_CHANNEL_BONDING_MODE_ENABLE) { + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, + "OBSS Scan Start Req: session id %d" + "htSupportedChannelWidthSet %d", + session->peSessionId, + session->htSupportedChannelWidthSet); + lim_send_ht40_obss_scanind(mac_ctx, session); + } else { + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO, + "OBSS Scan not started: channel width - %d session %d", + session->htSupportedChannelWidthSet, + session->peSessionId); + } + return; +} + /** * lim_handle_hw_mode_change_on_csa() - Do HW mode change on CSA for STA mode * @mac_ctx: Global MAC context @@ -1973,6 +2005,11 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; break; + case eWNI_SME_HT40_OBSS_SCAN_IND: + lim_process_sme_obss_scan_ind(mac_ctx, msg); + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + break; default: qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; @@ -2208,6 +2245,7 @@ handle_ht_capabilityand_ht_info(struct sAniSirGlobal *pMac, IS_DOT11_MODE_HT(psessionEntry->dot11mode); psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = (uint8_t) macHTInfoField3.lsigTXOPProtectionFullSupport; + lim_init_obss_params(pMac, psessionEntry); } } diff --git a/core/mac/src/pe/lim/lim_send_messages.c b/core/mac/src/pe/lim/lim_send_messages.c index 5151cd45149c..1023060347d2 100644 --- a/core/mac/src/pe/lim/lim_send_messages.c +++ b/core/mac/src/pe/lim/lim_send_messages.c @@ -42,6 +42,7 @@ #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */ #include "host_diag_core_log.h" #endif /* FEATURE_WLAN_DIAG_SUPPORT */ +#include "cds_regdomain_common.h" /* When beacon filtering is enabled, firmware will * analyze the selected beacons received during BMPS, * and monitor any changes in the IEs as listed below. @@ -821,3 +822,97 @@ tSirRetStatus lim_send_exclude_unencrypt_ind(tpAniSirGlobal pMac, return retCode; } #endif + +/** + * lim_send_ht40_obss_scanind() - send ht40 obss start scan request + * mac: mac context + * session PE session handle + * + * LIM sends a HT40 start scan message to WMA + * + * Return: status of operation + */ +tSirRetStatus lim_send_ht40_obss_scanind(tpAniSirGlobal mac_ctx, + struct sPESession *session) +{ + enum eSirRetStatus ret = eSIR_SUCCESS; + struct obss_ht40_scanind *ht40_obss_scanind; + uint32_t channelnum; + struct sSirMsgQ msg; + uint8_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + uint8_t channel24gnum, count; + + ht40_obss_scanind = qdf_mem_malloc(sizeof(struct obss_ht40_scanind)); + if (NULL == ht40_obss_scanind) { + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, + "Memory allocation failed"); + return eSIR_FAILURE; + } + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, + "OBSS Scan Indication bssIdx- %d staId %d", + session->bssIdx, session->staId); + + ht40_obss_scanind->cmd = HT40_OBSS_SCAN_PARAM_START; + ht40_obss_scanind->scan_type = eSIR_ACTIVE_SCAN; + ht40_obss_scanind->obss_passive_dwelltime = + session->obss_ht40_scanparam.obss_passive_dwelltime; + ht40_obss_scanind->obss_active_dwelltime = + session->obss_ht40_scanparam.obss_active_dwelltime; + ht40_obss_scanind->obss_width_trigger_interval = + session->obss_ht40_scanparam.obss_width_trigger_interval; + ht40_obss_scanind->obss_passive_total_per_channel = + session->obss_ht40_scanparam.obss_passive_total_per_channel; + ht40_obss_scanind->obss_active_total_per_channel = + session->obss_ht40_scanparam.obss_active_total_per_channel; + ht40_obss_scanind->bsswidth_ch_trans_delay = + session->obss_ht40_scanparam.bsswidth_ch_trans_delay; + ht40_obss_scanind->obss_activity_threshold = + session->obss_ht40_scanparam.obss_activity_threshold; + ht40_obss_scanind->current_operatingclass = + cds_regdm_get_opclass_from_channel( + mac_ctx->scan.countryCodeCurrent, + session->currentOperChannel, + session->ch_width); + channelnum = WNI_CFG_VALID_CHANNEL_LIST_LEN; + if (wlan_cfg_get_str(mac_ctx, WNI_CFG_VALID_CHANNEL_LIST, + chan_list, &channelnum) != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("could not retrieve Valid channel list")); + qdf_mem_free(ht40_obss_scanind); + return eSIR_FAILURE; + } + /* Extract 24G channel list */ + channel24gnum = 0; + for (count = 0; count < channelnum && + (channel24gnum < SIR_ROAM_MAX_CHANNELS); count++) { + if ((chan_list[count] > CHAN_ENUM_1) && + (chan_list[count] < CHAN_ENUM_14)) { + ht40_obss_scanind->channels[channel24gnum] = + chan_list[count]; + channel24gnum++; + } + } + ht40_obss_scanind->channel_count = channel24gnum; + /* FW API requests BSS IDX */ + ht40_obss_scanind->self_sta_idx = session->staId; + ht40_obss_scanind->bss_id = session->bssIdx; + ht40_obss_scanind->fortymhz_intolerent = 0; + ht40_obss_scanind->iefield_len = 0; + msg.type = WMA_HT40_OBSS_SCAN_IND; + msg.reserved = 0; + msg.bodyptr = (void *)ht40_obss_scanind; + msg.bodyval = 0; + lim_log(mac_ctx, LOG1, + FL("Sending WDA_HT40_OBSS_SCAN_IND to WDA" + "Obss Scan trigger width = %d, delay factor = %d"), + ht40_obss_scanind->obss_width_trigger_interval, + ht40_obss_scanind->bsswidth_ch_trans_delay); + ret = wma_post_ctrl_msg(mac_ctx, &msg); + if (eSIR_SUCCESS != ret) { + lim_log(mac_ctx, LOGP, + FL("WDA_HT40_OBSS_SCAN_IND msg failed, reason=%X"), + ret); + qdf_mem_free(ht40_obss_scanind); + } + return ret; +} diff --git a/core/mac/src/pe/lim/lim_send_messages.h b/core/mac/src/pe/lim/lim_send_messages.h index 5bca22005521..9ac8fada3971 100644 --- a/core/mac/src/pe/lim/lim_send_messages.h +++ b/core/mac/src/pe/lim/lim_send_messages.h @@ -104,4 +104,6 @@ tSirRetStatus lim_send_exclude_unencrypt_ind(tpAniSirGlobal pMac, bool excludeUnenc, tpPESession psessionEntry); #endif +tSirRetStatus lim_send_ht40_obss_scanind(tpAniSirGlobal mac_ctx, + tpPESession session); #endif diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 81769c79a6b5..16eabf4c7ea1 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -7105,3 +7105,147 @@ const char *lim_bss_type_to_string(const uint16_t bss_type) return "Unknown bss_type"; } } + +/** + * lim_init_obss_params(): Initializes the OBSS Scan Parameters + * @sesssion: LIM session + * @mac_ctx: Mac context + * + * Return: None + */ +void lim_init_obss_params(tpAniSirGlobal mac_ctx, tpPESession session) +{ + uint32_t cfg_value; + + if (wlan_cfg_get_int(mac_ctx, WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME, + &cfg_value) != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("Fail to retrieve %x value"), + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME); + return; + } + session->obss_ht40_scanparam.obss_active_dwelltime = cfg_value; + + if (wlan_cfg_get_int(mac_ctx, WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME, + &cfg_value) != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("Fail to retrieve %x value"), + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME); + return; + } + session->obss_ht40_scanparam.obss_passive_dwelltime = cfg_value; + + if (wlan_cfg_get_int(mac_ctx, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + &cfg_value) != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("Fail to retrieve %x value"), + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL); + return; + } + session->obss_ht40_scanparam.obss_width_trigger_interval = cfg_value; + if (wlan_cfg_get_int(mac_ctx, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL, + &cfg_value) != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("Fail to retrieve %x value"), + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL); + return; + } + session->obss_ht40_scanparam.obss_active_total_per_channel = cfg_value; + if (wlan_cfg_get_int(mac_ctx, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL, &cfg_value) + != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("Fail to retrieve %x value"), + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL); + return; + } + session->obss_ht40_scanparam.obss_passive_total_per_channel = cfg_value; + + if (wlan_cfg_get_int(mac_ctx, + WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY, &cfg_value) + != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("Fail to retrieve %x value"), + WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY); + return; + } + session->obss_ht40_scanparam.bsswidth_ch_trans_delay = + cfg_value; + + if (wlan_cfg_get_int(mac_ctx, WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD, + &cfg_value) != eSIR_SUCCESS) { + lim_log(mac_ctx, LOGE, + FL("Fail to retrieve %x value"), + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD); + return; + } + session->obss_ht40_scanparam.obss_activity_threshold = cfg_value; +} + +/** + * lim_update_obss_scanparams(): Updates OBSS SCAN IE parameters to session + * @sesssion: LIM session + * @scan_params: Scan parameters + * + * Return: None + */ +void lim_update_obss_scanparams(tpPESession session, + tDot11fIEOBSSScanParameters *scan_params) +{ + /* + * If the recieved value is not in the range specified + * by the Specification then it will be the default value + * configured through cfg + */ + if ((scan_params->obssScanActiveDwell > + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMIN) && + (scan_params->obssScanActiveDwell < + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMAX)) + session->obss_ht40_scanparam.obss_active_dwelltime = + scan_params->obssScanActiveDwell; + + if ((scan_params->obssScanPassiveDwell > + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMIN) && + (scan_params->obssScanPassiveDwell < + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMAX)) + session->obss_ht40_scanparam.obss_active_dwelltime = + scan_params->obssScanPassiveDwell; + + if ((scan_params->bssWidthChannelTransitionDelayFactor > + WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STAMIN) && + (scan_params->bssWidthChannelTransitionDelayFactor < + WNI_CFG_OBSS_HT40_WIDTH_CH_TRANSITION_DELAY_STAMAX)) + session->obss_ht40_scanparam.bsswidth_ch_trans_delay = + scan_params->bssWidthChannelTransitionDelayFactor; + + if ((scan_params->obssScanActiveTotalPerChannel > + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMIN) && + (scan_params->obssScanActiveTotalPerChannel < + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMAX)) + session->obss_ht40_scanparam.obss_active_total_per_channel = + scan_params->obssScanActiveTotalPerChannel; + + if ((scan_params->obssScanPassiveTotalPerChannel > + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMIN) && + (scan_params->obssScanPassiveTotalPerChannel < + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMAX)) + session->obss_ht40_scanparam.obss_passive_total_per_channel = + scan_params->obssScanPassiveTotalPerChannel; + + if ((scan_params->bssChannelWidthTriggerScanInterval > + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMIN) && + (scan_params->bssChannelWidthTriggerScanInterval < + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMAX)) + session->obss_ht40_scanparam.obss_width_trigger_interval = + scan_params->bssChannelWidthTriggerScanInterval; + + if ((scan_params->obssScanActivityThreshold > + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMIN) && + (scan_params->obssScanActivityThreshold < + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMAX)) + session->obss_ht40_scanparam.obss_activity_threshold = + scan_params->obssScanActivityThreshold; + return; +} diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 999ea46f49df..b7b8715a9eb5 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -582,4 +582,8 @@ tSirRetStatus lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx, void lim_merge_extcap_struct(tDot11fIEExtCap *dst, tDot11fIEExtCap *src); uint8_t lim_get_80Mhz_center_channel(uint8_t primary_channel); +void lim_update_obss_scanparams(tpPESession session, + tDot11fIEOBSSScanParameters *scan_params); +void lim_init_obss_params(tpAniSirGlobal mac_ctx, tpPESession session); + #endif /* __LIM_UTILS_H */ diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 7bec234109a7..8336d4866d65 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -2877,7 +2877,11 @@ sir_convert_assoc_resp_frame2_struct(tpAniSirGlobal pMac, pAssocRsp->vendor2_ie.type = ar.vendor2_ie.type; pAssocRsp->vendor2_ie.sub_type = ar.vendor2_ie.sub_type; } - + if (ar.OBSSScanParameters.present) { + qdf_mem_copy(&pAssocRsp->obss_scanparams, + &ar.OBSSScanParameters, + sizeof(struct sDot11fIEOBSSScanParameters)); + } if (ar.vendor2_ie.VHTCaps.present) { qdf_mem_copy(&pAssocRsp->vendor2_ie.VHTCaps, &ar.vendor2_ie.VHTCaps, @@ -3967,7 +3971,11 @@ sir_convert_beacon_frame2_struct(tpAniSirGlobal pMac, pBeacon->QComVendorIE.channel; } #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ - + if (pBeacon->OBSSScanParameters.present) { + qdf_mem_copy(&pBeaconStruct->obss_scanparams, + &pBeacon->OBSSScanParameters, + sizeof(struct sDot11fIEOBSSScanParameters)); + } qdf_mem_free(pBeacon); return eSIR_SUCCESS; diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 19884c35231b..6072d95ec379 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -1214,6 +1214,9 @@ typedef struct tagCsrConfigParam { uint32_t roam_dense_traffic_thresh; uint32_t roam_dense_rssi_thresh_offset; uint32_t roam_dense_min_aps; + uint32_t obss_width_interval; + uint32_t obss_active_dwelltime; + uint32_t obss_passive_dwelltime; } tCsrConfigParam; /* Tush */ diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index acc4a890420c..7d883931ee18 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -94,7 +94,8 @@ (((pMac)->roam.configParam.bFastRoamInConIniFeatureEnabled) ? \ true : false) \ ) - +#define CSR_IS_CHANNEL_24GHZ(chnNum) \ + (((chnNum) > 0) && ((chnNum) <= 14)) /* Support for "Fast roaming" (i.e., ESE, LFR, or 802.11r.) */ #define CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15 @@ -633,6 +634,9 @@ typedef struct tagCsrConfig { bool early_stop_scan_enable; int8_t early_stop_scan_min_threshold; int8_t early_stop_scan_max_threshold; + uint32_t obss_width_interval; + uint32_t obss_active_dwelltime; + uint32_t obss_passive_dwelltime; } tCsrConfig; typedef struct tagCsrChannelPowerInfo { diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index f0b226819714..c50e837962ce 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1083,5 +1083,6 @@ static inline QDF_STATUS sme_send_egap_conf_params(uint32_t enable, #endif void sme_update_fine_time_measurement_capab(tHalHandle hal, uint32_t val); +QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hHal, uint32_t vdev_id); #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 bc48a8392eec..d393a0fa7546 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -14964,3 +14964,24 @@ QDF_STATUS sme_send_egap_conf_params(uint32_t enable, uint32_t inactivity_time, return status; } #endif + +/** + * sme_ht40_stop_obss_scan() - ht40 obss stop scan + * @hal: mac handel + * @vdev_id: vdev identifier + * + * Return: Return QDF_STATUS, otherwise appropriate failure code + */ +QDF_STATUS sme_ht40_stop_obss_scan(tHalHandle hal, uint32_t vdev_id) +{ + void *wma_handle; + + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + "wma handle is NULL"); + return QDF_STATUS_E_FAILURE; + } + wma_ht40_stop_obss_scan(wma_handle, vdev_id); + return QDF_STATUS_SUCCESS; +} diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 47f8827ad10e..94500ed91419 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1861,6 +1861,27 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac, pMac->roam.configParam.scanAgeTimeCPS = pParam->scanAgeTimeCPS; } + if (pParam->obss_width_interval) { + pMac->roam.configParam.obss_width_interval = + pParam->obss_width_interval; + cfg_set_int(pMac, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + pParam->obss_width_interval); + } + if (pParam->obss_active_dwelltime) { + pMac->roam.configParam.obss_active_dwelltime = + pParam->obss_active_dwelltime; + cfg_set_int(pMac, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME, + pParam->obss_active_dwelltime); + } + if (pParam->obss_passive_dwelltime) { + pMac->roam.configParam.obss_passive_dwelltime = + pParam->obss_passive_dwelltime; + cfg_set_int(pMac, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME, + pParam->obss_passive_dwelltime); + } pMac->first_scan_bucket_threshold = pParam->first_scan_bucket_threshold; @@ -2263,6 +2284,13 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam) pMac->roam.configParam.early_stop_scan_min_threshold; pParam->early_stop_scan_max_threshold = pMac->roam.configParam.early_stop_scan_max_threshold; + pParam->obss_width_interval = + pMac->roam.configParam.obss_width_interval; + pParam->obss_active_dwelltime = + pMac->roam.configParam.obss_active_dwelltime; + pParam->obss_passive_dwelltime = + pMac->roam.configParam.obss_passive_dwelltime; + return QDF_STATUS_SUCCESS; } @@ -10792,6 +10820,28 @@ csr_roam_chk_lnk_set_ctx_rsp(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) } else { result = eCSR_ROAM_RESULT_NONE; } + /* + * OBSS SCAN Indication will be sent to Firmware + * to start OBSS Scan + */ + if (CSR_IS_CHANNEL_24GHZ( + session->connectedProfile.operationChannel) + && (session->connectState == + eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED) + && session->pCurRoamProfile + && ((QDF_P2P_CLIENT_MODE == + session->pCurRoamProfile->csrPersona) + || (QDF_STA_MODE == + session->pCurRoamProfile->csrPersona))) { + struct sme_obss_ht40_scanind_msg *msg; + msg = qdf_mem_malloc(sizeof( + struct sme_obss_ht40_scanind_msg)); + msg->msg_type = eWNI_SME_HT40_OBSS_SCAN_IND; + msg->length = sizeof(struct sme_obss_ht40_scanind_msg); + qdf_copy_macaddr(&msg->mac_addr, + &session->connectedProfile.bssid); + status = cds_send_mb_message_to_mac(msg); + } roam_info_ptr = &roam_info; } else { result = eCSR_ROAM_RESULT_FAILURE; @@ -11891,18 +11941,8 @@ static ePhyChanBondState csr_get_cb_mode_from_ies(tpAniSirGlobal pMac, uint8_t centerChn; uint32_t ChannelBondingMode; if (CDS_IS_CHANNEL_24GHZ(primaryChn)) { - /* - * gChannelBondingMode24GHz configuration item is common for - * SAP and STA mode and currently MDM does not support - * HT40 in 2.4Ghz STA mode. - * So disabling the HT40 in 2.4GHz station mode - */ -#ifdef QCA_HT_20_24G_STA_ONLY - ChannelBondingMode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; -#else ChannelBondingMode = pMac->roam.configParam.channelBondingMode24GHz; -#endif } else { ChannelBondingMode = pMac->roam.configParam.channelBondingMode5GHz; diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 87b0fb396c12..c20b6820f89b 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2022,5 +2022,10 @@ static inline QDF_STATUS wma_lro_config_cmd(tp_wma_handle wma_handle, void wma_indicate_err(enum ol_rx_err_type err_type, struct ol_error_info *err_info); + +QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma_handle, + int32_t vdev_id); +QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma, + struct obss_ht40_scanind *req); #endif struct wma_ini_config *wma_get_ini_handle(tp_wma_handle wma_handle); diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index f018b0c7bbb7..9d4d1af58cc9 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -196,6 +196,8 @@ #define WMA_TSM_STATS_RSP SIR_HAL_TSM_STATS_RSP #endif +#define WMA_HT40_OBSS_SCAN_IND SIR_HAL_HT40_OBSS_SCAN_IND + #define WMA_SET_MIMOPS_REQ SIR_HAL_SET_MIMOPS_REQ #define WMA_SET_MIMOPS_RSP SIR_HAL_SET_MIMOPS_RSP #define WMA_SYS_READY_IND SIR_HAL_SYS_READY_IND diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 0299508559db..9d4a9e2d4c0a 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -5183,6 +5183,11 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) (struct egap_conf_params *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; + case WMA_HT40_OBSS_SCAN_IND: + wma_send_ht40_obss_scanind(wma_handle, + (struct obss_ht40_scanind *)msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; default: WMA_LOGD("unknow msg type %x", msg->type); /* Do Nothing? MSG Body should be freed at here */ diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 9d151ee73e95..42362073e2e9 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -5511,3 +5511,142 @@ QDF_STATUS wma_set_gateway_params(tp_wma_handle wma, } #endif /* FEATURE_LFR_SUBNET_DETECTION */ +/** + * wma_ht40_stop_obss_scan() - ht40 obss stop scan + * @wma: WMA handel + * @vdev_id: vdev identifier + * + * Return: Return QDF_STATUS, otherwise appropriate failure code + */ +QDF_STATUS wma_ht40_stop_obss_scan(tp_wma_handle wma, int32_t vdev_id) +{ + + wmi_buf_t buf; + wmi_obss_scan_disable_cmd_fixed_param *cmd; + int ret; + int len = sizeof(*cmd); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return QDF_STATUS_E_NOMEM; + } + + WMA_LOGD("cmd %x vdev_id %d", WMI_OBSS_SCAN_DISABLE_CMDID, vdev_id); + + cmd = (wmi_obss_scan_disable_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_obss_scan_disable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_obss_scan_disable_cmd_fixed_param)); + + cmd->vdev_id = vdev_id; + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_OBSS_SCAN_DISABLE_CMDID); + if (ret != EOK) { + WMA_LOGE("Failed to send gw config parameter to fw, ret: %d", + ret); + wmi_buf_free(buf); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * wma_send_ht40_obss_scanind() - ht40 obss start scan indication + * @wma: WMA handel + * @req: start scan request + * + * Return: Return QDF_STATUS, otherwise appropriate failure code + */ +QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma, + struct obss_ht40_scanind *req) +{ + wmi_buf_t buf; + wmi_obss_scan_enable_cmd_fixed_param *cmd; + int ret; + int len = 0; + uint8_t *buf_ptr, i; + uint8_t *channel_list; + + len += sizeof(wmi_obss_scan_enable_cmd_fixed_param); + + len += WMI_TLV_HDR_SIZE; + len += qdf_roundup(sizeof(uint8_t) * req->channel_count, + sizeof(uint32_t)); + + len += WMI_TLV_HDR_SIZE; + len += qdf_roundup(sizeof(uint8_t) * 1, sizeof(uint32_t)); + + WMA_LOGE("cmdlen %d vdev_id %d channel count %d iefield_len %d", + len, req->bss_id, req->channel_count, req->iefield_len); + + WMA_LOGE("scantype %d active_time %d passive %d Obss interval %d", + req->scan_type, req->obss_active_dwelltime, + req->obss_passive_dwelltime, + req->obss_width_trigger_interval); + + buf = wmi_buf_alloc(wma->wmi_handle, len); + if (!buf) { + WMA_LOGP("%s: wmi_buf_alloc failed", __func__); + return QDF_STATUS_E_NOMEM; + } + + cmd = (wmi_obss_scan_enable_cmd_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_obss_scan_enable_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_obss_scan_enable_cmd_fixed_param)); + + buf_ptr = (uint8_t *) cmd; + + cmd->vdev_id = req->bss_id; + cmd->scan_type = req->scan_type; + cmd->obss_scan_active_dwell = + req->obss_active_dwelltime; + cmd->obss_scan_passive_dwell = + req->obss_passive_dwelltime; + cmd->bss_channel_width_trigger_scan_interval = + req->obss_width_trigger_interval; + cmd->bss_width_channel_transition_delay_factor = + req->bsswidth_ch_trans_delay; + cmd->obss_scan_active_total_per_channel = + req->obss_active_total_per_channel; + cmd->obss_scan_passive_total_per_channel = + req->obss_passive_total_per_channel; + cmd->obss_scan_activity_threshold = + req->obss_activity_threshold; + + cmd->channel_len = req->channel_count; + cmd->forty_mhz_intolerant = req->fortymhz_intolerent; + cmd->current_operating_class = req->current_operatingclass; + cmd->ie_len = req->iefield_len; + + buf_ptr += sizeof(wmi_obss_scan_enable_cmd_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + qdf_roundup(req->channel_count, sizeof(uint32_t))); + + buf_ptr += WMI_TLV_HDR_SIZE; + channel_list = (uint8_t *) buf_ptr; + + for (i = 0; i < req->channel_count; i++) { + channel_list[i] = req->channels[i]; + WMA_LOGD("Ch[%d]: %d ", i, channel_list[i]); + } + + buf_ptr += qdf_roundup(sizeof(uint8_t) * req->channel_count, + sizeof(uint32_t)); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, + qdf_roundup(1, sizeof(uint32_t))); + buf_ptr += WMI_TLV_HDR_SIZE; + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_OBSS_SCAN_ENABLE_CMDID); + if (ret != EOK) { + WMA_LOGE("Failed to send gw config parameter to fw, ret: %d", + ret); + wmi_buf_free(buf); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; +}