qcacmn: Drop mpdus received on non-monitor PMAC
Currently the monitor mode filter settings are set for both the PMAC. Hence it is possible that the non-monitor PMAC (the PMAC on which monitor vdev is not running), can receive packets and forward them to the monitor destination ring. The above scenario will lead to a ppdu_id mismatch when reaping the monitor status ring and comparing the ppdu_id in status ring with the one in monitor destination ring, since monitor status ring will have ppdu_id from the PMAC on which monitor vdev is running, whereas monitor destination ring will have packets from both the PMAC. In order to mitigate the above issue, detect the packets in the monitor destination ring, which are not from the PMAC where monitor vdev is running, and drop them. Change-Id: I32392ceeadffd9cb7a4dd76336004a9dcbb99404 CRs-Fixed: 3318036
Šī revīzija ir iekļauta:

revīziju iesūtīja
Madan Koyyalamudi

vecāks
2158048410
revīzija
f533809136
@@ -463,6 +463,153 @@ next_msdu:
|
||||
return rx_bufs_used;
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_NON_MON_PMAC)
|
||||
static int dp_rx_mon_drop_one_mpdu(struct dp_pdev *pdev,
|
||||
uint32_t mac_id,
|
||||
hal_rxdma_desc_t rxdma_dst_ring_desc,
|
||||
union dp_rx_desc_list_elem_t **head,
|
||||
union dp_rx_desc_list_elem_t **tail)
|
||||
{
|
||||
struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
hal_soc_handle_t hal_soc = soc->hal_soc;
|
||||
struct hal_buf_info buf_info;
|
||||
uint32_t msdu_count = 0;
|
||||
uint32_t rx_bufs_used = 0;
|
||||
void *rx_msdu_link_desc;
|
||||
struct hal_rx_msdu_list msdu_list;
|
||||
uint16_t num_msdus;
|
||||
qdf_nbuf_t nbuf;
|
||||
uint32_t i;
|
||||
uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
|
||||
uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS];
|
||||
struct rx_desc_pool *rx_desc_pool;
|
||||
|
||||
rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id);
|
||||
hal_rx_reo_ent_buf_paddr_get(hal_soc, rxdma_dst_ring_desc,
|
||||
&buf_info, &msdu_count);
|
||||
|
||||
do {
|
||||
rx_msdu_link_desc = dp_rx_cookie_2_mon_link_desc(pdev,
|
||||
buf_info,
|
||||
mac_id);
|
||||
if (qdf_unlikely(!rx_msdu_link_desc)) {
|
||||
mon_pdev->rx_mon_stats.mon_link_desc_invalid++;
|
||||
return rx_bufs_used;
|
||||
}
|
||||
|
||||
hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc,
|
||||
&msdu_list, &num_msdus);
|
||||
|
||||
for (i = 0; i < num_msdus; i++) {
|
||||
struct dp_rx_desc *rx_desc;
|
||||
qdf_dma_addr_t buf_paddr;
|
||||
|
||||
rx_desc = dp_rx_get_mon_desc(soc,
|
||||
msdu_list.sw_cookie[i]);
|
||||
|
||||
if (qdf_unlikely(!rx_desc)) {
|
||||
mon_pdev->rx_mon_stats.
|
||||
mon_rx_desc_invalid++;
|
||||
continue;
|
||||
}
|
||||
|
||||
nbuf = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc);
|
||||
buf_paddr =
|
||||
dp_rx_mon_get_paddr_from_desc(rx_desc);
|
||||
|
||||
if (qdf_unlikely(!rx_desc->in_use || !nbuf ||
|
||||
msdu_list.paddr[i] !=
|
||||
buf_paddr)) {
|
||||
mon_pdev->rx_mon_stats.
|
||||
mon_nbuf_sanity_err++;
|
||||
continue;
|
||||
}
|
||||
rx_bufs_used++;
|
||||
|
||||
if (!rx_desc->unmapped) {
|
||||
dp_rx_mon_buffer_unmap(soc, rx_desc,
|
||||
rx_desc_pool->buf_size);
|
||||
rx_desc->unmapped = 1;
|
||||
}
|
||||
|
||||
qdf_nbuf_free(nbuf);
|
||||
dp_rx_add_to_free_desc_list(head, tail, rx_desc);
|
||||
|
||||
if (!(msdu_list.msdu_info[i].msdu_flags &
|
||||
HAL_MSDU_F_MSDU_CONTINUATION))
|
||||
msdu_count--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the current link buffer into to the local
|
||||
* structure to be used for release purpose.
|
||||
*/
|
||||
hal_rxdma_buff_addr_info_set(soc->hal_soc,
|
||||
rx_link_buf_info,
|
||||
buf_info.paddr,
|
||||
buf_info.sw_cookie,
|
||||
buf_info.rbm);
|
||||
|
||||
hal_rx_mon_next_link_desc_get(soc->hal_soc,
|
||||
rx_msdu_link_desc,
|
||||
&buf_info);
|
||||
if (dp_rx_monitor_link_desc_return(pdev,
|
||||
(hal_buff_addrinfo_t)
|
||||
rx_link_buf_info,
|
||||
mac_id, bm_action) !=
|
||||
QDF_STATUS_SUCCESS)
|
||||
dp_info_rl("monitor link desc return failed");
|
||||
} while (buf_info.paddr && msdu_count);
|
||||
|
||||
return rx_bufs_used;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id,
|
||||
hal_rxdma_desc_t rxdma_dst_ring_desc,
|
||||
union dp_rx_desc_list_elem_t **head,
|
||||
union dp_rx_desc_list_elem_t **tail,
|
||||
uint32_t *rx_bufs_dropped)
|
||||
{
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
|
||||
uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
|
||||
uint8_t src_link_id;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (mon_pdev->mon_chan_band == REG_BAND_UNKNOWN)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
lmac_id = pdev->ch_band_lmac_id_mapping[mon_pdev->mon_chan_band];
|
||||
|
||||
status = hal_rx_reo_ent_get_src_link_id(soc->hal_soc,
|
||||
rxdma_dst_ring_desc,
|
||||
&src_link_id);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
if (src_link_id == lmac_id)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
*rx_bufs_dropped = dp_rx_mon_drop_one_mpdu(pdev, mac_id,
|
||||
rxdma_dst_ring_desc,
|
||||
head, tail);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static inline QDF_STATUS
|
||||
dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id,
|
||||
hal_rxdma_desc_t rxdma_dst_ring_desc,
|
||||
union dp_rx_desc_list_elem_t **head,
|
||||
union dp_rx_desc_list_elem_t **tail,
|
||||
uint32_t *rx_bufs_dropped)
|
||||
{
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx,
|
||||
uint32_t mac_id, uint32_t quota)
|
||||
{
|
||||
@@ -517,10 +664,23 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx,
|
||||
hal_srng_dst_peek(hal_soc, mon_dst_srng))) {
|
||||
qdf_nbuf_t head_msdu, tail_msdu;
|
||||
uint32_t npackets;
|
||||
uint32_t rx_bufs_dropped;
|
||||
|
||||
rx_bufs_dropped = 0;
|
||||
head_msdu = (qdf_nbuf_t)NULL;
|
||||
tail_msdu = (qdf_nbuf_t)NULL;
|
||||
|
||||
if (QDF_STATUS_SUCCESS ==
|
||||
dp_rx_mon_check_n_drop_mpdu(pdev, mac_id,
|
||||
rxdma_dst_ring_desc,
|
||||
&head, &tail,
|
||||
&rx_bufs_dropped)) {
|
||||
/* Increment stats */
|
||||
rx_bufs_used += rx_bufs_dropped;
|
||||
hal_srng_dst_get_next(hal_soc, mon_dst_srng);
|
||||
continue;
|
||||
}
|
||||
|
||||
mpdu_rx_bufs_used =
|
||||
dp_rx_mon_mpdu_pop(soc, mac_id,
|
||||
rxdma_dst_ring_desc,
|
||||
@@ -1037,6 +1197,18 @@ dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_NON_MON_PMAC)
|
||||
static QDF_STATUS
|
||||
dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id,
|
||||
hal_rxdma_desc_t rxdma_dst_ring_desc,
|
||||
union dp_rx_desc_list_elem_t **head,
|
||||
union dp_rx_desc_list_elem_t **tail,
|
||||
uint32_t *rx_bufs_dropped)
|
||||
{
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user