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

qcacmn: Define Peer free notification framework

Define framework to notify registered callbacks on peer freed.
Interested modules can register their callbacks with object manager.

Change-Id: I9ab0e45f7841b1609b9ada3b50335299b462b630
CRs-Fixed: 2578099
Srinivas Pitla 6 жил өмнө
parent
commit
8e869fff23

+ 3 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h

@@ -174,6 +174,9 @@ typedef QDF_STATUS (*wlan_objmgr_vdev_destroy_handler)(
 typedef void (*wlan_objmgr_vdev_status_handler)(
 				struct wlan_objmgr_vdev *vdev, void *arg,
 						QDF_STATUS status);
+typedef void (*wlan_objmgr_vdev_peer_free_notify_handler)(
+				struct wlan_objmgr_vdev *vdev);
+
 
 typedef QDF_STATUS (*wlan_objmgr_peer_create_handler)(
 				struct wlan_objmgr_peer *peer, void *arg);

+ 33 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_global_obj.h

@@ -374,6 +374,39 @@ QDF_STATUS wlan_objmgr_unregister_vdev_status_handler(
 		wlan_objmgr_vdev_status_handler handler,
 		void *args);
 
+/**
+ * wlan_objmgr_register_vdev_peer_free_notify_handler() - register vdev peer
+ *                                                        free handler
+ * @id: component id
+ * @handler: function pointer of the component
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on VDEV Peer gets freed
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_vdev_peer_free_notify_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_peer_free_notify_handler handler);
+
+/**
+ * wlan_objmgr_unregister_vdev_peer_free_notify_handler() - unregister vdev
+ *                                                          peer free handler
+ * @id: component id
+ * @handler: function pointer of the component
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_vdev_peer_free_notify_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_peer_free_notify_handler handler);
+
 /**
  * wlan_objmgr_register_peer_create_handler() - register peer create handler
  * @id: component id

+ 10 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h

@@ -1293,6 +1293,16 @@ QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev,
 void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev,
 						wlan_objmgr_ref_dbgid id);
 
+/**
+ * wlan_objmgr_vdev_peer_freed_notify() - Notifies modules about peer freed
+ * @vdev: VDEV object
+ *
+ * API to invokes registered callbacks to notify about peer freed
+ *
+ * Return: void
+ */
+void wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev *vdev);
+
 /**
  * wlan_vdev_set_max_peer_count() - set max peer count
  * @vdev: VDEV object

+ 49 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj.c

@@ -556,6 +556,55 @@ QDF_STATUS wlan_objmgr_unregister_vdev_status_handler(
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS wlan_objmgr_register_vdev_peer_free_notify_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_peer_free_notify_handler handler)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		obj_mgr_err("Component %d is out of range", id);
+		WLAN_OBJMGR_BUG(0);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->vdev_peer_free_notify_handler[id]) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		obj_mgr_err("Callback for comp %d is already registered", id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler in Global object table */
+	g_umac_glb_obj->vdev_peer_free_notify_handler[id] = handler;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_vdev_peer_free_notify_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_peer_free_notify_handler handler)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		obj_mgr_err("Component %d is out of range", id);
+		WLAN_OBJMGR_BUG(0);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->vdev_peer_free_notify_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		obj_mgr_err("Callback for Component %d is not registered", id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers to NULL */
+	g_umac_glb_obj->vdev_peer_free_notify_handler[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
 
 QDF_STATUS wlan_objmgr_register_peer_create_handler(
 		enum wlan_umac_comp_id id,

+ 4 - 1
umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj_i.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019 The Linux Foundation. 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
@@ -44,6 +44,7 @@ struct wlan_objmgr_debug_info;
  *  @vdev_create_handler_arg[]: VDEV create handler args array
  *  @vdev_destroy_handler[]:     VDEV destroy handler array
  *  @vdev_destroy_handler_arg[]: VDEV destroy handler args array
+ *  @vdev_peer_free_notify_handler[]: VDEV peer free notify handler array
  *  @vdev_status_handler[]:     VDEV status handler array
  *  @vdev_status_handler_arg[]: VDEV status handler args array
  *  @peer_create_handler[]:     PEER create handler array
@@ -81,6 +82,8 @@ struct wlan_objmgr_global {
 	wlan_objmgr_vdev_destroy_handler
 		vdev_destroy_handler[WLAN_UMAC_MAX_COMPONENTS];
 	void *vdev_destroy_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_vdev_peer_free_notify_handler
+		vdev_peer_free_notify_handler[WLAN_UMAC_MAX_COMPONENTS];
 	wlan_objmgr_vdev_status_handler
 		vdev_status_handler[WLAN_UMAC_MAX_COMPONENTS];
 	void *vdev_status_handler_arg[WLAN_UMAC_MAX_COMPONENTS];

+ 7 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c

@@ -109,12 +109,15 @@ static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer)
 		wlan_objmgr_peer_release_ref(wlan_vdev_get_bsspeer(vdev),
 					     WLAN_OBJMGR_ID);
 
+	wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
+
 	/* Detach peer from VDEV's peer list */
 	if (wlan_objmgr_vdev_peer_detach(vdev, peer) == QDF_STATUS_E_FAILURE) {
 		obj_mgr_err(
 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) VDEV detach fail, vdev id: %d",
 			macaddr[0], macaddr[1], macaddr[2],
 			macaddr[3], macaddr[4], macaddr[5], vdev_id);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
 		return QDF_STATUS_E_FAILURE;
 	}
 	/* Detach peer from PSOC's peer list */
@@ -123,11 +126,15 @@ static QDF_STATUS wlan_objmgr_peer_obj_free(struct wlan_objmgr_peer *peer)
 		"Peer(%02x:%02x:%02x:%02x:%02x:%02x) PSOC detach failure",
 			macaddr[0], macaddr[1], macaddr[2],
 			macaddr[3], macaddr[4], macaddr[5]);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
 		return QDF_STATUS_E_FAILURE;
 	}
 	qdf_spinlock_destroy(&peer->peer_lock);
 	qdf_mem_free(peer);
 
+	wlan_objmgr_vdev_peer_freed_notify(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
+
 	return QDF_STATUS_SUCCESS;
 
 }

+ 11 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c

@@ -1154,3 +1154,14 @@ void wlan_print_vdev_info(struct wlan_objmgr_vdev *vdev)
 qdf_export_symbol(wlan_print_vdev_info);
 #endif
 
+void wlan_objmgr_vdev_peer_freed_notify(struct wlan_objmgr_vdev *vdev)
+{
+	wlan_objmgr_vdev_peer_free_notify_handler stat_handler;
+	uint8_t i;
+
+	for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+		stat_handler = g_umac_glb_obj->vdev_peer_free_notify_handler[i];
+		if (stat_handler)
+			stat_handler(vdev);
+	}
+}