From 95fc62f8fc658970dc7d47c18990be090ac844d0 Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Tue, 24 Jul 2018 18:52:27 +0530 Subject: [PATCH] qcacmn: populate RSSI for the neighbor clients Populate the RSSI value for the non associated clients added in pdev->neighbour_peers_list from monitor status ring Change-Id: I509d06bec6eafe8377681c8a3da9a64f301c3c73 CRs-fixed: 2286571 --- dp/inc/cdp_txrx_ctrl.h | 35 ++++++++++++-- dp/inc/cdp_txrx_ops.h | 5 +- dp/wifi3.0/dp_main.c | 88 ++++++++++++++++++++++++++++------- dp/wifi3.0/dp_rx.c | 41 ---------------- dp/wifi3.0/dp_rx_mon_status.c | 21 +++++++++ dp/wifi3.0/dp_types.h | 20 ++++---- hal/wifi3.0/hal_api_mon.h | 42 +++++++++++++++++ 7 files changed, 178 insertions(+), 74 deletions(-) diff --git a/dp/inc/cdp_txrx_ctrl.h b/dp/inc/cdp_txrx_ctrl.h index aec17fc1e289..726b7086dc95 100644 --- a/dp/inc/cdp_txrx_ctrl.h +++ b/dp/inc/cdp_txrx_ctrl.h @@ -100,14 +100,14 @@ cdp_set_filter_neighbour_peers(ol_txrx_soc_handle soc, * which needs to be filtered * * @param soc - the pointer to soc object - * @param pdev - the pointer to physical device object + * @param vdev - the pointer to vdev * @param cmd - add/del entry into peer table * @param macaddr - the address of neighbour peer * @return - int */ static inline int cdp_update_filter_neighbour_peers(ol_txrx_soc_handle soc, - struct cdp_pdev *pdev, uint32_t cmd, uint8_t *macaddr) + struct cdp_vdev *vdev, uint32_t cmd, uint8_t *macaddr) { if (!soc || !soc->ops) { QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG, @@ -121,7 +121,7 @@ cdp_update_filter_neighbour_peers(ol_txrx_soc_handle soc, return 0; return soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers - (pdev, cmd, macaddr); + (vdev, cmd, macaddr); } /** @@ -759,5 +759,34 @@ static inline QDF_STATUS cdp_vdev_config_for_nac_rssi(ol_txrx_soc_handle soc, return soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi(vdev, nac_cmd, bssid, client_macaddr, chan_num); } + +/* + * cdp_vdev_get_neighbour_rssi(): To invoke dp callback to get rssi value of nac + * @soc: soc pointer + * @vdev: vdev pointer + * @macaddr: Non-Associated client MAC + * @rssi: rssi + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS cdp_vdev_get_neighbour_rssi(ol_txrx_soc_handle soc, + struct cdp_vdev *vdev, + char *macaddr, + uint8_t *rssi) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->ctrl_ops || + !soc->ops->ctrl_ops->txrx_vdev_get_neighbour_rssi) + return QDF_STATUS_E_FAILURE; + + return soc->ops->ctrl_ops->txrx_vdev_get_neighbour_rssi(vdev, macaddr, + rssi); +} #endif #endif diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 74c2b51c80ac..7cb6c6668d36 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -332,7 +332,7 @@ struct cdp_ctrl_ops { uint32_t val); int (*txrx_update_filter_neighbour_peers)( - struct cdp_pdev *pdev, + struct cdp_vdev *vdev, uint32_t cmd, uint8_t *macaddr); /** * @brief set the safemode of the device @@ -531,6 +531,9 @@ struct cdp_ctrl_ops { QDF_STATUS (*txrx_vdev_config_for_nac_rssi)(struct cdp_vdev *vdev, enum cdp_nac_param_cmd cmd, char *bssid, char *client_macaddr, uint8_t chan_num); + QDF_STATUS (*txrx_vdev_get_neighbour_rssi)(struct cdp_vdev *vdev, + char *macaddr, + uint8_t *rssi); #endif void (*set_key)(struct cdp_peer *peer_handle, bool is_unicast, uint32_t *key); diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 9d74060d2e31..6939c0801d04 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -65,6 +65,8 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle, uint8_t *peer_mac_addr, struct cdp_ctrl_objmgr_peer *ctrl_peer); static void dp_peer_delete_wifi3(void *peer_handle, uint32_t bitmap); +static void dp_ppdu_ring_reset(struct dp_pdev *pdev); +static void dp_ppdu_ring_cfg(struct dp_pdev *pdev); #define DP_INTR_POLL_TIMER_MS 10 #define DP_WDS_AGING_TIMER_DEFAULT_MS 120000 @@ -2846,6 +2848,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, qdf_spinlock_create(&pdev->tx_mutex); qdf_spinlock_create(&pdev->neighbour_peer_mutex); TAILQ_INIT(&pdev->neighbour_peers_list); + pdev->neighbour_peers_added = false; if (dp_soc_cmn_setup(soc)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -3683,6 +3686,7 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; struct dp_pdev *pdev = vdev->pdev; struct dp_soc *soc = pdev->soc; + struct dp_neighbour_peer *peer = NULL; /* preconditions */ qdf_assert(vdev); @@ -3724,6 +3728,13 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, } qdf_spin_unlock_bh(&soc->peer_ref_mutex); + qdf_spin_lock_bh(&pdev->neighbour_peer_mutex); + TAILQ_FOREACH(peer, &pdev->neighbour_peers_list, + neighbour_peer_list_elem) { + QDF_ASSERT(peer->vdev != vdev); + } + qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex); + dp_tx_vdev_detach(vdev); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, FL("deleting vdev object %pK (%pM)"), vdev, vdev->mac_addr.raw); @@ -4105,16 +4116,17 @@ static int dp_set_filter_neighbour_peers(struct cdp_pdev *pdev_handle, /* * dp_update_filter_neighbour_peers() - set neighbour peers(nac clients) * address for smart mesh filtering - * @pdev_handle: device object + * @vdev_handle: virtual device object * @cmd: Add/Del command * @macaddr: nac client mac address * * Return: void */ -static int dp_update_filter_neighbour_peers(struct cdp_pdev *pdev_handle, - uint32_t cmd, uint8_t *macaddr) +static int dp_update_filter_neighbour_peers(struct cdp_vdev *vdev_handle, + uint32_t cmd, uint8_t *macaddr) { - struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; + struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle; + struct dp_pdev *pdev = vdev->pdev; struct dp_neighbour_peer *peer = NULL; if (!macaddr) @@ -4135,14 +4147,21 @@ static int dp_update_filter_neighbour_peers(struct cdp_pdev *pdev_handle, qdf_mem_copy(&peer->neighbour_peers_macaddr.raw[0], macaddr, DP_MAC_ADDR_LEN); - + peer->vdev = vdev; qdf_spin_lock_bh(&pdev->neighbour_peer_mutex); + /* add this neighbour peer into the list */ TAILQ_INSERT_TAIL(&pdev->neighbour_peers_list, peer, neighbour_peer_list_elem); qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex); + /* 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; + } return 1; } else if (cmd == DP_NAC_PARAM_DEL) { @@ -4158,8 +4177,15 @@ static int dp_update_filter_neighbour_peers(struct cdp_pdev *pdev_handle, break; } } + /* last neighbour deleted */ + if (TAILQ_EMPTY(&pdev->neighbour_peers_list)) + pdev->neighbour_peers_added = false; + qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex); + if (!pdev->mcopy_mode && !pdev->neighbour_peers_added && + !pdev->enhanced_stats_en) + dp_ppdu_ring_reset(pdev); return 1; } @@ -6461,7 +6487,7 @@ dp_enable_enhanced_stats(struct cdp_pdev *pdev_handle) struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle; pdev->enhanced_stats_en = 1; - if (!pdev->mcopy_mode) + if (!pdev->mcopy_mode && !pdev->neighbour_peers_added) dp_ppdu_ring_cfg(pdev); if (is_ppdu_txrx_capture_enabled(pdev) && !pdev->bpr_enable) { @@ -6493,7 +6519,8 @@ dp_disable_enhanced_stats(struct cdp_pdev *pdev_handle) DP_PPDU_STATS_CFG_BPR, pdev->pdev_id); } - if (!pdev->mcopy_mode) + + if (!pdev->mcopy_mode && !pdev->neighbour_peers_added) dp_ppdu_ring_reset(pdev); } @@ -7308,6 +7335,37 @@ static void dp_peer_teardown_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl) #endif #ifdef ATH_SUPPORT_NAC_RSSI +/** + * dp_vdev_get_neighbour_rssi(): Store RSSI for configured NAC + * @vdev_hdl: DP vdev handle + * @rssi: rssi value + * + * Return: 0 for success. nonzero for failure. + */ +QDF_STATUS dp_vdev_get_neighbour_rssi(struct cdp_vdev *vdev_hdl, + char *mac_addr, + uint8_t *rssi) +{ + struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl; + struct dp_pdev *pdev = vdev->pdev; + struct dp_neighbour_peer *peer = NULL; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + *rssi = 0; + qdf_spin_lock_bh(&pdev->neighbour_peer_mutex); + TAILQ_FOREACH(peer, &pdev->neighbour_peers_list, + neighbour_peer_list_elem) { + if (qdf_mem_cmp(&peer->neighbour_peers_macaddr.raw[0], + mac_addr, DP_MAC_ADDR_LEN) == 0) { + *rssi = peer->rssi; + status = QDF_STATUS_SUCCESS; + break; + } + } + qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex); + return status; +} + static QDF_STATUS dp_config_for_nac_rssi(struct cdp_vdev *vdev_handle, enum cdp_nac_param_cmd cmd, char *bssid, char *client_macaddr, uint8_t chan_num) @@ -7323,17 +7381,12 @@ static QDF_STATUS dp_config_for_nac_rssi(struct cdp_vdev *vdev_handle, */ if (cmd == CDP_NAC_PARAM_ADD) { - qdf_mem_copy(vdev->cdp_nac_rssi.client_mac, - client_macaddr, DP_MAC_ADDR_LEN); - vdev->cdp_nac_rssi_enabled = 1; + dp_update_filter_neighbour_peers(vdev_handle, DP_NAC_PARAM_ADD, + client_macaddr); } else if (cmd == CDP_NAC_PARAM_DEL) { - if (!qdf_mem_cmp(vdev->cdp_nac_rssi.client_mac, - client_macaddr, DP_MAC_ADDR_LEN)) { - /* delete this peer from the list */ - qdf_mem_zero(vdev->cdp_nac_rssi.client_mac, - DP_MAC_ADDR_LEN); - } - vdev->cdp_nac_rssi_enabled = 0; + dp_update_filter_neighbour_peers(vdev_handle, + DP_NAC_PARAM_DEL, + client_macaddr); } if (soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi) @@ -7473,6 +7526,7 @@ static struct cdp_ctrl_ops dp_ops_ctrl = { .txrx_set_pdev_param = dp_set_pdev_param, #ifdef ATH_SUPPORT_NAC_RSSI .txrx_vdev_config_for_nac_rssi = dp_config_for_nac_rssi, + .txrx_vdev_get_neighbour_rssi = dp_vdev_get_neighbour_rssi, #endif .set_key = dp_set_michael_key, }; diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 0043dad024c2..4d7aba10662a 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -634,45 +634,6 @@ struct dp_vdev *dp_rx_nac_filter(struct dp_pdev *pdev, return NULL; } -/** - * dp_rx_process_nac_rssi_frames(): Store RSSI for configured NAC - * @pdev: DP pdev handle - * @rx_tlv_hdr: tlv hdr buf - * - * return: None - */ -#ifdef ATH_SUPPORT_NAC_RSSI -static void dp_rx_process_nac_rssi_frames(struct dp_pdev *pdev, uint8_t *rx_tlv_hdr) -{ - struct dp_vdev *vdev = NULL; - struct dp_soc *soc = pdev->soc; - uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr); - struct ieee80211_frame *wh = (struct ieee80211_frame *)rx_pkt_hdr; - - if (pdev->nac_rssi_filtering) { - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { - if (vdev->cdp_nac_rssi_enabled && - (qdf_mem_cmp(vdev->cdp_nac_rssi.client_mac, - wh->i_addr1, DP_MAC_ADDR_LEN) == 0)) { - QDF_TRACE(QDF_MODULE_ID_DP, - QDF_TRACE_LEVEL_DEBUG, "RSSI updated"); - vdev->cdp_nac_rssi.vdev_id = vdev->vdev_id; - vdev->cdp_nac_rssi.client_rssi = - hal_rx_msdu_start_get_rssi(rx_tlv_hdr); - dp_wdi_event_handler(WDI_EVENT_NAC_RSSI, soc, - (void *)&vdev->cdp_nac_rssi, - HTT_INVALID_PEER, WDI_NO_VAL, - pdev->pdev_id); - } - } - } -} -#else -static void dp_rx_process_nac_rssi_frames(struct dp_pdev *pdev, uint8_t *rx_tlv_hdr) -{ -} -#endif - /** * dp_rx_process_invalid_peer(): Function to pass invalid peer list to umac * @soc: DP SOC handle @@ -730,8 +691,6 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu) } - dp_rx_process_nac_rssi_frames(pdev, rx_tlv_hdr); - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw, diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 19ef21ac6a81..32569eba8edb 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -282,6 +282,27 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev, if (ppdu_info->com_info.mpdu_cnt_fcs_ok == 0) return; + if (ppdu_info->nac_info.fc_valid && + ppdu_info->nac_info.to_ds_flag && + ppdu_info->nac_info.mac_addr2_valid) { + struct dp_neighbour_peer *peer = NULL; + uint8_t rssi = ppdu_info->rx_status.rssi_comb; + + qdf_spin_lock_bh(&pdev->neighbour_peer_mutex); + if (pdev->neighbour_peers_added) { + TAILQ_FOREACH(peer, &pdev->neighbour_peers_list, + neighbour_peer_list_elem) { + if (!qdf_mem_cmp(&peer->neighbour_peers_macaddr, + &ppdu_info->nac_info.mac_addr2, + DP_MAC_ADDR_LEN)) { + peer->rssi = rssi; + break; + } + } + } + qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex); + } + if (!pdev->mcopy_mode) { if (!ppdu_info->rx_status.frame_control_info_valid) return; diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index b341de8194a5..6a765a659344 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -949,10 +949,15 @@ enum dp_nac_param_cmd { * struct dp_neighbour_peer - neighbour peer list type for smart mesh * @neighbour_peers_macaddr: neighbour peer's mac address * @neighbour_peer_list_elem: neighbour peer list TAILQ element + * @ast_entry: ast_entry for neighbour peer + * @rssi: rssi value */ struct dp_neighbour_peer { /* MAC address of neighbour's peer */ union dp_align_mac_addr neighbour_peers_macaddr; + struct dp_vdev *vdev; + struct dp_ast_entry *ast_entry; + uint8_t rssi; /* node in the list of neighbour's peer */ TAILQ_ENTRY(dp_neighbour_peer) neighbour_peer_list_elem; }; @@ -1066,6 +1071,9 @@ struct dp_pdev { /* Smart Mesh */ bool filter_neighbour_peers; + + /*flag to indicate neighbour_peers_list not empty */ + bool neighbour_peers_added; /* smart mesh mutex */ qdf_spinlock_t neighbour_peer_mutex; /* Neighnour peer list */ @@ -1335,18 +1343,6 @@ struct dp_vdev { uint32_t ap_bridge_enabled; enum cdp_sec_type sec_type; - -#ifdef ATH_SUPPORT_NAC_RSSI - bool cdp_nac_rssi_enabled; - struct { - uint8_t bssid_mac[6]; - uint8_t client_mac[6]; - uint8_t chan_num; - uint8_t client_rssi_valid; - uint8_t client_rssi; - uint8_t vdev_id; - } cdp_nac_rssi; -#endif }; diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index 431942f562b2..0cb1bfc6fb72 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -139,6 +139,8 @@ #define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs) #endif +#define HAL_MAC_ADDR_LEN 6 + enum { HAL_HW_RX_DECAP_FORMAT_RAW = 0, HAL_HW_RX_DECAP_FORMAT_NWIFI, @@ -416,11 +418,26 @@ struct hal_rx_msdu_payload_info { uint32_t payload_len; }; +/** + * struct hal_rx_nac_info - struct for neighbour info + * @fc_valid: flag indicate if it has valid frame control information + * @to_ds_flag: flag indicate to_ds bit + * @mac_addr2_valid: flag indicate if mac_addr2 is valid + * @mac_addr2: mac address2 in wh + */ +struct hal_rx_nac_info { + uint8_t fc_valid; + uint8_t to_ds_flag; + uint8_t mac_addr2_valid; + uint8_t mac_addr2[HAL_MAC_ADDR_LEN]; +}; + struct hal_rx_ppdu_info { struct hal_rx_ppdu_common_info com_info; struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS]; struct mon_rx_status rx_status; struct hal_rx_msdu_payload_info msdu_info; + struct hal_rx_nac_info nac_info; /* status ring PPDU start and end state */ uint32_t rx_state; }; @@ -1275,6 +1292,31 @@ hal_rx_status_get_tlv_info(void *rx_tlv_hdr, struct hal_rx_ppdu_info *ppdu_info, uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0, PHY_PPDU_ID); + ppdu_info->nac_info.fc_valid = + HAL_RX_GET(rx_mpdu_start, + RX_MPDU_INFO_2, + MPDU_FRAME_CONTROL_VALID); + + ppdu_info->nac_info.to_ds_flag = + HAL_RX_GET(rx_mpdu_start, + RX_MPDU_INFO_2, + TO_DS); + + ppdu_info->nac_info.mac_addr2_valid = + HAL_RX_GET(rx_mpdu_start, + RX_MPDU_INFO_2, + MAC_ADDR_AD2_VALID); + + *(uint16_t *)&ppdu_info->nac_info.mac_addr2[0] = + HAL_RX_GET(rx_mpdu_start, + RX_MPDU_INFO_16, + MAC_ADDR_AD2_15_0); + + *(uint32_t *)&ppdu_info->nac_info.mac_addr2[2] = + HAL_RX_GET(rx_mpdu_start, + RX_MPDU_INFO_17, + MAC_ADDR_AD2_47_16); + if (ppdu_info->rx_status.prev_ppdu_id != ppdu_id) { ppdu_info->rx_status.prev_ppdu_id = ppdu_id; ppdu_info->rx_status.ppdu_len =