From 8d8d9fe4854bb591b3b5e94a0444f480a25773f0 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 18 Jul 2017 16:01:25 -0700 Subject: [PATCH] qcacld-3.0: Add enhanced multicast enable/disable APIs Currently, a hard-coded enhanced multicast filter configuration is being sent to firmware. Instead, create a set of enable/disable APIs, and configure enhanced multicast filter based on advertised firmware capability. Change-Id: I488b4a921612e1081266be8831be098d755375f9 CRs-Fixed: 2078615 --- .../pmo/core/inc/wlan_pmo_mc_addr_filtering.h | 16 ++ components/pmo/core/inc/wlan_pmo_objmgr.h | 10 +- .../pmo/core/src/wlan_pmo_mc_addr_filtering.c | 145 +++++++++--------- .../pmo/dispatcher/inc/wlan_pmo_tgt_api.h | 4 +- .../pmo/dispatcher/inc/wlan_pmo_ucfg_api.h | 25 +++ .../src/wlan_pmo_tgt_static_config.c | 5 +- core/hdd/src/wlan_hdd_main.c | 10 ++ core/wma/inc/wma_api.h | 1 + core/wma/src/wma_utils.c | 20 +-- 9 files changed, 136 insertions(+), 100 deletions(-) diff --git a/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h b/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h index ddedb64036..cdfd35c3b8 100644 --- a/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h +++ b/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h @@ -66,6 +66,22 @@ QDF_STATUS pmo_core_cache_mc_addr_list( QDF_STATUS pmo_core_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); +/** + * pmo_core_enhance_mc_filter_enable() - enable enhanced multicast filtering + * @vdev: the vdev to enable enhanced multicast filtering for + * + * Return: QDF_STATUS + */ +QDF_STATUS pmo_core_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev); + +/** + * pmo_core_enhance_mc_filter_disable() - disable enhanced multicast filtering + * @vdev: the vdev to disable enhanced multicast filtering for + * + * Return: QDF_STATUS + */ +QDF_STATUS pmo_core_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev); + /** * pmo_core_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr * @psoc: objmgr psoc handle diff --git a/components/pmo/core/inc/wlan_pmo_objmgr.h b/components/pmo/core/inc/wlan_pmo_objmgr.h index 10b98894cc..75fa3d038d 100644 --- a/components/pmo/core/inc/wlan_pmo_objmgr.h +++ b/components/pmo/core/inc/wlan_pmo_objmgr.h @@ -60,7 +60,6 @@ pmo_vdev_get_id(struct wlan_objmgr_vdev *vdev) uint8_t vdev_id; vdev_id = wlan_vdev_get_id(vdev); - QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS); return vdev_id; @@ -122,10 +121,9 @@ pmo_psoc_get_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) { struct wlan_objmgr_vdev *vdev; - if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { - QDF_BUG(0); + QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS); + if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) return NULL; - } wlan_psoc_obj_lock(psoc); vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id]; @@ -140,7 +138,6 @@ pmo_psoc_get_priv(struct wlan_objmgr_psoc *psoc) struct pmo_psoc_priv_obj *psoc_priv; psoc_priv = pmo_psoc_get_priv_nolock(psoc); - QDF_BUG(psoc_priv); return psoc_priv; @@ -154,7 +151,6 @@ pmo_pdev_get_psoc(struct wlan_objmgr_pdev *pdev) struct wlan_objmgr_psoc *psoc; psoc = wlan_pdev_get_psoc(pdev); - QDF_BUG(psoc); return psoc; @@ -174,7 +170,6 @@ pmo_vdev_get_priv(struct wlan_objmgr_vdev *vdev) struct pmo_vdev_priv_obj *vdev_priv; vdev_priv = pmo_vdev_get_priv_nolock(vdev); - QDF_BUG(vdev_priv); return vdev_priv; @@ -186,7 +181,6 @@ pmo_vdev_get_pdev(struct wlan_objmgr_vdev *vdev) struct wlan_objmgr_pdev *pdev; pdev = wlan_vdev_get_pdev(vdev); - QDF_BUG(pdev); return pdev; diff --git a/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c index be4bb2dab2..04a5e0f866 100644 --- a/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c +++ b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c @@ -102,40 +102,55 @@ static QDF_STATUS pmo_core_flush_mc_addr_list_from_vdev_priv( return QDF_STATUS_SUCCESS; } +QDF_STATUS pmo_core_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status; + + PMO_ENTER(); + + status = pmo_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) + goto exit_with_status; + + pmo_tgt_send_enhance_multicast_offload_req(vdev, true); + + pmo_vdev_put_ref(vdev); + +exit_with_status: + PMO_EXIT(); + + return status; +} + +QDF_STATUS pmo_core_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status; + + PMO_ENTER(); + + status = pmo_vdev_get_ref(vdev); + if (QDF_IS_STATUS_ERROR(status)) + goto exit_with_status; + + pmo_tgt_send_enhance_multicast_offload_req(vdev, false); + + pmo_vdev_put_ref(vdev); + +exit_with_status: + PMO_EXIT(); + + return status; +} + QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev, struct pmo_mc_addr_list *mc_list) { - uint8_t vdev_id; int i; PMO_ENTER(); - vdev_id = pmo_vdev_get_id(vdev); - /* - * Configure enhance multicast offload feature for filtering out - * multicast IP data packets transmitted using unicast MAC address - */ - - /* - * TODO - {//(WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, - //WMI_SERVICE_ENHANCED_MCAST_FILTER)) { - */ - if (1) { - pmo_info("FW supports enhance multicast offload"); - pmo_tgt_send_enhance_multicast_offload_req(vdev, vdev_id, - false); - } else { - pmo_info("FW does not support enhance multicast offload"); - } - - /* - * set mc_param->action to clear MCList and reset - * to configure the MCList in FW - */ for (i = 0; i < mc_list->mc_cnt; i++) { - pmo_tgt_set_mc_filter_req(vdev, - mc_list->mc_addr[i]); + pmo_tgt_set_mc_filter_req(vdev, mc_list->mc_addr[i]); } PMO_EXIT(); @@ -146,35 +161,10 @@ QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev, QDF_STATUS pmo_core_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev, struct pmo_mc_addr_list *mc_list) { - uint8_t vdev_id; int i; PMO_ENTER(); - vdev_id = pmo_vdev_get_id(vdev); - - /* - * Configure enhance multicast offload feature for filtering out - * multicast IP data packets transmitted using unicast MAC address - */ - - /* - * TODO - {//(WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap, - //WMI_SERVICE_ENHANCED_MCAST_FILTER)) { - */ - if (1) { - pmo_info("FW supports enhance multicast offload"); - pmo_tgt_send_enhance_multicast_offload_req(vdev, vdev_id, - true); - } else { - pmo_info("FW does not support enhance multicast offload"); - } - - /* - * set mcbc_param->action to clear MCList and reset - * to configure the MCList in FW - */ for (i = 0; i < mc_list->mc_cnt; i++) { pmo_tgt_clear_mc_filter_req(vdev, mc_list->mc_addr[i]); } @@ -439,46 +429,51 @@ static QDF_STATUS pmo_core_handle_enable_mc_list_trigger( { struct pmo_vdev_priv_obj *vdev_ctx; QDF_STATUS status; - struct pmo_mc_addr_list *op_mc_list_req = NULL; + struct pmo_mc_addr_list *op_mc_list_req; + + PMO_ENTER(); vdev_ctx = pmo_vdev_get_priv(vdev); op_mc_list_req = qdf_mem_malloc(sizeof(*op_mc_list_req)); if (!op_mc_list_req) { pmo_err("op_mc_list_req is NULL"); - status = QDF_STATUS_E_NULL_VALUE; - goto out; + status = QDF_STATUS_E_NOMEM; + goto exit_with_status; } switch (trigger) { case pmo_mc_list_change_notify: if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) { pmo_info("active offload is disabled, skip in mode: %d", - trigger); + trigger); status = QDF_STATUS_E_INVAL; - goto out; + goto free_req; } status = pmo_core_do_enable_mc_addr_list(vdev, vdev_ctx, - op_mc_list_req); + op_mc_list_req); break; case pmo_apps_suspend: if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) { pmo_info("active offload is enabled, skip in mode: %d", trigger); status = QDF_STATUS_E_INVAL; - goto out; + goto free_req; } status = pmo_core_do_enable_mc_addr_list(vdev, vdev_ctx, - op_mc_list_req); + op_mc_list_req); break; default: status = QDF_STATUS_E_INVAL; pmo_err("invalid pmo trigger for enable mc list"); break; } -out: - if (op_mc_list_req) - qdf_mem_free(op_mc_list_req); + +free_req: + qdf_mem_free(op_mc_list_req); + +exit_with_status: + PMO_EXIT(); return status; } @@ -492,32 +487,36 @@ QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr( struct wlan_objmgr_vdev *vdev; PMO_ENTER(); - if (!psoc) { - pmo_err("psoc is NULL"); - status = QDF_STATUS_E_NULL_VALUE; - goto out; - } + + status = pmo_psoc_get_ref(psoc); + if (QDF_IS_STATUS_ERROR(status)) + goto exit_with_status; vdev = pmo_psoc_get_vdev(psoc, vdev_id); if (!vdev) { pmo_err("vdev is NULL"); - status = QDF_STATUS_E_NULL_VALUE; - goto out; + status = QDF_STATUS_E_INVAL; + goto put_psoc; } status = pmo_vdev_get_ref(vdev); if (QDF_IS_STATUS_ERROR(status)) - goto out; + goto put_psoc; status = pmo_core_mc_addr_flitering_sanity(vdev); if (status != QDF_STATUS_SUCCESS) - goto dec_ref; + goto put_vdev; pmo_info("enable mclist trigger: %d", trigger); status = pmo_core_handle_enable_mc_list_trigger(vdev, trigger); -dec_ref: + +put_vdev: pmo_vdev_put_ref(vdev); -out: + +put_psoc: + pmo_psoc_put_ref(psoc); + +exit_with_status: PMO_EXIT(); return status; diff --git a/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h index e702da8690..0ba54992e4 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h @@ -172,15 +172,13 @@ QDF_STATUS pmo_tgt_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev, /** * pmo_tgt_send_enhance_multicast_offload_req() - send enhance mc offload req - * @wma_handle: wma handle - * @vdev_id: vdev id + * @vdev: the vdev to configure * @action: enable or disable enhance multicast offload * * Return: QDF_STATUS_SUCCESS on success else error code */ QDF_STATUS pmo_tgt_send_enhance_multicast_offload_req( struct wlan_objmgr_vdev *vdev, - uint8_t vdev_id, uint8_t action); /** diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index beb2adea6d..eba29a71d7 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -25,6 +25,7 @@ #include "wlan_pmo_arp_public_struct.h" #include "wlan_pmo_ns_public_struct.h" #include "wlan_pmo_gtk_public_struct.h" +#include "wlan_pmo_mc_addr_filtering.h" #include "wlan_pmo_mc_addr_filtering_public_struct.h" #include "wlan_pmo_wow_public_struct.h" #include "wlan_pmo_common_public_struct.h" @@ -228,6 +229,30 @@ QDF_STATUS pmo_ucfg_cache_mc_addr_list( QDF_STATUS pmo_ucfg_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); +/** + * pmo_ucfg_enhance_mc_filter_enable() - enable enhanced multicast filtering + * @vdev: the vdev to enable enhanced multicast filtering for + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +pmo_ucfg_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev) +{ + return pmo_core_enhanced_mc_filter_enable(vdev); +} + +/** + * pmo_ucfg_enhance_mc_filter_disable() - disable enhanced multicast filtering + * @vdev: the vdev to disable enhanced multicast filtering for + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +pmo_ucfg_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev) +{ + return pmo_core_enhanced_mc_filter_disable(vdev); +} + /** * pmo_ucfg_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr * @psoc: objmgr psoc handle diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c index bd322f9eed..d2e087f979 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c +++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c @@ -25,9 +25,8 @@ #include "wlan_pmo_main.h" QDF_STATUS pmo_tgt_send_enhance_multicast_offload_req( - struct wlan_objmgr_vdev *vdev, - uint8_t vdev_id, - uint8_t action) + struct wlan_objmgr_vdev *vdev, + uint8_t action) { QDF_STATUS status; struct wlan_objmgr_psoc *psoc; diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 6e62ae9486..2e8bddfe5a 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -3028,7 +3028,17 @@ int hdd_vdev_ready(hdd_adapter_t *adapter) QDF_STATUS status; status = pmo_vdev_ready(adapter->hdd_vdev); + if (QDF_IS_STATUS_ERROR(status)) + return qdf_status_to_os_return(status); + status = ucfg_reg_11d_vdev_created_update(adapter->hdd_vdev); + if (QDF_IS_STATUS_ERROR(status)) + return qdf_status_to_os_return(status); + + if (wma_capability_enhanced_mcast_filter()) + status = pmo_ucfg_enhanced_mc_filter_enable(adapter->hdd_vdev); + else + status = pmo_ucfg_enhanced_mc_filter_disable(adapter->hdd_vdev); return qdf_status_to_os_return(status); } diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index db132e7947..8eb36e73df 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -223,6 +223,7 @@ static inline QDF_STATUS wma_register_ndp_cb(QDF_STATUS (*pe_ndp_event_handler) bool wma_is_csa_offload_enabled(void); bool wma_is_p2p_lo_capable(void); +bool wma_capability_enhanced_mcast_filter(void); QDF_STATUS wma_p2p_lo_start(struct sir_p2p_lo_start *params); QDF_STATUS wma_p2p_lo_stop(u_int32_t vdev_id); QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *wake_lock_stats); diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 77e6edf297..6f6b9cbdd7 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -4228,21 +4228,15 @@ wma_config_debug_module_cmd(wmi_unified_t wmi_handle, A_UINT32 param, */ bool wma_is_p2p_lo_capable(void) { - tp_wma_handle wma; - - wma = cds_get_context(QDF_MODULE_ID_WMA); - if (!wma) { - WMA_LOGE("%s: Invalid WMA handle", __func__); - return false; - } - - if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap, - WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT)) - return true; - - return false; + return wma_is_service_enabled(WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT); } +bool wma_capability_enhanced_mcast_filter(void) +{ + return wma_is_service_enabled(WMI_SERVICE_ENHANCED_MCAST_FILTER); +} + + bool wma_is_vdev_up(uint8_t vdev_id) { struct wlan_objmgr_vdev *vdev;