Эх сурвалжийг харах

qcacld-3.0: extract NAN vdev_id from mgmt BSSID

Currently, driver finds PASN peer from BSSID in mgmt auth frame
and with help of this peer, it extracts the vdev_id. It uses this
vdev_id to retrieve the adapter in hdd.
But for NAN iface, there is no PASN peer and driver drops the
auth mgmt frame as no valid vdev_id available.

The NAN Cluster ID is a MAC address that takes a value from
50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF and is carried in the A3
field of some of the NAN frames.
So, to fix this, compare the first four bytes BSSID with
"50-6F-9A-01" and extract the vdev from vdev_list for NAN opmode.

Change-Id: Ie4f15549e3bd8378e362538da4d7ec49e84ad138
CRs-Fixed: 3382962
Rahul Gusain 2 жил өмнө
parent
commit
6e78070bc6

+ 89 - 1
components/nan/core/src/nan_main.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -1441,3 +1441,91 @@ bool wlan_nan_is_beamforming_supported(struct wlan_objmgr_psoc *psoc)
 {
 	return ucfg_nan_is_beamforming_supported(psoc);
 }
+
+/*
+ * The NAN Cluster ID is a MAC address that takes a value from
+ * 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF and is carried in the A3 field of
+ * some of the NAN frames. The NAN Cluster ID is randomly chosen by the device
+ * that initiates the NAN Cluster.
+ */
+#define NAN_CLUSTER_MATCH      "\x50\x6F\x9A\x01"
+#define NAN_CLUSTER_MATCH_SIZE 4
+
+/**
+ * wlan_nan_is_bssid_in_cluster() - to check whether BSSID is a part of NAN
+ * cluster
+ * @bssid: BSSID present in mgmt frame
+ *
+ * Return: true if BSSID is part of NAN cluster
+ */
+static
+bool wlan_nan_is_bssid_in_cluster(tSirMacAddr bssid)
+{
+	if (qdf_mem_cmp(bssid, NAN_CLUSTER_MATCH, NAN_CLUSTER_MATCH_SIZE) == 0)
+		return true;
+
+	return false;
+}
+
+/**
+ * wlan_nan_extract_vdev_id_from_vdev_list() -retrieve vdev from vdev list in
+ * pdev and check for nan vdev_id
+ * @pdev: PDEV object
+ * @dbg_id: Object Manager ref debug id
+ *
+ * API to get NAN vdev_id for only NAN BSSID.
+ *
+ * Return: NAN vdev_id
+ */
+static
+uint8_t wlan_nan_extract_vdev_id_from_vdev_list(struct wlan_objmgr_pdev *pdev,
+						wlan_objmgr_ref_dbgid dbg_id)
+{
+	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
+	qdf_list_t *vdev_list = NULL;
+	struct wlan_objmgr_vdev *vdev;
+	qdf_list_node_t *node = NULL;
+	qdf_list_node_t *prev_node = NULL;
+	uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+
+	wlan_pdev_obj_lock(pdev);
+
+	vdev_list = &objmgr->wlan_vdev_list;
+	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS)
+		goto end;
+
+	do {
+		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
+					vdev_node);
+		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
+		    QDF_STATUS_SUCCESS) {
+			if (wlan_vdev_mlme_get_opmode(vdev) ==
+			    QDF_NAN_DISC_MODE) {
+				vdev_id = wlan_vdev_get_id(vdev);
+				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
+				goto end;
+			}
+
+			wlan_objmgr_vdev_release_ref(vdev, dbg_id);
+		}
+
+		prev_node = node;
+	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
+		 QDF_STATUS_SUCCESS);
+end:
+	wlan_pdev_obj_unlock(pdev);
+
+	return vdev_id;
+}
+
+uint8_t nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
+				   tSirMacAddr bssid,
+				   wlan_objmgr_ref_dbgid dbg_id)
+{
+	uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+
+	if (wlan_nan_is_bssid_in_cluster(bssid))
+		vdev_id = wlan_nan_extract_vdev_id_from_vdev_list(pdev, dbg_id);
+
+	return vdev_id;
+}

