Ver Fonte

qcacld-3.0: Add checks to NS and ARP offload requests

Currently the offloading of the NS and ARP to firmware is inefficient;
redundant caching is performed even if offload is not sent. This causes
wastage of resources and increases code complexity.

Introduce checks before caching and offload to ensure that the mentioned
inefficiencies are taken care of.

Change-Id: I6013810e1e08adb15c801f4fc21e1b50371bacda
CRs-Fixed: 2569763
Sourav Mohapatra há 5 anos atrás
pai
commit
60c3b2b014

+ 13 - 1
components/pmo/core/inc/wlan_pmo_arp.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-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
@@ -36,6 +36,18 @@
  */
 QDF_STATUS pmo_core_cache_arp_offload_req(struct pmo_arp_req *arp_req);
 
+/**
+ * pmo_core_arp_check_offload(): API to check if arp offload cache/send is req
+ * @psoc: objmgr psoc handle
+ * @trigger: trigger reason
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_arp_check_offload(struct wlan_objmgr_psoc *psoc,
+				      enum pmo_offload_trigger trigger,
+				      uint8_t vdev_id);
+
 /**
  * pmo_core_flush_arp_offload_req() - API to flush arp req from pmo vdev ctx
  * @vdev: objmgr vdev

+ 13 - 1
components/pmo/core/inc/wlan_pmo_ns.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-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
@@ -37,6 +37,18 @@
  */
 QDF_STATUS pmo_core_cache_ns_offload_req(struct pmo_ns_req *ns_req);
 
+/**
+ * pmo_core_ns_check_offload() - API to check if offload cache/send is required
+ * @psoc: objmgr psoc handle
+ * @trigger: trigger reason enable ns offload
+ * @vdev_id: vdev id
+ *
+ * Return:QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_ns_check_offload(struct wlan_objmgr_psoc *psoc,
+				     enum pmo_offload_trigger trigger,
+				     uint8_t vdev_id);
+
 /**
  * pmo_core_flush_ns_offload_req() - API to flush ns req from pmo vdev priv ctx
  * @vdev: vdev objmgr handle

+ 45 - 12
components/pmo/core/src/wlan_pmo_arp.c

@@ -134,12 +134,6 @@ pmo_core_do_enable_arp_offload(struct wlan_objmgr_vdev *vdev,
 		status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
 		break;
 	case pmo_apps_suspend:
-		if (psoc_ctx->psoc_cfg.active_mode_offload) {
-			pmo_debug("active offload is enabled, skip in mode %d",
-				  trigger);
-			status = QDF_STATUS_SUCCESS;
-			goto out;
-		}
 		/* enable arp when active offload is false (apps suspend) */
 		status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
 		break;
