From 59a2d33a2d728e63678464f5bfb4f1858c2e99b9 Mon Sep 17 00:00:00 2001 From: sumedh baikady Date: Tue, 22 May 2018 01:50:38 -0700 Subject: [PATCH] qcacmn: Use monitor direct for smart monitor Set monitor direct filter when smart monitor is enabled. Deliver header from NAC if md bit is set and smart mesh feature is used. Change-Id: If1ef865e013c21bbb58bcb89a87856b12d6c7278 Crs-fixed: 2246660 --- dp/wifi3.0/dp_htt.c | 187 ++++++++++++++++++++++++---------- dp/wifi3.0/dp_htt.h | 3 + dp/wifi3.0/dp_main.c | 13 ++- dp/wifi3.0/dp_rx_mon_status.c | 65 +++++++++++- dp/wifi3.0/dp_types.h | 4 + hal/wifi3.0/hal_generic_api.h | 6 ++ qdf/inc/qdf_nbuf.h | 1 + 7 files changed, 219 insertions(+), 60 deletions(-) diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index e1ef69d0ab..8a63799ee0 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 6ce2c3aab3..d84e923726 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 fc508c80c0..ac3a696c09 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 8c6941b204..53d308a357 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 dfd6d8918b..a58557e9c0 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 3d61bebeef..b60e076f30 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 3c62da74f0..ba9b7b1ca7 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; }; /**