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 4062353019e0..4d8a42dd7382 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 @@ -982,6 +982,8 @@ struct wlan_lmac_if_reg_rx_ops { struct cur_regdmn_info *cur_regdmn); QDF_STATUS (*reg_enable_dfs_channels)(struct wlan_objmgr_pdev *pdev, bool dfs_enable); + QDF_STATUS (*reg_modify_pdev_chan_range)(struct + wlan_objmgr_pdev *pdev); }; #ifdef CONVERGED_P2P_ENABLE @@ -1253,8 +1255,10 @@ struct wlan_lmac_if_wifi_pos_rx_ops { * @dfs_dfs_cac_complete_ind: Process cac complete indication. * @dfs_agile_precac_start: Initiate Agile PreCAC run. * @dfs_set_agile_precac_state: Set agile precac state. + * @dfs_reset_adfs_config: Reset agile dfs variables. * @dfs_dfs_ocac_complete_ind: Process offchan cac complete indication. * @dfs_stop: Clear dfs timers. + * @dfs_reinit_timers: Reinitialize DFS timers. * @dfs_enable_stadfs: Enable/Disable STADFS capability. * @dfs_is_stadfs_enabled: Get STADFS capability value. * @dfs_process_phyerr_filter_offload:Process radar event. @@ -1308,6 +1312,7 @@ struct wlan_lmac_if_dfs_rx_ops { QDF_STATUS (*dfs_agile_precac_start)(struct wlan_objmgr_pdev *pdev); QDF_STATUS (*dfs_set_agile_precac_state)(struct wlan_objmgr_pdev *pdev, int agile_precac_state); + QDF_STATUS (*dfs_reset_adfs_config)(struct wlan_objmgr_psoc *psoc); QDF_STATUS (*dfs_dfs_ocac_complete_ind)(struct wlan_objmgr_pdev *pdev, struct vdev_adfs_complete_status *ocac_st); @@ -1348,6 +1353,7 @@ struct wlan_lmac_if_dfs_rx_ops { uint32_t vdev_id); #endif QDF_STATUS (*dfs_stop)(struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*dfs_reinit_timers)(struct wlan_objmgr_pdev *pdev); void (*dfs_enable_stadfs)(struct wlan_objmgr_pdev *pdev, bool val); bool (*dfs_is_stadfs_enabled)(struct wlan_objmgr_pdev *pdev); QDF_STATUS (*dfs_process_phyerr_filter_offload)( 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 c4d843318aeb..f8a7d70dc274 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 @@ -323,6 +323,9 @@ static void wlan_lmac_if_umac_reg_rx_ops_register( rx_ops->reg_rx_ops.reg_enable_dfs_channels = ucfg_reg_enable_dfs_channels; + + rx_ops->reg_rx_ops.reg_modify_pdev_chan_range = + wlan_reg_modify_pdev_chan_range; } #ifdef CONVERGED_P2P_ENABLE @@ -394,6 +397,7 @@ wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) tgt_dfs_set_agile_precac_state; dfs_rx_ops->dfs_start_precac_timer = utils_dfs_start_precac_timer; dfs_rx_ops->dfs_cancel_precac_timer = utils_dfs_cancel_precac_timer; + dfs_rx_ops->dfs_reset_adfs_config = ucfg_dfs_reset_agile_config; dfs_rx_ops->dfs_override_precac_timeout = ucfg_dfs_override_precac_timeout; dfs_rx_ops->dfs_set_precac_enable = ucfg_dfs_set_precac_enable; @@ -405,6 +409,7 @@ wlan_lmac_if_umac_dfs_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) dfs_rx_ops->dfs_dfs_cac_complete_ind = tgt_dfs_cac_complete; dfs_rx_ops->dfs_dfs_ocac_complete_ind = tgt_dfs_ocac_complete; dfs_rx_ops->dfs_stop = tgt_dfs_stop; + dfs_rx_ops->dfs_reinit_timers = ucfg_dfs_reinit_timers; dfs_rx_ops->dfs_enable_stadfs = tgt_dfs_enable_stadfs; dfs_rx_ops->dfs_is_stadfs_enabled = tgt_dfs_is_stadfs_enabled; dfs_rx_ops->dfs_process_phyerr_filter_offload = diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c index c10a431f28ae..8cf19a04226f 100644 --- a/umac/regulatory/core/src/reg_services_common.c +++ b/umac/regulatory/core/src/reg_services_common.c @@ -2023,3 +2023,87 @@ bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev) return reg_en302_502_regdmn(cur_reg_dmn.regdmn_pair_id); } + +QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; + struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap_ptr; + uint32_t cnt; + uint32_t pdev_id; + enum direction dir; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + reg_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc_priv_obj = reg_get_psoc_obj(psoc); + if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { + reg_err("psoc reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + + reg_cap_ptr = psoc_priv_obj->reg_cap; + + for (cnt = 0; cnt < PSOC_MAX_PHY_REG_CAP; cnt++) { + if (!reg_cap_ptr) { + qdf_mem_free(pdev_priv_obj); + reg_err("reg cap ptr is NULL"); + return QDF_STATUS_E_FAULT; + } + + if (reg_cap_ptr->phy_id == pdev_id) + break; + reg_cap_ptr++; + } + + if (cnt == PSOC_MAX_PHY_REG_CAP) { + qdf_mem_free(pdev_priv_obj); + reg_err("extended capabilities not found for pdev"); + return QDF_STATUS_E_FAULT; + } + + if (psoc_priv_obj->offload_enabled) { + dir = NORTHBOUND; + } else { + dir = SOUTHBOUND; + } + + pdev_priv_obj->range_2g_low = reg_cap_ptr->low_2ghz_chan; + pdev_priv_obj->range_2g_high = reg_cap_ptr->high_2ghz_chan; + pdev_priv_obj->range_5g_low = reg_cap_ptr->low_5ghz_chan; + pdev_priv_obj->range_5g_high = reg_cap_ptr->high_5ghz_chan; + pdev_priv_obj->wireless_modes = reg_cap_ptr->wireless_modes; + + reg_compute_pdev_current_chan_list(pdev_priv_obj); + + reg_tx_ops = reg_get_psoc_tx_ops(psoc); + + /* Fill the ic channel list with the updated current channel + * chan list. + */ + if (reg_tx_ops->fill_umac_legacy_chanlist) { + reg_tx_ops->fill_umac_legacy_chanlist(pdev, + pdev_priv_obj->cur_chan_list); + + } else { + if (dir == NORTHBOUND) + status = reg_send_scheduler_msg_nb(psoc, pdev); + else + status = reg_send_scheduler_msg_sb(psoc, pdev); + } + + return status; +} diff --git a/umac/regulatory/core/src/reg_services_common.h b/umac/regulatory/core/src/reg_services_common.h index d2ed228f755e..52df9be9558e 100644 --- a/umac/regulatory/core/src/reg_services_common.h +++ b/umac/regulatory/core/src/reg_services_common.h @@ -514,4 +514,13 @@ QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev, bool enable); * Return: True if en302_502 is applicable, else false. */ bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev); + +/** + * reg_modify_pdev_chan_range() - Compute current channel list + * in accordance with the modified reg caps. + * @pdev: The physical dev for which channel list must be built. + * + * Return: QDF_STATUS + */ +QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev); #endif diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index f7da9e3d51d8..b3a7d3290867 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -703,4 +703,13 @@ void wlan_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, * False: otherwise. */ bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_reg_modify_pdev_chan_range() - Compute current channel list for the + * modified channel range in the regcap. + * @pdev: pointer to wlan_objmgr_pdev. + * + * Return : QDF_STATUS + */ +QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev); #endif diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 67e5d745e955..5b9172521267 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -713,3 +713,14 @@ bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev) { return reg_is_regdmn_en302502_applicable(pdev); } + +/** + * wlan_reg_modify_pdev_chan_range() - Compute current channel list for the + * modified regcap. + * @pdev: pointer to struct wlan_objmgr_pdev + * + */ +QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev) +{ + return reg_modify_pdev_chan_range(pdev); +} diff --git a/umac/wifi_pos/inc/wifi_pos_api.h b/umac/wifi_pos/inc/wifi_pos_api.h index 9841b15433bc..72665e1b7ddf 100644 --- a/umac/wifi_pos/inc/wifi_pos_api.h +++ b/umac/wifi_pos/inc/wifi_pos_api.h @@ -412,4 +412,33 @@ QDF_STATUS wifi_pos_register_get_phy_mode_cb( struct wlan_objmgr_psoc *psoc, void (*handler)(uint8_t, uint32_t, uint32_t *)); +/** + * wifi_pos_register_send_action: API to register callback to send + * action frames + * @psoc: pointer to psoc object + * @handler: callback to be registered + * + * Return: QDF_STATUS_SUCCESS in case of success, error codes in + * case of failure + */ +QDF_STATUS wifi_pos_register_send_action( + struct wlan_objmgr_psoc *psoc, + void (*handler)(struct wlan_objmgr_psoc *psoc, + uint32_t sub_type, + uint8_t *buf, + uint32_t buf_len)); + +/** + * wifi_pos_send_report_resp: Send report to osif + * @psoc: pointer to psoc object + * @req_id: Request id + * @dest_mac: destination mac address + * @err_code: Error code to be sent + * + * Return: QDF_STATUS_SUCCESS in case of success, error codes in + * case of failure + */ +QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc, + int req_id, uint8_t *dest_mac, + int err_code); #endif diff --git a/umac/wifi_pos/src/wifi_pos_api.c b/umac/wifi_pos/src/wifi_pos_api.c index c421fa38bdc8..cbcf95cedd84 100644 --- a/umac/wifi_pos/src/wifi_pos_api.c +++ b/umac/wifi_pos/src/wifi_pos_api.c @@ -350,3 +350,31 @@ QDF_STATUS wifi_pos_register_get_phy_mode_cb( return QDF_STATUS_SUCCESS; } +QDF_STATUS wifi_pos_register_send_action( + struct wlan_objmgr_psoc *psoc, + void (*handler)(struct wlan_objmgr_psoc *psoc, + uint32_t sub_type, + uint8_t *buf, + uint32_t buf_len)) +{ + struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; + + if (!psoc) { + wifi_pos_err("psoc is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!handler) { + wifi_pos_err("Null callback"); + return QDF_STATUS_E_NULL_VALUE; + } + wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); + if (!wifi_pos_psoc) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + wifi_pos_psoc->wifi_pos_send_action = handler; + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/wifi_pos/src/wifi_pos_main.c b/umac/wifi_pos/src/wifi_pos_main.c index de5951062112..b298cbf69b31 100644 --- a/umac/wifi_pos/src/wifi_pos_main.c +++ b/umac/wifi_pos/src/wifi_pos_main.c @@ -99,6 +99,13 @@ static QDF_STATUS wifi_pos_process_data_req(struct wlan_objmgr_psoc *psoc, struct oem_data_req data_req; struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; struct wlan_objmgr_pdev *pdev; + struct wifi_pos_psoc_priv_obj *wifi_pos_obj = + wifi_pos_get_psoc_priv_obj(psoc); + + if (!wifi_pos_obj) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_INVAL; + } wifi_pos_debug("Received data req pid(%d), len(%d)", req->pid, req->buf_len); @@ -151,10 +158,18 @@ static QDF_STATUS wifi_pos_process_data_req(struct wlan_objmgr_psoc *psoc, /* TBD */ break; case TARGET_OEM_CONFIGURE_FTMRR: - /* TBD */ + wifi_pos_debug("FTMRR request"); + if (wifi_pos_obj->wifi_pos_send_action) + wifi_pos_obj->wifi_pos_send_action(psoc, sub_type, + req->buf, + req->buf_len); break; case TARGET_OEM_CONFIGURE_WRU: - /* TBD */ + wifi_pos_debug("WRU request"); + if (wifi_pos_obj->wifi_pos_send_action) + wifi_pos_obj->wifi_pos_send_action(psoc, sub_type, + req->buf, + req->buf_len); break; default: wifi_pos_debug("invalid sub type or not passed"); @@ -234,6 +249,40 @@ static QDF_STATUS wifi_pos_process_get_cap_req(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS wifi_pos_send_report_resp(struct wlan_objmgr_psoc *psoc, + int req_id, uint8_t *dest_mac, + int err_code) +{ + struct wifi_pos_err_msg_report err_report = {0}; + struct wifi_pos_psoc_priv_obj *wifi_pos_obj = + wifi_pos_get_psoc_priv_obj(psoc); + + if (!wifi_pos_obj) { + wifi_pos_err("wifi_pos priv obj is null"); + return QDF_STATUS_E_INVAL; + } + + err_report.msg_tag_len = OEM_MSG_RSP_HEAD_TAG_ID << 16; + err_report.msg_tag_len |= (sizeof(err_report) - + sizeof(err_report.err_rpt)) & 0x0000FFFF; + err_report.msg_subtype = TARGET_OEM_ERROR_REPORT_RSP; + err_report.req_id = req_id & 0xFFFF; + err_report.req_id |= ((err_code & 0xFF) << 16); + err_report.req_id |= (0x1 << 24); + err_report.time_left = 0xFFFFFFFF; + err_report.err_rpt.tag_len = OEM_MEAS_RSP_HEAD_TAG_ID << 16; + err_report.err_rpt.tag_len |= + (sizeof(struct wifi_pos_err_rpt)) & 0x0000FFFF; + memcpy(&err_report.err_rpt.dest_mac, dest_mac, QDF_MAC_ADDR_SIZE); + + wifi_pos_obj->wifi_pos_send_rsp(wifi_pos_obj->app_pid, + ANI_MSG_OEM_DATA_RSP, + sizeof(err_report), + (uint8_t *)&err_report); + + return QDF_STATUS_SUCCESS; +} + static void wifi_update_channel_bw_info(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_pdev *pdev, uint16_t chan, diff --git a/umac/wifi_pos/src/wifi_pos_utils_i.h b/umac/wifi_pos/src/wifi_pos_utils_i.h index 4c23460b1b4c..c94269b51e56 100644 --- a/umac/wifi_pos/src/wifi_pos_utils_i.h +++ b/umac/wifi_pos/src/wifi_pos_utils_i.h @@ -188,6 +188,42 @@ struct qdf_packed wifi_pos_oem_get_cap_rsp { struct wifi_pos_user_defined_caps user_defined_cap; }; +/** + * struct wifi_pos_err_rpt - Error report response for userspace. + * @tag_len: tlv header of the message. + * @info: Report info. Reserved for error report. + * @dest_mac: Mac address of the sta in the request. + * @reserved: Reserved in error report. + */ +struct qdf_packed wifi_pos_err_rpt { + uint32_t tag_len; + uint32_t info; + uint8_t dest_mac[QDF_MAC_ADDR_SIZE + 2]; + uint32_t reserved; +}; + +#define OEM_MSG_RSP_HEAD_TAG_ID 33 +#define OEM_MEAS_RSP_HEAD_TAG_ID 41 +/** + * struct wifi_pos_err_msg_report - Error report message + * @msg_tag_len: Message tlv header + * @msg_subtype: Message subtype + * @req_id: id corresponding to the request. + * @fragment_info: Valid only for fragments. + * @pdev_id: pdev_id of radion. + * @time_left: time left in the measurment req. + * @err_rpt: Error report data. + */ +struct qdf_packed wifi_pos_err_msg_report { + uint32_t msg_tag_len; + uint32_t msg_subtype; + uint32_t req_id; + uint32_t fragment_info; + uint32_t pdev_id; + uint32_t time_left; + struct wifi_pos_err_rpt err_rpt; +}; + /** * struct wifi_pos_dma_rings_cap - capabilities requested by firmware. * @pdev_id: pdev_id or mac_id of ring @@ -306,6 +342,9 @@ struct wifi_pos_psoc_priv_obj { struct wifi_pos_req_msg *req); void (*wifi_pos_send_rsp)(uint32_t, uint32_t, uint32_t, uint8_t *); void (*wifi_pos_get_phy_mode)(uint8_t, uint32_t, uint32_t *); + void (*wifi_pos_send_action)(struct wlan_objmgr_psoc *psoc, + uint32_t oem_subtype, uint8_t *buf, + uint32_t len); }; /**