diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index e1ef69d0abff..8a63799ee0fc 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -928,26 +928,48 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, } if (htt_tlv_filter->enable_md) { + /* TYPE: MGMT */ + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 0000, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_ASSOC_REQ) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 0001, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_ASSOC_RES) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 0010, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_REASSOC_REQ) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 0011, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_REASSOC_RES) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 0100, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_PROBE_REQ) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 0101, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_PROBE_RES) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 0110, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_TIM_ADVT) ? 1 : 0); + /* reserved */ htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 0000, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 0001, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 0010, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 0011, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 0100, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 0101, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 0110, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 0111, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 1000, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD, - MGMT, 1001, 1); + MGMT, 0111, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_RESERVED_7) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 1000, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_BEACON) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, + MD, MGMT, 1001, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_ATIM) ? 1 : 0); } if (htt_tlv_filter->enable_mo) { @@ -1029,16 +1051,27 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, } if (htt_tlv_filter->enable_md) { - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD, - MGMT, 1010, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD, - MGMT, 1011, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD, - MGMT, 1100, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD, - MGMT, 1101, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD, - MGMT, 1110, 1); + /* TYPE: MGMT */ + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, + MD, MGMT, 1010, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_DISASSOC) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, + MD, MGMT, 1011, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_AUTH) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, + MD, MGMT, 1100, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_DEAUTH) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, + MD, MGMT, 1101, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_ACTION) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, + MD, MGMT, 1110, + (htt_tlv_filter->md_mgmt_filter & + FILTER_MGMT_ACT_NO_ACK) ? 1 : 0); } if (htt_tlv_filter->enable_mo) { @@ -1122,26 +1155,50 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, } if (htt_tlv_filter->enable_md) { - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO, - CTRL, 0000, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO, - CTRL, 0001, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO, - CTRL, 0010, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO, - CTRL, 0011, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO, - CTRL, 0100, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO, - CTRL, 0101, 1); - htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO, - CTRL, 0110, 1); + /* TYPE: CTRL */ + /* reserved */ htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, - CTRL, 0111, 1); + CTRL, 0000, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_RESERVED_1) ? 1 : 0); + /* reserved */ htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, - CTRL, 1000, 1); + CTRL, 0001, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_RESERVED_2) ? 1 : 0); htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, - CTRL, 1001, 1); + CTRL, 0010, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_TRIGGER) ? 1 : 0); + /* reserved */ + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, + CTRL, 0011, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_RESERVED_4) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, + CTRL, 0100, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_BF_REP_POLL) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, + CTRL, 0101, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_VHT_NDP) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, + CTRL, 0110, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_FRAME_EXT) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, + CTRL, 0111, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_CTRLWRAP) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, + CTRL, 1000, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_BA_REQ) ? 1 : 0); + htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD, + CTRL, 1001, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_BA) ? 1 : 0); } if (htt_tlv_filter->enable_mo) { @@ -1236,24 +1293,44 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, } if (htt_tlv_filter->enable_md) { + /* TYPE: CTRL */ htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - CTRL, 1010, 1); + CTRL, 1010, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_PSPOLL) ? 1 : 0); htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - CTRL, 1011, 1); + CTRL, 1011, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_RTS) ? 1 : 0); htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - CTRL, 1100, 1); + CTRL, 1100, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_CTS) ? 1 : 0); htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - CTRL, 1101, 1); + CTRL, 1101, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_ACK) ? 1 : 0); htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - CTRL, 1110, 1); + CTRL, 1110, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_CFEND) ? 1 : 0); htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - CTRL, 1111, 1); + CTRL, 1111, + (htt_tlv_filter->md_ctrl_filter & + FILTER_CTRL_CFEND_CFACK) ? 1 : 0); + /* TYPE: DATA */ htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - DATA, MCAST, 1); + DATA, MCAST, + (htt_tlv_filter->md_data_filter & + FILTER_DATA_MCAST) ? 1 : 0); htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - DATA, UCAST, 1); + DATA, UCAST, + (htt_tlv_filter->md_data_filter & + FILTER_DATA_UCAST) ? 1 : 0); htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD, - DATA, NULL, 1); + DATA, NULL, + (htt_tlv_filter->md_data_filter & + FILTER_DATA_NULL) ? 1 : 0); } if (htt_tlv_filter->enable_mo) { diff --git a/dp/wifi3.0/dp_htt.h b/dp/wifi3.0/dp_htt.h index 6ce2c3aab3c9..d84e92372651 100644 --- a/dp/wifi3.0/dp_htt.h +++ b/dp/wifi3.0/dp_htt.h @@ -132,6 +132,9 @@ struct htt_rx_ring_tlv_filter { mo_ctrl_filter:16; u_int32_t fp_data_filter:16, mo_data_filter:16; + u_int16_t md_data_filter; + u_int16_t md_mgmt_filter; + u_int16_t md_ctrl_filter; }; void * diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index fc508c80c001..ac3a696c091a 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -4250,9 +4250,8 @@ static int dp_update_filter_neighbour_peers(struct cdp_vdev *vdev_handle, /* first neighbour */ if (!pdev->neighbour_peers_added) { - if (!pdev->mcopy_mode && !pdev->enhanced_stats_en) - dp_ppdu_ring_cfg(pdev); pdev->neighbour_peers_added = true; + dp_ppdu_ring_cfg(pdev); } return 1; @@ -6468,6 +6467,11 @@ dp_ppdu_ring_cfg(struct dp_pdev *pdev) htt_tlv_filter.ppdu_end_status_done = 1; htt_tlv_filter.enable_fp = 1; htt_tlv_filter.enable_md = 0; + if (pdev->neighbour_peers_added && + pdev->soc->hw_nac_monitor_support) { + htt_tlv_filter.enable_md = 1; + htt_tlv_filter.packet_header = 1; + } if (pdev->mcopy_mode) { htt_tlv_filter.packet_header = 1; htt_tlv_filter.enable_mo = 1; @@ -6478,6 +6482,9 @@ dp_ppdu_ring_cfg(struct dp_pdev *pdev) htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL; + if (pdev->neighbour_peers_added && + pdev->soc->hw_nac_monitor_support) + htt_tlv_filter.md_data_filter = FILTER_DATA_ALL; for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, @@ -8124,11 +8131,13 @@ void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle, wlan_cfg_set_reo_dst_ring_size(soc->wlan_cfg_ctx, REO_DST_RING_SIZE_QCA8074); wlan_cfg_set_raw_mode_war(soc->wlan_cfg_ctx, true); + soc->hw_nac_monitor_support = 1; break; case TARGET_TYPE_QCA8074V2: wlan_cfg_set_reo_dst_ring_size(soc->wlan_cfg_ctx, REO_DST_RING_SIZE_QCA8074); wlan_cfg_set_raw_mode_war(soc->wlan_cfg_ctx, false); + soc->hw_nac_monitor_support = 1; break; default: qdf_print("%s: Unknown tgt type %d\n", __func__, target_type); diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 8c6941b20497..53d308a3571d 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -296,6 +296,57 @@ dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, } #endif +/** + * dp_rx_handle_smart_mesh_mode() - Deliver header for smart mesh + * @soc: Datapath SOC handle + * @pdev: Datapath PDEV handle + * @ppdu_info: Structure for rx ppdu info + * @nbuf: Qdf nbuf abstraction for linux skb + * + * Return: 0 on success, 1 on failure + */ +static inline int +dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev, + struct hal_rx_ppdu_info *ppdu_info, + qdf_nbuf_t nbuf) +{ + uint8_t size = 0; + + if (!pdev->monitor_vdev) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "[%s]:[%d] Monitor vdev is NULL !!", + __func__, __LINE__); + return 1; + } + if (ppdu_info->msdu_info.first_msdu_payload == NULL) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "[%s]:[%d] First msdu payload not present", + __func__, __LINE__); + return 1; + } + + /* Include 2 bytes of reserved space appended to the msdu payload */ + size = (ppdu_info->msdu_info.first_msdu_payload - + qdf_nbuf_data(nbuf)) + 2; + ppdu_info->msdu_info.first_msdu_payload = NULL; + + if (qdf_nbuf_pull_head(nbuf, size) == NULL) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "[%s]:[%d] No header present", + __func__, __LINE__); + return 1; + } + + /* only retain RX MSDU payload in the skb */ + qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - + ppdu_info->msdu_info.payload_len); + qdf_nbuf_update_radiotap(&(pdev->ppdu_info.rx_status), + nbuf, sizeof(struct rx_pkt_tlvs)); + pdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev, + nbuf, NULL); + + return 0; +} /** * dp_rx_handle_ppdu_stats() - Allocate and deliver ppdu stats to cdp layer @@ -400,6 +451,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, uint32_t tlv_status = HAL_TLV_STATUS_BUF_DONE; QDF_STATUS m_copy_status = QDF_STATUS_SUCCESS; struct cdp_pdev_mon_stats *rx_mon_stats; + int smart_mesh_status; ppdu_info = &pdev->ppdu_info; rx_mon_stats = &pdev->rx_mon_stats; @@ -437,21 +489,28 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, } while (tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE); } + if (ppdu_info->rx_status.monitor_direct_used && pdev->neighbour_peers_added + && pdev->monitor_vdev) { + smart_mesh_status = dp_rx_handle_smart_mesh_mode(soc, + pdev, ppdu_info, status_nbuf); + if (smart_mesh_status) + qdf_nbuf_free(status_nbuf); + } if (pdev->mcopy_mode) { m_copy_status = dp_rx_handle_mcopy_mode(soc, pdev, ppdu_info, status_nbuf); if (m_copy_status == QDF_STATUS_SUCCESS) qdf_nbuf_free(status_nbuf); - } else { - qdf_nbuf_free(status_nbuf); } + if (!pdev->neighbour_peers_added && !pdev->mcopy_mode) + qdf_nbuf_free(status_nbuf); if (tlv_status == HAL_TLV_STATUS_PPDU_NON_STD_DONE) { dp_rx_mon_deliver_non_std(soc, mac_id); } else if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { rx_mon_stats->status_ppdu_done++; if (pdev->enhanced_stats_en || - pdev->mcopy_mode) + pdev->mcopy_mode || pdev->neighbour_peers_added) dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info); pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE; diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index dfd6d8918bfe..a58557e9c06d 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -915,6 +915,9 @@ struct dp_soc { #endif /* Device ID coming from Bus sub-system */ uint32_t device_id; + + /* Smart monitor capability for HKv2 */ + uint8_t hw_nac_monitor_support; }; #ifdef IPA_OFFLOAD @@ -1128,6 +1131,7 @@ struct dp_pdev { uint16_t mo_mgmt_filter; uint16_t mo_ctrl_filter; uint16_t mo_data_filter; + uint16_t md_data_filter; qdf_atomic_t num_tx_outstanding; diff --git a/hal/wifi3.0/hal_generic_api.h b/hal/wifi3.0/hal_generic_api.h index 3d61bebeef6f..b60e076f3008 100644 --- a/hal/wifi3.0/hal_generic_api.h +++ b/hal/wifi3.0/hal_generic_api.h @@ -997,6 +997,7 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, RX_MPDU_INFO_RX_MPDU_INFO_DETAILS); uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, PHY_PPDU_ID); + uint8_t filter_category = 0; ppdu_info->nac_info.fc_valid = HAL_RX_GET(rx_mpdu_start, @@ -1033,6 +1034,11 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo, HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13, MPDU_LENGTH); } + + filter_category = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, + RXPCU_MPDU_FILTER_IN_CATEGORY); + if (filter_category == 1) + ppdu_info->rx_status.monitor_direct_used = 1; break; } case 0: diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 3c62da74f015..ba9b7b1ca774 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -289,6 +289,7 @@ struct mon_rx_status { uint32_t ppdu_id; uint32_t device_id; int16_t chan_noise_floor; + uint8_t monitor_direct_used; }; /**