Browse Source

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
Chaithanya Garrepalli 6 years ago
parent
commit
95fc62f8fc

+ 32 - 3
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

+ 4 - 1
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);

+ 71 - 17
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,
 };

+ 0 - 41
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,

+ 21 - 0
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;

+ 8 - 12
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
 };
 
 

+ 42 - 0
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 =