Browse Source

qcacld-3.0: Introduce iterator API for active link info

MACRO: hdd_adapter_for_each_active_link_info()
      The new iterator will only iterate through the link info
      elements in the link_info array which are set to active.
      The bitmap of active link info indices is saved in
      active_links member in adapter structure.

MACRO: hdd_adapter_for_each_link_info()
      Modify the existing hdd_adapter_for_each_link_entry()
      iterator MACRO to have similar prototype as
      hdd_adapter_for_each_active_link_info()

Change-Id: I02b8a297ea809f860e041a71c180af2a8f946b3d
CRs-Fixed: 3515068
Vinod Kumar Pirla 1 year ago
parent
commit
855472fdfa
2 changed files with 89 additions and 32 deletions
  1. 86 18
      core/hdd/inc/wlan_hdd_main.h
  2. 3 14
      core/hdd/src/wlan_hdd_main.c

+ 86 - 18
core/hdd/inc/wlan_hdd_main.h

@@ -2591,33 +2591,101 @@ void hdd_validate_next_adapter(struct hdd_adapter **curr,
 	     __hdd_take_ref_and_fetch_next_adapter_safe(hdd_ctx, adapter, \
 							next_adapter, dbgid))
 
-#define __hdd_adapter_deflink_idx(link_idx) (link_idx = WLAN_HDD_DEFLINK_IDX)
-#define __hdd_is_link_idx_valid(link_idx) ((link_idx) < WLAN_MAX_MLD)
-#define __hdd_adapter_next_link_idx(link_idx) ((link_idx)++)
-
-/**
- * hdd_adapter_for_each_link_entry() - Link info iterator for all
- * link_info fields.
- * @adapter: HDD adapter to iterate each link_info
- * @link_idx: Variable to save each iterating index
- *
- * The function iterates from the start index of link_info array
- * in @adapter till the end of the link_info array.
+/* Helper MACROS and APIs definition to iterate
+ * link info array in HDD adapter.
  */
+#define __hdd_adapter_is_active_link(adapter, link_idx) \
+			qdf_atomic_test_bit(link_idx, &(adapter)->active_links)
+
+#define hdd_adapter_get_link_info_if_active(adapter, link_idx) \
+		__hdd_adapter_is_active_link((adapter), (link_idx)) ? \
+			&((adapter)->link_info[(link_idx)]) : NULL
+
+#define __hdd_is_link_info_valid(_link_info) !!_link_info
+
+#define __hdd_adapter_get_first_active_link_info(adapter, link_info) \
+	link_info = NULL, \
+	hdd_adapter_get_next_active_link_info(adapter, &link_info)
 
-#define hdd_adapter_for_each_link_entry(adapter, link_idx) \
-	for (__hdd_adapter_deflink_idx(link_idx); \
-		__hdd_is_link_idx_valid(link_idx); \
-		__hdd_adapter_next_link_idx(link_idx))
 
 static inline uint8_t
 hdd_adapter_get_index_of_link_info(struct wlan_hdd_link_info *link_info)
 {
-	unsigned long offset = link_info - link_info->adapter->deflink;
+	return (link_info - &link_info->adapter->link_info[0]);
+}
+
+static inline void
+hdd_adapter_get_next_active_link_info(struct hdd_adapter *adapter,
+				      struct wlan_hdd_link_info **link_info)
+{
+	uint8_t link_idx = WLAN_HDD_DEFLINK_IDX;
 
-	return (offset / sizeof(struct wlan_hdd_link_info));
+	if (!link_info || !adapter)
+		return;
+
+	/* If @link_info already points to valid link info address, get the
+	 * index of that link info and get the next valid link info which is
+	 * set to active.
+	 * If @link_info points to invalid address, then start the search
+	 * for active link info from WLAN_HDD_DEFLINK_IDX index.
+	 */
+	if (*link_info)
+		link_idx = hdd_adapter_get_index_of_link_info(*link_info) + 1;
+
+	*link_info = NULL;
+	while (link_idx < WLAN_MAX_MLD && !(*link_info)) {
+		*link_info = hdd_adapter_get_link_info_if_active(adapter,
+								 link_idx);
+		link_idx++;
+	}
 }
 
