Browse Source

qcacld-3.0: Update the connect ies to prevent 40 MHz roam

If "override_ht20_40_24g" ini is set, the host driver disables
the HT40/HE40 caps for 2.4 GHz after connection via SET IE. The
firmware uses this for roam. However, if reassoc comes from userspace
with the HT40 cap different from the initial connect, then host
does not update the IEs based on new cap. This leads to mismatch
between user configuration and firmware roam.

To fix this, modify and send the HE40/HT40 caps via SET IE for
every connect request. Reset it after disconnection to the default
self cap.

Change-Id: I58e14e8ae8e8842e1d79a0284c4240ac7d279272
CRs-Fixed: 3651600
Surya Prakash Sivaraj 1 year ago
parent
commit
298b451a67

+ 3 - 0
components/mlme/core/inc/wlan_mlme_main.h

@@ -428,6 +428,8 @@ struct assoc_channel_info {
  * @ext_cap_ie: Ext CAP IE
  * @assoc_btm_cap: BSS transition management cap used in (re)assoc req
  * @assoc_chan_info: store channel info at the time of association
+ * @force_20mhz_in_24ghz: Only 20 MHz BW allowed in 2.4 GHz
+ *
  */
 struct mlme_connect_info {
 	uint8_t timing_meas_cap;
@@ -454,6 +456,7 @@ struct mlme_connect_info {
 	uint8_t ext_cap_ie[DOT11F_IE_EXTCAP_MAX_LEN + 2];
 	bool assoc_btm_cap;
 	struct assoc_channel_info assoc_chan_info;
+	bool force_20mhz_in_24ghz;
 };
 
 /** struct wait_for_key_timer - wait for key timer object

+ 16 - 9
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_api.h

@@ -41,7 +41,6 @@
  * struct cm_vdev_join_req - connect req from legacy CM to vdev manager
  * @vdev_id: vdev id
  * @cm_id: Connect manager id
- * @force_24ghz_in_ht20: force 24ghz_in ht20
  * @force_rsne_override: force the arbitrary rsne received in connect req to be
  * used with out validation, used for the scenarios where the device is used
  * as a testbed device with special functionality and not recommended
@@ -58,8 +57,7 @@
 struct cm_vdev_join_req {
 	uint8_t vdev_id;
 	wlan_cm_id cm_id;
-	uint8_t force_24ghz_in_ht20:1,
-		force_rsne_override:1,
+	uint8_t force_rsne_override:1,
 		is_wps_connection:1,
 		is_osen_connection:1;
 	struct element_info assoc_ie;
@@ -300,6 +298,15 @@ QDF_STATUS cm_get_rssi_snr_by_bssid(struct wlan_objmgr_pdev *pdev,
  */
 void cm_csr_send_set_ie(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * cm_csr_get_vdev_dot11_mode() - Wrapper for CM to get the dot11mode for
+ * the vdev id
+ * @vdev_id: vdev id
+ *
+ * Return: dot11 mode
+ */
+uint16_t cm_csr_get_vdev_dot11_mode(uint8_t vdev_id);
+
 static inline QDF_STATUS
 cm_ext_hdl_create(struct wlan_objmgr_vdev *vdev, cm_ext_t **ext_cm_ptr)
 {
@@ -355,8 +362,8 @@ QDF_STATUS cm_csr_handle_join_req(struct wlan_objmgr_vdev *vdev,
 				  bool reassoc);
 
 /**
- * cm_handle_connect_req() - Connection manager ext connect request to start
- * vdev and peer assoc state machine
+ * cm_handle_connect_req() - Connection manager ext connect request to
+ * start vdev and peer assoc state machine
  * @vdev: VDEV object
  * @req: Vdev connect request
  *
@@ -364,7 +371,7 @@ QDF_STATUS cm_csr_handle_join_req(struct wlan_objmgr_vdev *vdev,
  */
 QDF_STATUS
 cm_handle_connect_req(struct wlan_objmgr_vdev *vdev,
-		      struct wlan_cm_vdev_connect_req *req);
+			    struct wlan_cm_vdev_connect_req *req);
 
 /**
  * cm_send_bss_peer_create_req() - Connection manager ext bss peer create
@@ -505,7 +512,7 @@ cm_disconnect_complete_ind(struct wlan_objmgr_vdev *vdev,
 			   struct wlan_cm_discon_rsp *rsp);
 
 /**
- * cm_csr_diconnect_done_ind() - Connection manager call to csr to update
+ * cm_csr_disconnect_done_ind() - Connection manager call to csr to update
  * legacy structures on disconnect complete
  * @vdev: VDEV object
  * @rsp: Connection manager disconnect response
@@ -517,8 +524,8 @@ cm_disconnect_complete_ind(struct wlan_objmgr_vdev *vdev,
  * Return: QDF_STATUS
  */
 QDF_STATUS
-cm_csr_diconnect_done_ind(struct wlan_objmgr_vdev *vdev,
-			  struct wlan_cm_discon_rsp *rsp);
+cm_csr_disconnect_done_ind(struct wlan_objmgr_vdev *vdev,
+			   struct wlan_cm_discon_rsp *rsp);
 
 /**
  * cm_send_vdev_down_req() - Connection manager ext req to send vdev down

+ 1 - 4
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -1422,7 +1422,7 @@ cm_update_hlp_data_from_assoc_ie(struct wlan_objmgr_vdev *vdev,
 
 QDF_STATUS
 cm_handle_connect_req(struct wlan_objmgr_vdev *vdev,
-		      struct wlan_cm_vdev_connect_req *req)
+			    struct wlan_cm_vdev_connect_req *req)
 {
 	struct cm_vdev_join_req *join_req;
 	struct scheduler_msg msg;
@@ -1473,9 +1473,6 @@ cm_handle_connect_req(struct wlan_objmgr_vdev *vdev,
 			   req->bss->entry->bssid.bytes,
 			   req->bss->entry->neg_sec_info.key_mgmt,
 			   req->bss->entry->channel.chan_freq);
-	if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g &&
-	    !(req->ht_caps & WLAN_HTCAP_C_CHWIDTH40))
-		join_req->force_24ghz_in_ht20 = true;
 
 	msg.bodyptr = join_req;
 	msg.type = CM_CONNECT_REQ;

+ 1 - 1
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_disconnect.c

@@ -241,7 +241,7 @@ cm_disconnect_complete_ind(struct wlan_objmgr_vdev *vdev,
 		mlme_err("vdev or rsp is NULL");
 		return QDF_STATUS_E_INVAL;
 	}
-	cm_csr_diconnect_done_ind(vdev, rsp);
+	cm_csr_disconnect_done_ind(vdev, rsp);
 
 	vdev_id = wlan_vdev_get_id(vdev);
 	op_mode = wlan_vdev_mlme_get_opmode(vdev);

+ 34 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -2080,6 +2080,40 @@ wlan_cm_get_assoc_btm_cap(struct wlan_objmgr_vdev *vdev);
  */
 bool wlan_cm_is_self_mld_roam_supported(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * wlan_cm_set_force_20mhz_in_24ghz() - Sets the config to (dis)allow
+ * the 40 MHz connection in 2.4 GHz
+ *
+ * @vdev: pointer to vdev
+ * @is_40mhz_cap: is 40 MHz supported
+ *
+ * Return: None
+ */
+void
+wlan_cm_set_force_20mhz_in_24ghz(struct wlan_objmgr_vdev *vdev,
+				 bool is_40mhz_cap);
+
+/**
+ * wlan_cm_get_force_20mhz_in_24ghz - Gets the 40 MHz (dis)allowed on 2.4 GHz
+ * config
+ * @vdev: pointer to vdev
+ *
+ * Return: 40 MHz allowed on 2.4 GHz
+ */
+bool
+wlan_cm_get_force_20mhz_in_24ghz(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * cm_send_ies_for_roam_invoke - Send IEs to firmware based on the reassoc
+ * req received from the userspace
+ * @vdev: vdev
+ * @dot11_mode: dot11 mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+cm_send_ies_for_roam_invoke(struct wlan_objmgr_vdev *vdev, uint16_t dot11_mode);
+
 #ifdef WLAN_FEATURE_11BE_MLO
 /**
  * wlan_cm_is_sae_auth_addr_conversion_required() - check whether address

+ 56 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -4931,6 +4931,62 @@ bool wlan_cm_is_self_mld_roam_supported(struct wlan_objmgr_psoc *psoc)
 				   wmi_service_self_mld_roam_between_dbs_and_hbs);
 }
 
+void
+wlan_cm_set_force_20mhz_in_24ghz(struct wlan_objmgr_vdev *vdev,
+				 bool is_40mhz_cap)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
+	struct mlme_legacy_priv *mlme_priv;
+	uint16_t dot11_mode;
+	bool send_ie_to_fw = false;
+
+	if (!vdev)
+		return;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc)
+		return;
+
+	mlme_obj = mlme_get_psoc_ext_obj(psoc);
+	if (!mlme_obj || !mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g)
+		return;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv)
+		return;
+
+	/*
+	 * Force 20 MHz in 2.4 GHz only if "override_ht20_40_24g" ini
+	 * is set and userspace connect req doesn't have 40 MHz HT caps
+	 */
+	if (mlme_priv->connect_info.force_20mhz_in_24ghz != !is_40mhz_cap)
+		send_ie_to_fw = true;
+
+	mlme_priv->connect_info.force_20mhz_in_24ghz = !is_40mhz_cap;
+
+	if (cm_is_vdev_connected(vdev) && send_ie_to_fw) {
+		dot11_mode =
+			cm_csr_get_vdev_dot11_mode(wlan_vdev_get_id(vdev));
+		cm_send_ies_for_roam_invoke(vdev, dot11_mode);
+	}
+}
+
+bool
+wlan_cm_get_force_20mhz_in_24ghz(struct wlan_objmgr_vdev *vdev)
+{
+	struct mlme_legacy_priv *mlme_priv;
+
+	if (!vdev)
+		return true;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv)
+		return true;
+
+	return mlme_priv->connect_info.force_20mhz_in_24ghz;
+}
+
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 QDF_STATUS
 wlan_cm_update_offload_ssid_from_candidate(struct wlan_objmgr_pdev *pdev,

+ 17 - 0
core/mac/inc/sir_api.h

@@ -640,6 +640,22 @@ typedef QDF_STATUS
 		     uint8_t session_id, uint8_t reason,
 		     enum wlan_cm_rso_control_requestor requestor);
 
+/**
+ * typedef set_ies_fn_t - Set IEs routine pointer
+ * @mac_ctx: Global MAC context
+ * @vdev_id: vdev id
+ * @dot11_mode: dot11 mode
+ * @opmode: device opmode
+ *
+ * This type is for callbacks registered with WMA to set the IEs for a
+ * given vdev id to the firmware.
+ *
+ * Return: Success or Failure
+ */
+typedef QDF_STATUS
+(*set_ies_fn_t)(struct mac_context *mac_ctx, uint8_t vdev_id,
+		uint16_t dot11_mode, enum QDF_OPMODE device_mode);
+
 /* / Definition for indicating all modules ready on STA */
 struct sme_ready_req {
 	uint16_t messageType;   /* eWNI_SME_SYS_READY_IND */
@@ -657,6 +673,7 @@ struct sme_ready_req {
 					uint8_t *deauth_disassoc_frame,
 					uint16_t deauth_disassoc_frame_len,
 					uint16_t reason_code);
+	set_ies_fn_t pe_roam_set_ie_cb;
 };
 
 /**

+ 11 - 0
core/mac/src/pe/include/lim_api.h

@@ -371,6 +371,10 @@ pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id,
 		       uint16_t deauth_disassoc_frame_len,
 		       uint16_t reason_code);
 
+QDF_STATUS
+pe_set_ie_for_roam_invoke(struct mac_context *mac_ctx, uint8_t vdev_id,
+			  uint16_t dot11_mode, enum QDF_OPMODE opmode);
+
 #else
 static inline QDF_STATUS
 pe_roam_synch_callback(struct mac_context *mac_ctx,
@@ -390,6 +394,13 @@ pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id,
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
+
+static inline QDF_STATUS
+pe_set_ie_for_roam_invoke(struct mac_context *mac_ctx, uint8_t vdev_id,
+			  uint16_t dot11_mode, enum QDF_OPMODE opmode)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
 #endif
 
 /**

+ 0 - 2
core/mac/src/pe/include/lim_session.h

@@ -635,7 +635,6 @@ struct wlan_mlo_ie_info {
  * @deauth_retry:
  * @enable_bcast_probe_rsp:
  * @ht_client_cnt:
- * @force_24ghz_in_ht20:
  * @ch_switch_in_progress:
  * @he_with_wep_tkip:
  * @fils_info:
@@ -957,7 +956,6 @@ struct pe_session {
 	struct deauth_retry_params deauth_retry;
 	bool enable_bcast_probe_rsp;
 	uint8_t ht_client_cnt;
-	bool force_24ghz_in_ht20;
 	bool ch_switch_in_progress;
 	bool he_with_wep_tkip;
 #ifdef WLAN_FEATURE_FILS_SK

+ 16 - 1
core/mac/src/pe/lim/lim_api.c

@@ -1369,7 +1369,8 @@ void pe_register_callbacks_with_wma(struct mac_context *mac,
 	status = wma_register_roaming_callbacks(
 			ready_req->csr_roam_auth_event_handle_cb,
 			ready_req->pe_roam_synch_cb,
-			ready_req->pe_disconnect_cb);
+			ready_req->pe_disconnect_cb,
+			ready_req->pe_roam_set_ie_cb);
 	if (status != QDF_STATUS_SUCCESS)
 		pe_err("Registering roaming callbacks with WMA failed");
 }
@@ -3184,6 +3185,20 @@ roam_sync_fail:
 	pe_delete_session(mac_ctx, ft_session_ptr);
 	return status;
 }
+
+QDF_STATUS
+pe_set_ie_for_roam_invoke(struct mac_context *mac_ctx, uint8_t vdev_id,
+			  uint16_t dot11_mode, enum QDF_OPMODE opmode)
+{
+	QDF_STATUS status;
+
+	if (!mac_ctx)
+		return QDF_STATUS_E_FAILURE;
+
+	status = lim_send_ies_per_band(mac_ctx, vdev_id, dot11_mode, opmode);
+	return status;
+}
+
 #endif
 
 static bool lim_is_beacon_miss_scenario(struct mac_context *mac,

+ 3 - 3
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -429,6 +429,7 @@ static bool __lim_process_sme_sys_ready_ind(struct mac_context *mac,
 	if (ANI_DRIVER_TYPE(mac) != QDF_DRIVER_TYPE_MFG) {
 		ready_req->pe_roam_synch_cb = pe_roam_synch_callback;
 		ready_req->pe_disconnect_cb = pe_disconnect_callback;
+		ready_req->pe_roam_set_ie_cb = pe_set_ie_for_roam_invoke;
 		pe_register_mgmt_rx_frm_callback(mac);
 		pe_register_callbacks_with_wma(mac, ready_req);
 		mac->lim.sme_msg_callback = ready_req->sme_msg_cb;
@@ -3277,8 +3278,9 @@ lim_fill_pe_session(struct mac_context *mac_ctx, struct pe_session *session,
 	}
 	cb_mode = wlan_get_cb_mode(mac_ctx, session->curr_op_freq, ie_struct,
 				   session);
+
 	if (WLAN_REG_IS_24GHZ_CH_FREQ(bss_desc->chan_freq) &&
-	    session->force_24ghz_in_ht20)
+	    wlan_cm_get_force_20mhz_in_24ghz(session->vdev))
 		cb_mode = PHY_SINGLE_CHANNEL_CENTERED;
 
 	status = wlan_get_rate_set(mac_ctx, ie_struct, session);
@@ -4552,8 +4554,6 @@ lim_fill_session_params(struct mac_context *mac_ctx,
 	qdf_mem_copy(session->ssId.ssId, req->entry->ssid.ssid,
 		     session->ssId.length);
 
-	session->force_24ghz_in_ht20 = req->force_24ghz_in_ht20;
-
 	status = lim_fill_pe_session(mac_ctx, session, bss_desc);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		pe_err("Failed to fill pe session vdev id %d",

+ 1 - 1
core/mac/src/pe/lim/lim_session.c

@@ -1124,7 +1124,7 @@ void lim_dump_session_info(struct mac_context *mac_ctx,
 
 	pe_nofl_debug(" MaxTxPwr %d RMF %d force_20_24 %d UAPSD flag 0x%2x auth type %d privacy %d",
 		      pe_session->maxTxPower, pe_session->limRmfEnabled,
-		      pe_session->force_24ghz_in_ht20,
+		      wlan_cm_get_force_20mhz_in_24ghz(pe_session->vdev),
 		      pe_session->gUapsdPerAcBitmask,
 		      mac_ctx->mlme_cfg->wep_params.auth_type,
 		      mac_ctx->mlme_cfg->wep_params.is_privacy_enabled);

+ 13 - 5
core/mac/src/pe/lim/lim_utils.c

@@ -3823,7 +3823,7 @@ uint8_t lim_get_cb_mode_for_freq(struct mac_context *mac,
 	uint8_t cb_mode = mac->roam.configParam.channelBondingMode5GHz;
 
 	if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
-		if (session->force_24ghz_in_ht20) {
+		if (wlan_cm_get_force_20mhz_in_24ghz(session->vdev)) {
 			cb_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
 			pe_debug_rl("vdev %d force 20 Mhz in 2.4 GHz",
 				    session->vdev_id);
@@ -3839,14 +3839,22 @@ static
 uint8_t lim_get_sta_cb_mode_for_24ghz(struct mac_context *mac,
 				      uint8_t vdev_id)
 {
-	struct pe_session *session;
+	struct wlan_objmgr_vdev *vdev;
 	uint8_t cb_mode = mac->roam.configParam.channelBondingMode24GHz;
 
-	session = pe_find_session_by_vdev_id(mac, vdev_id);
-	if (!session || !session->force_24ghz_in_ht20)
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc,
+						    vdev_id, WLAN_MLME_SB_ID);
+	if (!vdev)
 		return cb_mode;
 
-	return WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+	if (!wlan_cm_get_force_20mhz_in_24ghz(vdev))
+		goto end;
+
+	cb_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+
+end:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
+	return cb_mode;
 }
 
 void lim_update_sta_run_time_ht_switch_chnl_params(struct mac_context *mac,

+ 17 - 6
core/sme/src/csr/csr_api_roam.c

@@ -5760,8 +5760,10 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev,
 	 * Update the IEs after connection to reconfigure
 	 * any capability that changed during connection.
 	 */
-	sme_set_vdev_ies_per_band(mac_handle, vdev_id,
-				  wlan_vdev_mlme_get_opmode(vdev));
+	if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g)
+		sme_set_vdev_ies_per_band(mac_handle, vdev_id,
+					  wlan_vdev_mlme_get_opmode(vdev));
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -5818,12 +5820,13 @@ QDF_STATUS cm_csr_handle_diconnect_req(struct wlan_objmgr_vdev *vdev,
 }
 
 QDF_STATUS
-cm_csr_diconnect_done_ind(struct wlan_objmgr_vdev *vdev,
-			  struct wlan_cm_discon_rsp *rsp)
+cm_csr_disconnect_done_ind(struct wlan_objmgr_vdev *vdev,
+			   struct wlan_cm_discon_rsp *rsp)
 {
 	mac_handle_t mac_handle;
 	struct mac_context *mac_ctx;
 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
+	struct wlan_mlme_psoc_ext_obj *mlme_obj;
 
 	/*
 	 * This API is to update legacy struct and should be removed once
@@ -5836,6 +5839,10 @@ cm_csr_diconnect_done_ind(struct wlan_objmgr_vdev *vdev,
 	if (!mac_ctx)
 		return QDF_STATUS_E_INVAL;
 
+	mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc);
+	if (!mlme_obj)
+		return QDF_STATUS_E_INVAL;
+
 	cm_csr_set_idle(vdev_id);
 	if (cm_is_vdev_roaming(vdev))
 		sme_qos_update_hand_off(vdev_id, false);
@@ -5846,8 +5853,12 @@ cm_csr_diconnect_done_ind(struct wlan_objmgr_vdev *vdev,
 	 * any connection specific capability change and
 	 * to reset back to self cap
 	 */
-	sme_set_vdev_ies_per_band(mac_handle, vdev_id,
-				  wlan_vdev_mlme_get_opmode(vdev));
+	if (mlme_obj->cfg.obss_ht40.is_override_ht20_40_24g) {
+		wlan_cm_set_force_20mhz_in_24ghz(vdev, true);
+		sme_set_vdev_ies_per_band(mac_handle, vdev_id,
+					  wlan_vdev_mlme_get_opmode(vdev));
+	}
+
 	return QDF_STATUS_SUCCESS;
 }
 

+ 16 - 0
core/sme/src/csr/csr_util.c

@@ -303,6 +303,22 @@ bool csr_is_conn_state_wds(struct mac_context *mac, uint32_t sessionId)
 	       csr_is_conn_state_disconnected_wds(mac, sessionId);
 }
 
+uint16_t cm_csr_get_vdev_dot11_mode(uint8_t vdev_id)
+{
+	mac_handle_t mac_handle;
+	struct mac_context *mac_ctx;
+	enum csr_cfgdot11mode curr_dot11_mode;
+
+	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
+	mac_ctx = MAC_CONTEXT(mac_handle);
+	if (!mac_ctx)
+		return eCSR_CFG_DOT11_MODE_AUTO;
+
+	curr_dot11_mode = mac_ctx->roam.configParam.uCfgDot11Mode;
+
+	return csr_get_vdev_dot11_mode(mac_ctx, vdev_id, curr_dot11_mode);
+}
+
 enum csr_cfgdot11mode
 csr_get_vdev_dot11_mode(struct mac_context *mac,
 			uint8_t vdev_id,

+ 4 - 0
core/wma/inc/wma.h

@@ -889,6 +889,7 @@ struct wma_wlm_stats_data {
  * @pe_roam_synch_cb: pe callback for firmware Roam Sync events
  * @csr_roam_auth_event_handle_cb: CSR callback for target authentication
  * offload event.
+ * @pe_roam_set_ie_cb: PE callback to set IEs to firmware.
  * @wmi_cmd_rsp_wake_lock: wmi command response wake lock
  * @wmi_cmd_rsp_runtime_lock: wmi command response bus lock
  * @active_uc_apf_mode: Setting that determines how APF is applied in
@@ -1017,6 +1018,9 @@ typedef struct {
 					uint8_t *deauth_disassoc_frame,
 					uint16_t deauth_disassoc_frame_len,
 					uint16_t reason_code);
+	QDF_STATUS (*pe_roam_set_ie_cb)(struct mac_context *mac_ctx,
+					uint8_t vdev_id, uint16_t dot11_mode,
+					enum QDF_OPMODE device_mode);
 	qdf_wake_lock_t wmi_cmd_rsp_wake_lock;
 	qdf_runtime_lock_t wmi_cmd_rsp_runtime_lock;
 	qdf_runtime_lock_t sap_prevent_runtime_pm_lock;

+ 4 - 2
core/wma/inc/wma_types.h

@@ -746,7 +746,8 @@ QDF_STATUS wma_register_roaming_callbacks(
 			uint8_t vdev_id,
 			uint8_t *deauth_disassoc_frame,
 			uint16_t deauth_disassoc_frame_len,
-			uint16_t reason_code));
+			uint16_t reason_code),
+		set_ies_fn_t pe_roam_set_ie_cb);
 #else
 static inline QDF_STATUS wma_register_roaming_callbacks(
 		QDF_STATUS (*csr_roam_auth_event_handle_cb)(
@@ -759,7 +760,8 @@ static inline QDF_STATUS wma_register_roaming_callbacks(
 			uint8_t vdev_id,
 			uint8_t *deauth_disassoc_frame,
 			uint16_t deauth_disassoc_frame_len,
-			uint16_t reason_code))
+			uint16_t reason_code),
+		set_ies_fn_t pe_roam_set_ie_cb)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }

