Переглянути джерело

qcacld-3.0: Send bridge Address in WMI_WOW_ADD_WAKE_PATTERN_CMDID

Currently, in WMI_WOW_ADD_WAKE_PATTERN_CMDID driver sends only SAP mac
address and pattern_id. So, FW does not have bridge mac address.

To fix it, driver will send bridge mac address and pattern_id along
with SAP mac address and pattern_id.

Change-Id: I3fae9f0383a1ba8c64edfa6cf8518ab9a5604a14
CRs-Fixed: 3456318
Deeksha Gupta 2 роки тому
батько
коміт
3ef027a672

+ 25 - 1
components/pmo/core/inc/wlan_pmo_main.h

@@ -110,7 +110,7 @@ QDF_STATUS pmo_psoc_close(struct wlan_objmgr_psoc *psoc);
  * pmo_get_vdev_bss_peer_mac_addr() - API to get bss peer mac address
  * @vdev: objmgr vdev
  * @bss_peer_mac_address: bss peer mac address
- *.
+ *
  * Helper function to  get bss peer mac address
  *
  * Return: if success pmo vdev ctx else NULL
@@ -419,6 +419,30 @@ pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc *psoc);
  */
 uint32_t pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * pmo_get_vdev_bridge_addr() - API to get Bridge mac address
+ * @vdev: vdev object
+ * @bridgeaddr: Bridge mac address
+ *
+ * Helper function to get Bridge mac address
+ *
+ * Return: if success pmo vdev ctx else NULL
+ */
+QDF_STATUS pmo_get_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
+				    struct qdf_mac_addr *bridgeaddr);
+
+/**
+ * pmo_set_vdev_bridge_addr() - API to set Bridge mac address
+ * @vdev: vdev object
+ * @bridgeaddr: Bridge mac address
+ *
+ * API to set the Bridge MAC address
+ *
+ * Return: if success pmo vdev ctx else NULL
+ */
+QDF_STATUS pmo_set_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
+				    struct qdf_mac_addr *bridgeaddr);
+
 #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
 
 #endif /* end  of _WLAN_PMO_MAIN_H_ */

+ 2 - 0
components/pmo/core/inc/wlan_pmo_priv.h

@@ -120,6 +120,7 @@ struct wlan_pmo_ctx {
  * @dyn_arp_ns_offload_disable: true when arp/ns offload is disable
  * @dyn_arp_ns_offload_rt_lock: wake lock which prevent runtime pm happen if
  *                              arp/ns offload is disable
+ * @bridgeaddr: Bridge MAC address
  */
 struct pmo_vdev_priv_obj {
 	struct pmo_psoc_priv_obj *pmo_psoc_ctx;
@@ -148,6 +149,7 @@ struct pmo_vdev_priv_obj {
 	bool dyn_arp_ns_offload_disable;
 	qdf_runtime_lock_t dyn_arp_ns_offload_rt_lock;
 #endif
+	uint8_t bridgeaddr[QDF_MAC_ADDR_SIZE];
 };
 
 #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */

+ 1 - 1
components/pmo/core/inc/wlan_pmo_wow.h

@@ -109,7 +109,7 @@
 #define PMO_WOW_MAX_EVENT_BM_LEN 4
 
 #define PMO_WOW_FILTERS_ARP_NS		2
-#define PMO_WOW_FILTERS_PKT_OR_APF	5
+#define PMO_WOW_FILTERS_PKT_OR_APF	6
 
 /**
  * pmo_get_and_increment_wow_default_ptrn() -Get and increment wow default ptrn

+ 33 - 0
components/pmo/core/src/wlan_pmo_main.c

@@ -540,3 +540,36 @@ uint32_t pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc)
 
 	return pmo_psoc_ctx->psoc_cfg.ssr_frequency_on_pagefault;
 }
+
+QDF_STATUS pmo_get_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
+				    struct qdf_mac_addr *bridgeaddr)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	if (!vdev) {
+		pmo_err("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_mem_copy(bridgeaddr->bytes, vdev_ctx->bridgeaddr,
+		     QDF_MAC_ADDR_SIZE);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_set_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
+				    struct qdf_mac_addr *bridgeaddr)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	if (!vdev) {
+		pmo_err("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_mem_copy(vdev_ctx->bridgeaddr, bridgeaddr->bytes, QDF_MAC_ADDR_SIZE);
+
+	return QDF_STATUS_SUCCESS;
+}

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

@@ -117,6 +117,7 @@ static QDF_STATUS pmo_configure_wow_ap(struct wlan_objmgr_vdev *vdev)
 	QDF_STATUS ret;
 	uint8_t mac_mask[QDF_MAC_ADDR_SIZE];
 	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct qdf_mac_addr bridgeaddr;
 
 	vdev_ctx = pmo_vdev_get_priv(vdev);
 
@@ -136,6 +137,20 @@ static QDF_STATUS pmo_configure_wow_ap(struct wlan_objmgr_vdev *vdev)
 		return ret;
 	}
 
+	/* Setup Bridge MAC address */
+	pmo_get_vdev_bridge_addr(vdev, &bridgeaddr);
+	if (qdf_is_macaddr_zero(&bridgeaddr))
+		return ret;
+
+	ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+			pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+			bridgeaddr.bytes, QDF_MAC_ADDR_SIZE, 0, mac_mask,
+			QDF_MAC_ADDR_SIZE, false);
+	if (ret != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to add Bridge MAC address");
+		return ret;
+	}
+
 	return ret;
 }
 