+/**
+ * hdd_adapter_for_each_active_link_info() - Link info iterator which loops
+ * through the link info array elements which are set to active.
+ * @adapter: HDD adapter to iterate for each active link info pointer.
+ * @link_info: Pointer of active link info.
+ *
+ * The "active_links" bitmap in @adapter says which indices are active
+ * in the link info array.
+ * The MACRO iterates through all the active link info elements in link info
+ * array and ends loop when no more active link info entries are present.
+ * The @link_info points next active link info pointer on each iteration or
+ * NULL value at the end of the loop.
+ *
+ * Callers to take reference of adapter if needed.
+ */
+#define hdd_adapter_for_each_active_link_info(adapter, link_info) \
+	for (__hdd_adapter_get_first_active_link_info(adapter, link_info); \
+	     __hdd_is_link_info_valid(link_info); \
+	     hdd_adapter_get_next_active_link_info(adapter, &link_info))
+
+#define __hdd_adapter_get_firstlink(adapter, __link_info)	\
+		(__link_info = adapter ? &((adapter)->link_info[0]) : NULL)
+
+#define __hdd_is_link_info_idx_valid(adapter, __link_info) \
+		((__link_info - &(adapter)->link_info[0]) < WLAN_MAX_MLD)
+
+#define __hdd_adapter_next_link_info(link_info)	((link_info)++)
+
+/**
+ * hdd_adapter_for_each_link_info() - Link info iterator for all
+ * link_info fields.
+ * @adapter: HDD adapter to iterate each link_info.
+ * @link_info: Pointer to each link info element in the array.
+ *
+ * The function iterates from the start index of link_info array
+ * in @adapter till the end of the link_info array.
+ *
+ * Callers to take reference of adapter if needed.
+ */
+
+#define hdd_adapter_for_each_link_info(adapter, link_info) \
+	for (__hdd_adapter_get_firstlink(adapter, link_info); \
+	     __hdd_is_link_info_valid(link_info) && \
+	     __hdd_is_link_info_idx_valid(adapter, link_info); \
+	     __hdd_adapter_next_link_info(link_info))
+
 /**
  * wlan_hdd_get_link_info_from_objmgr() - Fetch adapter from objmgr
  * @vdev: the vdev whose corresponding adapter has to be fetched

+ 3 - 14
core/hdd/src/wlan_hdd_main.c

@@ -7466,7 +7466,6 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
 {
 	struct net_device *dev = NULL;
 	struct wlan_hdd_link_info *link_info;
-	uint8_t link_idx;
 
 	if (adapter)
 		dev = adapter->dev;
@@ -7477,13 +7476,8 @@ static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
 
 	hdd_apf_context_destroy(adapter);
 	qdf_spinlock_destroy(&adapter->mc_list_lock);
-	hdd_adapter_for_each_link_entry(adapter, link_idx) {
-		link_info = hdd_adapter_get_link_info_ptr(adapter, link_idx);
-		if (!link_info)
-			continue;
-
+	hdd_adapter_for_each_link_info(adapter, link_info)
 		qdf_spinlock_destroy(&link_info->vdev_lock);
-	}
 
 	hdd_sta_info_deinit(&adapter->sta_info_list);
 	hdd_sta_info_deinit(&adapter->cache_sta_info_list);
@@ -8028,12 +8022,10 @@ wlan_hdd_set_ml_cap_for_sap_intf(struct hdd_adapter_create_param *create_params,
 
 static void hdd_adapter_init_link_info(struct hdd_adapter *adapter)
 {
-	uint8_t link_idx;
 	struct wlan_hdd_link_info *link_info;
 
 	/* Initialize each member in link info array to default values */
-	hdd_adapter_for_each_link_entry(adapter, link_idx) {
-		link_info = &adapter->link_info[link_idx];
+	hdd_adapter_for_each_link_info(adapter, link_info) {
 		link_info->adapter = adapter;
 		link_info->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
 		qdf_spinlock_create(&link_info->vdev_lock);
@@ -9871,7 +9863,6 @@ hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id)
 {
 	struct hdd_adapter *adapter, *next_adapter = NULL;
 	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER_BY_VDEV;
-	uint8_t link_idx;
 	struct wlan_hdd_link_info *link_info;
 
 	if (vdev_id == WLAN_INVALID_VDEV_ID)
@@ -9879,9 +9870,7 @@ hdd_get_link_info_by_vdev(struct hdd_context *hdd_ctx, uint32_t vdev_id)
 
 	hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
 					   dbgid) {
-		hdd_adapter_for_each_link_entry(adapter, link_idx) {
-			link_info = hdd_adapter_get_link_info_ptr(adapter,
-								  link_idx);
+		hdd_adapter_for_each_active_link_info(adapter, link_info) {
 			if (link_info->vdev_id == vdev_id) {
 				hdd_adapter_dev_put_debug(adapter, dbgid);
 				if (next_adapter)