@@ -174,12 +168,6 @@ static QDF_STATUS pmo_core_do_disable_arp_offload(struct wlan_objmgr_vdev *vdev,
 
 	switch (trigger) {
 	case pmo_apps_resume:
-		if (psoc_ctx->psoc_cfg.active_mode_offload) {
-			pmo_debug("active offload is enabled, skip in mode: %d",
-				trigger);
-			status = QDF_STATUS_SUCCESS;
-			goto out;
-		}
 		/* disable arp on apps resume when active offload is disable */
 		status = pmo_tgt_disable_arp_offload_req(vdev, vdev_id);
 		break;
@@ -222,6 +210,51 @@ static QDF_STATUS pmo_core_arp_offload_sanity(
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS pmo_core_arp_check_offload(struct wlan_objmgr_psoc *psoc,
+				      enum pmo_offload_trigger trigger,
+				      uint8_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	bool active_offload_cond, is_applied_cond;
+
+	pmo_enter();
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+
+	if (trigger == pmo_apps_suspend || trigger == pmo_apps_resume) {
+		active_offload_cond = psoc_ctx->psoc_cfg.active_mode_offload;
+
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		is_applied_cond = vdev_ctx->vdev_arp_req.enable &&
+				  vdev_ctx->vdev_arp_req.is_offload_applied;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+		if (active_offload_cond && is_applied_cond) {
+			pmo_debug("active offload is enabled and offload already sent");
+			pmo_vdev_put_ref(vdev);
+			return QDF_STATUS_E_INVAL;
+		}
+	}
+	pmo_vdev_put_ref(vdev);
+out:
+	return status;
+}
+
 QDF_STATUS pmo_core_cache_arp_offload_req(struct pmo_arp_req *arp_req)
 {
 	QDF_STATUS status;

+ 46 - 13
components/pmo/core/src/wlan_pmo_ns.c

@@ -170,11 +170,6 @@ static QDF_STATUS pmo_core_do_enable_ns_offload(struct wlan_objmgr_vdev *vdev,
 		status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
 		break;
 	case pmo_apps_suspend:
-		if (psoc_ctx->psoc_cfg.active_mode_offload) {
-			pmo_debug("active offload is enabled, skip in mode: %d",
-				  trigger);
-			goto out;
-		}
 		/* enable arp when active offload is false (apps suspend) */
 		status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
 		break;
@@ -211,12 +206,6 @@ static QDF_STATUS pmo_core_do_disable_ns_offload(struct wlan_objmgr_vdev *vdev,
 		status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
 		break;
 	case pmo_apps_resume:
-		if (psoc_ctx->psoc_cfg.active_mode_offload) {
-			pmo_debug("active offload is enabled, skip in mode: %d",
-				  trigger);
-			goto out;
-		}
-		/* config arp/ns when active offload is disable */
 		status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
 		break;
 	default:
@@ -259,8 +248,52 @@ static QDF_STATUS pmo_core_ns_offload_sanity(struct wlan_objmgr_vdev *vdev)
 	return QDF_STATUS_SUCCESS;
 }
 
-QDF_STATUS pmo_core_cache_ns_offload_req(
-		struct pmo_ns_req *ns_req)
+QDF_STATUS pmo_core_ns_check_offload(struct wlan_objmgr_psoc *psoc,
+				     enum pmo_offload_trigger trigger,
+				     uint8_t vdev_id)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_objmgr_vdev *vdev;
+	bool active_offload_cond, is_applied_cond;
+
+	pmo_enter();
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+
+	if (trigger == pmo_apps_suspend || trigger == pmo_apps_resume) {
+		active_offload_cond = psoc_ctx->psoc_cfg.active_mode_offload;
+
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		is_applied_cond = vdev_ctx->vdev_ns_req.enable &&
+			       vdev_ctx->vdev_ns_req.is_offload_applied;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+		if (active_offload_cond && is_applied_cond) {
+			pmo_debug("active offload is enabled and offload already sent");
+			pmo_vdev_put_ref(vdev);
+			return QDF_STATUS_E_INVAL;
+		}
+	}
+	pmo_vdev_put_ref(vdev);
+out:
+	return status;
+}
+
+QDF_STATUS pmo_core_cache_ns_offload_req(struct pmo_ns_req *ns_req)
 {
 	QDF_STATUS status;
 	struct wlan_objmgr_vdev *vdev;

+ 39 - 0
components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h

@@ -290,6 +290,18 @@ void ucfg_pmo_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
  */
 QDF_STATUS ucfg_pmo_cache_arp_offload_req(struct pmo_arp_req *arp_req);
 
+/**
+ * ucfg_pmo_check_arp_offload(): API to check if arp offload cache/send is req
+ * @psoc: objmgr psoc handle
+ * @trigger: trigger reason
+ * @vdev_id: vdev_id
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS ucfg_pmo_check_arp_offload(struct wlan_objmgr_psoc *psoc,
+				      enum pmo_offload_trigger trigger,
+				      uint8_t vdev_id);
+
 /**
  * ucfg_pmo_flush_arp_offload_req(): API to flush arp req from pmo vdev priv ctx
  * @vdev: objmgr vdev param
@@ -342,6 +354,18 @@ ucfg_pmo_get_arp_offload_params(struct wlan_objmgr_vdev *vdev,
  */
 QDF_STATUS ucfg_pmo_cache_ns_offload_req(struct pmo_ns_req *ns_req);
 
+/**
+ * ucfg_pmo_ns_offload_check(): API to check if offload cache/send is required
+ * @psoc: pbjmgr psoc handle
+ * @trigger: trigger reason to enable ns offload
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS ucfg_pmo_ns_offload_check(struct wlan_objmgr_psoc *psoc,
+				     enum pmo_offload_trigger trigger,
+				     uint8_t vdev_id);
+
 /**
  * ucfg_pmo_flush_ns_offload_req(): API to flush ns req from pmo vdev priv ctx
  * @vdev: vdev ojbmgr handle
@@ -1171,6 +1195,14 @@ ucfg_pmo_cache_arp_offload_req(struct pmo_arp_req *arp_req)
 	return QDF_STATUS_SUCCESS;
 }
 
+static inline
+QDF_STATUS ucfg_pmo_check_arp_offload(struct wlan_objmgr_psoc *psoc,
+				      enum pmo_offload_trigger trigger,
+				      uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 static inline QDF_STATUS
 ucfg_pmo_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev)
 {
@@ -1206,6 +1238,13 @@ ucfg_pmo_cache_ns_offload_req(struct pmo_ns_req *ns_req)
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS ucfg_pmo_ns_offload_check(struct wlan_objmgr_psoc *psoc,
+				     enum pmo_offload_trigger trigger,
+				     uint8_t vdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 static inline QDF_STATUS
 ucfg_pmo_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev)
 {

+ 14 - 0
components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c

@@ -129,6 +129,13 @@ QDF_STATUS ucfg_pmo_cache_arp_offload_req(struct pmo_arp_req *arp_req)
 	return pmo_core_cache_arp_offload_req(arp_req);
 }
 
+QDF_STATUS ucfg_pmo_check_arp_offload(struct wlan_objmgr_psoc *psoc,
+				      enum pmo_offload_trigger trigger,
+				      uint8_t vdev_id)
+{
+	return pmo_core_arp_check_offload(psoc, trigger, vdev_id);
+}
+
 QDF_STATUS ucfg_pmo_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev)
 {
 	return pmo_core_flush_arp_offload_req(vdev);
@@ -160,6 +167,13 @@ QDF_STATUS ucfg_pmo_cache_ns_offload_req(struct pmo_ns_req *ns_req)
 	return pmo_core_cache_ns_offload_req(ns_req);
 }
 
+QDF_STATUS ucfg_pmo_ns_offload_check(struct wlan_objmgr_psoc *psoc,
+				     enum pmo_offload_trigger trigger,
+				     uint8_t vdev_id)
+{
+	return pmo_core_ns_check_offload(psoc, trigger, vdev_id);
+}
+
 QDF_STATUS ucfg_pmo_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev)
 {
 	return pmo_core_flush_ns_offload_req(vdev);

+ 31 - 0
core/hdd/src/wlan_hdd_power.c

@@ -403,6 +403,13 @@ void hdd_enable_ns_offload(struct hdd_adapter *adapter,
 	ns_req->trigger = trigger;
 	ns_req->count = 0;
 
+	/* check if offload cache and send is required or not */
+	status = ucfg_pmo_ns_offload_check(psoc, trigger, adapter->vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_info("NS offload is not required");
+		goto free_req;
+	}
+
 	/* Unicast Addresses */
 	errno = hdd_fill_ipv6_uc_addr(in6_dev, ns_req->ipv6_addr,
 				      ns_req->ipv6_addr_type, ns_req->scope,
@@ -450,8 +457,17 @@ void hdd_disable_ns_offload(struct hdd_adapter *adapter,
 		enum pmo_offload_trigger trigger)
 {
 	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
 	hdd_enter();
+
+	status = ucfg_pmo_ns_offload_check(hdd_ctx->psoc, trigger,
+					   adapter->vdev_id);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Flushing of NS offload not required");
+		goto out;
+	}
+
 	status = ucfg_pmo_flush_ns_offload_req(adapter->vdev);
 	if (status != QDF_STATUS_SUCCESS) {
 		hdd_err("Failed to flush NS Offload");
@@ -938,6 +954,12 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter,
 	arp_req->vdev_id = adapter->vdev_id;
 	arp_req->trigger = trigger;
 
+	status = ucfg_pmo_check_arp_offload(psoc, trigger, adapter->vdev_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		hdd_info("ARP offload not required");
+		goto free_req;
+	}
+
 	ifa = hdd_get_ipv4_local_interface(adapter);
 	if (!ifa || !ifa->ifa_local) {
 		hdd_info("IP Address is not assigned");
@@ -972,8 +994,17 @@ void hdd_disable_arp_offload(struct hdd_adapter *adapter,
 		enum pmo_offload_trigger trigger)
 {
 	QDF_STATUS status;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
 	hdd_enter();
+
+	status = ucfg_pmo_check_arp_offload(hdd_ctx->psoc, trigger,
+					    adapter->vdev_id);
+	if (status != QDF_STATUS_SUCCESS) {
+		hdd_err("Flushing of ARP offload not required");
+		goto out;
+	}
+
 	status = ucfg_pmo_flush_arp_offload_req(adapter->vdev);
 	if (status != QDF_STATUS_SUCCESS) {
 		hdd_err("Failed to flush arp Offload");