Parcourir la source

qcacmn: Add API to validate umac_cmd in serialization command

Since umac cmd is specific to the module adding cmd to serialization
queue, an API is needed to validate the umac_cmd associated with that
serialization context holding the serialization queue lock.

Change-Id: Iadb4deb17ffabd780432a29e7cbd37024fd431fe
CRs-Fixed: 2430764
Santosh Anbu il y a 6 ans
Parent
commit
a3d6f77c62

+ 29 - 1
umac/cmn_services/serialization/inc/wlan_serialization_api.h

@@ -145,6 +145,18 @@ typedef bool (*wlan_serialization_apply_rules_cb)(
 		union wlan_serialization_rules_info *comp_info,
 		uint8_t comp_id);
 
+/**
+ * wlan_ser_umac_cmd_cb() - callback to validate umac_cmd
+ * @umac_cmd: umac data associated with the serialization cmd
+ *
+ * This callback can be called at run time for a command in active queue to
+ * fetch the required information from the umac cmd data stored in serialization
+ * command buffer.
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE
+ */
+typedef QDF_STATUS (*wlan_ser_umac_cmd_cb)(void *umac_cmd);
+
 /**
  * enum wlan_umac_cmd_id - Command Type
  * @WLAN_SER_CMD_SCAN:     Scan command
@@ -565,7 +577,7 @@ enum wlan_serialization_cmd_type
 wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev);
 
 /**
- * wlan_ser_get_cmd_activation_status - Return active command status
+ * wlan_ser_get_cmd_activation_status() - Return active command status
  * @vdev: vdev object
  *
  * This API fetches active command state in the vdev active queue
@@ -576,4 +588,20 @@ wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev);
 QDF_STATUS
 wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev);
 
+/**
+ * wlan_ser_validate_umac_cmd() - validate umac cmd data
+ * @vdev: objmgr vdev pointer
+ * @cmd_type: cmd type to match
+ * @umac_cmd_cb: Callback to be called to validate the data
+ *
+ * This API returns the validation status of the umac cmd cb.
+ * The umac_cmd_cb callback is called with serialization lock held, and hence
+ * only atomic operations are allowed in the callback.
+ *
+ * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS
+wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev,
+			   enum wlan_serialization_cmd_type cmd_type,
+			   wlan_ser_umac_cmd_cb umac_cmd_cb);
 #endif

+ 57 - 0
umac/cmn_services/serialization/src/wlan_serialization_api.c

@@ -724,3 +724,60 @@ wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev)
 
 	return status;
 }
+
+QDF_STATUS
+wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev,
+			   enum wlan_serialization_cmd_type cmd_type,
+			   wlan_ser_umac_cmd_cb umac_cmd_cb)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_ser_pdev_obj *ser_pdev_obj;
+	struct wlan_serialization_command_list *cmd_list = NULL;
+	void *umac_cmd = NULL;
+	qdf_list_node_t *node = NULL;
+	qdf_list_t *queue;
+	struct wlan_serialization_pdev_queue *pdev_q;
+	QDF_STATUS status = QDF_STATUS_E_INVAL;
+
+	ser_enter();
+
+	if (!vdev) {
+		ser_err("invalid vdev");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		ser_err("invalid pdev");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
+	if (!ser_pdev_obj) {
+		ser_err("invalid ser_pdev_obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type);
+
+	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
+
+	queue = &pdev_q->active_list;
+	node = wlan_serialization_find_cmd(
+			queue, WLAN_SER_MATCH_CMD_TYPE_VDEV,
+			NULL, cmd_type, NULL, vdev,  WLAN_SER_PDEV_NODE);
+	if (node) {
+		cmd_list = qdf_container_of(
+				node,
+				struct wlan_serialization_command_list,
+				pdev_node);
+
+		umac_cmd = cmd_list->cmd.umac_cmd;
+		status = umac_cmd_cb(umac_cmd);
+	}
+
+	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
+	ser_exit();
+
+	return status;
+}