qcacmn: TSO fixes

1. Unmap tso common segment only after receiving
   completions for all the tso segments for a given
   skb.
2. Keep a track of num of free tso descriptors available
   in the pool of tso descriptors.

Change-Id: I01bdbb9e40b7259f77dbcfeec22c6d8cd0c0a6dd
CRs-Fixed: 2042950
This commit is contained in:
Venkata Sharath Chandra Manchala
2017-04-06 15:30:54 -07:00
کامیت شده توسط snandini
والد ae66cda533
کامیت 35503cce26
7فایلهای تغییر یافته به همراه367 افزوده شده و 32 حذف شده

مشاهده پرونده

@@ -296,6 +296,7 @@ QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
struct qdf_tso_seg_elem_t *c_element;
struct qdf_tso_seg_elem_t *temp;
soc->tx_tso_desc[pool_id].num_free = 0;
c_element = qdf_mem_malloc(sizeof(struct qdf_tso_seg_elem_t));
if (!c_element) {
@@ -306,10 +307,10 @@ QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
}
soc->tx_tso_desc[pool_id].freelist = c_element;
soc->tx_tso_desc[pool_id].num_free++;
for (i = 0; i < (num_elem - 1); i++) {
c_element->next =
qdf_mem_malloc(sizeof(struct qdf_tso_seg_elem_t));
if (!c_element->next) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
FL("Alloc Failed %p pool_id %d"),
@@ -317,10 +318,13 @@ QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
goto fail;
}
soc->tx_tso_desc[pool_id].num_free++;
c_element = c_element->next;
c_element->next = NULL;
}
}
TSO_DEBUG("Number of free descriptors: %u\n",
soc->tx_tso_desc[pool_id].num_free);
soc->tx_tso_desc[pool_id].pool_size = num_elem;
TX_DESC_LOCK_CREATE(&soc->tx_tso_desc[pool_id].lock);
@@ -336,13 +340,6 @@ fail:
return QDF_STATUS_E_NOMEM;
}
#else
QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
uint16_t num_elem)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
* dp_tx_tso_desc_pool_free() - free tx tso descriptor pool
@@ -351,7 +348,6 @@ QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
*
* Return: NONE
*/
#if defined(FEATURE_TSO)
void dp_tx_tso_desc_pool_free(struct dp_soc *soc, uint8_t pool_id)
{
int i;
@@ -382,9 +378,124 @@ void dp_tx_tso_desc_pool_free(struct dp_soc *soc, uint8_t pool_id)
TX_DESC_LOCK_DESTROY(&soc->tx_tso_desc[pool_id].lock);
return;
}
/**
* dp_tx_tso_num_seg_pool_alloc() - Allocate descriptors that tracks the
* fragments in each tso segment
*
* @soc: handle to dp soc structure
* @pool_id: descriptor pool id
* @num_elem: total number of descriptors to be allocated
*/
QDF_STATUS dp_tx_tso_num_seg_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
uint16_t num_elem)
{
int i;
struct qdf_tso_num_seg_elem_t *c_element;
struct qdf_tso_num_seg_elem_t *temp;
soc->tx_tso_num_seg[pool_id].num_free = 0;
c_element = qdf_mem_malloc(sizeof(struct qdf_tso_num_seg_elem_t));
if (!c_element) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
FL("Alloc Failed %p pool_id %d"),
soc, pool_id);
return QDF_STATUS_E_NOMEM;
}
soc->tx_tso_num_seg[pool_id].freelist = c_element;
soc->tx_tso_num_seg[pool_id].num_free++;
for (i = 0; i < (num_elem - 1); i++) {
c_element->next =
qdf_mem_malloc(sizeof(struct qdf_tso_num_seg_elem_t));
if (!c_element->next) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
FL("Alloc Failed %p pool_id %d"),
soc, pool_id);
goto fail;
}
soc->tx_tso_num_seg[pool_id].num_free++;
c_element = c_element->next;
c_element->next = NULL;
}
soc->tx_tso_num_seg[pool_id].num_seg_pool_size = num_elem;
TX_DESC_LOCK_CREATE(&soc->tx_tso_num_seg[pool_id].lock);
return QDF_STATUS_SUCCESS;
fail:
c_element = soc->tx_tso_num_seg[pool_id].freelist;
while (c_element) {
temp = c_element->next;
qdf_mem_free(c_element);
c_element = temp;
}
return QDF_STATUS_E_NOMEM;
}
/**
* dp_tx_tso_num_seg_pool_free() - free pool of descriptors that tracks
* the fragments in tso segment
*
*
* @soc: handle to dp soc structure
* @pool_id: descriptor pool_id
*/
void dp_tx_tso_num_seg_pool_free(struct dp_soc *soc, uint8_t pool_id)
{
int i;
struct qdf_tso_num_seg_elem_t *c_element;
struct qdf_tso_num_seg_elem_t *temp;
TX_DESC_LOCK_LOCK(&soc->tx_tso_num_seg[pool_id].lock);
c_element = soc->tx_tso_num_seg[pool_id].freelist;
if (!c_element) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
FL("Desc Pool Corrupt %d"), pool_id);
return;
}
for (i = 0; i < soc->tx_tso_num_seg[pool_id].num_seg_pool_size; i++) {
temp = c_element->next;
qdf_mem_free(c_element);
c_element = temp;
if (!c_element)
break;
}
soc->tx_tso_num_seg[pool_id].freelist = NULL;
soc->tx_tso_num_seg[pool_id].num_free = 0;
soc->tx_tso_num_seg[pool_id].num_seg_pool_size = 0;
TX_DESC_LOCK_UNLOCK(&soc->tx_tso_num_seg[pool_id].lock);
TX_DESC_LOCK_DESTROY(&soc->tx_tso_num_seg[pool_id].lock);
return;
}
#else
QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
uint16_t num_elem)
{
return QDF_STATUS_SUCCESS;
}
void dp_tx_tso_desc_pool_free(struct dp_soc *soc, uint8_t pool_id)
{
return;
}
QDF_STATUS dp_tx_tso_num_seg_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
uint16_t num_elem)
{
return QDF_STATUS_SUCCESS;
}
void dp_tx_tso_num_seg_pool_free(struct dp_soc *soc, uint8_t pool_id)
{
return;
}
#endif