Browse Source

qcacmn: Add support to get RSSI of Non associated clients

Add change in driver to get RSSI of non associated clients.

This is done in 2 levels of filtering
1. Send WMI to FW to configure BSSID in HW
2. Filter the neighbour BSSID packets received in host for
the configured client mac

Change-Id: I6b684b83cecb308dac326056aa77537aee07b933
CRs-Fixed: 2148773
Soumya Bhat 7 years ago
parent
commit
bc719e6b02
5 changed files with 156 additions and 4 deletions
  1. 32 1
      dp/inc/cdp_txrx_ctrl.h
  2. 22 1
      dp/inc/cdp_txrx_ops.h
  3. 41 0
      dp/wifi3.0/dp_main.c
  4. 46 2
      dp/wifi3.0/dp_rx.c
  5. 15 0
      dp/wifi3.0/dp_types.h

+ 32 - 1
dp/inc/cdp_txrx_ctrl.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -762,4 +762,35 @@ cdp_get_pldev(ol_txrx_soc_handle soc,
 	return soc->ops->ctrl_ops->txrx_get_pldev(pdev);
 }
 
+#ifdef ATH_SUPPORT_NAC_RSSI
+/**
+  * cdp_vdev_config_for_nac_rssi(): To invoke dp callback for nac rssi config
+  * @soc: soc pointer
+  * @vdev: vdev pointer
+  * @nac_cmd: specfies nac_rss config action add, del, list
+  * @bssid: Neighbour bssid
+  * @client_macaddr: Non-Associated client MAC
+  * @chan_num: channel number to scan
+  *
+  * Return: QDF_STATUS
+  */
+static inline QDF_STATUS cdp_vdev_config_for_nac_rssi(ol_txrx_soc_handle soc,
+		struct cdp_vdev *vdev, enum cdp_nac_param_cmd nac_cmd,
+		char *bssid, char *client_macaddr, uint8_t chan_num)
+{
+	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_config_for_nac_rssi)
+		return QDF_STATUS_E_FAILURE;
+
+	return soc->ops->ctrl_ops->txrx_vdev_config_for_nac_rssi(vdev,
+			nac_cmd, bssid, client_macaddr, chan_num);
+}
+#endif
 #endif

+ 22 - 1
dp/inc/cdp_txrx_ops.h

@@ -45,6 +45,15 @@
 #define CDP_PEER_DELETE_NO_SPECIAL             0
 #define CDP_PEER_DO_NOT_START_UNMAP_TIMER      1
 
+/* same as ieee80211_nac_param */
+enum cdp_nac_param_cmd {
+	/* IEEE80211_NAC_PARAM_ADD */
+	CDP_NAC_PARAM_ADD = 1,
+	/* IEEE80211_NAC_PARAM_DEL */
+	CDP_NAC_PARAM_DEL,
+	/* IEEE80211_NAC_PARAM_LIST */
+	CDP_NAC_PARAM_LIST,
+};
 /******************************************************************************
  *
  * Control Interface (A Interface)
@@ -473,6 +482,12 @@ struct cdp_ctrl_ops {
 	int (*txrx_wdi_event_handler)(struct cdp_pdev *pdev,
 					uint32_t event, void *evt_data);
 	void * (*txrx_get_pldev)(struct cdp_pdev *pdev);
+
+#ifdef ATH_SUPPORT_NAC_RSSI
+	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);
+#endif
 };
 
 struct cdp_me_ops {
@@ -699,7 +714,13 @@ struct ol_if_ops {
 
 	void (*record_act_change)(struct wlan_objmgr_pdev *pdev,
 				  u_int8_t *dstmac, bool active);
-
+#ifdef ATH_SUPPORT_NAC_RSSI
+	int (*config_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev,
+		u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid,
+		char *client_macaddr, uint8_t chan_num);
+	int (*config_bssid_in_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev,
+		u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid);
+#endif
 	/* TODO: Add any other control path calls required to OL_IF/WMA layer */
 };
 

+ 41 - 0
dp/wifi3.0/dp_main.c

@@ -6303,6 +6303,43 @@ static void dp_peer_teardown_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl)
 }
 #endif
 
+#ifdef ATH_SUPPORT_NAC_RSSI
+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)
+{
+
+	struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
+	struct dp_pdev *pdev = (struct dp_pdev *)vdev->pdev;
+	struct dp_soc *soc = (struct dp_soc *) vdev->pdev->soc;
+
+	pdev->nac_rssi_filtering = 1;
+	/* Store address of NAC (neighbour peer) which will be checked
+	 * against TA of received packets.
+	 */
+
+	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;
+	} 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;
+	}
+
+	if (soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi)
+		soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi
+			(vdev->pdev->osif_pdev, vdev->vdev_id, cmd, bssid);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 static struct cdp_cmn_ops dp_ops_cmn = {
 	.txrx_soc_attach_target = dp_soc_attach_target_wifi3,
 	.txrx_vdev_attach = dp_vdev_attach_wifi3,
@@ -6391,6 +6428,9 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
 	.txrx_get_pldev = dp_get_pldev,
 #endif
 	.txrx_set_pdev_param = dp_set_pdev_param,
+#ifdef ATH_SUPPORT_NAC_RSSI
+	.txrx_vdev_config_for_nac_rssi = dp_config_for_nac_rssi,
+#endif
 };
 
 static struct cdp_me_ops dp_ops_me = {
@@ -7101,3 +7141,4 @@ static void dp_pktlogmod_exit(struct dp_pdev *handle)
 #else
 static void dp_pktlogmod_exit(struct dp_pdev *handle) { }
 #endif
+

+ 46 - 2
dp/wifi3.0/dp_rx.c

@@ -636,6 +636,45 @@ 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
@@ -650,10 +689,10 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu)
 	struct dp_pdev *pdev = NULL;
 	struct ieee80211_frame *wh;
 	uint8_t i;
-	uint8_t *rx_pkt_hdr;
 	qdf_nbuf_t curr_nbuf, next_nbuf;
+	uint8_t *rx_tlv_hdr = qdf_nbuf_data(mpdu);
+	uint8_t *rx_pkt_hdr = hal_rx_pkt_hdr_get(rx_tlv_hdr);
 
-	rx_pkt_hdr = hal_rx_pkt_hdr_get(qdf_nbuf_data(mpdu));
 	wh = (struct ieee80211_frame *)rx_pkt_hdr;
 
 	if (!DP_FRAME_IS_DATA(wh)) {
@@ -687,7 +726,12 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t mpdu)
 				return 0;
 			}
 		}
+
+
+		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,
 						DP_MAC_ADDR_LEN) == 0) {
 				goto out;

+ 15 - 0
dp/wifi3.0/dp_types.h

@@ -1129,6 +1129,10 @@ struct dp_pdev {
 	bool pktlog_ppdu_stats;
 
 	void *dp_txrx_handle; /* Advanced data path handle */
+
+#ifdef ATH_SUPPORT_NAC_RSSI
+	bool nac_rssi_filtering;
+#endif
 };
 
 struct dp_peer;
@@ -1268,6 +1272,17 @@ struct dp_vdev {
 
 	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
 };