diff --git a/dp/inc/cdp_txrx_mob_def.h b/dp/inc/cdp_txrx_mob_def.h index cb52d0737713..fdd4e37732dc 100644 --- a/dp/inc/cdp_txrx_mob_def.h +++ b/dp/inc/cdp_txrx_mob_def.h @@ -420,4 +420,16 @@ typedef void (*tx_pause_callback)(uint8_t vdev_id, typedef void (*ipa_uc_op_cb_type)(uint8_t *op_msg, void *osif_ctxt); +/** + * struct ol_rx_inv_peer_params - rx invalid peer data parameters + * @vdev_id: Virtual device ID + * @ra: RX data receiver MAC address + * @ta: RX data transmitter MAC address + */ +struct ol_rx_inv_peer_params { + uint8_t vdev_id; + uint8_t ra[OL_TXRX_MAC_ADDR_LEN]; + uint8_t ta[OL_TXRX_MAC_ADDR_LEN]; +}; + #endif /* __CDP_TXRX_MOB_DEF_H */ diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 9e325e1da183..94172fd6ba23 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -801,8 +801,11 @@ struct ol_if_ops { struct cdp_lro_hash_config *rx_offld_hash); void (*update_dp_stats)(void *soc, void *stats, uint16_t id, uint8_t type); +#ifdef CONFIG_WIN uint8_t (*rx_invalid_peer)(void *ctrl_pdev, void *msg); - +#else + uint8_t (*rx_invalid_peer)(uint8_t vdev_id, void *wh); +#endif int (*peer_map_event)(void *ol_soc_handle, uint16_t peer_id, uint16_t hw_peer_id, uint8_t vdev_id, uint8_t *peer_mac_addr, enum cdp_txrx_ast_entry_type peer_type); diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index ed81a3e1a966..7efb1ca08f32 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -748,30 +748,68 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu) qdf_nbuf_t curr_nbuf, next_nbuf; struct dp_pdev *pdev; uint8_t i; + struct dp_vdev *vdev = NULL; + struct ieee80211_frame *wh; + uint8_t *rx_tlv_hdr = qdf_nbuf_data(mpdu); + uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr); - curr_nbuf = mpdu; - while (curr_nbuf) { - next_nbuf = qdf_nbuf_next(curr_nbuf); - /* Drop and free packet */ - DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1, - qdf_nbuf_len(curr_nbuf)); - qdf_nbuf_free(curr_nbuf); - curr_nbuf = next_nbuf; + wh = (struct ieee80211_frame *)rx_pkt_hdr; + + if (!DP_FRAME_IS_DATA(wh)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "only for data frames"); + goto free; } + if (qdf_nbuf_len(mpdu) < sizeof(struct ieee80211_frame)) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Invalid nbuf length"); + goto free; + } /* reset the head and tail pointers */ for (i = 0; i < MAX_PDEV_CNT; i++) { pdev = soc->pdev_list[i]; if (!pdev) { QDF_TRACE(QDF_MODULE_ID_DP, - QDF_TRACE_LEVEL_ERROR, - "PDEV not found"); + QDF_TRACE_LEVEL_ERROR, + "PDEV not found"); continue; } pdev->invalid_peer_head_msdu = NULL; pdev->invalid_peer_tail_msdu = NULL; + + qdf_spin_lock_bh(&pdev->vdev_list_lock); + DP_PDEV_ITERATE_VDEV_LIST(pdev, vdev) { + if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw, + DP_MAC_ADDR_LEN) == 0) { + qdf_spin_unlock_bh(&pdev->vdev_list_lock); + goto out; + } + } + qdf_spin_unlock_bh(&pdev->vdev_list_lock); } + + if (NULL == vdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "VDEV not found"); + goto free; + } + +out: + if (soc->cdp_soc.ol_ops->rx_invalid_peer) + soc->cdp_soc.ol_ops->rx_invalid_peer(vdev->vdev_id, wh); +free: + /* Drop and free packet */ + curr_nbuf = mpdu; + while (curr_nbuf) { + next_nbuf = qdf_nbuf_next(curr_nbuf); + DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1, + qdf_nbuf_len(curr_nbuf)); + qdf_nbuf_free(curr_nbuf); + curr_nbuf = next_nbuf; + } + return 0; }