+ 4 - 2
components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h

@@ -85,6 +85,7 @@ QDF_STATUS pmo_vdev_object_created_notification(struct wlan_objmgr_vdev *vdev,
 /**
  * pmo_vdev_ready() - handles vdev ready in firmware event
  * @vdev: vdev which is ready in firmware
+ * @bridgeaddr: Bridge MAC address
  *
  * Objmgr vdev_create event does not guarantee vdev creation in firmware.
  * Any logic that would normally go in the vdev_create event, but needs to
@@ -92,7 +93,8 @@ QDF_STATUS pmo_vdev_object_created_notification(struct wlan_objmgr_vdev *vdev,
  *
  * Return QDF_STATUS
  */
-QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev);
+QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev,
+			  struct qdf_mac_addr *bridgeaddr);
 
 /**
  * pmo_vdev_object_destroyed_notification(): pmo vdev delete handler
@@ -351,7 +353,7 @@ pmo_vdev_object_created_notification(struct wlan_objmgr_vdev *vdev, void *arg)
 }
 
 static inline QDF_STATUS
-pmo_vdev_ready(struct wlan_objmgr_vdev *vdev)
+pmo_vdev_ready(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bridgeaddr)
 {
 	return QDF_STATUS_SUCCESS;
 }

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

@@ -2383,4 +2383,24 @@ void ucfg_pmo_notify_system_resume(struct wlan_objmgr_psoc *psoc)
 {
 }
 #endif
+
+/**
+ * ucfg_pmo_set_vdev_bridge_addr() - API to set Bridge mac address
+ * @vdev: objmgr vdev
+ * @bridgeaddr: Bridge mac address
+ *
+ * Return: if success pmo vdev ctx else NULL
+ */
+QDF_STATUS ucfg_pmo_set_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
+					 struct qdf_mac_addr *bridgeaddr);
+
+/**
+ * ucfg_pmo_get_vdev_bridge_addr() - API to get Bridge mac address
+ * @vdev: objmgr vdev
+ * @bridgeaddr: Bridge mac address
+ *
+ * Return: if success pmo vdev ctx else NULL
+ */
+QDF_STATUS ucfg_pmo_get_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
+					 struct qdf_mac_addr *bridgeaddr);
 #endif /* end  of _WLAN_PMO_UCFG_API_H_ */

+ 5 - 1
components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c

@@ -292,7 +292,8 @@ out:
 	return QDF_STATUS_SUCCESS;
 }
 
-QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev)
+QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev,
+			  struct qdf_mac_addr *bridgeaddr)
 {
 	QDF_STATUS status;
 
@@ -300,6 +301,9 @@ QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev)
 	if (QDF_IS_STATUS_ERROR(status))
 		return status;
 
+	/* Set Bridge MAC address */
+	pmo_set_vdev_bridge_addr(vdev, bridgeaddr);
+
 	/* Register static configuration with firmware */
 	pmo_register_wow_wakeup_events(vdev);
 

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

@@ -1059,3 +1059,15 @@ QDF_STATUS ucfg_pmo_config_icmp_offload(struct wlan_objmgr_psoc *psoc,
 	return pmo_tgt_config_icmp_offload_req(psoc, pmo_icmp_req);
 }
 #endif
+
+QDF_STATUS ucfg_pmo_set_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
+					 struct qdf_mac_addr *bridgeaddr)
+{
+	return pmo_set_vdev_bridge_addr(vdev, bridgeaddr);
+}
+
+QDF_STATUS ucfg_pmo_get_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
+					 struct qdf_mac_addr *bridgeaddr)
+{
+	return pmo_get_vdev_bridge_addr(vdev, bridgeaddr);
+}

+ 5 - 1
core/hdd/inc/wlan_hdd_main.h