+ 16 - 1
components/nan/core/src/nan_main_i.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -31,6 +31,7 @@
 #include "nan_public_structs.h"
 #include "wlan_objmgr_cmn.h"
 #include "cfg_nan.h"
+#include "sir_mac_prot_def.h"
 
 struct wlan_objmgr_vdev;
 struct wlan_objmgr_psoc;
@@ -288,5 +289,19 @@ QDF_STATUS
 nan_get_connection_info(struct wlan_objmgr_psoc *psoc, uint8_t *chan,
 			uint8_t *mac_id);
 
+/**
+ * nan_get_vdev_id_from_bssid() -get NAN vdev_id for NAN BSSID
+ * @pdev: PDEV object
+ * @bssid: BSSID present in mgmt frame
+ * @dbg_id: Object Manager ref debug id
+ *
+ * API to get NAN vdev_id for only NAN BSSID.
+ *
+ * Return: NAN vdev_id
+ */
+uint8_t nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
+				   tSirMacAddr bssid,
+				   wlan_objmgr_ref_dbgid dbg_id);
+
 #endif /* _WLAN_NAN_MAIN_I_H_ */
 #endif /* WLAN_FEATURE_NAN */

+ 21 - 0
components/nan/dispatcher/inc/wlan_nan_api_i.h

@@ -33,11 +33,32 @@
  */
 enum nan_datapath_state wlan_nan_get_ndi_state(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * wlan_nan_get_vdev_id_from_bssid() - get NAN vdev_id for BSSID
+ * @pdev: PDEV object
+ * @bssid: BSSID present in mgmt frame
+ * @dbg_id:   Object Manager ref debug id
+ *
+ * This is wrapper API for nan_get_vdev_id_from_bssid()
+ *
+ * Return: NAN vdev_id
+ */
+uint8_t wlan_nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
+					tSirMacAddr bssid,
+					wlan_objmgr_ref_dbgid dbg_id);
 #else
 static inline
 enum nan_datapath_state wlan_nan_get_ndi_state(struct wlan_objmgr_vdev *vdev)
 {
 	return NAN_DATA_INVALID_STATE;
 }
+
+static inline
+uint8_t wlan_nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
+					tSirMacAddr bssid,
+					wlan_objmgr_ref_dbgid dbg_id)
+{
+	return INVALID_VDEV_ID;
+}
 #endif /*WLAN_FEATURE_NAN */
 #endif /*_WLAN_NAN_API_I_H_ */

+ 7 - 0
components/nan/dispatcher/src/wlan_nan_api.c

@@ -41,3 +41,10 @@ inline enum nan_datapath_state wlan_nan_get_ndi_state(
 
 	return val;
 }
+
+uint8_t wlan_nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
+					tSirMacAddr bssid,
+					wlan_objmgr_ref_dbgid dbg_id)
+{
+	return nan_get_vdev_id_from_bssid(pdev, bssid, dbg_id);
+}

+ 15 - 4
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -47,7 +47,7 @@
 #include "wlan_connectivity_logging.h"
 #include "lim_types.h"
 #include <wlan_mlo_mgr_main.h>
-
+#include "wlan_nan_api_i.h"
 /**
  * is_auth_valid
  *
@@ -2032,8 +2032,19 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac,
 
 	if (auth_alg == eSIR_AUTH_TYPE_PASN) {
 		vdev_id = lim_get_pasn_peer_vdev_id(mac, mac_hdr->bssId);
-		if (vdev_id == WLAN_UMAC_VDEV_ID_MAX)
-			return QDF_STATUS_E_FAILURE;
+		if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
+			/*
+			 * This can be NAN auth mgmt frame and for NAN, PASN
+			 * peer is not available.
+			 */
+			vdev_id = wlan_nan_get_vdev_id_from_bssid(mac->pdev,
+							mac_hdr->bssId,
+							WLAN_MGMT_RX_ID);
+			if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
+				pe_err("NAN vdev_id not found");
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
 
 		return lim_process_pasn_auth_frame(mac, vdev_id, pBd);
 	}