diff --git a/target_if/regulatory/src/target_if_reg.c b/target_if/regulatory/src/target_if_reg.c index e44a6d8570..ad8e2d6404 100644 --- a/target_if/regulatory/src/target_if_reg.c +++ b/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, ®_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, ®_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; + 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; } - - diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 2b93fdb456..59d64eda16 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/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 diff --git a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c index 18145b140e..330b6553d6 100644 --- a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c +++ b/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); diff --git a/umac/regulatory/core/src/reg_services.c b/umac/regulatory/core/src/reg_services.c index ec02bd1513..932ca6ee36 100644 --- a/umac/regulatory/core/src/reg_services.c +++ b/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; +} diff --git a/umac/regulatory/core/src/reg_services.h b/umac/regulatory/core/src/reg_services.h index 8c3f4ad6e9..18ef48a778 100644 --- a/umac/regulatory/core/src/reg_services.h +++ b/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 diff --git a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h index 86f2f685aa..2bd75b0e86 100644 --- a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h +++ b/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 diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index 52252cd60c..0401061f69 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/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 diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h index 3ff4276452..7d19cd0c72 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h +++ b/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 diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 6b9d60182b..2c057ac107 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/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); +} diff --git a/umac/regulatory/dispatcher/src/wlan_reg_tgt_api.c b/umac/regulatory/dispatcher/src/wlan_reg_tgt_api.c index 89221669c3..5c325e4f78 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_tgt_api.c +++ b/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); +} + diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index a1b75349bc..569bf8ae22 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/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); diff --git a/wmi/inc/wmi_unified_reg_api.h b/wmi/inc/wmi_unified_reg_api.h index e986536e5b..5ac9b91458 100644 --- a/wmi/inc/wmi_unified_reg_api.h +++ b/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_ */ diff --git a/wmi/src/wmi_unified_reg_api.c b/wmi/src/wmi_unified_reg_api.c index b10f5bc3cc..78226bc4b5 100644 --- a/wmi/src/wmi_unified_reg_api.c +++ b/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; +} + diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index fd50d18d22..3fd05387ff 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/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, + ®_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, }; /**