Selaa lähdekoodia

qcacmn: Add support for 11d FW commands and events

Add support to send 11d scan start and stop commands to FW and
process the 11d new country update event from FW.

Change-Id: I5c1588cfb5af672cdb5738784de1bd0b83bdbe77
CRs-Fixed: 2048784
Kiran Kumar Lokere 8 vuotta sitten
vanhempi
sitoutus
82c8645b38

+ 94 - 2
target_if/regulatory/src/target_if_reg.c

@@ -108,6 +108,48 @@ static int tgt_reg_chan_list_update_handler(ol_scn_t handle,
 	return 0;
 }
 
+static int tgt_reg_11d_new_cc_handler(ol_scn_t handle,
+		uint8_t *event_buf, uint32_t len)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
+	struct reg_11d_new_country reg_11d_new_cc;
+	QDF_STATUS status;
+
+	TARGET_IF_ENTER();
+
+	psoc = target_if_get_psoc_from_scn_hdl(handle);
+	if (!psoc) {
+		target_if_err("psoc ptr is NULL");
+		return -EINVAL;
+	}
+
+	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
+
+	if (!reg_rx_ops->reg_11d_new_cc_handler) {
+		target_if_err("reg_11d_new_cc_handler is NULL");
+		return -EINVAL;
+	}
+
+	if (wmi_extract_reg_11d_new_cc_event(GET_WMI_HDL_FROM_PSOC(psoc),
+				event_buf, &reg_11d_new_cc, len) !=
+			QDF_STATUS_SUCCESS) {
+
+		target_if_err("Extraction of new country event failed");
+		return -EFAULT;
+	}
+
+	status = reg_rx_ops->reg_11d_new_cc_handler(psoc, &reg_11d_new_cc);
+	if (status != QDF_STATUS_SUCCESS) {
+		target_if_err("Failed to process new country code event");
+		return -EFAULT;
+	}
+
+	target_if_debug("processed 11d new country code event");
+
+	return 0;
+}
+
 static QDF_STATUS tgt_if_regulatory_register_master_list_handler(
 	struct wlan_objmgr_psoc *psoc, void *arg)
 {
@@ -135,7 +177,49 @@ static QDF_STATUS tgt_if_regulatory_set_country_code(
 	wmi_unified_t wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
 
 	return wmi_unified_set_country_cmd_send(wmi_handle, arg);
+
 }
+
+static QDF_STATUS tgt_if_regulatory_register_11d_new_cc_handler(
+	struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	wmi_unified_t wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+
+	return wmi_unified_register_event_handler(wmi_handle,
+						  WMI_11D_NEW_COUNTRY_EVENTID,
+						  tgt_reg_11d_new_cc_handler,
+						  WMI_RX_UMAC_CTX);
+}
+
+static QDF_STATUS tgt_if_regulatory_unregister_11d_new_cc_handler(
+	struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	wmi_unified_t wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+
+	return wmi_unified_unregister_event_handler(wmi_handle,
+			WMI_11D_NEW_COUNTRY_EVENTID);
+}
+
+static QDF_STATUS tgt_if_regulatory_start_11d_scan(
+		struct wlan_objmgr_psoc *psoc,
+		struct reg_start_11d_scan_req *reg_start_11d_scan_req)
+{
+	wmi_unified_t wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+
+	return wmi_unified_send_start_11d_scan_cmd(wmi_handle,
+			reg_start_11d_scan_req);
+}
+
+static QDF_STATUS tgt_if_regulatory_stop_11d_scan(
+		struct wlan_objmgr_psoc *psoc,
+		struct reg_stop_11d_scan_req *reg_stop_11d_scan_req)
+{
+	wmi_unified_t wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+
+	return wmi_unified_send_stop_11d_scan_cmd(wmi_handle,
+			reg_stop_11d_scan_req);
+}
+
 QDF_STATUS target_if_register_regulatory_tx_ops(struct wlan_lmac_if_tx_ops
 						*tx_ops)
 {
@@ -151,8 +235,16 @@ QDF_STATUS target_if_register_regulatory_tx_ops(struct wlan_lmac_if_tx_ops
 
 	reg_ops->fill_umac_legacy_chanlist = NULL;
 
-	return QDF_STATUS_SUCCESS;
-}
+	reg_ops->register_11d_new_cc_handler =
+		tgt_if_regulatory_register_11d_new_cc_handler;
+
+	reg_ops->unregister_11d_new_cc_handler =
+		tgt_if_regulatory_unregister_11d_new_cc_handler;
 
+	reg_ops->start_11d_scan = tgt_if_regulatory_start_11d_scan;
 
+	reg_ops->stop_11d_scan = tgt_if_regulatory_stop_11d_scan;
+
+	return QDF_STATUS_SUCCESS;
+}
 

+ 13 - 0
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -541,16 +541,27 @@ struct wlan_lmac_if_nan_tx_ops {
  *                  pointers for regulatory component
  * @register_master_handler: pointer to register event handler
  * @unregister_master_handler:  pointer to unregister event handler
+ * @register_11d_new_cc_handler: pointer to register 11d cc event handler
+ * @unregister_11d_new_cc_handler:  pointer to unregister 11d cc event handler
  */
 struct wlan_lmac_if_reg_tx_ops {
 	QDF_STATUS (*register_master_handler)(struct wlan_objmgr_psoc *psoc,
 					      void *arg);
 	QDF_STATUS (*unregister_master_handler)(struct wlan_objmgr_psoc *psoc,
 						void *arg);
+
 	QDF_STATUS (*set_country_code)(struct wlan_objmgr_psoc *psoc,
 						void *arg);
 	QDF_STATUS (*fill_umac_legacy_chanlist)(struct wlan_objmgr_pdev *pdev,
 			struct regulatory_channel *cur_chan_list);
+	QDF_STATUS (*register_11d_new_cc_handler)(
+			struct wlan_objmgr_psoc *psoc, void *arg);
+	QDF_STATUS (*unregister_11d_new_cc_handler)(
+			struct wlan_objmgr_psoc *psoc, void *arg);
+	QDF_STATUS (*start_11d_scan)(struct wlan_objmgr_psoc *psoc,
+			struct reg_start_11d_scan_req *reg_start_11d_scan_req);
+	QDF_STATUS (*stop_11d_scan)(struct wlan_objmgr_psoc *psoc,
+			struct reg_stop_11d_scan_req *reg_stop_11d_scan_req);
 };
 
 /**
@@ -741,6 +752,8 @@ struct wlan_lmac_if_pmo_rx_ops {
 struct wlan_lmac_if_reg_rx_ops {
 	QDF_STATUS (*master_list_handler)(struct cur_regulatory_info
 					  *reg_info);
+	QDF_STATUS (*reg_11d_new_cc_handler)(struct wlan_objmgr_psoc *psoc,
+			struct reg_11d_new_country *reg_11d_new_cc);
 };
 
 #ifdef CONVERGED_P2P_ENABLE

+ 3 - 0
umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c

@@ -319,6 +319,9 @@ wlan_lmac_if_umac_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
 	rx_ops->reg_rx_ops.master_list_handler =
 		tgt_reg_process_master_chan_list;
 
+	rx_ops->reg_rx_ops.reg_11d_new_cc_handler =
+		tgt_reg_process_11d_new_country;
+
 	/* p2p rx ops */
 	wlan_lmac_if_umac_rx_ops_register_p2p(rx_ops);
 

+ 21 - 6
umac/regulatory/core/src/reg_services.c

@@ -244,10 +244,8 @@ static struct wlan_regulatory_psoc_priv_obj *reg_get_psoc_obj(
 		reg_alert("psoc is NULL");
 		return NULL;
 	}
-	wlan_psoc_obj_lock(psoc);
 	soc_reg = wlan_objmgr_psoc_get_comp_private_obj(psoc,
 				WLAN_UMAC_COMP_REGULATORY);
-	wlan_psoc_obj_unlock(psoc);
 
 	return soc_reg;
 }
@@ -267,10 +265,8 @@ static struct wlan_regulatory_pdev_priv_obj *reg_get_pdev_obj(
 		reg_alert("pdev is NULL");
 		return NULL;
 	}
-	wlan_pdev_obj_lock(pdev);
 	pdev_reg = wlan_objmgr_pdev_get_comp_private_obj(pdev,
 				WLAN_UMAC_COMP_REGULATORY);
-	wlan_pdev_obj_unlock(pdev);
 
 	return pdev_reg;
 }
