From bb47e130a0be6fefe9e1fdfdab6bf93409b4fc00 Mon Sep 17 00:00:00 2001 From: jiad Date: Fri, 30 Mar 2018 16:28:30 +0800 Subject: [PATCH] qcacld-3.0: fix ipa mcc scc event notification Issue is under AP-AP MCC config, mcc event is not sent from wlan to IPA driver. mcc mode is decided with the help of connection table. But for AP mode, mcc mode is checked and updated before connection table is updated by adding the SAP vdev entry. Fix is to make ipa mcc mode check and notification when connection table is updated. Since block is not allowed when conn table is updated, a new work_struct mcc_work is introduced. Change-Id: I935222e26bb3f6b31685f52b75084b034daccad2 CRs-Fixed: 2075876 --- components/ipa/core/inc/wlan_ipa_core.h | 12 ++-- components/ipa/core/inc/wlan_ipa_priv.h | 1 + components/ipa/core/src/wlan_ipa_core.c | 94 ++++++++++++++++--------- core/hdd/inc/wlan_hdd_ipa.h | 14 ++++ core/hdd/src/wlan_hdd_assoc.c | 2 - core/hdd/src/wlan_hdd_hostapd.c | 4 -- core/hdd/src/wlan_hdd_ipa.c | 16 ++++- core/hdd/src/wlan_hdd_main.c | 1 + 8 files changed, 94 insertions(+), 50 deletions(-) diff --git a/components/ipa/core/inc/wlan_ipa_core.h b/components/ipa/core/inc/wlan_ipa_core.h index 0a20a767f389..c857342d9d85 100644 --- a/components/ipa/core/inc/wlan_ipa_core.h +++ b/components/ipa/core/inc/wlan_ipa_core.h @@ -439,15 +439,11 @@ void wlan_ipa_reg_send_to_nw_cb(struct wlan_ipa_priv *ipa_ctx, void *cb) /** * wlan_ipa_set_mcc_mode() - Set MCC mode * @ipa_ctx: IPA context - * @mcc_mode: 0=MCC/1=SCC + * @mcc_mode: 1=MCC/0=SCC * * Return: void */ -static inline -void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode) -{ - ipa_ctx->mcc_mode = mcc_mode; -} +void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode); /** * wlan_ipa_set_dfs_cac_tx() - Set DFS cac tx block @@ -537,6 +533,10 @@ QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx, { return QDF_STATUS_SUCCESS; } + +static inline void wlan_ipa_mcc_work_handler(void *data) +{ +} #endif /** diff --git a/components/ipa/core/inc/wlan_ipa_priv.h b/components/ipa/core/inc/wlan_ipa_priv.h index 5814ef7ef09b..0e6f523222a3 100644 --- a/components/ipa/core/inc/wlan_ipa_priv.h +++ b/components/ipa/core/inc/wlan_ipa_priv.h @@ -631,6 +631,7 @@ struct wlan_ipa_priv { uint8_t vdev_to_iface[WLAN_IPA_MAX_SESSION]; bool vdev_offload_enabled[WLAN_IPA_MAX_SESSION]; bool mcc_mode; + qdf_work_t mcc_work; bool ap_intrabss_fwd; bool dfs_cac_block_tx; #ifdef FEATURE_METERING diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 688694b30ed5..37f4e4d0e4dc 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -2061,6 +2061,53 @@ static void wlan_ipa_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx) } } +#ifndef QCA_LL_TX_FLOW_CONTROL_V2 +QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx, + bool mcc_mode) +{ + qdf_ipa_msg_meta_t meta; + qdf_ipa_wlan_msg_t *msg; + int ret; + + if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) + return QDF_STATUS_SUCCESS; + + /* Send SCC/MCC Switching event to IPA */ + QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*msg); + msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); + if (msg == NULL) { + ipa_err("msg allocation failed"); + return QDF_STATUS_E_NOMEM; + } + + if (mcc_mode) + QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_MCC); + else + QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_SCC); + WLAN_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, + "ipa_send_msg(Evt:%d)", + QDF_IPA_MSG_META_MSG_TYPE(&meta)); + + ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn); + + if (ret) { + ipa_err("ipa_send_msg(Evt:%d) - fail=%d", + QDF_IPA_MSG_META_MSG_TYPE(&meta), ret); + qdf_mem_free(msg); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +static void wlan_ipa_mcc_work_handler(void *data) +{ + struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data; + + wlan_ipa_send_mcc_scc_msg(ipa_ctx, ipa_ctx->mcc_mode); +} +#endif + /** * wlan_ipa_setup() - IPA initialization function * @ipa_ctx: IPA context @@ -2134,6 +2181,9 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx, ret = wlan_ipa_setup_sys_pipe(ipa_ctx); if (ret) goto fail_create_sys_pipe; + + qdf_create_work(0, &ipa_ctx->mcc_work, + wlan_ipa_mcc_work_handler, ipa_ctx); } status = wlan_ipa_wdi_init(ipa_ctx); @@ -2208,8 +2258,10 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx) wlan_ipa_teardown_sys_pipe(ipa_ctx); /* Teardown IPA sys_pipe for MCC */ - if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) + if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { wlan_ipa_teardown_sys_pipe(ipa_ctx); + qdf_cancel_work(&ipa_ctx->mcc_work); + } wlan_ipa_wdi_destroy_rm(ipa_ctx); @@ -2253,45 +2305,17 @@ struct wlan_ipa_iface_context return NULL; } -#ifndef QCA_LL_TX_FLOW_CONTROL_V2 -QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx, - bool mcc_mode) +void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode) { - qdf_ipa_msg_meta_t meta; - qdf_ipa_wlan_msg_t *msg; - int ret; - if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) - return QDF_STATUS_SUCCESS; + return; - /* Send SCC/MCC Switching event to IPA */ - QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*msg); - msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); - if (msg == NULL) { - ipa_err("msg allocation failed"); - return QDF_STATUS_E_NOMEM; - } + if (ipa_ctx->mcc_mode == mcc_mode) + return; - if (mcc_mode) - QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_MCC); - else - QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_SCC); - WLAN_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, - "ipa_send_msg(Evt:%d)", - QDF_IPA_MSG_META_MSG_TYPE(&meta)); - - ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn); - - if (ret) { - ipa_err("ipa_send_msg(Evt:%d) - fail=%d", - QDF_IPA_MSG_META_MSG_TYPE(&meta), ret); - qdf_mem_free(msg); - return QDF_STATUS_E_FAILURE; - } - - return QDF_STATUS_SUCCESS; + ipa_ctx->mcc_mode = mcc_mode; + qdf_sched_work(0, &ipa_ctx->mcc_work); } -#endif /** * wlan_ipa_uc_loaded_handler() - Process IPA uC loaded indication diff --git a/core/hdd/inc/wlan_hdd_ipa.h b/core/hdd/inc/wlan_hdd_ipa.h index af87be16f1f9..12bc194c5fb0 100644 --- a/core/hdd/inc/wlan_hdd_ipa.h +++ b/core/hdd/inc/wlan_hdd_ipa.h @@ -61,6 +61,16 @@ void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev); */ void hdd_ipa_set_tx_flow_info(void); +/** + * hdd_ipa_set_mcc_mode() - To set mcc mode if IPA is enabled + * @mcc_mode: mcc mode + * + * This routine is called to set mcc mode if IPA is enabled + * + * Return: None + */ +void hdd_ipa_set_mcc_mode(bool mcc_mode); + #else static inline void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev) @@ -71,5 +81,9 @@ static inline void hdd_ipa_set_tx_flow_info(void) { } +static inline void hdd_ipa_set_mcc_mode(bool mcc_mode) +{ +} + #endif #endif /* HDD_IPA_H__ */ diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index d4c048d6f9c2..700257598105 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1485,8 +1485,6 @@ static void hdd_send_association_event(struct net_device *dev, #endif } hdd_ipa_set_tx_flow_info(); - /* Send SCC/MCC Switching event to IPA */ - ucfg_ipa_send_mcc_scc_msg(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode); msg = NULL; /* During the WLAN uninitialization,supplicant is stopped before the diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index b088614d2cac..89bd71e01cf0 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1784,8 +1784,6 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, we_event = IWEVCUSTOM; we_custom_event_generic = we_custom_start_event; hdd_ipa_set_tx_flow_info(); - /* Send SCC/MCC Switching event to IPA */ - ucfg_ipa_send_mcc_scc_msg(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode); if (policy_mgr_is_hw_mode_change_after_vdev_up( hdd_ctx->hdd_psoc)) { @@ -2553,8 +2551,6 @@ stopbss: qdf_event_set(&hostapd_state->qdf_stop_bss_event); hdd_ipa_set_tx_flow_info(); - /* Send SCC/MCC Switching event to IPA */ - ucfg_ipa_send_mcc_scc_msg(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode); } return QDF_STATUS_SUCCESS; } diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index 61b993ed3bf5..dcfc97f927cf 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -320,9 +320,6 @@ void hdd_ipa_set_tx_flow_info(void) targetChannel = 0; #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ } - - hdd_ctx->mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc); - ucfg_ipa_set_mcc_mode(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode); } #ifdef QCA_CONFIG_SMP @@ -404,3 +401,16 @@ void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev) else ++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index]; } + +void hdd_ipa_set_mcc_mode(bool mcc_mode) +{ + struct hdd_context *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (!hdd_ctx) { + hdd_err("HDD context is NULL"); + return; + } + + ucfg_ipa_set_mcc_mode(hdd_ctx->hdd_pdev, mcc_mode); +} diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 1461f1e1eb8c..a9f541aaa312 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -10041,6 +10041,7 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) dp_cbs.hdd_disable_lro_in_concurrency = hdd_disable_lro_in_concurrency; dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps; + dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode; status = policy_mgr_register_dp_cb(hdd_ctx->hdd_psoc, &dp_cbs); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_debug("Failed to register DP cb with Policy Manager");