Browse Source

qcacld-3.0: Change wow event API's to accept wow event types

Current ucfg API's that disables wow events accept a u32 bitmap
variable. A pointer to that variable is passed to core API where
it assumes it as a u32 array of 4 bytes. This will lead to out of
bound memory access.

Change wow enable/disable API's to accept wow event type as the
parameter.

Change-Id: I220aaddfea62ab96f121014d0d65a1406988c946
CRs-Fixed: 2233108
Nachiket Kukade 6 years ago
parent
commit
107f639cce

+ 6 - 4
components/pmo/core/inc/wlan_pmo_wow.h

@@ -325,23 +325,25 @@ QDF_STATUS pmo_core_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
  * pmo_core_enable_wakeup_event() -  enable wow wakeup events
  * @psoc: objmgr psoc
  * @vdev_id: vdev id
- * @bitmap: Event bitmap
+ * @wow_event: wow event to enable
  *
  * Return: none
  */
 void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
-	uint32_t vdev_id, uint32_t *bitmap);
+				  uint32_t vdev_id,
+				  WOW_WAKE_EVENT_TYPE wow_event);
 
 /**
  * pmo_core_disable_wakeup_event() -  disable wow wakeup events
  * @psoc: objmgr psoc
  * @vdev_id: vdev id
- * @bitmap: Event bitmap
+ * @wow_event: wow event to disable
  *
  * Return: none
  */
 void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
