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 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; }; /**