summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhanashri Atre <datre@qca.qualcomm.com>2014-05-08 15:41:13 -0700
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-06-02 19:40:00 -0700
commit2df6f1f43eb0285e4c8c311a2c4deb361e24fc10 (patch)
treee410f1ed6a096cb98fa21e790f0b2707e555d3d9
parente70da66caf7457dee58063357de491e0aaaf9a6d (diff)
wlan: qcacld: Recovery Mechanism During Rx Data Error
Change to drop current chain of MSDUs that have been popped when there is an error in the attention field in the RX descriptor. Change-Id: I0bc62a8deef0af65e1efa3f712fd9d507a9a64dd CRs-Fixed: 661747
-rw-r--r--CORE/CLD_TXRX/HTT/htt_rx.c11
-rw-r--r--CORE/CLD_TXRX/HTT/htt_types.h3
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_rx.c30
3 files changed, 44 insertions, 0 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_rx.c b/CORE/CLD_TXRX/HTT/htt_rx.c
index 72f8a05f7622..7d255c8b6ecd 100644
--- a/CORE/CLD_TXRX/HTT/htt_rx.c
+++ b/CORE/CLD_TXRX/HTT/htt_rx.c
@@ -903,9 +903,17 @@ htt_rx_amsdu_pop_ll(
& RX_ATTENTION_0_MSDU_DONE_MASK)))
{
+#ifdef HTT_RX_RESTORE
+ adf_os_print("RX done bit error detected!\n");
+ adf_nbuf_set_next(msdu, NULL);
+ *tail_msdu = msdu;
+ pdev->rx_ring.rx_reset = 1;
+ return msdu_chained;
+#else
process_wma_set_command(0,(int)GEN_PARAM_CRASH_INJECT,
0, GEN_CMD);
HTT_ASSERT_ALWAYS(0);
+#endif
}
pdev->rx_ring.dbg_sync_success++;
adf_os_print("debug iter %d success %d\n", dbg_iter,
@@ -1813,6 +1821,9 @@ htt_rx_attach(struct htt_pdev_t *pdev)
{
adf_os_dma_addr_t paddr;
if (!pdev->cfg.is_high_latency) {
+#ifdef HTT_RX_RESTORE
+ pdev->rx_ring.rx_reset = 0;
+#endif
pdev->rx_ring.size = htt_rx_ring_size(pdev);
HTT_ASSERT2(IS_PWR2(pdev->rx_ring.size));
pdev->rx_ring.size_mask = pdev->rx_ring.size - 1;
diff --git a/CORE/CLD_TXRX/HTT/htt_types.h b/CORE/CLD_TXRX/HTT/htt_types.h
index c8a4926f9cbb..83783ae9d60d 100644
--- a/CORE/CLD_TXRX/HTT/htt_types.h
+++ b/CORE/CLD_TXRX/HTT/htt_types.h
@@ -187,6 +187,9 @@ struct htt_pdev_t {
u_int32_t dbg_refill_cnt;
u_int32_t dbg_sync_success;
#endif
+#ifdef HTT_RX_RESTORE
+ int rx_reset;
+#endif
} rx_ring;
int rx_desc_size_hl;
long rx_fw_desc_offset;
diff --git a/CORE/CLD_TXRX/TXRX/ol_rx.c b/CORE/CLD_TXRX/TXRX/ol_rx.c
index b21d0c5f846f..174ed9552e4a 100644
--- a/CORE/CLD_TXRX/TXRX/ol_rx.c
+++ b/CORE/CLD_TXRX/TXRX/ol_rx.c
@@ -67,6 +67,24 @@
vdev->osif_rx(vdev->osif_dev, msdus)
#endif /* OSIF_NEED_RX_PEER_ID */
+#ifdef HTT_RX_RESTORE
+void ol_rx_trigger_restore(htt_pdev_handle htt_pdev, adf_nbuf_t head_msdu,
+ adf_nbuf_t tail_msdu)
+{
+ while (1) {
+ adf_nbuf_t next;
+ next = adf_nbuf_next(head_msdu);
+ adf_os_print("freeing %p\n", head_msdu);
+ htt_rx_desc_frame_free(htt_pdev, head_msdu);
+ if (NULL == next) {
+ adf_os_print("next is NULL\n");
+ break;
+ }
+ head_msdu = next;
+ }
+}
+#endif
+
static void ol_rx_process_inv_peer(
ol_txrx_pdev_handle pdev,
void *rx_mpdu_desc,
@@ -262,6 +280,12 @@ ol_rx_indication_handler(
msdu_chaining = htt_rx_amsdu_pop(
htt_pdev, rx_ind_msg, &head_msdu, &tail_msdu);
+#ifdef HTT_RX_RESET
+ if (htt_pdev->rx_ring.rx_reset) {
+ ol_rx_trigger_restore(htt_pdev, head_msdu, tail_msdu);
+ return;
+ }
+#endif
rx_mpdu_desc =
htt_rx_mpdu_desc_list_next(htt_pdev, rx_ind_msg);
@@ -365,6 +389,12 @@ ol_rx_indication_handler(
for (i = 0; i < num_mpdus; i++) {
/* pull the MPDU's MSDUs off the buffer queue */
htt_rx_amsdu_pop(htt_pdev, rx_ind_msg, &msdu, &tail_msdu);
+#ifdef HTT_RX_RESTORE
+ if (htt_pdev->rx_ring.rx_reset) {
+ ol_rx_trigger_restore(htt_pdev, msdu, tail_msdu);
+ return;
+ }
+#endif
/* pull the MPDU desc off the desc queue */
rx_mpdu_desc =
htt_rx_mpdu_desc_list_next(htt_pdev, rx_ind_msg);