-	uint32_t vdev_id, uint32_t *bitmap);
+				   uint32_t vdev_id,
+				   WOW_WAKE_EVENT_TYPE wow_event);
 
 /**
  * pmo_is_wow_applicable(): should enable wow

+ 0 - 4
components/pmo/core/src/wlan_pmo_static_config.c

@@ -102,10 +102,6 @@ void pmo_register_wow_wakeup_events(struct wlan_objmgr_vdev *vdev)
 		return;
 	}
 
-	pmo_info("Selected %s wake event mask 0x%x%x%x%x, vdev %d",
-		 iface_type, event_bitmap[0], event_bitmap[1],
-		 event_bitmap[2], event_bitmap[3], vdev_id);
-
 	pmo_tgt_enable_wow_wakeup_event(vdev, event_bitmap);
 }
 

+ 10 - 14
components/pmo/core/src/wlan_pmo_suspend_resume.c

@@ -250,7 +250,7 @@ void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc)
 							 BM_LEN,
 							 disable_mask);
 				disable_configured = true;
-		}
+			}
 		}
 
 		adapter_type = pmo_get_vdev_opmode(vdev);
@@ -258,26 +258,22 @@ void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc)
 		psoc_ctx = pmo_psoc_get_priv(psoc);
 
 		if (psoc_ctx->psoc_cfg.auto_power_save_fail_mode ==
-		     PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE &&
+		    PMO_FW_TO_SEND_WOW_IND_ON_PWR_FAILURE &&
 		    (adapter_type == QDF_STA_MODE ||
-		     adapter_type == QDF_P2P_CLIENT_MODE)
-		   ) {
+		     adapter_type == QDF_P2P_CLIENT_MODE)) {
 			if (psoc_ctx->is_device_in_low_pwr_mode &&
-				psoc_ctx->is_device_in_low_pwr_mode(vdev_id))
+			    psoc_ctx->is_device_in_low_pwr_mode(vdev_id)) {
 				pmo_set_wow_event_bitmap(EV_PWR,
-						 BM_LEN,
-						 enable_mask);
-			pmo_core_enable_wakeup_event(psoc, vdev_id,
-				enable_mask);
+							 BM_LEN,
+							 enable_mask);
 				enable_configured = true;
+			}
 		}
-		if (enable_configured)
-			pmo_core_enable_wakeup_event(psoc, vdev_id,
-				enable_mask);
 
+		if (enable_configured)
+			pmo_tgt_enable_wow_wakeup_event(vdev, enable_mask);
 		if (disable_configured)
-			pmo_core_disable_wakeup_event(psoc, vdev_id,
-					disable_mask);
+			pmo_tgt_disable_wow_wakeup_event(vdev, disable_mask);
 	}
 
 }

+ 25 - 24
components/pmo/core/src/wlan_pmo_wow.c

@@ -27,6 +27,21 @@
 #include "wlan_pmo_static_config.h"
 #include "wlan_reg_services_api.h"
 
+void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event,
+			      uint32_t wow_bitmap_size,
+			      uint32_t *bitmask)
+{
+	uint32_t bit_idx = 0, idx = 0;
+
+	if (!bitmask || wow_bitmap_size < PMO_WOW_MAX_EVENT_BM_LEN) {
+		pmo_err("wow bitmask length shorter than %d",
+			PMO_WOW_MAX_EVENT_BM_LEN);
+		return;
+	}
+	pmo_get_event_bitmap_idx(event, wow_bitmap_size, &bit_idx, &idx);
+	bitmask[idx] |= 1 << bit_idx;
+}
+
 QDF_STATUS pmo_core_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev,
 		struct pmo_wow_add_pattern *ptrn)
 {
@@ -128,10 +143,12 @@ out:
 }
 
 void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
-				  uint32_t vdev_id, uint32_t *bitmap)
+				  uint32_t vdev_id,
+				  WOW_WAKE_EVENT_TYPE wow_event)
 {
 	QDF_STATUS status;
 	struct wlan_objmgr_vdev *vdev;
+	uint32_t bitmap[PMO_WOW_MAX_EVENT_BM_LEN] = {0};
 
 	pmo_enter();
 
@@ -150,8 +167,8 @@ void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
 	if (QDF_IS_STATUS_ERROR(status))
 		goto out;
 
-	pmo_info("enable wakeup event vdev_id %d wake up event 0x%x%x%x%x",
-		 vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]);
+	pmo_set_wow_event_bitmap(wow_event, PMO_WOW_MAX_EVENT_BM_LEN, bitmap);
+
 	pmo_tgt_enable_wow_wakeup_event(vdev, bitmap);
 
 	pmo_vdev_put_ref(vdev);
@@ -161,10 +178,12 @@ out:
 }
 
 void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
-	uint32_t vdev_id, uint32_t *bitmap)
+				   uint32_t vdev_id,
+				   WOW_WAKE_EVENT_TYPE wow_event)
 {
 	QDF_STATUS status;
 	struct wlan_objmgr_vdev *vdev;
+	uint32_t bitmap[PMO_WOW_MAX_EVENT_BM_LEN] = {0};
 
 	pmo_enter();
 	if (!psoc) {
@@ -182,8 +201,8 @@ void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
 	if (QDF_IS_STATUS_ERROR(status))
 		goto out;
 
-	pmo_info("Disable wakeup event vdev_id %d wake up event 0x%x%x%x%x",
-		 vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]);
+	pmo_set_wow_event_bitmap(wow_event, PMO_WOW_MAX_EVENT_BM_LEN, bitmap);
+
 	pmo_tgt_disable_wow_wakeup_event(vdev, bitmap);
 
 	pmo_vdev_put_ref(vdev);
@@ -317,24 +336,6 @@ bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc)
 	return false;
 }
 
-void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event,
-			      uint32_t wow_bitmap_size,
-			      uint32_t *bitmask)
-{
-	uint32_t bit_idx = 0, idx = 0;
-
-	if (!bitmask || wow_bitmap_size < PMO_WOW_MAX_EVENT_BM_LEN) {
-		pmo_err("wow bitmask length shorter than %d",
-			PMO_WOW_MAX_EVENT_BM_LEN);
-		return;
-	}
-	pmo_get_event_bitmap_idx(event, wow_bitmap_size, &bit_idx, &idx);
-	bitmask[idx] |= 1 << bit_idx;
-
-	pmo_debug("%s: bitmask updated %x%x%x%x",
-		  __func__, bitmask[0], bitmask[1], bitmask[2], bitmask[3]);
-}
-
 void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
 {
 

+ 6 - 4
components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h

@@ -122,23 +122,25 @@ QDF_STATUS ucfg_pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc,
  * pmo_ucfg_enable_wakeup_event() -  enable wow wakeup events
  * @psoc: objmgr psoc
  * @vdev_id: vdev id
- * @bitmap: Event bitmap
+ * @wow_event: wow event to enable
  *
  * Return: none
  */
 void pmo_ucfg_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
-	uint32_t vdev_id, uint32_t *bitmap);
+				  uint32_t vdev_id,
+				  WOW_WAKE_EVENT_TYPE wow_event);
 
 /**
  * pmo_ucfg_disable_wakeup_event() -  disable wow wakeup events
  * @psoc: objmgr psoc
  * @vdev_id: vdev id
- * @bitmap: Event bitmap
+ * @wow_event: wow event to disable
  *
  * Return: none
  */
 void pmo_ucfg_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
