From 0dd9904c14be77da19978b83045bd232b893478f Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Mon, 28 Sep 2015 11:09:09 -0700 Subject: [PATCH] qcacld-3.0: Enable enahnced flow control a) Enabled flow control b) Add small helper functions to avoid duplication of code. c) Fix thermal mitigation unpause issue with flow control. CRs-Fixed: 916716 Change-Id: Ic02b66d1c23768a1c71dc08ed50dcedd02b647ce --- Kbuild | 6 ++- core/dp/txrx/ol_tx_desc.c | 19 ++------ core/dp/txrx/ol_tx_desc.h | 76 +++++++++++++++++++++++++++++ core/dp/txrx/ol_tx_queue.c | 3 +- core/dp/txrx/ol_txrx.c | 3 +- core/dp/txrx/ol_txrx_flow_control.c | 30 ++---------- 6 files changed, 95 insertions(+), 42 deletions(-) diff --git a/Kbuild b/Kbuild index 79c831f5eb..825909f521 100644 --- a/Kbuild +++ b/Kbuild @@ -116,7 +116,11 @@ ifeq ($(KERNEL_BUILD), 0) CONFIG_WLAN_NAPI_DEBUG := n # Flag to enable FW based TX Flow control - CONFIG_WLAN_TX_FLOW_CONTROL_V2 := n + ifeq ($(CONFIG_CNSS_EOS),y) + CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y + else + CONFIG_WLAN_TX_FLOW_CONTROL_V2 := n + endif # Flag to enable LRO (Large Receive Offload) ifeq ($(CONFIG_CNSS_EOS), y) diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c index 1fa78723aa..4b80f5c375 100644 --- a/core/dp/txrx/ol_tx_desc.c +++ b/core/dp/txrx/ol_tx_desc.c @@ -122,9 +122,7 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, cdf_spin_lock_bh(&pdev->tx_mutex); if (pdev->tx_desc.freelist) { - pdev->tx_desc.num_free--; - tx_desc = &pdev->tx_desc.freelist->tx_desc; - pdev->tx_desc.freelist = pdev->tx_desc.freelist->next; + tx_desc = ol_tx_get_desc_global_pool(pdev); ol_tx_desc_sanity_checks(pdev, tx_desc); ol_tx_desc_compute_delay(tx_desc); } @@ -175,9 +173,8 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, if (pool) { cdf_spin_lock_bh(&pool->flow_pool_lock); if (pool->avail_desc) { - tx_desc = &pool->freelist->tx_desc; - pool->freelist = pool->freelist->next; - if (cdf_unlikely(--pool->avail_desc < pool->stop_th)) { + tx_desc = ol_tx_get_desc_flow_pool(pool); + if (cdf_unlikely(pool->avail_desc < pool->stop_th)) { pool->status = FLOW_POOL_ACTIVE_PAUSED; cdf_spin_unlock_bh(&pool->flow_pool_lock); /* pause network queues */ @@ -253,10 +250,7 @@ void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) ol_tx_desc_reset_pkt_type(tx_desc); ol_tx_desc_reset_timestamp(tx_desc); - ((union ol_tx_desc_list_elem_t *)tx_desc)->next = - pdev->tx_desc.freelist; - pdev->tx_desc.freelist = (union ol_tx_desc_list_elem_t *)tx_desc; - pdev->tx_desc.num_free++; + ol_tx_put_desc_global_pool(pdev, tx_desc); #if defined(CONFIG_PER_VDEV_TX_DESC_POOL) #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL if ((cdf_atomic_read(&tx_desc->vdev->os_q_paused)) && @@ -298,10 +292,7 @@ void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) ol_tx_desc_reset_timestamp(tx_desc); cdf_spin_lock_bh(&pool->flow_pool_lock); - ((union ol_tx_desc_list_elem_t *)tx_desc)->next = - pool->freelist; - pool->freelist = (union ol_tx_desc_list_elem_t *)tx_desc; - pool->avail_desc++; + ol_tx_put_desc_flow_pool(pool, tx_desc); switch (pool->status) { case FLOW_POOL_ACTIVE_PAUSED: if (pool->avail_desc > pool->start_th) { diff --git a/core/dp/txrx/ol_tx_desc.h b/core/dp/txrx/ol_tx_desc.h index 392e192249..c96c47a052 100644 --- a/core/dp/txrx/ol_tx_desc.h +++ b/core/dp/txrx/ol_tx_desc.h @@ -165,8 +165,84 @@ void ol_tso_free_segment(struct ol_txrx_pdev_t *pdev, struct cdf_tso_seg_elem_t *tso_seg); #endif +/** + * ol_tx_get_desc_global_pool() - get descriptor from global pool + * @pdev: pdev handler + * + * Caller needs to take lock and do sanity checks. + * + * Return: tx descriptor + */ +static inline +struct ol_tx_desc_t *ol_tx_get_desc_global_pool(struct ol_txrx_pdev_t *pdev) +{ + struct ol_tx_desc_t *tx_desc = &pdev->tx_desc.freelist->tx_desc; + pdev->tx_desc.freelist = pdev->tx_desc.freelist->next; + pdev->tx_desc.num_free--; + return tx_desc; +} + +/** + * ol_tx_put_desc_global_pool() - put descriptor to global pool freelist + * @pdev: pdev handle + * @tx_desc: tx descriptor + * + * Caller needs to take lock and do sanity checks. + * + * Return: none + */ +static inline +void ol_tx_put_desc_global_pool(struct ol_txrx_pdev_t *pdev, + struct ol_tx_desc_t *tx_desc) +{ + ((union ol_tx_desc_list_elem_t *)tx_desc)->next = + pdev->tx_desc.freelist; + pdev->tx_desc.freelist = + (union ol_tx_desc_list_elem_t *)tx_desc; + pdev->tx_desc.num_free++; + return; +} + + #ifdef QCA_LL_TX_FLOW_CONTROL_V2 int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool); +/** + * ol_tx_get_desc_flow_pool() - get descriptor from flow pool + * @pool: flow pool + * + * Caller needs to take lock and do sanity checks. + * + * Return: tx descriptor + */ +static inline +struct ol_tx_desc_t *ol_tx_get_desc_flow_pool(struct ol_tx_flow_pool_t *pool) +{ + struct ol_tx_desc_t *tx_desc = &pool->freelist->tx_desc; + pool->freelist = pool->freelist->next; + pool->avail_desc--; + return tx_desc; +} + +/** + * ol_tx_put_desc_flow_pool() - put descriptor to flow pool freelist + * @pool: flow pool + * @tx_desc: tx descriptor + * + * Caller needs to take lock and do sanity checks. + * + * Return: none + */ +static inline +void ol_tx_put_desc_flow_pool(struct ol_tx_flow_pool_t *pool, + struct ol_tx_desc_t *tx_desc) +{ + tx_desc->pool = pool; + ((union ol_tx_desc_list_elem_t *)tx_desc)->next = pool->freelist; + pool->freelist = (union ol_tx_desc_list_elem_t *)tx_desc; + pool->avail_desc++; + return; +} + #else static inline int ol_tx_free_invalid_flow_pool(void *pool) { diff --git a/core/dp/txrx/ol_tx_queue.c b/core/dp/txrx/ol_tx_queue.c index d24ae0bb2f..a894b1c30c 100644 --- a/core/dp/txrx/ol_tx_queue.c +++ b/core/dp/txrx/ol_tx_queue.c @@ -219,7 +219,7 @@ void ol_txrx_pdev_unpause(struct ol_txrx_pdev_t *pdev, uint32_t reason) struct ol_txrx_vdev_t *vdev = NULL, *tmp; TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) { - ol_txrx_vdev_pause(vdev, reason); + ol_txrx_vdev_unpause(vdev, reason); } } @@ -357,6 +357,7 @@ void ol_tx_throttle_set_level(struct ol_txrx_pdev_t *pdev, int level) /* Reset the phase */ pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF; + ol_txrx_thermal_unpause(pdev); /* Start with the new time */ ms = pdev->tx_throttle. diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index ae164368f6..02ab1793af 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -272,7 +272,6 @@ setup_fastpath_ce_handles(struct ol_softc *osc, struct ol_txrx_pdev_t *pdev) * * Return: none */ -inline void ol_tx_set_desc_global_pool_size(uint32_t num_msdu_desc) { struct ol_txrx_pdev_t *pdev = cds_get_context(CDF_MODULE_ID_TXRX); @@ -281,6 +280,8 @@ void ol_tx_set_desc_global_pool_size(uint32_t num_msdu_desc) return; } pdev->num_msdu_desc = num_msdu_desc + TX_FLOW_MGMT_POOL_SIZE; + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Global pool size: %d = %d + %d\n", + pdev->num_msdu_desc, num_msdu_desc, TX_FLOW_MGMT_POOL_SIZE); return; } diff --git a/core/dp/txrx/ol_txrx_flow_control.c b/core/dp/txrx/ol_txrx_flow_control.c index fd759baee8..82785837ac 100644 --- a/core/dp/txrx/ol_txrx_flow_control.c +++ b/core/dp/txrx/ol_txrx_flow_control.c @@ -51,12 +51,9 @@ #include #include -#define TX_FLOW_START_TH 25 -#define TX_FLOW_STOP_TH 10 #define INVALID_FLOW_ID 0xFF #define MAX_INVALID_BIN 3 - #ifdef QCA_LL_TX_FLOW_GLOBAL_MGMT_POOL #define TX_FLOW_MGMT_POOL_ID 0xEF #define TX_FLOW_MGMT_POOL_SIZE 32 @@ -232,9 +229,7 @@ static int ol_tx_move_desc_n(struct ol_tx_flow_pool_t *src_pool, /* Take descriptors from source pool and put it in temp_list */ cdf_spin_lock_bh(&src_pool->flow_pool_lock); for (i = 0; i < desc_move_count; i++) { - tx_desc = &src_pool->freelist->tx_desc; - src_pool->freelist = src_pool->freelist->next; - src_pool->avail_desc--; + tx_desc = ol_tx_get_desc_flow_pool(src_pool); ((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list; temp_list = (union ol_tx_desc_list_elem_t *)tx_desc; @@ -250,11 +245,7 @@ static int ol_tx_move_desc_n(struct ol_tx_flow_pool_t *src_pool, break; tx_desc = &temp_list->tx_desc; temp_list = temp_list->next; - tx_desc->pool = dst_pool; - ((union ol_tx_desc_list_elem_t *)tx_desc)->next = - dst_pool->freelist; - dst_pool->freelist = (union ol_tx_desc_list_elem_t *)tx_desc; - dst_pool->avail_desc++; + ol_tx_put_desc_flow_pool(dst_pool, tx_desc); count++; } cdf_spin_unlock_bh(&dst_pool->flow_pool_lock); @@ -264,11 +255,7 @@ static int ol_tx_move_desc_n(struct ol_tx_flow_pool_t *src_pool, while (temp_list) { tx_desc = &temp_list->tx_desc; temp_list = temp_list->next; - tx_desc->pool = src_pool; - ((union ol_tx_desc_list_elem_t *)tx_desc)->next = - src_pool->freelist; - src_pool->freelist = (union ol_tx_desc_list_elem_t *)tx_desc; - src_pool->avail_desc++; + ol_tx_put_desc_flow_pool(src_pool, tx_desc); } cdf_spin_unlock_bh(&src_pool->flow_pool_lock); @@ -370,9 +357,7 @@ struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id, size = pdev->tx_desc.num_free; for (i = 0; i < size; i++) { - pdev->tx_desc.num_free--; - tx_desc = &pdev->tx_desc.freelist->tx_desc; - pdev->tx_desc.freelist = pdev->tx_desc.freelist->next; + tx_desc = ol_tx_get_desc_global_pool(pdev); tx_desc->pool = pool; ((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list; temp_list = (union ol_tx_desc_list_elem_t *)tx_desc; @@ -458,12 +443,7 @@ int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool) tx_desc = &temp_list->tx_desc; temp_list = temp_list->next; - ((union ol_tx_desc_list_elem_t *)tx_desc)->next = - pdev->tx_desc.freelist; - pdev->tx_desc.freelist = - (union ol_tx_desc_list_elem_t *)tx_desc; - pdev->tx_desc.num_free++; - + ol_tx_put_desc_global_pool(pdev, tx_desc); } cdf_spin_unlock_bh(&pdev->tx_mutex);