qcacld-2.0: Fix potential BUG_ON in the htt_rx_offload_msdu_pop_ll

For HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND, the msdu_cnt is a signed
integer coming from firmware. If set the msdu_cnt to a negative value,
or be greater than the number of current elements in the queue, the loop
will execute lots of times in ol_rx_offload_deliver_ind_handler, the
htt_rx_netbuf_pop will cause the BUG_ON issue sooner or later if it is
low latency solution.

Change the msdu_cnt type from signed to unsigned and add the validity
msdu_cnt checking will fix this issue.

Change-Id: I436557a124074f59ab11fd937dfdc975b9caebe8
CRs-Fixed: 2149461
diff --git a/CORE/CLD_TXRX/HTT/htt_rx.c b/CORE/CLD_TXRX/HTT/htt_rx.c
index b38043d..57762e0 100644
--- a/CORE/CLD_TXRX/HTT/htt_rx.c
+++ b/CORE/CLD_TXRX/HTT/htt_rx.c
@@ -1291,6 +1291,13 @@
 }
 
 int
+htt_rx_offload_msdu_cnt_ll(
+    htt_pdev_handle pdev)
+{
+    return htt_rx_ring_elems(pdev);
+}
+
+int
 htt_rx_offload_msdu_pop_ll(
     htt_pdev_handle pdev,
     adf_nbuf_t offload_deliver_msg,
@@ -1914,6 +1921,13 @@
 	return 0;
 }
 
+int
+htt_rx_offload_msdu_cnt_hl(
+    htt_pdev_handle pdev)
+{
+    return 1;
+}
+
 /* Return values: 1 - success, 0 - failure */
 int
 htt_rx_offload_msdu_pop_hl(
@@ -2577,6 +2591,10 @@
     adf_nbuf_t *tail_msdu);
 
 int
+(*htt_rx_offload_msdu_cnt)(
+    htt_pdev_handle pdev);
+
+int
 (*htt_rx_offload_msdu_pop)(
     htt_pdev_handle pdev,
     adf_nbuf_t offload_deliver_msg,
@@ -3404,6 +3422,7 @@
         if (VOS_MONITOR_MODE == vos_get_conparam())
             htt_rx_amsdu_pop = htt_rx_mon_amsdu_rx_in_order_pop_ll;
 
+        htt_rx_offload_msdu_cnt = htt_rx_offload_msdu_cnt_ll;
         htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_ll;
         htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_ll;
         htt_rx_mpdu_desc_seq_num = htt_rx_mpdu_desc_seq_num_ll;
@@ -3430,6 +3449,7 @@
         if (VOS_MONITOR_MODE == vos_get_conparam())
             htt_rx_amsdu_pop = htt_rx_mon_amsdu_pop_hl;
         htt_rx_frag_pop = htt_rx_frag_pop_hl;
+        htt_rx_offload_msdu_cnt = htt_rx_offload_msdu_cnt_hl;
         htt_rx_offload_msdu_pop = htt_rx_offload_msdu_pop_hl;
         htt_rx_mpdu_desc_list_next = htt_rx_mpdu_desc_list_next_hl;
         htt_rx_mpdu_desc_retry = htt_rx_mpdu_desc_retry_hl;
diff --git a/CORE/CLD_TXRX/HTT/htt_t2h.c b/CORE/CLD_TXRX/HTT/htt_t2h.c
index 4467ca7..6dedfb9 100644
--- a/CORE/CLD_TXRX/HTT/htt_t2h.c
+++ b/CORE/CLD_TXRX/HTT/htt_t2h.c
@@ -196,7 +196,7 @@
         }
     case  HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND:
         {
-            int msdu_cnt;
+            u_int16_t msdu_cnt;
             msdu_cnt = HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_GET(*msg_word);
             ol_rx_offload_deliver_ind_handler(
                 pdev->txrx_pdev,
diff --git a/CORE/CLD_TXRX/TXRX/ol_rx.c b/CORE/CLD_TXRX/TXRX/ol_rx.c
index 22fab03..6e8ced2 100644
--- a/CORE/CLD_TXRX/TXRX/ol_rx.c
+++ b/CORE/CLD_TXRX/TXRX/ol_rx.c
@@ -815,7 +815,7 @@
 ol_rx_offload_deliver_ind_handler(
     ol_txrx_pdev_handle pdev,
     adf_nbuf_t msg,
-    int msdu_cnt)
+    u_int16_t msdu_cnt)
 {
     int vdev_id, peer_id, tid;
     adf_nbuf_t head_buf, tail_buf, buf;
@@ -824,6 +824,17 @@
     u_int8_t fw_desc;
     htt_pdev_handle htt_pdev = pdev->htt_pdev;
 
+    if (msdu_cnt > htt_rx_offload_msdu_cnt(htt_pdev)) {
+        TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
+            "%s: invalid msdu_cnt=%u\n",
+            __func__,
+            msdu_cnt);
+        if (pdev->cfg.is_high_latency)
+            htt_rx_desc_frame_free(htt_pdev, msg);
+
+        return;
+    }
+
     while (msdu_cnt) {
         if (!htt_rx_offload_msdu_pop(
             htt_pdev, msg, &vdev_id, &peer_id,
diff --git a/CORE/SERVICES/COMMON/ol_htt_rx_api.h b/CORE/SERVICES/COMMON/ol_htt_rx_api.h
index 34a209c..3ac1aff 100644
--- a/CORE/SERVICES/COMMON/ol_htt_rx_api.h
+++ b/CORE/SERVICES/COMMON/ol_htt_rx_api.h
@@ -671,6 +671,15 @@
     adf_nbuf_t *tail_msdu);
 
 /**
+ * @brief Return the maximum number of available msdus currently
+ *
+ * @param pdev - the HTT instance the rx data was received on
+ */
+extern int
+(*htt_rx_offload_msdu_cnt)(
+    htt_pdev_handle pdev);
+
+/**
  * @brief Return a linked list of buffers holding one MSDU
  *  In some systems the buffers are delivered along with offload delivery
  *  indication message itself, while in other systems the buffers are uploaded
diff --git a/CORE/SERVICES/COMMON/ol_txrx_htt_api.h b/CORE/SERVICES/COMMON/ol_txrx_htt_api.h
index cb6b828..6918a6d 100644
--- a/CORE/SERVICES/COMMON/ol_txrx_htt_api.h
+++ b/CORE/SERVICES/COMMON/ol_txrx_htt_api.h
@@ -448,7 +448,7 @@
 ol_rx_offload_deliver_ind_handler(
     ol_txrx_pdev_handle pdev,
     adf_nbuf_t msg,
-    int msdu_cnt);
+    u_int16_t msdu_cnt);
 
 /**
  * @brief Process a peer map message sent by the target.