@@ -2466,7 +2462,6 @@ void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
 	wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
 }
 
-
 void reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
 				       reg_chan_change_callback cbk,
 				       void *arg)
@@ -2540,7 +2535,8 @@ enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
 
 	if (NULL == psoc_priv_obj) {
 		reg_err("reg psoc private obj is NULL");
-		return false;
+
+		return SOURCE_UNKNOWN;
 	}
 
 	qdf_mem_copy(alpha2, psoc_priv_obj->current_country,
@@ -2711,3 +2707,22 @@ QDF_STATUS reg_get_current_cc(struct wlan_objmgr_psoc *psoc,
 
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc,
+		uint8_t *country)
+{
+	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
+
+	psoc_priv_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+					  WLAN_UMAC_COMP_REGULATORY);
+	if (!psoc_priv_obj) {
+		reg_err("reg psoc private obj is NULL");
+
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_copy(psoc_priv_obj->current_country, country, REG_ALPHA2_LEN);
+	psoc_priv_obj->new_11d_ctry_pending = true;
+
+	return QDF_STATUS_SUCCESS;
+}

+ 10 - 0
umac/regulatory/core/src/reg_services.h

@@ -320,4 +320,14 @@ struct chan_change_cbk_entry {
 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
 				    uint8_t *alpha2);
 
+/**
+ * reg_save_new_11d_country() - Save the 11d new country
+ * @psoc: psoc for country information
+ * @country: country value
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc,
+		uint8_t *country);
+
 #endif

+ 28 - 0
umac/regulatory/dispatcher/inc/reg_services_public_struct.h

@@ -295,6 +295,34 @@ struct reg_dmn_supp_op_classes {
 	uint8_t classes[REG_MAX_SUPP_OPER_CLASSES];
 };
 
+/**
+ * struct reg_start_11d_scan_req: start 11d scan request
+ * @vdev_id: vdev id
+ * @scan_period_msec: scan duration in milli-seconds
+ * @start_interval_msec: offset duration to start the scan in milli-seconds
+ */
+struct reg_start_11d_scan_req {
+	uint8_t vdev_id;
+	uint32_t scan_period_msec;
+	uint32_t start_interval_msec;
+};
+
+/**
+ * struct reg_stop_11d_scan_req: stop 11d scan request
+ * @vdev_id: vdev id
+ */
+struct reg_stop_11d_scan_req {
+	uint8_t vdev_id;
+};
+
+/**
+ * struct reg_11d_new_country: regulatory 11d new coutry code
+ * @alpha2: new 11d alpha2
+ */
+struct reg_11d_new_country {
+	uint8_t alpha2[REG_ALPHA2_LEN + 1];
+};
+
 /**
  * enum country_src: country source
  * @SOURCE_QUERY: source query

+ 11 - 3
umac/regulatory/dispatcher/inc/wlan_reg_services_api.h

@@ -349,7 +349,7 @@ QDF_STATUS wlan_reg_set_country(struct wlan_objmgr_pdev *pdev,
 
 /**
  * wlan_reg_register_chan_change_callback () - add chan change cbk
- * @psoc: channel number
+ * @psoc: psoc ptr
  * @cbk: callback
  * @arg: argument
  *
@@ -361,8 +361,8 @@ void wlan_reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
 
 /**
  * wlan_reg_unregister_chan_change_callback () - remove chan change cbk
- * @psoc: channel number
- * @cbk: callback
+ * @psoc: psoc ptr
+ * @cbk:callback
  *
  * Return: true or false
  */
@@ -394,4 +394,12 @@ QDF_STATUS wlan_reg_get_freq_range(struct wlan_objmgr_pdev *pdev,
 		uint32_t *high_2g,
 		uint32_t *low_5g,
 		uint32_t *high_5g);
+/**
+ * wlan_reg_get_tx_ops () - get regulatory tx ops
+ * @psoc: psoc ptr
+ *
+ */
+struct wlan_lmac_if_reg_tx_ops *
+wlan_reg_get_tx_ops(struct wlan_objmgr_psoc *psoc);
+
 #endif

+ 9 - 0
umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h

@@ -33,4 +33,13 @@
 QDF_STATUS tgt_reg_process_master_chan_list(struct cur_regulatory_info
 					    *reg_info);
 
+/**
+ * tgt_reg_process_11d_new_country() - process new 11d country event
+ * @psoc: pointer to psoc
+ * @reg_11d_new_cc: new 11d country pointer
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS tgt_reg_process_11d_new_country(struct wlan_objmgr_psoc *psoc,
+		struct reg_11d_new_country *reg_11d_new_cc);
 #endif

+ 12 - 2
umac/regulatory/dispatcher/src/wlan_reg_services_api.c

@@ -343,20 +343,24 @@ QDF_STATUS regulatory_psoc_open(struct wlan_objmgr_psoc *psoc)
 	tx_ops = reg_get_psoc_tx_ops(psoc);
 	if (tx_ops->register_master_handler)
 		tx_ops->register_master_handler(psoc, NULL);
+	if (tx_ops->register_11d_new_cc_handler)
+		tx_ops->register_11d_new_cc_handler(psoc, NULL);
 
 	return QDF_STATUS_SUCCESS;
-};
+}
 
 QDF_STATUS regulatory_psoc_close(struct wlan_objmgr_psoc *psoc)
 {
 	struct wlan_lmac_if_reg_tx_ops *tx_ops;
 
 	tx_ops = reg_get_psoc_tx_ops(psoc);
+	if (tx_ops->unregister_11d_new_cc_handler)
+		tx_ops->unregister_11d_new_cc_handler(psoc, NULL);
 	if (tx_ops->unregister_master_handler)
 		tx_ops->unregister_master_handler(psoc, NULL);
 
 	return QDF_STATUS_SUCCESS;
-};
+}
 
 void wlan_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list,
 		uint8_t num_ch, bool nol_ch)
@@ -456,3 +460,9 @@ QDF_STATUS wlan_reg_get_freq_range(struct wlan_objmgr_pdev *pdev,
 
 	return QDF_STATUS_SUCCESS;
 }
+
+struct wlan_lmac_if_reg_tx_ops *
+wlan_reg_get_tx_ops(struct wlan_objmgr_psoc *psoc)
+{
+	return reg_get_psoc_tx_ops(psoc);
+}

+ 7 - 0
umac/regulatory/dispatcher/src/wlan_reg_tgt_api.c

@@ -38,3 +38,10 @@ QDF_STATUS tgt_reg_process_master_chan_list(struct cur_regulatory_info
 {
 	return reg_process_master_chan_list(reg_info);
 }
+
+QDF_STATUS tgt_reg_process_11d_new_country(struct wlan_objmgr_psoc *psoc,
+		struct reg_11d_new_country *reg_11d_new_cc)
+{
+	return reg_save_new_11d_country(psoc, reg_11d_new_cc->alpha2);
+}
+

+ 14 - 0
wmi/inc/wmi_unified_priv.h

@@ -1028,6 +1028,14 @@ QDF_STATUS
 (*send_btcoex_wlan_priority_cmd)(wmi_unified_t wmi_handle,
 			struct btcoex_cfg_params *param);
 
+QDF_STATUS
+(*send_start_11d_scan_cmd)(wmi_unified_t wmi_handle,
+			struct reg_start_11d_scan_req *param);
+
+QDF_STATUS
+(*send_stop_11d_scan_cmd)(wmi_unified_t wmi_handle,
+			struct reg_stop_11d_scan_req *param);
+
 QDF_STATUS
 (*send_btcoex_duty_cycle_cmd)(wmi_unified_t wmi_handle,
 			struct btcoex_cfg_params *param);
@@ -1313,6 +1321,12 @@ QDF_STATUS (*extract_reg_chan_list_update_event)(wmi_unified_t wmi_handle,
 						 struct cur_regulatory_info
 						 *reg_info,
 						 uint32_t len);
+
+QDF_STATUS (*extract_reg_11d_new_country_event)(wmi_unified_t wmi_handle,
+		uint8_t *evt_buf,
+		struct reg_11d_new_country *reg_11d_country,
+		uint32_t len);
+
 QDF_STATUS (*extract_chainmask_tables)(wmi_unified_t wmi_handle,
 		uint8_t *evt_buf,
 		struct wlan_psoc_host_chainmask_table *chainmask_table);

+ 34 - 0
wmi/inc/wmi_unified_reg_api.h

@@ -37,4 +37,38 @@ QDF_STATUS wmi_extract_reg_chan_list_update_event(void *wmi_hdl,
 						  struct cur_regulatory_info
 						  *reg_info,
 						  uint32_t len);
+
+/*
+ * wmi_unified_send_stop_11d_scan_cmd() - stop 11d scan
+ * @wmi_handle: wmi handle
+ * @stop_11d_scan: pointer to 11d scan stop req.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wmi_unified_send_stop_11d_scan_cmd(wmi_unified_t wmi_handle,
+		struct reg_stop_11d_scan_req *stop_11d_scan);
+
+/*
+ * wmi_unified_send_start_11d_scan_cmd() - start 11d scan
+ * @wmi_handle: wmi handle
+ * @start_11d_scan: pointer to 11d scan start req.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wmi_unified_send_start_11d_scan_cmd(wmi_unified_t wmi_handle,
+		struct reg_start_11d_scan_req *start_11d_scan);
+
+/**
+ * wmi_extract_reg_11d_new_cc_event() - function to extract the 11d new country
+ * @wmi_hdl: wmi handle
+ * @evt_buf: event buffer
+ * @reg_11d_new_cc: pointer to new 11d country info
+ * @len: length of buffer
+ *
+ * Return: 0 for success or error code
+ */
+QDF_STATUS wmi_extract_reg_11d_new_cc_event(void *wmi_hdl,
+		uint8_t *evt_buf,
+		struct reg_11d_new_country *reg_11d_new_cc,
+		uint32_t len);
 #endif /* _WMI_UNIFIED_REG_API_H_ */

+ 49 - 0
wmi/src/wmi_unified_reg_api.c

@@ -41,3 +41,52 @@ QDF_STATUS wmi_extract_reg_chan_list_update_event(void *wmi_hdl,
 
 	return QDF_STATUS_E_FAILURE;
 }
+
+/*
+ * wmi_unified_send_start_11d_scan_cmd() - start 11d scan
+ * @wmi_handle: wmi handle
+ * @start_11d_scan: pointer to 11d scan start req.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wmi_unified_send_start_11d_scan_cmd(wmi_unified_t wmi_handle,
+		struct reg_start_11d_scan_req *start_11d_scan)
+{
+	if (wmi_handle->ops->send_start_11d_scan_cmd)
+		return wmi_handle->ops->send_start_11d_scan_cmd(wmi_handle,
+				start_11d_scan);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+/*
+ * wmi_unified_send_stop_11d_scan_cmd() - stop 11d scan
+ * @wmi_handle: wmi handle
+ * @stop_11d_scan: pointer to 11d scan stop req.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wmi_unified_send_stop_11d_scan_cmd(wmi_unified_t wmi_handle,
+		struct reg_stop_11d_scan_req *stop_11d_scan)
+{
+	if (wmi_handle->ops->send_stop_11d_scan_cmd)
+		return wmi_handle->ops->send_stop_11d_scan_cmd(wmi_handle,
+				stop_11d_scan);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_extract_reg_11d_new_cc_event(void *wmi_hdl,
+		uint8_t *evt_buf,
+		struct reg_11d_new_country *reg_11d_new_cc,
+		uint32_t len)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *)wmi_hdl;
+
+	if (wmi_handle->ops->extract_reg_11d_new_country_event)
+		return wmi_handle->ops->extract_reg_11d_new_country_event(
+				wmi_handle, evt_buf, reg_11d_new_cc, len);
+
+	return QDF_STATUS_E_FAILURE;
+}
+

+ 122 - 0
wmi/src/wmi_unified_tlv.c

@@ -7956,6 +7956,100 @@ static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle,
 }
 #endif
 
+/**
+ * send_start_11d_scan_cmd_tlv() - start 11d scan request
+ * @wmi_handle: wmi handle
+ * @start_11d_scan: 11d scan start request parameters
+ *
+ * This function request FW to start 11d scan.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_start_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
+			  struct reg_start_11d_scan_req *start_11d_scan)
+{
+	wmi_11d_scan_start_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	int ret;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_11d_scan_start_cmd_fixed_param *)wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_11d_scan_start_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_11d_scan_start_cmd_fixed_param));
+
+	cmd->vdev_id = start_11d_scan->vdev_id;
+	cmd->scan_period_msec = start_11d_scan->scan_period_msec;
+	cmd->start_interval_msec = start_11d_scan->start_interval_msec;
+
+	WMI_LOGD("vdev %d sending 11D scan start req", cmd->vdev_id);
+
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_11D_SCAN_START_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send start 11d scan wmi cmd", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_stop_11d_scan_cmd_tlv() - stop 11d scan request
+ * @wmi_handle: wmi handle
+ * @start_11d_scan: 11d scan stop request parameters
+ *
+ * This function request FW to stop 11d scan.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS send_stop_11d_scan_cmd_tlv(wmi_unified_t wmi_handle,
+			  struct reg_stop_11d_scan_req *stop_11d_scan)
+{
+	wmi_11d_scan_stop_cmd_fixed_param *cmd;
+	int32_t len;
+	wmi_buf_t buf;
+	int ret;
+
+	len = sizeof(*cmd);
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf) {
+		WMI_LOGE("%s: Failed allocate wmi buffer", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	cmd = (wmi_11d_scan_stop_cmd_fixed_param *)wmi_buf_data(buf);
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_11d_scan_stop_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+		       (wmi_11d_scan_stop_cmd_fixed_param));
+
+	cmd->vdev_id = stop_11d_scan->vdev_id;
+
+	WMI_LOGD("vdev %d sending 11D scan stop req", cmd->vdev_id);
+
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_11D_SCAN_STOP_CMDID);
+	if (ret) {
+		WMI_LOGE("%s: Failed to send stop 11d scan wmi cmd", __func__);
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * send_start_oem_data_cmd_tlv() - start OEM data request to target
  * @wmi_handle: wmi handle
@@ -17559,6 +17653,29 @@ static QDF_STATUS extract_reg_chan_list_update_event_tlv(
 	return QDF_STATUS_SUCCESS;
 }
 
+static QDF_STATUS extract_reg_11d_new_country_event_tlv(
+	wmi_unified_t wmi_handle, uint8_t *evt_buf,
+	struct reg_11d_new_country *reg_11d_country, uint32_t len)
+{
+	wmi_11d_new_country_event_fixed_param *reg_11d_country_event;
+	WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *param_buf;
+
+	param_buf = (WMI_11D_NEW_COUNTRY_EVENTID_param_tlvs *)evt_buf;
+	if (!param_buf) {
+		WMI_LOGE("invalid 11d country event buf");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	reg_11d_country_event = param_buf->fixed_param;
+
+	qdf_mem_copy(reg_11d_country->alpha2,
+			&reg_11d_country_event->new_alpha2, REG_ALPHA2_LEN);
+
+	WMI_LOGD("processed 11d country event, new cc %s",
+			reg_11d_country->alpha2);
+
+	return QDF_STATUS_SUCCESS;
+}
 #ifdef DFS_COMPONENT_ENABLE
 /**
  * extract_dfs_cac_complete_event_tlv() - extract cac complete event
@@ -18084,6 +18201,11 @@ struct wmi_ops tlv_ops =  {
 		convert_host_pdev_id_to_target_pdev_id_legacy,
 	.convert_pdev_id_target_to_host =
 		convert_target_pdev_id_to_host_pdev_id_legacy,
+
+	.send_start_11d_scan_cmd = send_start_11d_scan_cmd_tlv,
+	.send_stop_11d_scan_cmd = send_stop_11d_scan_cmd_tlv,
+	.extract_reg_11d_new_country_event =
+		extract_reg_11d_new_country_event_tlv,
 };
 
 /**