diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 4d438f93273d..16209c795854 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -3906,6 +3906,9 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, int access_policy = 0; char vendor_ie[SIR_MAC_MAX_IE_LENGTH + 2]; bool vendor_ie_present = false, access_policy_present = false; + uint16_t scan_ie_len = 0; + uint8_t *scan_ie; + ENTER_DEV(dev); if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { @@ -4039,6 +4042,25 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, ret_val = hdd_enable_disable_ca_event(hdd_ctx, set_value); } + if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]) { + scan_ie_len = nla_len( + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]); + hdd_info("Received default scan IE of len %d session %d device mode %d", + scan_ie_len, adapter->sessionId, + adapter->device_mode); + if (scan_ie_len && (scan_ie_len <= MAX_DEFAULT_SCAN_IE_LEN)) { + scan_ie = (uint8_t *) nla_data(tb + [QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES]); + if (adapter->device_mode == QDF_STA_MODE) { + status = sme_set_default_scan_ie(hdd_ctx->hHal, + adapter->sessionId, scan_ie, + scan_ie_len); + if (QDF_STATUS_SUCCESS != status) + ret_val = -EPERM; + } + } else + ret_val = -EPERM; + } return ret_val; } diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 2e478fb7af8f..585ddeb8d81f 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -5361,6 +5361,34 @@ struct fw_dump_rsp { uint32_t dump_complete; }; +/** + * DEFAULT_SCAN_IE_ID - Identifier for the collection of IE's added + * by default to the probe request + */ +#define DEFAULT_SCAN_IE_ID 256 + + /* MAX_DEFAULT_SCAN_IE_LEN - Maxmimum length of Default Scan IE's */ +#define MAX_DEFAULT_SCAN_IE_LEN 1024 + + /* Extended Capabilities IE header(IE Id + IE Length) length */ +#define EXT_CAP_IE_HDR_LEN 2 + +/** + * struct hdd_default_scan_ie - HDD default scan IE structure + * @message_type: message type to be set with eWNI_SME_DEFAULT_SCAN_IE + * @length: length of the struct hdd_default_scan_ie + * @session_id: Session Id + * @ie_len: Default scan IE length + * @ie_data: Pointer to default scan IE data + */ +struct hdd_default_scan_ie { + uint16_t message_type; + uint16_t length; + uint16_t session_id; + uint16_t ie_len; + uint8_t ie_data[MAX_DEFAULT_SCAN_IE_LEN]; +}; + /** * struct vdev_ie_info - IE info * @vdev_id - vdev for which the IE is being sent diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index 0e30f298e8d9..43c0c75c4eef 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -264,6 +264,7 @@ enum eWniMsgTypes { eWNI_SME_REGISTER_P2P_ACK_CB, eWNI_SME_SEND_DISASSOC_FRAME, eWNI_SME_UPDATE_ACCESS_POLICY_VENDOR_IE, + eWNI_SME_DEFAULT_SCAN_IE, eWNI_SME_MSG_TYPES_END }; 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 607b42acf9f7..4b2fe9dda9c9 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -241,6 +241,130 @@ static void lim_process_set_antenna_resp(tpAniSirGlobal mac, void *body) return; } +/** + * lim_update_default_scan_ies() - Update Extended capabilities IE(if present) + * with capabilities of Fine Time measurements(FTM) if set in driver + * + * @mac_ctx: Pointer to Global MAC structure + * @ie_data: Default Scan IE data + * @local_ie_buf: Local Scan IE data + * @local_ie_len: Pointer to length of @ie_data + * + * Return: eSIR_SUCCESS on success, eSIR_FAILURE otherwise + */ +tSirRetStatus lim_update_default_scan_ies(tpAniSirGlobal mac_ctx, + uint8_t *ie_data, uint8_t *local_ie_buf, uint16_t *local_ie_len) +{ + uint32_t dot11mode; + bool vht_enabled = false; + tDot11fIEExtCap default_scan_ext_cap = {0}, driver_ext_cap = {0}; + uint8_t ext_cap_ie_hdr[EXT_CAP_IE_HDR_LEN] = { + DOT11F_EID_EXTCAP, DOT11F_IE_EXTCAP_MAX_LEN}; + tSirRetStatus status; + + status = lim_strip_extcap_update_struct(mac_ctx, ie_data, + local_ie_len, &default_scan_ext_cap); + if (eSIR_SUCCESS != status || + (((*local_ie_len) + EXT_CAP_IE_HDR_LEN + + DOT11F_IE_EXTCAP_MAX_LEN) > MAX_DEFAULT_SCAN_IE_LEN)) { + lim_log(mac_ctx, LOGE, FL("Strip ext cap fails(%d)"), status); + return eSIR_FAILURE; + } + + qdf_mem_copy(local_ie_buf, ie_data, (*local_ie_len)); + qdf_mem_copy(local_ie_buf + (*local_ie_len), + ext_cap_ie_hdr, EXT_CAP_IE_HDR_LEN); + (*local_ie_len) += EXT_CAP_IE_HDR_LEN; + + wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &dot11mode); + if (IS_DOT11_MODE_VHT(dot11mode)) + vht_enabled = true; + + status = populate_dot11f_ext_cap(mac_ctx, vht_enabled, + &driver_ext_cap, NULL); + if (eSIR_SUCCESS != status) { + lim_log(mac_ctx, LOGE, FL("Update ext cap fails")); + qdf_mem_copy(local_ie_buf + (*local_ie_len), + default_scan_ext_cap.bytes, + DOT11F_IE_EXTCAP_MAX_LEN); + (*local_ie_len) += DOT11F_IE_EXTCAP_MAX_LEN; + return eSIR_SUCCESS; + } + lim_merge_extcap_struct(&driver_ext_cap, &default_scan_ext_cap); + + qdf_mem_copy(local_ie_buf + (*local_ie_len), + driver_ext_cap.bytes, DOT11F_IE_EXTCAP_MAX_LEN); + (*local_ie_len) += DOT11F_IE_EXTCAP_MAX_LEN; + return eSIR_SUCCESS; +} + +/** + * lim_process_set_default_scan_ie_request() - Process the Set default + * Scan IE request from HDD. + * @mac_ctx: Pointer to Global MAC structure + * @msg_buf: Pointer to incoming data + * + * This function receives the default scan IEs and updates the ext cap IE + * (if present) with FTM capabilities and pass the Scan IEs to WMA. + * + * Return: None + */ +static void lim_process_set_default_scan_ie_request(tpAniSirGlobal mac_ctx, + uint32_t *msg_buf) +{ + struct hdd_default_scan_ie *set_ie_params; + struct vdev_ie_info *wma_ie_params; + uint8_t *local_ie_buf; + uint16_t local_ie_len; + tSirMsgQ msg_q; + tSirRetStatus ret_code; + + if (!msg_buf) { + lim_log(mac_ctx, LOGE, FL("msg_buf is NULL")); + return; + } + + set_ie_params = (struct hdd_default_scan_ie *) msg_buf; + local_ie_len = set_ie_params->ie_len; + + local_ie_buf = qdf_mem_malloc(MAX_DEFAULT_SCAN_IE_LEN); + if (!local_ie_buf) { + lim_log(mac_ctx, LOGE, + FL("Scan IE Update fails due to malloc failure")); + return; + } + + if (lim_update_default_scan_ies(mac_ctx, + (uint8_t *)set_ie_params->ie_data, + local_ie_buf, &local_ie_len)) { + lim_log(mac_ctx, LOGE, FL("Update default scan IEs fails")); + goto scan_ie_send_fail; + } + + wma_ie_params = qdf_mem_malloc(sizeof(*wma_ie_params) + local_ie_len); + if (!wma_ie_params) { + lim_log(mac_ctx, LOGE, FL("fail to alloc wma_ie_params")); + goto scan_ie_send_fail; + } + wma_ie_params->vdev_id = set_ie_params->session_id; + wma_ie_params->ie_id = DEFAULT_SCAN_IE_ID; + wma_ie_params->length = local_ie_len; + wma_ie_params->data = (uint8_t *)(wma_ie_params) + + sizeof(*wma_ie_params); + qdf_mem_copy(wma_ie_params->data, local_ie_buf, local_ie_len); + + msg_q.type = WMA_SET_IE_INFO; + msg_q.bodyptr = wma_ie_params; + msg_q.bodyval = 0; + ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q); + if (eSIR_SUCCESS != ret_code) { + lim_log(mac_ctx, LOGE, FL("fail to send WMA_SET_IE_INFO")); + qdf_mem_free(wma_ie_params); + } +scan_ie_send_fail: + qdf_mem_free(local_ie_buf); +} + /** * lim_process_hw_mode_trans_ind() - Process set HW mode transition indication * @mac: Global MAC pointer @@ -1895,6 +2019,11 @@ void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; break; + case eWNI_SME_DEFAULT_SCAN_IE: + lim_process_set_default_scan_ie_request(mac_ctx, msg->bodyptr); + qdf_mem_free((void *)msg->bodyptr); + msg->bodyptr = NULL; + break; default: qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 9e0e659691a5..810a35d987f9 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1261,4 +1261,6 @@ QDF_STATUS sme_update_sta_roam_policy(tHalHandle hal, uint8_t session_id); QDF_STATUS sme_enable_disable_chanavoidind_event(tHalHandle hal, uint8_t set_value); +QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id, + uint8_t *ie_data, uint16_t ie_len); #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 44c132c10e89..9eb816c34755 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -16570,6 +16570,40 @@ QDF_STATUS sme_enable_disable_chanavoidind_event(tHalHandle hal, sme_release_global_lock(&mac_ctx->sme); return status; } - + return status; +} + +/* + * sme_set_default_scan_ie() - API to send default scan IE to LIM + * @hal: reference to the HAL + * @session_id: current session ID + * @ie_data: Pointer to Scan IE data + * @ie_len: Length of @ie_data + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id, + uint8_t *ie_data, uint16_t ie_len) +{ + QDF_STATUS status; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + struct hdd_default_scan_ie *set_ie_params; + + status = sme_acquire_global_lock(&mac_ctx->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + set_ie_params = qdf_mem_malloc(sizeof(*set_ie_params)); + if (!set_ie_params) + status = QDF_STATUS_E_NOMEM; + else { + set_ie_params->message_type = eWNI_SME_DEFAULT_SCAN_IE; + set_ie_params->length = sizeof(*set_ie_params); + set_ie_params->session_id = session_id; + set_ie_params->ie_len = ie_len; + qdf_mem_copy(set_ie_params->ie_data, ie_data, ie_len); + status = cds_send_mb_message_to_mac(set_ie_params); + } + sme_release_global_lock(&mac_ctx->sme); + } + sms_log(mac_ctx, LOG1, FL("Set default scan IE status %d"), status); return status; } diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 84f2f6650c0b..9a823e8c7932 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -100,6 +100,13 @@ (1 << WOW_DISASSOC_RECVD_EVENT) |\ (1 << WOW_HTT_EVENT))\ +/** + * WMA_SET_VDEV_IE_SOURCE_HOST - Flag to identify the source of VDEV SET IE + * command. The value is 0x0 for the VDEV SET IE WMI commands from mobile + * MCL platform. + */ +#define WMA_SET_VDEV_IE_SOURCE_HOST 0x0 + static const uint8_t arp_ptrn[] = {0x08, 0x06}; static const uint8_t arp_mask[] = {0xff, 0xff}; static const uint8_t ns_ptrn[] = {0x86, 0xDD}; @@ -7730,6 +7737,7 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma, cmd.length = ie_info->length; cmd.band = ie_info->band; cmd.data = ie_info->data; + cmd.ie_source = WMA_SET_VDEV_IE_SOURCE_HOST; WMA_LOGD(FL("ie_id: %d, band: %d, len: %d"), ie_info->ie_id, ie_info->band, ie_info->length); @@ -7739,7 +7747,6 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma, ret = wmi_unified_process_set_ie_info_cmd(wma->wmi_handle, &cmd); - return ret; }