Переглянути джерело

qcacmn: Changes to support LFR

Setup all TID queues during rx peer init
Add support to handle ADDBA HTT msg
Allow pkts to be fwd to stack even if peer isn't found

Change-Id: Icdfec2eeaa3e0ca62202ed278cd63209b8f79cb2
CRs-Fixed: 2016138
Pramod Simha 8 роки тому
батько
коміт
b17d067de0
4 змінених файлів з 173 додано та 13 видалено
  1. 39 0
      dp/wifi3.0/dp_htt.c
  2. 39 0
      dp/wifi3.0/dp_peer.c
  3. 35 0
      dp/wifi3.0/dp_peer.h
  4. 60 13
      dp/wifi3.0/dp_rx.c

+ 39 - 0
dp/wifi3.0/dp_htt.c

@@ -21,6 +21,7 @@
 #include "dp_htt.h"
 #include "dp_peer.h"
 #include "dp_types.h"
+#include "dp_internal.h"
 
 #define HTT_HTC_PKT_POOL_INIT_SIZE 64
 
@@ -524,6 +525,10 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
 			peer_mac_addr = htt_t2h_mac_addr_deswizzle(
 				(u_int8_t *) (msg_word+1),
 				&mac_addr_deswizzle_buf[0]);
+			QDF_TRACE(QDF_MODULE_ID_TXRX,
+				QDF_TRACE_LEVEL_INFO,
+				"HTT_T2H_MSG_TYPE_PEER_MAP msg for peer id %d vdev id %d n",
+				peer_id, vdev_id);
 
 			dp_rx_peer_map_handler(
 				soc->dp_soc, peer_id, vdev_id, peer_mac_addr);
@@ -590,6 +595,40 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
 			}
 			break;
 		}
+	case HTT_T2H_MSG_TYPE_RX_ADDBA:
+		{
+			uint16_t peer_id;
+			uint8_t tid;
+			uint8_t win_sz;
+			uint16_t status;
+			struct dp_peer *peer;
+
+			/*
+			 * Update REO Queue Desc with new values
+			 */
+			peer_id = HTT_RX_ADDBA_PEER_ID_GET(*msg_word);
+			tid = HTT_RX_ADDBA_TID_GET(*msg_word);
+			win_sz = HTT_RX_ADDBA_WIN_SIZE_GET(*msg_word);
+			peer = dp_peer_find_by_id(soc->dp_soc, peer_id);
+
+			if (peer) {
+				status = dp_addba_requestprocess_wifi3(peer,
+						0, tid, 0, win_sz, 0xffff);
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					QDF_TRACE_LEVEL_INFO,
+					FL("PeerID %d BAW %d TID %d stat %d\n"),
+					peer_id, win_sz, tid, status);
+
+			} else {
+				QDF_TRACE(QDF_MODULE_ID_TXRX,
+					QDF_TRACE_LEVEL_ERROR,
+					FL("Peer not found peer id %d\n"),
+					peer_id);
+			}
+			break;
+		}
+
+
 	default:
 		break;
 	};

+ 39 - 0
dp/wifi3.0/dp_peer.c

@@ -30,6 +30,23 @@
 #include <cdp_txrx_handle.h>
 #include <wlan_cfg.h>
 
+#ifdef DP_LFR
+static inline void
+dp_set_ssn_valid_flag(struct hal_reo_cmd_params *params,
+					uint8_t valid)
+{
+	params->u.upd_queue_params.update_svld = 1;
+	params->u.upd_queue_params.svld = valid;
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+		"%s: Setting SSN valid bit to %d\n",
+				__func__, valid);
+}
+#else
+static inline void
+dp_set_ssn_valid_flag(struct hal_reo_cmd_params *params,
+					uint8_t valid) {};
+#endif
+
 static inline int dp_peer_find_mac_addr_cmp(
 	union dp_align_mac_addr *mac_addr1,
 	union dp_align_mac_addr *mac_addr2)
@@ -482,6 +499,8 @@ static int dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
 		params.u.upd_queue_params.ssn = start_seq;
 	}
 
+	dp_set_ssn_valid_flag(&params, 0);
+
 	dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, &params, dp_rx_tid_update_cb, rx_tid);
 	return 0;
 }
@@ -738,6 +757,21 @@ static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid)
 	return 0;
 }
 
+#ifdef DP_LFR
+static void dp_peer_setup_remaining_tids(struct dp_peer *peer)
+{
+	int tid;
+
+	for (tid = 1; tid < DP_MAX_TIDS-1; tid++) {
+		dp_rx_tid_setup_wifi3(peer, tid, 1, 0);
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
+			"Setting up TID %d for peer %p peer->local_id %d\n",
+			tid, peer, peer->local_id);
+	}
+}
+#else
+static void dp_peer_setup_remaining_tids(struct dp_peer *peer) {};
+#endif
 /*
  * dp_peer_rx_init() – Initialize receive TID state
  * @pdev: Datapath pdev
@@ -775,6 +809,11 @@ void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer)
 	 */
 	dp_rx_tid_setup_wifi3(peer, 0, 1, 0);
 
