瀏覽代碼

qcacmn: AST based MEC support for HAWKEYE

Implemented MEC support using AST entries rather than
using a separate MEC table.

Change-Id: Ifaafb4be1f8a981ad28609ea9740e8bbccec9046
Tallapragada Kalyan 7 年之前
父節點
當前提交
fb72b637f7
共有 8 個文件被更改,包括 119 次插入89 次删除
  1. 4 3
      dp/wifi3.0/dp_main.c
  2. 16 5
      dp/wifi3.0/dp_peer.c
  3. 5 2
      dp/wifi3.0/dp_peer.h
  4. 4 7
      dp/wifi3.0/dp_rx.c
  5. 28 18
      dp/wifi3.0/dp_rx_err.c
  6. 58 42
      dp/wifi3.0/dp_tx.c
  7. 3 11
      dp/wifi3.0/dp_types.h
  8. 1 1
      dp/wifi3.0/hal_rx.h

+ 4 - 3
dp/wifi3.0/dp_main.c

@@ -52,7 +52,7 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
 #include "dp_ipa.h"
 
 #define DP_INTR_POLL_TIMER_MS	10
-#define DP_WDS_AGING_TIMER_DEFAULT_MS	6000
+#define DP_WDS_AGING_TIMER_DEFAULT_MS	120000
 #define DP_MCS_LENGTH (6*MAX_MCS)
 #define DP_NSS_LENGTH (6*SS_COUNT)
 #define DP_RXDMA_ERR_LENGTH (6*HAL_RXDMA_ERR_MAX)
@@ -2839,12 +2839,13 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle,
 
 	TAILQ_INIT(&peer->ast_entry_list);
 
+	/* store provided params */
+	peer->vdev = vdev;
+
 	dp_peer_add_ast(soc, peer, peer_mac_addr, 1);
 
 	qdf_spinlock_create(&peer->peer_info_lock);
 
-	/* store provided params */
-	peer->vdev = vdev;
 	qdf_mem_copy(
 		&peer->mac_addr.raw[0], peer_mac_addr, OL_TXRX_MAC_ADDR_LEN);
 

+ 16 - 5
dp/wifi3.0/dp_peer.c