+ 22 - 1
core/wma/src/wma_mgmt.c

@@ -3930,7 +3930,8 @@ QDF_STATUS wma_register_roaming_callbacks(
 					uint8_t vdev_id,
 					uint8_t *deauth_disassoc_frame,
 					uint16_t deauth_disassoc_frame_len,
-					uint16_t reason_code))
+					uint16_t reason_code),
+	set_ies_fn_t pe_roam_set_ie_cb)
 {
 
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
@@ -3941,6 +3942,7 @@ QDF_STATUS wma_register_roaming_callbacks(
 	wma->csr_roam_auth_event_handle_cb = csr_roam_auth_event_handle_cb;
 	wma->pe_roam_synch_cb = pe_roam_synch_cb;
 	wma->pe_disconnect_cb = pe_disconnect_cb;
+	wma->pe_roam_set_ie_cb = pe_roam_set_ie_cb;
 	wma_debug("Registered roam synch callbacks with WMA successfully");
 
 	return QDF_STATUS_SUCCESS;
@@ -4189,3 +4191,22 @@ wma_update_bss_peer_phy_mode(struct wlan_channel *des_chan,
 
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS
+cm_send_ies_for_roam_invoke(struct wlan_objmgr_vdev *vdev, uint16_t dot11_mode)
+{
+	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
+	enum QDF_OPMODE op_mode;
+	QDF_STATUS status;
+	uint8_t vdev_id;
+
+	if (!wma)
+		return QDF_STATUS_E_FAILURE;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+	op_mode = wlan_vdev_mlme_get_opmode(vdev);
+
+	status = wma->pe_roam_set_ie_cb(wma->mac_context, vdev_id, dot11_mode,
+					op_mode);
+	return status;
+}