@@ -1898,6 +1898,7 @@ enum wlan_state_ctrl_str_id {
  * @dbam_mode:
  * @last_pagefault_ssr_time: Time when last recovery was triggered because of
  * @host wakeup from fw with reason as pagefault
+ * @bridgeaddr: Bridge MAC address
  */
 struct hdd_context {
 	struct wlan_objmgr_psoc *psoc;
@@ -2173,6 +2174,7 @@ struct hdd_context {
 	enum coex_dbam_config_mode dbam_mode;
 #endif
 	qdf_time_t last_pagefault_ssr_time;
+	uint8_t bridgeaddr[QDF_MAC_ADDR_SIZE];
 };
 
 /**
@@ -2713,6 +2715,7 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter);
 /**
  * hdd_vdev_ready() - Configure FW post VDEV create
  * @vdev: VDEV object.
+ * @bridgeaddr: Bridge MAC address
  *
  * The function is used send configuration to the FW
  * post VDEV creation.
@@ -2720,7 +2723,8 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter);
  *
  * Return: 0 on success, negative value on failure.
  */
-int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev);
+int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev,
+		   struct qdf_mac_addr *bridgeaddr);
 
 QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter);
 struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,

+ 75 - 3
core/hdd/src/wlan_hdd_main.c

@@ -807,6 +807,70 @@ static int __hdd_netdev_notifier_call(struct net_device *net_dev,
 	return NOTIFY_DONE;
 }
 
+static int hdd_netdev_notifier_bridge_intf(struct net_device *net_dev,
+					   unsigned long state)
+{
+	struct hdd_adapter *adapter, *next_adapter = NULL;
+	wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
+	struct hdd_context *hdd_ctx;
+	QDF_STATUS status;
+
+	hdd_enter_dev(net_dev);
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (wlan_hdd_validate_context(hdd_ctx))
+		return NOTIFY_DONE;
+
+	hdd_debug("%s New Net Device State = %lu, flags 0x%x bridge mac address: "QDF_MAC_ADDR_FMT,
+		  net_dev->name, state, net_dev->flags, QDF_MAC_ADDR_REF(net_dev->dev_addr));
+
+	if (!qdf_mem_cmp(hdd_ctx->bridgeaddr, net_dev->dev_addr,
+			 QDF_MAC_ADDR_SIZE))
+		return NOTIFY_DONE;
+
+	switch (state) {
+	case NETDEV_REGISTER:
+	case NETDEV_CHANGEADDR:
+		/* Update FW WoW pattern with new MAC address */
+		qdf_mem_copy(hdd_ctx->bridgeaddr, net_dev->dev_addr,
+			     QDF_MAC_ADDR_SIZE);
+
+		hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
+						   dbgid) {
+			if (adapter->device_mode != QDF_SAP_MODE)
+				goto loop_next;
+
+			if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
+				goto loop_next;
+
+			status = wlan_objmgr_vdev_try_get_ref(adapter->deflink->vdev,
+							      WLAN_HDD_ID_OBJ_MGR);
+			if (QDF_IS_STATUS_ERROR(status))
+				goto loop_next;
+
+			ucfg_pmo_set_vdev_bridge_addr(adapter->deflink->vdev,
+				(struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
+			ucfg_pmo_del_wow_pattern(adapter->deflink->vdev);
+			ucfg_pmo_register_wow_default_patterns(adapter->deflink->vdev);
+
+			wlan_objmgr_vdev_release_ref(adapter->deflink->vdev,
+						     WLAN_HDD_ID_OBJ_MGR);
+
+loop_next:
+			hdd_adapter_dev_put_debug(adapter, dbgid);
+		}
+
+		break;
+	case NETDEV_UNREGISTER:
+		qdf_zero_macaddr((struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
 /**
  * hdd_netdev_notifier_call() - netdev notifier callback function
  * @nb: pointer to notifier block
@@ -823,6 +887,12 @@ static int hdd_netdev_notifier_call(struct notifier_block *nb,
 	struct osif_vdev_sync *vdev_sync;
 	int errno;
 
+	if (net_dev->priv_flags & IFF_EBRIDGE) {
+		errno = hdd_netdev_notifier_bridge_intf(net_dev, state);
+		if (errno)
+			return NOTIFY_DONE;
+	}
+
 	errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
 	if (errno)
 		return NOTIFY_DONE;
@@ -6240,11 +6310,12 @@ QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id)
 	return QDF_STATUS_SUCCESS;
 }
 
-int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev)
+int hdd_vdev_ready(struct wlan_objmgr_vdev *vdev,
+		   struct qdf_mac_addr *bridgeaddr)
 {
 	QDF_STATUS status;
 
-	status = pmo_vdev_ready(vdev);
+	status = pmo_vdev_ready(vdev, bridgeaddr);
 	if (QDF_IS_STATUS_ERROR(status))
 		return qdf_status_to_os_return(status);
 
@@ -6728,7 +6799,8 @@ int hdd_vdev_create(struct hdd_adapter *adapter)
 	}
 
 	/* firmware ready for component communication, raise vdev_ready event */
-	errno = hdd_vdev_ready(vdev);
+	errno = hdd_vdev_ready(vdev,
+			       (struct qdf_mac_addr *)hdd_ctx->bridgeaddr);
 	if (errno) {
 		hdd_err("failed to dispatch vdev ready event: %d", errno);
 		goto hdd_vdev_destroy_procedure;