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
This commit is contained in:
Nirav Shah
2015-09-28 11:09:09 -07:00
committed by Satish Singh
parent 2a85ce72a2
commit 0dd9904c14
6 changed files with 95 additions and 42 deletions

6
Kbuild
View File

@@ -116,7 +116,11 @@ ifeq ($(KERNEL_BUILD), 0)
CONFIG_WLAN_NAPI_DEBUG := n CONFIG_WLAN_NAPI_DEBUG := n
# Flag to enable FW based TX Flow control # 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) # Flag to enable LRO (Large Receive Offload)
ifeq ($(CONFIG_CNSS_EOS), y) ifeq ($(CONFIG_CNSS_EOS), y)

View File

@@ -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); cdf_spin_lock_bh(&pdev->tx_mutex);
if (pdev->tx_desc.freelist) { if (pdev->tx_desc.freelist) {
pdev->tx_desc.num_free--; tx_desc = ol_tx_get_desc_global_pool(pdev);
tx_desc = &pdev->tx_desc.freelist->tx_desc;
pdev->tx_desc.freelist = pdev->tx_desc.freelist->next;
ol_tx_desc_sanity_checks(pdev, tx_desc); ol_tx_desc_sanity_checks(pdev, tx_desc);
ol_tx_desc_compute_delay(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) { if (pool) {
cdf_spin_lock_bh(&pool->flow_pool_lock); cdf_spin_lock_bh(&pool->flow_pool_lock);
if (pool->avail_desc) { if (pool->avail_desc) {
tx_desc = &pool->freelist->tx_desc; tx_desc = ol_tx_get_desc_flow_pool(pool);
pool->freelist = pool->freelist->next; if (cdf_unlikely(pool->avail_desc < pool->stop_th)) {
if (cdf_unlikely(--pool->avail_desc < pool->stop_th)) {
pool->status = FLOW_POOL_ACTIVE_PAUSED; pool->status = FLOW_POOL_ACTIVE_PAUSED;
cdf_spin_unlock_bh(&pool->flow_pool_lock); cdf_spin_unlock_bh(&pool->flow_pool_lock);
/* pause network queues */ /* 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_pkt_type(tx_desc);
ol_tx_desc_reset_timestamp(tx_desc); ol_tx_desc_reset_timestamp(tx_desc);
((union ol_tx_desc_list_elem_t *)tx_desc)->next = ol_tx_put_desc_global_pool(pdev, tx_desc);
pdev->tx_desc.freelist;
pdev->tx_desc.freelist = (union ol_tx_desc_list_elem_t *)tx_desc;
pdev->tx_desc.num_free++;
#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) #if defined(CONFIG_PER_VDEV_TX_DESC_POOL)
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
if ((cdf_atomic_read(&tx_desc->vdev->os_q_paused)) && 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); ol_tx_desc_reset_timestamp(tx_desc);
cdf_spin_lock_bh(&pool->flow_pool_lock); cdf_spin_lock_bh(&pool->flow_pool_lock);
((union ol_tx_desc_list_elem_t *)tx_desc)->next = ol_tx_put_desc_flow_pool(pool, tx_desc);
pool->freelist;
pool->freelist = (union ol_tx_desc_list_elem_t *)tx_desc;
pool->avail_desc++;
switch (pool->status) { switch (pool->status) {
case FLOW_POOL_ACTIVE_PAUSED: case FLOW_POOL_ACTIVE_PAUSED:
if (pool->avail_desc > pool->start_th) { if (pool->avail_desc > pool->start_th) {

View File

@@ -165,8 +165,84 @@ void ol_tso_free_segment(struct ol_txrx_pdev_t *pdev,
struct cdf_tso_seg_elem_t *tso_seg); struct cdf_tso_seg_elem_t *tso_seg);
#endif #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 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool); 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 #else
static inline int ol_tx_free_invalid_flow_pool(void *pool) static inline int ol_tx_free_invalid_flow_pool(void *pool)
{ {

View File

@@ -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; struct ol_txrx_vdev_t *vdev = NULL, *tmp;
TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, 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 */ /* Reset the phase */
pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF; pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;
ol_txrx_thermal_unpause(pdev);
/* Start with the new time */ /* Start with the new time */
ms = pdev->tx_throttle. ms = pdev->tx_throttle.

View File

@@ -272,7 +272,6 @@ setup_fastpath_ce_handles(struct ol_softc *osc, struct ol_txrx_pdev_t *pdev)
* *
* Return: none * Return: none
*/ */
inline
void ol_tx_set_desc_global_pool_size(uint32_t num_msdu_desc) 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); 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; return;
} }
pdev->num_msdu_desc = num_msdu_desc + TX_FLOW_MGMT_POOL_SIZE; 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; return;
} }

View File

@@ -51,12 +51,9 @@
#include <ol_tx.h> #include <ol_tx.h>
#include <ol_cfg.h> #include <ol_cfg.h>
#define TX_FLOW_START_TH 25
#define TX_FLOW_STOP_TH 10
#define INVALID_FLOW_ID 0xFF #define INVALID_FLOW_ID 0xFF
#define MAX_INVALID_BIN 3 #define MAX_INVALID_BIN 3
#ifdef QCA_LL_TX_FLOW_GLOBAL_MGMT_POOL #ifdef QCA_LL_TX_FLOW_GLOBAL_MGMT_POOL
#define TX_FLOW_MGMT_POOL_ID 0xEF #define TX_FLOW_MGMT_POOL_ID 0xEF
#define TX_FLOW_MGMT_POOL_SIZE 32 #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 */ /* Take descriptors from source pool and put it in temp_list */
cdf_spin_lock_bh(&src_pool->flow_pool_lock); cdf_spin_lock_bh(&src_pool->flow_pool_lock);
for (i = 0; i < desc_move_count; i++) { for (i = 0; i < desc_move_count; i++) {
tx_desc = &src_pool->freelist->tx_desc; tx_desc = ol_tx_get_desc_flow_pool(src_pool);
src_pool->freelist = src_pool->freelist->next;
src_pool->avail_desc--;
((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list; ((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list;
temp_list = (union ol_tx_desc_list_elem_t *)tx_desc; 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; break;
tx_desc = &temp_list->tx_desc; tx_desc = &temp_list->tx_desc;
temp_list = temp_list->next; temp_list = temp_list->next;
tx_desc->pool = dst_pool; ol_tx_put_desc_flow_pool(dst_pool, tx_desc);
((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++;
count++; count++;
} }
cdf_spin_unlock_bh(&dst_pool->flow_pool_lock); 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) { while (temp_list) {
tx_desc = &temp_list->tx_desc; tx_desc = &temp_list->tx_desc;
temp_list = temp_list->next; temp_list = temp_list->next;
tx_desc->pool = src_pool; ol_tx_put_desc_flow_pool(src_pool, tx_desc);
((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++;
} }
cdf_spin_unlock_bh(&src_pool->flow_pool_lock); 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; size = pdev->tx_desc.num_free;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
pdev->tx_desc.num_free--; tx_desc = ol_tx_get_desc_global_pool(pdev);
tx_desc = &pdev->tx_desc.freelist->tx_desc;
pdev->tx_desc.freelist = pdev->tx_desc.freelist->next;
tx_desc->pool = pool; tx_desc->pool = pool;
((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list; ((union ol_tx_desc_list_elem_t *)tx_desc)->next = temp_list;
temp_list = (union ol_tx_desc_list_elem_t *)tx_desc; 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; tx_desc = &temp_list->tx_desc;
temp_list = temp_list->next; temp_list = temp_list->next;
((union ol_tx_desc_list_elem_t *)tx_desc)->next = ol_tx_put_desc_global_pool(pdev, tx_desc);
pdev->tx_desc.freelist;
pdev->tx_desc.freelist =
(union ol_tx_desc_list_elem_t *)tx_desc;
pdev->tx_desc.num_free++;
} }
cdf_spin_unlock_bh(&pdev->tx_mutex); cdf_spin_unlock_bh(&pdev->tx_mutex);