diff options
| author | Mohit Khanna <mkhannaqca@codeaurora.org> | 2016-08-31 19:49:22 -0700 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-09-10 19:26:50 -0700 |
| commit | 38d0e9335d44bae802c5d8e7a8d445000faa36d2 (patch) | |
| tree | de494721bbd51502b868a64cc4ce4a384c9f7f3e | |
| parent | f821d418abc45028e0d82a8c5da3fce61655bbd3 (diff) | |
qcacld-3.0: Maintain length for each TSO segment
In current codeflow, we are maintaining the length of the TSO segments
belonging to one jumbo packet inside tso_info, which is common for
all the segments of one jumbo packet. This works if the length of
the segments (frag[1]) is the same. In case it is not, it ends up
assigning incorrect length to all the segments. This is resulting
GMS login failure.
Fix issue by maintaining the total length of the segment in the
qdf_tso_seg_t structure.
Re-factor code for easy readability
Add TSO_DEBUG prints which can be enabled (compile time) to debug
TSO issues
Change-Id: Ie0cf8434902c0713ef8d36dc36c105afa6b5eabc
CRs-Fixed: 1062556
(cherry picked from commit 0a851f054171cf4b2f5bd7e8cd6841e90d999928)
| -rw-r--r-- | core/dp/htt/htt_tx.c | 29 | ||||
| -rw-r--r-- | core/dp/txrx/ol_tx_desc.c | 4 | ||||
| -rw-r--r-- | core/dp/txrx/ol_txrx_internal.h | 2 |
3 files changed, 30 insertions, 5 deletions
diff --git a/core/dp/htt/htt_tx.c b/core/dp/htt/htt_tx.c index 3a1539e4140f..a3246eeaa3f5 100644 --- a/core/dp/htt/htt_tx.c +++ b/core/dp/htt/htt_tx.c @@ -1355,6 +1355,18 @@ htt_tx_desc_fill_tso_info(htt_pdev_handle pdev, void *desc, tso_seg->seg.tso_flags; /* First 24 bytes (6*4) contain the TSO flags */ + TSO_DEBUG("%s seq# %u l2 len %d, ip len %d flags 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, + tso_seg->seg.tso_flags.tcp_seq_num, + tso_seg->seg.tso_flags.l2_len, + tso_seg->seg.tso_flags.ip_len, + *word, + *(word + 1), + *(word + 2), + *(word + 3), + *(word + 4), + *(word + 5)); + word += 6; for (i = 0; i < tso_seg->seg.num_frags; i++) { @@ -1369,6 +1381,12 @@ htt_tx_desc_fill_tso_info(htt_pdev_handle pdev, void *desc, /* [31:16] length of the first buffer */ *word = (tso_seg->seg.tso_frags[i].length << 16) | hi; word++; + TSO_DEBUG("%s frag[%d] ptr_low 0x%x ptr_hi 0x%x len %u\n", + __func__, i, + msdu_ext_desc->frags[i].u.frag32.ptr_low, + msdu_ext_desc->frags[i].u.frag32.ptr_hi, + msdu_ext_desc->frags[i].u.frag32.len); + } if (tso_seg->seg.num_frags < FRAG_NUM_MAX) { @@ -1671,10 +1689,15 @@ htt_tx_desc_init(htt_pdev_handle pdev, local_word1 = 0; - if (tso_info->is_tso) - HTT_TX_DESC_FRM_LEN_SET(local_word1, tso_info->total_len); - else + if (tso_info->is_tso) { + uint32_t total_len = tso_info->curr_seg->seg.total_len; + + HTT_TX_DESC_FRM_LEN_SET(local_word1, total_len); + TSO_DEBUG("%s setting HTT TX DESC Len = curr_seg->seg.total_len %d\n", + __func__, total_len); + } else { HTT_TX_DESC_FRM_LEN_SET(local_word1, qdf_nbuf_len(msdu)); + } HTT_TX_DESC_FRM_ID_SET(local_word1, msdu_id); *word1 = local_word1; diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c index 8da961622a9b..5294c8a242fd 100644 --- a/core/dp/txrx/ol_tx_desc.c +++ b/core/dp/txrx/ol_tx_desc.c @@ -656,7 +656,9 @@ void ol_tx_desc_frame_list_free(struct ol_txrx_pdev_t *pdev, /* restore original hdr offset */ OL_TX_RESTORE_HDR(tx_desc, msdu); #endif - qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_TO_DEVICE); + if (qdf_nbuf_get_users(msdu) <= 1) + qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_TO_DEVICE); + /* free the tx desc */ ol_tx_desc_free(pdev, tx_desc); /* link the netbuf into a list to free as a batch */ diff --git a/core/dp/txrx/ol_txrx_internal.h b/core/dp/txrx/ol_txrx_internal.h index cb7368124328..0f6021013e41 100644 --- a/core/dp/txrx/ol_txrx_internal.h +++ b/core/dp/txrx/ol_txrx_internal.h @@ -693,7 +693,7 @@ NOT_IP_TCP: do { \ if (_p_cntrs == 1) { \ TXRX_STATS_ADD(_pdev, pub.tx.tso.tso_hist.pkts_1, 1); \ - } else if (_p_cntrs > 2 && _p_cntrs <= 5) { \ + } else if (_p_cntrs >= 2 && _p_cntrs <= 5) { \ TXRX_STATS_ADD(_pdev, \ pub.tx.tso.tso_hist.pkts_2_5, 1); \ } else if (_p_cntrs > 5 && _p_cntrs <= 10) { \ |