+	/*
+	 * Setup the rest of TID's to handle LFR
+	 */
+	dp_peer_setup_remaining_tids(peer);
+
 	/*
 	 * Set security defaults: no PN check, no security. The target may
 	 * send a HTT SEC_IND message to overwrite these defaults.

+ 35 - 0
dp/wifi3.0/dp_peer.h

@@ -54,4 +54,39 @@ void dp_rx_sec_ind_handler(void *soc_handle, uint16_t peer_id,
 uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle,
 		uint16_t peer_id, uint8_t *peer_mac);
 
+#ifdef DP_LFR
+/*
+ * dp_get_vdev_from_soc_vdev_id_wifi3() -
+ * Returns vdev object given the vdev id
+ * vdev id is unique across pdev's
+ *
+ * @soc         : core DP soc context
+ * @vdev_id     : vdev id from vdev object can be retrieved
+ *
+ * Return: struct dp_vdev*: Pointer to DP vdev object
+ */
+static inline struct dp_vdev *
+dp_get_vdev_from_soc_vdev_id_wifi3(struct dp_soc *soc,
+					uint8_t vdev_id)
+{
+	struct dp_pdev *pdev = NULL;
+	struct dp_vdev *vdev = NULL;
+	int i;
+
+	for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) {
+		pdev = soc->pdev_list[i];
+		TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
+			if (vdev->vdev_id == vdev_id) {
+				QDF_TRACE(QDF_MODULE_ID_DP,
+					QDF_TRACE_LEVEL_INFO,
+					FL("Found vdev 0x%p on pdev %d\n"),
+					vdev, i);
+				return vdev;
+			}
+		}
+	}
+	return NULL;
+
+}
+#endif
 #endif /* _DP_PEER_H_ */

+ 60 - 13
dp/wifi3.0/dp_rx.c

@@ -213,7 +213,60 @@ dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list)
 }
 
 
-
+#ifdef DP_LFR
+/*
+ * In case of LFR, data of a new peer might be sent up
+ * even before peer is added.
+ */
+static inline struct dp_vdev *
+dp_get_vdev_from_peer(struct dp_soc *soc,
+			uint16_t peer_id,
+			struct dp_peer *peer,
+			struct hal_rx_mpdu_desc_info mpdu_desc_info)
+{
+	struct dp_vdev *vdev;
+	uint8_t vdev_id;
+
+	if (unlikely(!peer)) {
+		if (peer_id != HTT_INVALID_PEER) {
+			vdev_id = DP_PEER_METADATA_ID_GET(
+					mpdu_desc_info.peer_meta_data);
+			QDF_TRACE(QDF_MODULE_ID_DP,
+				QDF_TRACE_LEVEL_ERROR,
+				FL("PeerID %d not found use vdevID %d"),
+				peer_id, vdev_id);
+			vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc,
+							vdev_id);
+		} else {
+			QDF_TRACE(QDF_MODULE_ID_DP,
+				QDF_TRACE_LEVEL_ERROR,
+				FL("Invalid PeerID %d"),
+				peer_id);
+			return NULL;
+		}
+	} else {
+		vdev = peer->vdev;
+	}
+	return vdev;
+}
+#else
+static inline struct dp_vdev *
+dp_get_vdev_from_peer(struct dp_soc *soc,
+			uint16_t peer_id,
+			struct dp_peer *peer,
+			struct hal_rx_mpdu_desc_info mpdu_desc_info)
+{
+	if (unlikely(!peer)) {
+		QDF_TRACE(QDF_MODULE_ID_DP,
+			QDF_TRACE_LEVEL_ERROR,
+			FL("Peer not found for peerID %d"),
+			peer_id);
+		return NULL;
+	} else {
+		return peer->vdev;
+	}
+}
+#endif
 /**
  * dp_rx_intrabss_fwd() - Implements the Intra-BSS forwarding logic
  *
@@ -474,17 +527,10 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
 				mpdu_desc_info.peer_meta_data);
 
 		peer = dp_peer_find_by_id(soc, peer_id);
-		if (!peer) {
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
-				 FL("peer look-up failed peer id %d"), peer_id);
 
-			/* Drop & free packet */
-			qdf_nbuf_free(rx_desc->nbuf);
-			/* Statistics */
-			goto fail;
-		}
+		vdev = dp_get_vdev_from_peer(soc, peer_id, peer,
+						mpdu_desc_info);
 
-		vdev = peer->vdev;
 		if (!vdev) {
 			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 				FL("vdev is NULL"));
@@ -595,7 +641,7 @@ done:
 			 * Cannot drop these packets right away.
 			 */
 			/* Peer lookup failed */
-			if (!peer) {
+			if (!peer && !vdev) {
 
 				/* Drop & free packet */
 				qdf_nbuf_free(nbuf);
@@ -604,7 +650,7 @@ done:
 				continue;
 			}
 
-			if (qdf_unlikely(peer->bss_peer)) {
+			if (peer && qdf_unlikely(peer->bss_peer)) {
 				QDF_TRACE(QDF_MODULE_ID_DP,
 					QDF_TRACE_LEVEL_INFO,
 					FL("received pkt with same src MAC"));
@@ -703,7 +749,8 @@ done:
 			dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, peer, nbuf);
 
 			/* Intrabss-fwd */
-			if (dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr, nbuf))
+			if (peer &&
+				dp_rx_intrabss_fwd(soc, peer, rx_tlv_hdr, nbuf))
 				continue; /* Get next descriptor */
 
 			rx_bufs_used++;