@@ -403,7 +403,7 @@ static inline void dp_peer_map_ast(struct dp_soc *soc,
  *         1 if entry already exists or if allocation has failed
  */
 int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
-		uint8_t *mac_addr, bool is_self)
+		uint8_t *mac_addr, uint8_t is_self)
 {
 	struct dp_ast_entry *ast_entry;
 
@@ -434,12 +434,23 @@ int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
 	qdf_mem_copy(&ast_entry->mac_addr.raw[0], mac_addr, DP_MAC_ADDR_LEN);
 	ast_entry->peer = peer;
 
-	if (is_self) {
+	switch (is_self) {
+	case 1:
 		peer->self_ast_entry = ast_entry;
 		ast_entry->is_static = TRUE;
-	} else {
+		break;
+	case 0:
+		ast_entry->next_hop = 1;
+		ast_entry->is_static = FALSE;
+		break;
+	case 2:
+		ast_entry->is_mec = 1;
 		ast_entry->next_hop = 1;
 		ast_entry->is_static = FALSE;
+		break;
+	default:
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			FL("Incorrect AST entry type"));
 	}
 
 	ast_entry->is_active = TRUE;
@@ -757,10 +768,10 @@ dp_rx_peer_map_handler(void *soc_handle, uint16_t peer_id, uint16_t hw_peer_id,
 
 	peer = soc->peer_id_to_obj_map[peer_id];
 
-	if ((hw_peer_id < 0) || (hw_peer_id > WLAN_UMAC_PSOC_MAX_PEERS)) {
+	if ((hw_peer_id < 0) || (hw_peer_id > (WLAN_UMAC_PSOC_MAX_PEERS * 2))) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			"invalid hw_peer_id: %d", hw_peer_id);
-		QDF_ASSERT(0);
+		qdf_assert_always(0);
 	}
 
 	/*

+ 5 - 2
dp/wifi3.0/dp_peer.h

@@ -54,14 +54,17 @@ 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);
 
+struct dp_ast_entry *dp_peer_ast_hash_find(struct dp_soc *soc,
+		uint8_t *ast_mac_addr, int mac_addr_is_aligned);
+
 #ifdef FEATURE_WDS
 int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
-		uint8_t *mac_addr, bool is_self);
+		uint8_t *mac_addr, uint8_t is_self);
 void dp_peer_del_ast(struct dp_soc *soc,
 		struct dp_ast_entry *ast_entry);
 #else
 static inline int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
-		uint8_t *mac_addr, bool is_self)
+		uint8_t *mac_addr, uint8_t is_self)
 {
 	return 0;
 }

+ 4 - 7
dp/wifi3.0/dp_rx.c

@@ -365,7 +365,6 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
 		if (da_peer->vdev == sa_peer->vdev && !da_peer->bss_peer) {
 			memset(nbuf->cb, 0x0, sizeof(nbuf->cb));
 			len = qdf_nbuf_len(nbuf);
-			qdf_nbuf_set_ftype(nbuf, CB_FTYPE_INTRABSS_FWD);
 
 			if (!dp_tx_send(sa_peer->vdev, nbuf)) {
 				DP_STATS_INC_PKT(sa_peer, rx.intra_bss.pkts,
@@ -393,7 +392,6 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
 			return false;
 		memset(nbuf_copy->cb, 0x0, sizeof(nbuf_copy->cb));
 		len = qdf_nbuf_len(nbuf_copy);
-		qdf_nbuf_set_ftype(nbuf_copy, CB_FTYPE_INTRABSS_FWD);
 
 		if (dp_tx_send(sa_peer->vdev, nbuf_copy)) {
 			DP_STATS_INC_PKT(sa_peer, rx.intra_bss.fail, 1, len);
@@ -1277,11 +1275,10 @@ done:
 						htt_cmn_pkt_type_ethernet) &&
 					(qdf_likely(!vdev->mesh_vdev))) {
 				/* WDS Source Port Learning */
-				if (qdf_likely(vdev->wds_enabled))
-					dp_rx_wds_srcport_learn(soc,
-								rx_tlv_hdr,
-								peer,
-								nbuf);
+				dp_rx_wds_srcport_learn(soc,
+							rx_tlv_hdr,
+							peer,
+							nbuf);
 
 				/* Intrabss-fwd */
 				if ((vdev->opmode != wlan_op_mode_sta) &&

+ 28 - 18
dp/wifi3.0/dp_rx_err.c

@@ -274,9 +274,6 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
 	uint16_t peer_id = 0xFFFF;
 	struct dp_peer *peer = NULL;
 	uint32_t sgi, rate_mcs, tid;
-	uint8_t count;
-	struct mect_entry *mect_entry;
-	uint8_t *nbuf_data = NULL;
 
 	rx_bufs_used++;
 
@@ -352,26 +349,39 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
 	 */
 	qdf_nbuf_pull_head(nbuf, (l2_hdr_offset + RX_PKT_TLVS_LEN));
 
-	nbuf_data = qdf_nbuf_data(nbuf);
-	for (count = 0; count < soc->mect_cnt; count++) {
-		mect_entry = &soc->mect_table[count];
-		mect_entry->ts = jiffies_64;
-		if (!(memcmp(mect_entry->mac_addr, &nbuf_data[DP_MAC_ADDR_LEN],
-				DP_MAC_ADDR_LEN))) {
-			QDF_TRACE(QDF_MODULE_ID_DP,
-				QDF_TRACE_LEVEL_INFO,
-				FL("received pkt with same src MAC"));
+	/*
+	 * This is a Multicast echo check, drop the pkt if we meet
+	 * the Multicast Echo Check condition
+	 */
+	if (hal_rx_msdu_end_sa_is_valid_get(rx_desc->rx_buf_start)) {
+		struct dp_ast_entry *ase;
+		uint16_t sa_idx;
+		uint8_t *nbuf_data = NULL;
+
+		nbuf_data = qdf_nbuf_data(nbuf);
+		sa_idx = hal_rx_msdu_end_sa_idx_get(rx_desc->rx_buf_start);
+		if ((sa_idx < 0) || (sa_idx > (WLAN_UMAC_PSOC_MAX_PEERS * 2))) {
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+					"invalid sa_idx: %d", sa_idx);
+			qdf_assert_always(0);
+		}
 
-			/* Drop & free packet */
-			qdf_nbuf_free(nbuf);
-			/* Statistics */
-			goto fail;
+		ase = soc->ast_table[sa_idx];
+		if (ase) {
+			if (ase->is_mec || (ase->peer != peer)) {
+				QDF_TRACE(QDF_MODULE_ID_DP,
+					QDF_TRACE_LEVEL_INFO,
+					"received pkt with same src mac %pM",
+					&nbuf_data[DP_MAC_ADDR_LEN]);
+
+				qdf_nbuf_free(nbuf);
+				goto fail;
+			}
 		}
 	}
 
 	/* WDS Source Port Learning */
-	if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet) &&
-			(vdev->wds_enabled))
+	if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet))
 		dp_rx_wds_srcport_learn(soc, rx_desc->rx_buf_start, peer, nbuf);
 
 	if (hal_rx_mpdu_start_mpdu_qos_control_valid_get(

+ 58 - 42
dp/wifi3.0/dp_tx.c

@@ -1378,53 +1378,11 @@ qdf_nbuf_t dp_tx_send(void *vap_dev, qdf_nbuf_t nbuf)
 	struct dp_tx_msdu_info_s msdu_info;
 	struct dp_tx_seg_info_s seg_info;
 	struct dp_vdev *vdev = (struct dp_vdev *) vap_dev;
-	struct dp_soc *soc = vdev->pdev->soc;
 	uint16_t peer_id = HTT_INVALID_PEER;
-	uint8_t count;
-	uint8_t found = 0;
-	uint8_t oldest_mec_entry_idx = 0;
-	uint64_t oldest_mec_ts = 0;
-	struct mect_entry *mect_entry;
-
 	qdf_mem_set(&msdu_info, sizeof(msdu_info), 0x0);
 	qdf_mem_set(&seg_info, sizeof(seg_info), 0x0);
 
-	if (qdf_nbuf_get_ftype(nbuf) == CB_FTYPE_INTRABSS_FWD)
-		goto out;
-
 	eh = (struct ether_header *)qdf_nbuf_data(nbuf);
-	if (DP_FRAME_IS_MULTICAST((eh)->ether_dhost)) {
-		for (count = 0; count < soc->mect_cnt; count++) {
-			mect_entry = &soc->mect_table[count];
-			if (!memcmp(mect_entry->mac_addr, eh->ether_shost,
-					DP_MAC_ADDR_LEN)) {
-				found = 1;
-				break;
-			}
-
-			if (!oldest_mec_ts) {
-				oldest_mec_entry_idx = count;
-				oldest_mec_ts = mect_entry->ts;
-			} else if (mect_entry->ts < oldest_mec_ts) {
-				oldest_mec_entry_idx = count;
-				oldest_mec_ts = mect_entry->ts;
-			}
-		}
-
-		if (!found) {
-			if (count >= DP_MAX_MECT_ENTRIES)
-				count = oldest_mec_entry_idx;
-			else
-				soc->mect_cnt++;
-
-			mect_entry = &soc->mect_table[count];
-			mect_entry->ts = jiffies_64;
-			memcpy(mect_entry->mac_addr, eh->ether_shost,
-				DP_MAC_ADDR_LEN);
-		}
-	}
-
-out:
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			"%s , skb %0x:%0x:%0x:%0x:%0x:%0x\n",
 			__func__, nbuf->data[0], nbuf->data[1], nbuf->data[2],
@@ -1716,6 +1674,57 @@ static inline void dp_tx_comp_free_buf(struct dp_soc *soc,
 	}
 }
 
+/**
+ * dp_tx_mec_handler() - Tx  MEC Notify Handler
+ * @vdev: pointer to dp dev handler
+ * @status : Tx completion status from HTT descriptor
+ *
+ * Handles MEC notify event sent from fw to Host
+ *
+ * Return: none
+ */
+#ifdef FEATURE_WDS
+static void dp_tx_mec_handler(struct dp_vdev *vdev, uint8_t *status)
+{
+
+	struct dp_soc *soc;
+	uint32_t flags = IEEE80211_NODE_F_WDS_HM;
+	struct dp_peer *peer;
+	uint8_t mac_addr[DP_MAC_ADDR_LEN], i;
+
+	soc = vdev->pdev->soc;
+	qdf_spin_lock_bh(&soc->peer_ref_mutex);
+	peer = TAILQ_FIRST(&vdev->peer_list);
+	qdf_spin_unlock_bh(&soc->peer_ref_mutex);
+
+	if (!peer) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
+				FL("peer is NULL"));
+		return;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
+			"%s Tx MEC Handler\n",
+			__func__);
+
+	for (i = 0; i < DP_MAC_ADDR_LEN; i++)
+		mac_addr[(DP_MAC_ADDR_LEN - 1) - i] =
+					status[(DP_MAC_ADDR_LEN - 2) + i];
+
+	if (!dp_peer_add_ast(soc, peer, mac_addr, 2)) {
+		soc->cdp_soc.ol_ops->peer_add_wds_entry(
+				vdev->pdev->osif_pdev,
+				mac_addr,
+				vdev->mac_addr.raw,
+				flags);
+	}
+}
+#else
+static void dp_tx_mec_handler(struct dp_vdev *vdev, uint8_t *status)
+{
+}
+#endif
+
 /**
  * dp_tx_process_htt_completion() - Tx HTT Completion Indication Handler
  * @tx_desc: software descriptor head pointer
@@ -1730,12 +1739,14 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status)
 {
 	uint8_t tx_status;
 	struct dp_pdev *pdev;
+	struct dp_vdev *vdev;
 	struct dp_soc *soc;
 	uint32_t *htt_status_word = (uint32_t *) status;
 
 	qdf_assert(tx_desc->pdev);
 
 	pdev = tx_desc->pdev;
+	vdev = tx_desc->vdev;
 	soc = pdev->soc;
 
 	tx_status = HTT_TX_WBM_COMPLETION_V2_TX_STATUS_GET(htt_status_word[0]);
@@ -1759,6 +1770,11 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status)
 		dp_tx_inspect_handler(tx_desc, status);
 		break;
 	}
+	case HTT_TX_FW2WBM_TX_STATUS_MEC_NOTIFY:
+	{
+		dp_tx_mec_handler(vdev, status);
+		break;
+	}
 	default:
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 				"%s Invalid HTT tx_status %d\n",

+ 3 - 11
dp/wifi3.0/dp_types.h

@@ -83,7 +83,6 @@
 #define MAX_TX_HW_QUEUES MAX_TCL_DATA_RINGS
 
 #define DP_MAX_INTERRUPT_CONTEXTS 8
-#define DP_MAX_MECT_ENTRIES 64
 
 #ifndef REMOVE_PKT_LOG
 enum rx_pktlog_mode {
@@ -528,17 +527,12 @@ struct dp_ast_entry {
 	bool next_hop;
 	bool is_active;
 	bool is_static;
+	bool is_mec;
+	bool is_bss;
 	TAILQ_ENTRY(dp_ast_entry) ase_list_elem;
 	TAILQ_ENTRY(dp_ast_entry) hash_list_elem;
 };
 
-struct mect_entry {
-	uint8_t idx;
-	uint8_t valid;
-	uint8_t mac_addr[6];
-	uint64_t ts;
-};
-
 /* SOC level structure for data path */
 struct dp_soc {
 	/* Common base structure - Should be the first member */
@@ -726,7 +720,7 @@ struct dp_soc {
 	/* Enable processing of Tx completion status words */
 	bool process_tx_status;
 
-	struct dp_ast_entry *ast_table[WLAN_UMAC_PSOC_MAX_PEERS];
+	struct dp_ast_entry *ast_table[WLAN_UMAC_PSOC_MAX_PEERS * 2];
 	struct {
 		unsigned mask;
 		unsigned idx_bits;
@@ -742,8 +736,6 @@ struct dp_soc {
 
 	qdf_list_t reo_desc_freelist;
 	qdf_spinlock_t reo_desc_freelist_lock;
-	struct mect_entry mect_table[DP_MAX_MECT_ENTRIES];
-	uint8_t mect_cnt;
 
 	/* Obj Mgr SoC */
 	struct wlan_objmgr_psoc *psoc;

+ 1 - 1
dp/wifi3.0/hal_rx.h

@@ -926,7 +926,7 @@ hal_rx_msdu_end_sa_idx_get(uint8_t *buf)
 {
 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
 	struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end;
-	uint8_t sa_idx;
+	uint16_t sa_idx;
 
 	sa_idx = HAL_RX_MSDU_END_SA_IDX_GET(msdu_end);