From e74e6090f6df58698d37eaafbc33c1bb4204e766 Mon Sep 17 00:00:00 2001 From: Yun Park Date: Fri, 27 Apr 2018 11:36:34 -0700 Subject: [PATCH] qcacld-3.0: Remove wake_lock and rm_lock when WDI_UNIFIED_API defined IPA RM is not used when WDI_UNIFIED_API is defined. Remove to use wake_lock and rm_lock, which are created from RM setup. Change-Id: I6c614fde7d6d7f0ab94aa9933578f3dca814a40e CRs-Fixed: 2231424 --- components/ipa/core/inc/wlan_ipa_core.h | 8 + components/ipa/core/src/wlan_ipa_core.c | 283 +++++++++++++----------- components/ipa/core/src/wlan_ipa_rm.c | 14 ++ 3 files changed, 179 insertions(+), 126 deletions(-) diff --git a/components/ipa/core/inc/wlan_ipa_core.h b/components/ipa/core/inc/wlan_ipa_core.h index df6123cfee21..1deb6050b2fa 100644 --- a/components/ipa/core/inc/wlan_ipa_core.h +++ b/components/ipa/core/inc/wlan_ipa_core.h @@ -223,6 +223,8 @@ int wlan_ipa_wdi_rm_inactivity_timer_destroy( return qdf_ipa_rm_inactivity_timer_destroy(res_name); } +bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx); + #else /* CONFIG_IPA_WDI_UNIFIED_API */ static inline int wlan_ipa_wdi_rm_request_resource( @@ -274,6 +276,12 @@ int wlan_ipa_wdi_rm_inactivity_timer_destroy( return 0; } +static inline +bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx) +{ + return true; +} + #endif /* CONFIG_IPA_WDI_UNIFIED_API */ #ifdef FEATURE_METERING diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 52da0e02eaf3..54055c9ce7bd 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -192,6 +192,86 @@ struct wlan_ipa_priv *wlan_ipa_get_obj_context(void) return gp_ipa; } +/** + * wlan_ipa_send_pkt_to_tl() - Send an IPA packet to TL + * @iface_context: interface-specific IPA context + * @ipa_tx_desc: packet data descriptor + * + * Return: None + */ +static void wlan_ipa_send_pkt_to_tl( + struct wlan_ipa_iface_context *iface_context, + qdf_ipa_rx_data_t *ipa_tx_desc) +{ + struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx; + qdf_nbuf_t skb; + struct wlan_ipa_tx_desc *tx_desc; + + qdf_spin_lock_bh(&iface_context->interface_lock); + /* + * During CAC period, data packets shouldn't be sent over the air so + * drop all the packets here + */ + if (iface_context->device_mode == QDF_SAP_MODE || + iface_context->device_mode == QDF_P2P_GO_MODE) { + if (ipa_ctx->dfs_cac_block_tx) { + ipa_free_skb(ipa_tx_desc); + qdf_spin_unlock_bh(&iface_context->interface_lock); + iface_context->stats.num_tx_cac_drop++; + wlan_ipa_wdi_rm_try_release(ipa_ctx); + return; + } + } + qdf_spin_unlock_bh(&iface_context->interface_lock); + + skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc); + + qdf_mem_set(skb->cb, sizeof(skb->cb), 0); + + /* Store IPA Tx buffer ownership into SKB CB */ + qdf_nbuf_ipa_owned_set(skb); + if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { + qdf_nbuf_mapped_paddr_set(skb, + QDF_IPA_RX_DATA_DMA_ADDR(ipa_tx_desc) + + WLAN_IPA_WLAN_FRAG_HEADER + + WLAN_IPA_WLAN_IPA_HEADER); + QDF_IPA_RX_DATA_SKB_LEN(ipa_tx_desc) -= + WLAN_IPA_WLAN_FRAG_HEADER + WLAN_IPA_WLAN_IPA_HEADER; + } else + qdf_nbuf_mapped_paddr_set(skb, ipa_tx_desc->dma_addr); + + qdf_spin_lock_bh(&ipa_ctx->q_lock); + /* get free Tx desc and assign ipa_tx_desc pointer */ + if (qdf_list_remove_front(&ipa_ctx->tx_desc_list, + (qdf_list_node_t **)&tx_desc) == + QDF_STATUS_SUCCESS) { + tx_desc->ipa_tx_desc_ptr = ipa_tx_desc; + ipa_ctx->stats.num_tx_desc_q_cnt++; + qdf_spin_unlock_bh(&ipa_ctx->q_lock); + /* Store Tx Desc index into SKB CB */ + QDF_NBUF_CB_TX_IPA_PRIV(skb) = tx_desc->id; + } else { + ipa_ctx->stats.num_tx_desc_error++; + qdf_spin_unlock_bh(&ipa_ctx->q_lock); + qdf_ipa_free_skb(ipa_tx_desc); + wlan_ipa_wdi_rm_try_release(ipa_ctx); + return; + } + + skb = cdp_ipa_tx_send_data_frame(cds_get_context(QDF_MODULE_ID_SOC), + (struct cdp_vdev *)iface_context->tl_context, + QDF_IPA_RX_DATA_SKB(ipa_tx_desc)); + if (skb) { + qdf_nbuf_free(skb); + iface_context->stats.num_tx_err++; + return; + } + + atomic_inc(&ipa_ctx->tx_ref_cnt); + + iface_context->stats.num_tx++; +} + #ifdef CONFIG_IPA_WDI_UNIFIED_API /* @@ -324,6 +404,42 @@ static inline int wlan_ipa_wdi_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx, return 0; } +/** + * wlan_ipa_pm_flush() - flush queued packets + * @work: pointer to the scheduled work + * + * Called during PM resume to send packets to TL which were queued + * while host was in the process of suspending. + * + * Return: None + */ +static void wlan_ipa_pm_flush(void *data) +{ + struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data; + struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL; + qdf_nbuf_t skb; + uint32_t dequeued = 0; + + qdf_spin_lock_bh(&ipa_ctx->pm_lock); + while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) != + NULL)) { + qdf_spin_unlock_bh(&ipa_ctx->pm_lock); + + pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; + dequeued++; + + wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, + pm_tx_cb->ipa_tx_desc); + + qdf_spin_lock_bh(&ipa_ctx->pm_lock); + } + qdf_spin_unlock_bh(&ipa_ctx->pm_lock); + + ipa_ctx->stats.num_tx_dequeued += dequeued; + if (dequeued > ipa_ctx->stats.num_max_pm_queue) + ipa_ctx->stats.num_max_pm_queue = dequeued; +} + #else /* CONFIG_IPA_WDI_UNIFIED_API */ static inline void wlan_ipa_wdi_get_wdi_version(struct wlan_ipa_priv *ipa_ctx) @@ -394,6 +510,46 @@ static inline int wlan_ipa_wdi_teardown_sys_pipe( return qdf_ipa_teardown_sys_pipe(handle); } +/** + * wlan_ipa_pm_flush() - flush queued packets + * @work: pointer to the scheduled work + * + * Called during PM resume to send packets to TL which were queued + * while host was in the process of suspending. + * + * Return: None + */ +static void wlan_ipa_pm_flush(void *data) +{ + struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data; + struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL; + qdf_nbuf_t skb; + uint32_t dequeued = 0; + + qdf_wake_lock_acquire(&ipa_ctx->wake_lock, + WIFI_POWER_EVENT_WAKELOCK_IPA); + qdf_spin_lock_bh(&ipa_ctx->pm_lock); + while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) != + NULL)) { + qdf_spin_unlock_bh(&ipa_ctx->pm_lock); + + pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; + dequeued++; + + wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, + pm_tx_cb->ipa_tx_desc); + + qdf_spin_lock_bh(&ipa_ctx->pm_lock); + } + qdf_spin_unlock_bh(&ipa_ctx->pm_lock); + qdf_wake_lock_release(&ipa_ctx->wake_lock, + WIFI_POWER_EVENT_WAKELOCK_IPA); + + ipa_ctx->stats.num_tx_dequeued += dequeued; + if (dequeued > ipa_ctx->stats.num_max_pm_queue) + ipa_ctx->stats.num_max_pm_queue = dequeued; +} + #endif /* CONFIG_IPA_WDI_UNIFIED_API */ /** @@ -635,86 +791,6 @@ static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, } } -/** - * wlan_ipa_send_pkt_to_tl() - Send an IPA packet to TL - * @iface_context: interface-specific IPA context - * @ipa_tx_desc: packet data descriptor - * - * Return: None - */ -static void wlan_ipa_send_pkt_to_tl( - struct wlan_ipa_iface_context *iface_context, - qdf_ipa_rx_data_t *ipa_tx_desc) -{ - struct wlan_ipa_priv *ipa_ctx = iface_context->ipa_ctx; - qdf_nbuf_t skb; - struct wlan_ipa_tx_desc *tx_desc; - - qdf_spin_lock_bh(&iface_context->interface_lock); - /* - * During CAC period, data packets shouldn't be sent over the air so - * drop all the packets here - */ - if (iface_context->device_mode == QDF_SAP_MODE || - iface_context->device_mode == QDF_P2P_GO_MODE) { - if (ipa_ctx->dfs_cac_block_tx) { - ipa_free_skb(ipa_tx_desc); - qdf_spin_unlock_bh(&iface_context->interface_lock); - iface_context->stats.num_tx_cac_drop++; - wlan_ipa_wdi_rm_try_release(ipa_ctx); - return; - } - } - qdf_spin_unlock_bh(&iface_context->interface_lock); - - skb = QDF_IPA_RX_DATA_SKB(ipa_tx_desc); - - qdf_mem_set(skb->cb, sizeof(skb->cb), 0); - - /* Store IPA Tx buffer ownership into SKB CB */ - qdf_nbuf_ipa_owned_set(skb); - if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) { - qdf_nbuf_mapped_paddr_set(skb, - QDF_IPA_RX_DATA_DMA_ADDR(ipa_tx_desc) - + WLAN_IPA_WLAN_FRAG_HEADER - + WLAN_IPA_WLAN_IPA_HEADER); - QDF_IPA_RX_DATA_SKB_LEN(ipa_tx_desc) -= - WLAN_IPA_WLAN_FRAG_HEADER + WLAN_IPA_WLAN_IPA_HEADER; - } else - qdf_nbuf_mapped_paddr_set(skb, ipa_tx_desc->dma_addr); - - qdf_spin_lock_bh(&ipa_ctx->q_lock); - /* get free Tx desc and assign ipa_tx_desc pointer */ - if (qdf_list_remove_front(&ipa_ctx->tx_desc_list, - (qdf_list_node_t **)&tx_desc) == - QDF_STATUS_SUCCESS) { - tx_desc->ipa_tx_desc_ptr = ipa_tx_desc; - ipa_ctx->stats.num_tx_desc_q_cnt++; - qdf_spin_unlock_bh(&ipa_ctx->q_lock); - /* Store Tx Desc index into SKB CB */ - QDF_NBUF_CB_TX_IPA_PRIV(skb) = tx_desc->id; - } else { - ipa_ctx->stats.num_tx_desc_error++; - qdf_spin_unlock_bh(&ipa_ctx->q_lock); - qdf_ipa_free_skb(ipa_tx_desc); - wlan_ipa_wdi_rm_try_release(ipa_ctx); - return; - } - - skb = cdp_ipa_tx_send_data_frame(cds_get_context(QDF_MODULE_ID_SOC), - (struct cdp_vdev *)iface_context->tl_context, - QDF_IPA_RX_DATA_SKB(ipa_tx_desc)); - if (skb) { - qdf_nbuf_free(skb); - iface_context->stats.num_tx_err++; - return; - } - - atomic_inc(&ipa_ctx->tx_ref_cnt); - - iface_context->stats.num_tx++; -} - /** * wlan_ipa_i2w_cb() - IPA to WLAN callback * @priv: pointer to private data registered with IPA (we register a @@ -796,13 +872,8 @@ QDF_STATUS wlan_ipa_suspend(struct wlan_ipa_priv *ipa_ctx) if (atomic_read(&ipa_ctx->tx_ref_cnt)) return QDF_STATUS_E_AGAIN; - qdf_spin_lock_bh(&ipa_ctx->rm_lock); - - if (ipa_ctx->rm_state != WLAN_IPA_RM_RELEASED) { - qdf_spin_unlock_bh(&ipa_ctx->rm_lock); + if (!wlan_ipa_is_rm_released(ipa_ctx)) return QDF_STATUS_E_AGAIN; - } - qdf_spin_unlock_bh(&ipa_ctx->rm_lock); qdf_spin_lock_bh(&ipa_ctx->pm_lock); ipa_ctx->suspended = true; @@ -822,46 +893,6 @@ QDF_STATUS wlan_ipa_resume(struct wlan_ipa_priv *ipa_ctx) return QDF_STATUS_SUCCESS; } -/** - * wlan_ipa_pm_flush() - flush queued packets - * @work: pointer to the scheduled work - * - * Called during PM resume to send packets to TL which were queued - * while host was in the process of suspending. - * - * Return: None - */ -static void wlan_ipa_pm_flush(void *data) -{ - struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data; - struct wlan_ipa_pm_tx_cb *pm_tx_cb = NULL; - qdf_nbuf_t skb; - uint32_t dequeued = 0; - - qdf_wake_lock_acquire(&ipa_ctx->wake_lock, - WIFI_POWER_EVENT_WAKELOCK_IPA); - qdf_spin_lock_bh(&ipa_ctx->pm_lock); - while (((skb = qdf_nbuf_queue_remove(&ipa_ctx->pm_queue_head)) != - NULL)) { - qdf_spin_unlock_bh(&ipa_ctx->pm_lock); - - pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; - dequeued++; - - wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, - pm_tx_cb->ipa_tx_desc); - - qdf_spin_lock_bh(&ipa_ctx->pm_lock); - } - qdf_spin_unlock_bh(&ipa_ctx->pm_lock); - qdf_wake_lock_release(&ipa_ctx->wake_lock, - WIFI_POWER_EVENT_WAKELOCK_IPA); - - ipa_ctx->stats.num_tx_dequeued += dequeued; - if (dequeued > ipa_ctx->stats.num_max_pm_queue) - ipa_ctx->stats.num_max_pm_queue = dequeued; -} - QDF_STATUS wlan_ipa_uc_enable_pipes(struct wlan_ipa_priv *ipa_ctx) { int result; diff --git a/components/ipa/core/src/wlan_ipa_rm.c b/components/ipa/core/src/wlan_ipa_rm.c index 8110c9305da5..4b0d47dfeb21 100644 --- a/components/ipa/core/src/wlan_ipa_rm.c +++ b/components/ipa/core/src/wlan_ipa_rm.c @@ -473,4 +473,18 @@ void wlan_ipa_wdi_destroy_rm(struct wlan_ipa_priv *ipa_ctx) if (ret) ipa_err("RM PROD resource delete failed %d", ret); } + +bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx) +{ + qdf_spin_lock_bh(&ipa_ctx->rm_lock); + + if (ipa_ctx->rm_state != WLAN_IPA_RM_RELEASED) { + qdf_spin_unlock_bh(&ipa_ctx->rm_lock); + return false; + } + + qdf_spin_unlock_bh(&ipa_ctx->rm_lock); + + return true; +} #endif /* CONFIG_IPA_WDI_UNIFIED_API */