diff --git a/init_deinit/dispatcher/src/dispatcher_init_deinit.c b/init_deinit/dispatcher/src/dispatcher_init_deinit.c index dbe9910a6d7f..f5d8484b3e04 100644 --- a/init_deinit/dispatcher/src/dispatcher_init_deinit.c +++ b/init_deinit/dispatcher/src/dispatcher_init_deinit.c @@ -462,6 +462,16 @@ static QDF_STATUS dispatcher_deinit_dfs(void) { return dfs_deinit(); } + +static QDF_STATUS dispatcher_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return wifi_dfs_psoc_enable(psoc); +} + +static QDF_STATUS dispatcher_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} #else static QDF_STATUS dispatcher_init_dfs(void) { @@ -472,6 +482,16 @@ static QDF_STATUS dispatcher_deinit_dfs(void) { return QDF_STATUS_SUCCESS; } + +static QDF_STATUS dispatcher_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS dispatcher_dfs_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} #endif #ifdef WLAN_OFFCHAN_TXRX_ENABLE @@ -701,8 +721,13 @@ QDF_STATUS dispatcher_psoc_enable(struct wlan_objmgr_psoc *psoc) if (QDF_STATUS_SUCCESS != dispatcher_nan_psoc_enable(psoc)) goto nan_psoc_enable_fail; + if (QDF_STATUS_SUCCESS != dispatcher_dfs_psoc_enable(psoc)) + goto wifi_dfs_psoc_enable_fail; + return QDF_STATUS_SUCCESS; +wifi_dfs_psoc_enable_fail: + dispatcher_nan_psoc_disable(psoc); nan_psoc_enable_fail: dispatcher_wifi_pos_disable(psoc); wifi_pos_psoc_enable_fail: @@ -738,6 +763,8 @@ QDF_STATUS dispatcher_psoc_disable(struct wlan_objmgr_psoc *psoc) QDF_BUG(QDF_STATUS_SUCCESS == ucfg_scan_psoc_disable(psoc)); + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_dfs_psoc_disable(psoc)); + return QDF_STATUS_SUCCESS; } EXPORT_SYMBOL(dispatcher_psoc_disable); diff --git a/umac/dfs/core/src/misc/dfs_cac.c b/umac/dfs/core/src/misc/dfs_cac.c index 1d5a27f18fdd..3f58c5976718 100644 --- a/umac/dfs/core/src/misc/dfs_cac.c +++ b/umac/dfs/core/src/misc/dfs_cac.c @@ -171,7 +171,7 @@ static os_timer_func(dfs_cac_timeout) } /* Iterate over the nodes, processing the CAC completion event. */ - dfs_mlme_proc_cac(dfs->dfs_pdev_obj); + dfs_mlme_proc_cac(dfs->dfs_pdev_obj, 0); /* Send a CAC timeout, VAP up event to user space */ dfs_mlme_deliver_event_up_afrer_cac(dfs->dfs_pdev_obj); diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_init_deinit_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_init_deinit_api.h index 24bfe089bff8..a35214ddd18e 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_init_deinit_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_init_deinit_api.h @@ -63,4 +63,10 @@ QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev, QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, void *arg); +/** + * wifi_dfs_psoc_enable() - handles registering dfs event handlers. + * @psoc: psoc object. + */ +QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc); + #endif /* _WLAN_DFS_INIT_DEINIT_API_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h index e3e0de7a4d7b..c2d02810eed4 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h @@ -70,8 +70,9 @@ void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, uint8_t ieeeChan); /** * dfs_mlme_proc_cac() - Process the CAC completion event. * @pdev: Pointer to DFS pdev object. + * @vdev_id: vdev id. */ -void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev); +void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id); /** * dfs_mlme_deliver_event_up_afrer_cac() - Send a CAC timeout, VAP up event to diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h index 09f89af02535..20c64baccaae 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h @@ -26,6 +26,7 @@ #define _WLAN_DFS_TGT_API_H_ #include "wlan_dfs_ucfg_api.h" +#include "wlan_dfs_utils_api.h" extern struct dfs_to_mlme global_dfs_to_mlme; @@ -185,4 +186,39 @@ QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, bool *dfs_set_cfreq2, bool *set_agile); +/** + * tgt_dfs_process_radar_ind() - Process radar found indication. + * @pdev: Pointer to DFS pdev object. + * @radar_found: radar found info. + * + * Process radar found indication. + * + * Return QDF_STATUS. + */ +QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev, + struct radar_found_info *radar_found); + +/** + * tgt_dfs_cac_complete() - Process cac complete indication. + * @pdev: Pointer to DFS pdev object. + * @vdev_id: vdev id. + * + * Process cac complete indication from firmware. + * + * Return QDF_STATUS. + */ +QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, + uint32_t vdev_id); + +/** + * tgt_dfs_reg_ev_handler() - Register dfs events. + * @psoc: Pointer to psoc. + * @dfs_offload: phy err processing offloaded to firmware. + * + * Register dfs events. + * + * Return: QDF_STATUS. + */ +QDF_STATUS tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc *psoc, + bool dfs_offload); #endif /* _WLAN_DFS_TGT_API_H_ */ diff --git a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c index ab0152493110..8b1a594de652 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c @@ -22,12 +22,15 @@ */ #include "wlan_dfs_ucfg_api.h" +#include "wlan_dfs_tgt_api.h" +#include "wlan_dfs_utils_api.h" #ifndef QCA_MCL_DFS_SUPPORT #include "ieee80211_mlme_dfs_interface.h" #endif #include "wlan_objmgr_global_obj.h" #include "wlan_dfs_init_deinit_api.h" #include "../../core/src/dfs.h" +#include "a_types.h" struct dfs_to_mlme global_dfs_to_mlme; @@ -138,35 +141,43 @@ QDF_STATUS wlan_dfs_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev, void *arg) { struct wlan_dfs *dfs = NULL; + struct wlan_objmgr_psoc *psoc; + bool dfs_offload = false; if (pdev == NULL) { - DFS_PRINTK("%s:PDEV is NULL\n", __func__); + DFS_PRINTK("%s: null pdev\n", __func__); return QDF_STATUS_E_FAILURE; } if (dfs_create_object(&dfs) == 1) { - DFS_PRINTK("%s : Failed to create DFS object\n", __func__); + DFS_PRINTK("%s: failed to create object\n", __func__); return QDF_STATUS_E_FAILURE; } global_dfs_to_mlme.pdev_component_obj_attach(pdev, - WLAN_UMAC_COMP_DFS, - (void *)dfs, - QDF_STATUS_SUCCESS); + WLAN_UMAC_COMP_DFS, (void *)dfs, QDF_STATUS_SUCCESS); dfs->dfs_pdev_obj = pdev; - - /* wlan_ar_ops are assigned to sc_wlan_ops in wlan_dev_attach. - * This function is called during module init. - * and wlan_dev_attach is called during wlan_attach. - * If we call dfs_attach here, seen crash in wlan_net80211_attach_dfs. - */ - if (dfs_attach(dfs) == 1) { - DFS_PRINTK("%s : dfs_attch failed\n", __func__); - dfs_destroy_object(dfs); + wlan_pdev_obj_lock(pdev); + psoc = wlan_pdev_get_psoc(pdev); + wlan_pdev_obj_unlock(pdev); + if (!psoc) { + DFS_PRINTK("%s: null psoc\n", __func__); return QDF_STATUS_E_FAILURE; } - - dfs_get_radars(dfs); + dfs_offload = + DFS_OFFLOAD_IS_ENABLED(psoc->service_param.service_bitmap); + DFS_PRINTK("%s: dfs_offload %d\n", __func__, dfs_offload); + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs_offload) { + if (dfs_attach(dfs) == 1) { + DFS_PRINTK("%s: dfs_attch failed\n", __func__); + dfs_destroy_object(dfs); + return QDF_STATUS_E_FAILURE; + } + dfs_get_radars(dfs); + } + dfs_init_nol(pdev); + dfs_print_nol(dfs); return QDF_STATUS_SUCCESS; } @@ -198,3 +209,17 @@ QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } +QDF_STATUS wifi_dfs_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + bool dfs_offload = + DFS_OFFLOAD_IS_ENABLED(psoc->service_param.service_bitmap); + + DFS_PRINTK("%s: dfs_offload %d\n", __func__, dfs_offload); + + if (QDF_STATUS_SUCCESS != tgt_dfs_reg_ev_handler(psoc, dfs_offload)) { + DFS_PRINTK("%s: tgt_dfs_reg_ev_handler failed\n", __func__); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c b/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c index 0457f7d49487..f65211124101 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c @@ -22,6 +22,13 @@ */ #include "wlan_dfs_mlme_api.h" +#include "wlan_objmgr_vdev_obj.h" +#include "wlan_objmgr_pdev_obj.h" +#include "../../core/src/dfs.h" +#include "scheduler_api.h" +#ifdef QCA_MCL_DFS_SUPPORT +#include "wni_api.h" +#endif void dfs_mlme_channel_mark_radar(struct wlan_objmgr_pdev *pdev, uint16_t freq, @@ -41,6 +48,7 @@ void dfs_mlme_start_rcsa(struct wlan_objmgr_pdev *pdev) global_dfs_to_mlme.dfs_start_rcsa(pdev); } +#ifndef QCA_MCL_DFS_SUPPORT void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, uint8_t ieee, uint16_t freq, @@ -54,6 +62,39 @@ void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, vhtop_ch_freq_seg2, flags); } +#else +static void dfs_send_radar_ind(struct wlan_objmgr_pdev *pdev, + void *object, + void *arg) +{ + struct scheduler_msg sme_msg = {0}; + uint8_t vdev_id = wlan_vdev_get_id((struct wlan_objmgr_vdev *)object); + + sme_msg.type = eWNI_SME_DFS_RADAR_FOUND; + sme_msg.bodyptr = NULL; + sme_msg.bodyval = vdev_id; + scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg); + DFS_PRINTK("%s: eWNI_SME_DFS_RADAR_FOUND pdev%d posted\n", + __func__, vdev_id); +} + +void dfs_mlme_mark_dfs(struct wlan_objmgr_pdev *pdev, + uint8_t ieee, + uint16_t freq, + uint8_t vhtop_ch_freq_seg2, + uint32_t flags) +{ + if (!pdev) { + DFS_PRINTK("%s: null pdev\n", __func__); + return; + } + + wlan_objmgr_pdev_iterate_obj_list(pdev, + WLAN_VDEV_OP, + dfs_send_radar_ind, + NULL, 0, WLAN_DFS_ID); +} +#endif void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, uint8_t ieeeChan) @@ -62,11 +103,25 @@ void dfs_mlme_start_csa(struct wlan_objmgr_pdev *pdev, global_dfs_to_mlme.mlme_start_csa(pdev, ieeeChan); } -void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev) +#ifndef QCA_MCL_DFS_SUPPORT +void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) { if (global_dfs_to_mlme.mlme_proc_cac != NULL) global_dfs_to_mlme.mlme_proc_cac(pdev); } +#else +void dfs_mlme_proc_cac(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) +{ + struct scheduler_msg sme_msg = {0}; + + sme_msg.type = eWNI_SME_DFS_CAC_COMPLETE; + sme_msg.bodyptr = NULL; + sme_msg.bodyval = vdev_id; + scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg); + DFS_PRINTK("%s: eWNI_SME_DFS_CAC_COMPLETE vdev%d posted\n", + __func__, vdev_id); +} +#endif void dfs_mlme_deliver_event_up_afrer_cac(struct wlan_objmgr_pdev *pdev) { diff --git a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c index a63be5338587..278bf0bcf5da 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c @@ -22,8 +22,18 @@ * to outside of DFS component. */ #include "wlan_dfs_tgt_api.h" +#include "wlan_lmac_if_def.h" +#include "wlan_lmac_if_api.h" +#include "wlan_dfs_mlme_api.h" #include "../../core/src/dfs.h" #include "../../core/src/dfs_zero_cac.h" +#include "../../core/src/dfs_process_radar_found_ind.h" + +static inline struct wlan_lmac_if_dfs_tx_ops * +wlan_psoc_get_dfs_txops(struct wlan_objmgr_psoc *psoc) +{ + return &((psoc->soc_cb.tx_ops.dfs_tx_ops)); +} QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev, uint16_t ic_freq, @@ -224,3 +234,63 @@ QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } EXPORT_SYMBOL(tgt_dfs_find_vht80_chan_for_precac); + +QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev, + struct radar_found_info *radar_found) +{ + struct wlan_dfs *dfs; + + if (!pdev) { + DFS_PRINTK("%s: null pdev\n", __func__); + return QDF_STATUS_E_FAILURE; + } + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs || !dfs->dfs_curchan) { + DFS_PRINTK("%s: err, dfs=%p, dfs->dfs_curchan=%p\n", + __func__, dfs, dfs->dfs_curchan); + return QDF_STATUS_E_FAILURE; + } + + dfs_process_radar_found_indication(dfs, radar_found); + dfs_mlme_mark_dfs(pdev, dfs->dfs_curchan->ic_ieee, + dfs->dfs_curchan->ic_freq, + dfs->dfs_curchan->ic_vhtop_ch_freq_seg2, + dfs->dfs_curchan->ic_flags); + + return QDF_STATUS_SUCCESS; +} +EXPORT_SYMBOL(tgt_dfs_process_radar_ind); + +QDF_STATUS tgt_dfs_cac_complete(struct wlan_objmgr_pdev *pdev, uint32_t vdev_id) +{ + dfs_mlme_proc_cac(pdev, vdev_id); + + return QDF_STATUS_SUCCESS; +} +EXPORT_SYMBOL(tgt_dfs_cac_complete); + +QDF_STATUS tgt_dfs_reg_ev_handler(struct wlan_objmgr_psoc *psoc, + bool dfs_offload) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops; + struct wlan_objmgr_pdev *pdev = NULL; + + pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_DFS_ID); + if (!pdev) { + DFS_PRINTK("%s: null pdev\n", __func__); + return QDF_STATUS_E_FAILURE; + } + + dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc); + if (dfs_tx_ops && dfs_tx_ops->dfs_reg_ev_handler) + status = dfs_tx_ops->dfs_reg_ev_handler(pdev, dfs_offload); + else + DFS_PRINTK("%s: err, dfs_tx_ops=%p\n", __func__, dfs_tx_ops); + + wlan_objmgr_pdev_release_ref(pdev, WLAN_DFS_ID); + + return status; +} +EXPORT_SYMBOL(tgt_dfs_reg_ev_handler);