-	uint32_t vdev_id, uint32_t bitmap);
+				   uint32_t vdev_id,
+				   WOW_WAKE_EVENT_TYPE wow_event);
 
 /**
  * pmo_ucfg_cache_arp_offload_req(): API to cache arp req in pmo vdev priv ctx

+ 12 - 0
components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c

@@ -32,10 +32,12 @@ QDF_STATUS pmo_tgt_enable_wow_wakeup_event(
 	QDF_STATUS status;
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_pmo_tx_ops pmo_tx_ops;
+	int vdev_id;
 
 	pmo_enter();
 
 	psoc = pmo_vdev_get_psoc(vdev);
+	vdev_id = pmo_vdev_get_id(vdev);
 
 	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
 	if (!pmo_tx_ops.send_enable_wow_wakeup_event_req) {
@@ -43,6 +45,10 @@ QDF_STATUS pmo_tgt_enable_wow_wakeup_event(
 		status = QDF_STATUS_E_NULL_VALUE;
 		goto out;
 	}
+
+	pmo_debug("Enable wakeup events 0x%x%x%x%x for vdev_id %d",
+		  bitmap[3], bitmap[2], bitmap[1], bitmap[0], vdev_id);
+
 	status = pmo_tx_ops.send_enable_wow_wakeup_event_req(vdev, bitmap);
 	if (status != QDF_STATUS_SUCCESS)
 		pmo_err("Failed to enable wow wakeup event");
@@ -59,10 +65,12 @@ QDF_STATUS pmo_tgt_disable_wow_wakeup_event(
 	QDF_STATUS status;
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_pmo_tx_ops pmo_tx_ops;
+	int vdev_id;
 
 	pmo_enter();
 
 	psoc = pmo_vdev_get_psoc(vdev);
+	vdev_id = pmo_vdev_get_id(vdev);
 
 	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
 	if (!pmo_tx_ops.send_disable_wow_wakeup_event_req) {
@@ -70,6 +78,10 @@ QDF_STATUS pmo_tgt_disable_wow_wakeup_event(
 		status = QDF_STATUS_E_NULL_VALUE;
 		goto out;
 	}
+
+	pmo_debug("Disable wakeup events 0x%x%x%x%x for vdev_id %d",
+		  bitmap[3], bitmap[2], bitmap[1], bitmap[0], vdev_id);
+
 	status = pmo_tx_ops.send_disable_wow_wakeup_event_req(vdev, bitmap);
 	if (status != QDF_STATUS_SUCCESS)
 		pmo_err("Failed to disable wow wakeup event");

+ 4 - 4
components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c

@@ -104,15 +104,15 @@ bool ucfg_pmo_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
 }
 
 void pmo_ucfg_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
-	uint32_t vdev_id, uint32_t *bitmap)
+	uint32_t vdev_id, WOW_WAKE_EVENT_TYPE wow_event)
 {
-	pmo_core_enable_wakeup_event(psoc, vdev_id, bitmap);
+	pmo_core_enable_wakeup_event(psoc, vdev_id, wow_event);
 }
 
 void pmo_ucfg_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
-	uint32_t vdev_id, uint32_t bitmap)
+	uint32_t vdev_id, WOW_WAKE_EVENT_TYPE wow_event)
 {
-	pmo_core_disable_wakeup_event(psoc, vdev_id, &bitmap);
+	pmo_core_disable_wakeup_event(psoc, vdev_id, wow_event);
 }
 
 QDF_STATUS pmo_ucfg_cache_arp_offload_req(struct pmo_arp_req *arp_req)

+ 1 - 1
core/wma/src/wma_dev_if.c

@@ -3775,7 +3775,7 @@ static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss)
 	}
 	if (SAP_WPS_DISABLED == add_bss->wps_state)
 		pmo_ucfg_disable_wakeup_event(wma->psoc, vdev_id,
-			(1 << WOW_PROBE_REQ_WPS_IE_EVENT));
+					      WOW_PROBE_REQ_WPS_IE_EVENT);
 	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
 	status = wma_create_peer(wma, pdev, vdev, add_bss->bssId,
 				 WMI_PEER_TYPE_DEFAULT, vdev_id, false);