diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 6fc7e790f7..9d4c67051d 100644 --- a/dp/wifi3.0/dp_main.c +++ b/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); diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 13ab459859..d66c6b2821 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/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); } /* diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index b93229b382..3b1cc31b44 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/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; } diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index c3212d50a0..b91b86d85c 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/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) && diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index ebfc4f440c..d78dba5a88 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/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; - /* Drop & free packet */ - qdf_nbuf_free(nbuf); - /* Statistics */ - goto fail; + 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); + } + + 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( diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 94fe5f7cf9..5ee5d28eb1 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/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", diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 158739913c..d8386f5e47 100644 --- a/dp/wifi3.0/dp_types.h +++ b/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; diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index a46808272d..1c823458b5 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/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);