Selaa lähdekoodia

qcacmn: Add new iterate PSOC API for all objects

The current iterate object API does not invoke operation on logically
deleted objects. The new API will invoke operation on all objects.

Change-Id: I7821dccf3ccb0c5d209e3bf27489fcb4bf99aef5
CRs-Fixed: 2028529
Srinivas Pitla 8 vuotta sitten
vanhempi
sitoutus
935cd2dae8

+ 25 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h

@@ -378,6 +378,7 @@ typedef void (*wlan_objmgr_op_handler)(struct wlan_objmgr_psoc *psoc,
 
 /**
  * wlan_objmgr_iterate_obj_list() - iterate through all psoc objects
+ *                                  (CREATED state)
  * @psoc: PSOC object
  * @obj_type: PDEV_OP/VDEV_OP/PEER_OP
  * @handler: the handler will be called for each object of requested type
@@ -400,6 +401,30 @@ QDF_STATUS wlan_objmgr_iterate_obj_list(
 		void *arg, uint8_t lock_free_op,
 		wlan_objmgr_ref_dbgid dbg_id);
 
+/**
+ * wlan_objmgr_iterate_obj_list_all() - iterate through all psoc objects
+ * @psoc: PSOC object
+ * @obj_type: PDEV_OP/VDEV_OP/PEER_OP
+ * @handler: the handler will be called for each object of requested type
+ *            the handler should be implemented to perform required operation
+ * @arg:     agruments passed by caller
+ * @lock_free_op: This gives provision to run this API with out lock protected
+ *                 It would be useful, for operations like Obj Delete, where
+ *                 lock should not be taken by caller.
+ * @dbg_id: id of the caller
+ *
+ * API to be used for performing the operations on all PDEV/VDEV/PEER objects
+ * of psoc
+ *
+ * Return: SUCCESS/FAILURE
+ */
+QDF_STATUS wlan_objmgr_iterate_obj_list_all(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_objmgr_obj_type obj_type,
+		wlan_objmgr_op_handler handler,
+		void *arg, uint8_t lock_free_op,
+		wlan_objmgr_ref_dbgid dbg_id);
+
 /**
  * wlan_objmgr_free_all_objects_per_psoc() - free all psoc objects
  * @psoc: PSOC object

+ 82 - 3
umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c

@@ -464,6 +464,85 @@ QDF_STATUS wlan_objmgr_iterate_obj_list(
 }
 EXPORT_SYMBOL(wlan_objmgr_iterate_obj_list);
 
+QDF_STATUS wlan_objmgr_iterate_obj_list_all(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_objmgr_obj_type obj_type,
+		wlan_objmgr_op_handler handler,
+		void *arg, uint8_t lock_free_op,
+		wlan_objmgr_ref_dbgid dbg_id)
+{
+	uint16_t obj_id;
+	uint8_t i;
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	struct wlan_peer_list *peer_list;
+	qdf_list_t *obj_list;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_peer *peer;
+	struct wlan_objmgr_peer *peer_next;
+
+	/* If caller requests for lock free opeation, do not acquire,
+	 * handler will handle the synchronization
+	 */
+	if (!lock_free_op)
+		wlan_psoc_obj_lock(psoc);
+
+	switch (obj_type) {
+	case WLAN_PDEV_OP:
+		/* Iterate through PDEV list, invoke handler for each pdev */
+		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
+			pdev = objmgr->wlan_pdev_list[obj_id];
+			if (pdev != NULL) {
+				wlan_objmgr_pdev_get_ref(pdev, dbg_id);
+				handler(psoc, (void *)pdev, arg);
+				wlan_objmgr_pdev_release_ref(pdev, dbg_id);
+			}
+		}
+		break;
+	case WLAN_VDEV_OP:
+		/* Iterate through VDEV list, invoke handler for each vdev */
+		for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) {
+			vdev = objmgr->wlan_vdev_list[obj_id];
+			if (vdev != NULL) {
+				wlan_objmgr_vdev_get_ref(vdev, dbg_id);
+				handler(psoc, vdev, arg);
+				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
+			}
+		}
+		break;
+	case WLAN_PEER_OP:
+		/* Iterate through PEER list, invoke handler for each peer */
+		peer_list = &objmgr->peer_list;
+		/* psoc lock should be taken before list lock */
+		if (!lock_free_op)
+			qdf_spin_lock_bh(&peer_list->peer_list_lock);
+		/* Since peer list has sublist, iterate through sublists */
+		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
+			obj_list = &peer_list->peer_hash[i];
+			peer = wlan_psoc_peer_list_peek_head(obj_list);
+			while (peer) {
+				/* Get next peer */
+				peer_next = wlan_peer_get_next_peer_of_psoc(
+								obj_list, peer);
+				wlan_objmgr_peer_get_ref(peer, dbg_id);
+				handler(psoc, (void *)peer, arg);
+				wlan_objmgr_peer_release_ref(peer, dbg_id);
+				peer = peer_next;
+			}
+		}
+		if (!lock_free_op)
+			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
+		break;
+	default:
+		break;
+	}
+	if (!lock_free_op)
+		wlan_psoc_obj_unlock(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_iterate_obj_list_all);
+
 static void wlan_objmgr_psoc_peer_delete(struct wlan_objmgr_psoc *psoc,
 					 void *obj, void *args)
 {
@@ -1617,15 +1696,15 @@ QDF_STATUS wlan_objmgr_print_ref_all_objects_per_psoc(
 		struct wlan_objmgr_psoc *psoc)
 {
 	qdf_print(" Ref counts of PEER\n");
-	wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
+	wlan_objmgr_iterate_obj_list_all(psoc, WLAN_PEER_OP,
 				     wlan_objmgr_psoc_peer_ref_print, NULL, 1,
 				     WLAN_OBJMGR_ID);
 	qdf_print(" Ref counts of VDEV\n");
-	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
+	wlan_objmgr_iterate_obj_list_all(psoc, WLAN_VDEV_OP,
 				     wlan_objmgr_psoc_vdev_ref_print, NULL, 1,
 				     WLAN_OBJMGR_ID);
 	qdf_print(" Ref counts of PDEV\n");
-	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
+	wlan_objmgr_iterate_obj_list_all(psoc, WLAN_PDEV_OP,
 				     wlan_objmgr_psoc_pdev_ref_print, NULL, 1,
 				     WLAN_OBJMGR_ID);