summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohit Khanna <mkhannaqca@codeaurora.org>2016-08-31 19:49:22 -0700
committerqcabuildsw <qcabuildsw@localhost>2016-09-10 19:26:50 -0700
commit38d0e9335d44bae802c5d8e7a8d445000faa36d2 (patch)
treede494721bbd51502b868a64cc4ce4a384c9f7f3e
parentf821d418abc45028e0d82a8c5da3fce61655bbd3 (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.c29
-rw-r--r--core/dp/txrx/ol_tx_desc.c4
-rw-r--r--core/dp/txrx/ol_txrx_internal.h2
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) { \