Ver Fonte

qcacld-3.0: Update firmware filter config (part 1)

In order to conserve firmware memory when various filtering features are
not in use, update the target configuration provided to firmware based
on the intersection of various filtering features and host
configuration.

Part 1
	num_wow_filters = ARP/NS offload enabled ? 2 : 5
	bpf_instruction_size - BPF enabled ? 0 (auto) : 0xffffffff

Part 2 (pending firmware support)
	pkt_filter_num = Packet Filter enabled ? 12 : 0 (disabled)

Change-Id: Ic6624ff04598b53d8321e4864618b12b9702780f
CRs-Fixed: 2196997
Dustin Brown há 7 anos atrás
pai
commit
b9987afb2c

+ 11 - 0
components/pmo/core/inc/wlan_pmo_apf.h

@@ -23,4 +23,15 @@
 #ifndef __WLAN_PMO_APF_H
 #define __WLAN_PMO_APF_H
 
+#include "qdf_types.h"
+#include "wlan_objmgr_psoc_obj.h"
+
+/**
+ * pmo_get_apf_instruction_size() - get the current APF instruction size
+ * @psoc: the psoc to query
+ *
+ * Return: APF instruction size
+ */
+uint32_t pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc);
+
 #endif /* __WLAN_PMO_APF_H */

+ 53 - 7
components/pmo/core/inc/wlan_pmo_main.h

@@ -48,14 +48,9 @@
 #define PMO_VDEV_IN_STA_MODE(mode) \
 	((mode) == QDF_STA_MODE || (mode) == QDF_P2P_CLIENT_MODE ? 1 : 0)
 
-static inline enum QDF_OPMODE pmo_get_vdev_opmode(
-			struct wlan_objmgr_vdev *vdev)
+static inline enum QDF_OPMODE pmo_get_vdev_opmode(struct wlan_objmgr_vdev *vdev)
 {
-	enum QDF_OPMODE opmode;
-
-	opmode = wlan_vdev_mlme_get_opmode(vdev);
-
-	return opmode;
+	return wlan_vdev_mlme_get_opmode(vdev);
 }
 
 /**
@@ -355,4 +350,55 @@ bool pmo_is_vdev_up(struct wlan_objmgr_vdev *vdev)
 	return state == WLAN_VDEV_S_RUN;
 }
 
+/**
+ * pmo_intersect_arp_ns_offload() - intersect config and firmware capability for
+ *	the ARP/NS Offload feature
+ * @psoc_ctx: A PMO psoc context
+ *
+ * Note: The caller is expected to grab the PMO context lock.
+ *
+ * Return: True if firmware supports and configuration has enabled the feature
+ */
+static inline bool
+pmo_intersect_arp_ns_offload(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	struct pmo_psoc_cfg *cfg = &psoc_ctx->psoc_cfg;
+	bool arp_ns_enabled =
+		cfg->ns_offload_enable_static ||
+		cfg->ns_offload_enable_dynamic ||
+		cfg->arp_offload_enable;
+
+	return arp_ns_enabled && psoc_ctx->caps.arp_ns_offload;
+}
+
+/**
+ * pmo_intersect_apf() - intersect config and firmware capability for
+ *	the BPF feature
+ * @psoc_ctx: A PMO psoc context
+ *
+ * Note: The caller is expected to grab the PMO context lock.
+ *
+ * Return: True if firmware supports and configuration has enabled the feature
+ */
+static inline bool pmo_intersect_apf(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	return psoc_ctx->psoc_cfg.apf_enable && psoc_ctx->caps.apf;
+}
+
+/**
+ * pmo_intersect_packet_filter() - intersect config and firmware capability for
+ *	the BPF feature
+ * @psoc_ctx: A PMO psoc context
+ *
+ * Note: The caller is expected to grab the PMO context lock.
+ *
+ * Return: True if firmware supports and configuration has enabled the feature
+ */
+static inline bool
+pmo_intersect_packet_filter(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	return psoc_ctx->psoc_cfg.packet_filter_enabled &&
+		psoc_ctx->caps.packet_filter;
+}
+
 #endif /* end  of _WLAN_PMO_MAIN_H_ */

+ 11 - 3
components/pmo/core/inc/wlan_pmo_pkt_filter.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 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
@@ -20,12 +20,20 @@
  */
 
 #ifndef _WLAN_PMO_PKT_FILTER_H_
-#define _WLAN_PMO_PKT_FILTER_
+#define _WLAN_PMO_PKT_FILTER_H_
 
 #include "wlan_pmo_pkt_filter_public_struct.h"
 
 struct wlan_objmgr_psoc;
 
+/**
+ * pmo_get_num_packet_filters() - get the number of packet filters
+ * @psoc: the psoc to query
+ *
+ * Return: number of packet filters
+ */
+uint8_t pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc);
+
 /**
  * pmo_set_pkt_fltr_req() - Set packet filter
  * @vdev: objmgr vdev
@@ -53,5 +61,5 @@ QDF_STATUS pmo_core_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
 		struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_req,
 		uint8_t vdev_id);
 
-#endif /* end  of _WLAN_PMO_PKT_FILTER_H_ */
+#endif /* _WLAN_PMO_PKT_FILTER_H_ */
 

+ 12 - 0
components/pmo/core/inc/wlan_pmo_wow.h

@@ -105,6 +105,10 @@
 
 #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_MAX		22
+
 /**
  * pmo_get_and_increment_wow_default_ptrn() -Get and increment wow default ptrn
  * @vdev_ctx: pmo vdev priv ctx
@@ -684,4 +688,12 @@ static inline void pmo_get_event_bitmap_idx(WOW_WAKE_EVENT_TYPE event,
 		*bit_idx = event % (wow_bitmap_size * 8);
 	}
 }
+
+/**
+ * pmo_get_num_wow_filters() - get the supported number of WoW filters
+ * @psoc: the psoc to query
+ *
+ * Return: number of WoW filters supported
+ */
+uint8_t pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc);
 #endif /* end  of _WLAN_PMO_WOW_H_ */

+ 18 - 0
components/pmo/core/src/wlan_pmo_apf.c

@@ -20,5 +20,23 @@
  * DOC: PMO implementations for Android Packet Filter (APF) functions
  */
 
+#include "qdf_types.h"
+#include "wlan_objmgr_psoc_obj.h"
 #include "wlan_pmo_apf.h"
+#include "wlan_pmo_main.h"
+
+#define PMO_APF_SIZE_AUTO	0
+#define PMO_APF_SIZE_DISABLE	0xffffffff
+
+uint32_t pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool enabled;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		enabled = pmo_intersect_apf(psoc_ctx);
+	}
+
+	return enabled ? PMO_APF_SIZE_AUTO : PMO_APF_SIZE_DISABLE;
+}
 

+ 16 - 1
components/pmo/core/src/wlan_pmo_pkt_filter.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018 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
@@ -24,6 +24,21 @@
 #include "wlan_pmo_main.h"
 #include "wlan_pmo_obj_mgmt_public_struct.h"
 
+#define PMO_PKT_FILTERS_DEFAULT 12
+#define PMO_PKT_FILTERS_DISABLED 0
+
+uint8_t pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool enabled;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		enabled = pmo_intersect_packet_filter(psoc_ctx);
+	}
+
+	return enabled ? PMO_PKT_FILTERS_DEFAULT : PMO_PKT_FILTERS_DISABLED;
+}
+
 QDF_STATUS pmo_core_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
 			struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
 			uint8_t vdev_id)

+ 23 - 1
components/pmo/core/src/wlan_pmo_wow.c

@@ -386,7 +386,6 @@ void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
 	pmo_set_wow_event_bitmap(WOW_11D_SCAN_EVENT,
 				 wow_bitmap_size,
 				 bitmask);
-
 }
 
 void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
@@ -420,3 +419,26 @@ void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
 				 wow_bitmap_size,
 				 bitmask);
 }
+
+uint8_t pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool apf;
+	bool arp_ns;
+	bool pkt_filter;
+
+	pmo_psoc_with_ctx(psoc, psoc_ctx) {
+		apf = pmo_intersect_apf(psoc_ctx);
+		arp_ns = pmo_intersect_arp_ns_offload(psoc_ctx);
+		pkt_filter = pmo_intersect_packet_filter(psoc_ctx);
+	}
+
+	if (!apf && !pkt_filter)
+		return PMO_WOW_FILTERS_MAX;
+
+	if (arp_ns)
+		return PMO_WOW_FILTERS_ARP_NS;
+
+	return PMO_WOW_FILTERS_PKT_OR_APF;
+}
+

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

@@ -261,12 +261,13 @@ enum pmo_auto_pwr_detect_failure_mode {
  * struct pmo_psoc_cfg - user configuration required for pmo
  * @ptrn_match_enable_all_vdev: true when pattern match is enable for all vdev
  * @ptrn_id_per_vdev: true when pattern id can be same for different vdev
- * @bpf_enable: true if psoc supports bpf else false
+ * @apf_enable: true if psoc supports bpf else false
  * @arp_offload_enable: true if arp offload is supported for psoc else false
  * @hw_filter_mode: which mode the hardware filter should use during DTIM
  * @ns_offload_enable_static: true if psoc supports ns offload in ini else false
  * @ns_offload_enable_dynamic: to enable / disable the ns offload using
  *    ioctl or vendor command.
+ * @packet_filter_enabled: true if feature is enabled by configuration
  * @ssdp:  true if psoc supports if ssdp configuration in wow mode
  * @enable_mc_list: true if psoc supports mc addr list else false
  * @active_mode_offload: true if psoc supports active mode offload else false
@@ -290,11 +291,12 @@ enum pmo_auto_pwr_detect_failure_mode {
 struct pmo_psoc_cfg {
 	bool ptrn_match_enable_all_vdev;
 	bool ptrn_id_per_vdev;
-	bool bpf_enable;
+	bool apf_enable;
 	bool arp_offload_enable;
 	enum pmo_hw_filter_mode hw_filter_mode;
 	bool ns_offload_enable_static;
 	bool ns_offload_enable_dynamic;
+	bool packet_filter_enabled;
 	bool ssdp;
 	bool enable_mc_list;
 	bool active_mode_offload;

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

@@ -33,6 +33,30 @@
 #include "wlan_pmo_pkt_filter_public_struct.h"
 #include "wlan_pmo_hw_filter_public_struct.h"
 
+/**
+ * ucfg_pmo_get_apf_instruction_size() - get the current APF instruction size
+ * @psoc: the psoc to query
+ *
+ * Return: APF instruction size
+ */
+uint32_t ucfg_pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_num_packet_filters() - get the number of packet filters
+ * @psoc: the psoc to query
+ *
+ * Return: number of packet filters
+ */
+uint8_t ucfg_pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_pmo_get_num_wow_filters() - get the supported number of WoW filters
+ * @psoc: the psoc to query
+ *
+ * Return: number of WoW filters supported
+ */
+uint8_t ucfg_pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc);
+
 /**
  * ucfg_pmo_is_ap_mode_supports_arp_ns() - Check ap mode support arp&ns offload
  * @psoc: objmgr psoc

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

@@ -20,6 +20,7 @@
  */
 
 #include "wlan_pmo_ucfg_api.h"
+#include "wlan_pmo_apf.h"
 #include "wlan_pmo_arp.h"
 #include "wlan_pmo_ns.h"
 #include "wlan_pmo_gtk.h"
@@ -31,6 +32,33 @@
 #include "wlan_pmo_pkt_filter.h"
 #include "wlan_pmo_hw_filter.h"
 
+uint32_t ucfg_pmo_get_apf_instruction_size(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_BUG(psoc);
+	if (!psoc)
+		return 0;
+
+	return pmo_get_apf_instruction_size(psoc);
+}
+
+uint8_t ucfg_pmo_get_num_packet_filters(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_BUG(psoc);
+	if (!psoc)
+		return 0;
+
+	return pmo_get_num_packet_filters(psoc);
+}
+
+uint8_t ucfg_pmo_get_num_wow_filters(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_BUG(psoc);
+	if (!psoc)
+		return 0;
+
+	return pmo_get_num_wow_filters(psoc);
+}
+
 QDF_STATUS ucfg_pmo_get_psoc_config(struct wlan_objmgr_psoc *psoc,
 		struct pmo_psoc_cfg *psoc_cfg)
 {

+ 12 - 17
core/hdd/src/wlan_hdd_main.c

@@ -12616,7 +12616,6 @@ static inline void hdd_ra_populate_pmo_config(
  */
 static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
 {
-	struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
 	struct pmo_psoc_cfg psoc_cfg;
 	QDF_STATUS status;
 
@@ -12632,40 +12631,36 @@ static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
 		(hdd_ctx->config->wowEnable & 0x01) ? true : false;
 	psoc_cfg.ptrn_match_enable_all_vdev =
 		(hdd_ctx->config->wowEnable & 0x02) ? true : false;
-	psoc_cfg.ptrn_id_per_vdev = wma_is_service_enabled(
-		wmi_service_unified_wow_capability);
-	psoc_cfg.bpf_enable =
-		hdd_ctx->config->bpf_packet_filter_enable;
+	psoc_cfg.ptrn_id_per_vdev =
+		wma_is_service_enabled(wmi_service_unified_wow_capability);
+	psoc_cfg.apf_enable = hdd_ctx->config->bpf_packet_filter_enable;
 	psoc_cfg.arp_offload_enable = hdd_ctx->config->fhostArpOffload;
 	psoc_cfg.hw_filter_mode = hdd_ctx->config->hw_filter_mode;
+	psoc_cfg.ns_offload_enable_dynamic = hdd_ctx->config->fhostNSOffload;
 	psoc_cfg.ns_offload_enable_static = hdd_ctx->config->fhostNSOffload;
-	if (hdd_ctx->config->fhostNSOffload)
-		psoc_cfg.ns_offload_enable_dynamic = true;
+	psoc_cfg.packet_filter_enabled = !hdd_ctx->config->disablePacketFilter;
 	psoc_cfg.ssdp = hdd_ctx->config->ssdp;
 	psoc_cfg.enable_mc_list = hdd_ctx->config->fEnableMCAddrList;
-	psoc_cfg.active_mode_offload =
-		hdd_ctx->config->active_mode_offload;
+	psoc_cfg.active_mode_offload = hdd_ctx->config->active_mode_offload;
 	psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
 	psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
 	psoc_cfg.max_wow_filters = hdd_ctx->config->maxWoWFilters;
 	psoc_cfg.sta_dynamic_dtim = hdd_ctx->config->enableDynamicDTIM;
 	psoc_cfg.sta_mod_dtim = hdd_ctx->config->enableModulatedDTIM;
 	psoc_cfg.sta_max_li_mod_dtim = hdd_ctx->config->fMaxLIModulatedDTIM;
-	psoc_cfg.power_save_mode =
-		hdd_ctx->config->enablePowersaveOffload;
+	psoc_cfg.power_save_mode = hdd_ctx->config->enablePowersaveOffload;
 	psoc_cfg.auto_power_save_fail_mode =
 		hdd_ctx->config->auto_pwr_save_fail_mode;
 
 	hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx);
 	hdd_nan_populate_pmo_config(&psoc_cfg, hdd_ctx);
 	hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
-	status = ucfg_pmo_update_psoc_config(psoc, &psoc_cfg);
-	if (status != QDF_STATUS_SUCCESS) {
-		hdd_err("failed pmo psoc configuration");
-		return -EINVAL;
-	}
 
-	return 0;
+	status = ucfg_pmo_update_psoc_config(hdd_ctx->hdd_psoc, &psoc_cfg);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed pmo psoc configuration; status:%d", status);
+
+	return qdf_status_to_os_return(status);
 }
 
 #ifdef FEATURE_WLAN_SCAN_PNO

+ 10 - 20
core/wma/src/wma_main.c

@@ -4486,33 +4486,23 @@ QDF_STATUS wma_close(void)
 
 /**
  * wma_update_fw_config() - update fw configuration
- * @wma_handle: wma handle
- * @tgt_cap: pointer to structure target_psoc_info
- * @tgt_hdl: Target capability info
+ * @psoc: psoc to query configuration from
+ * @tgt_hdl: target capability info
  *
  * Return: none
  */
-static void wma_update_fw_config(tp_wma_handle wma_handle,
-				 struct wma_target_cap *tgt_cap,
+static void wma_update_fw_config(struct wlan_objmgr_psoc *psoc,
 				 struct target_psoc_info *tgt_hdl)
 {
-	/*
-	 * tgt_cap contains default target resource configuration
-	 * which can be modified here, if required
-	 */
+	target_resource_config *cfg = &tgt_hdl->info.wlan_res_cfg;
+
 	/* Override the no. of max fragments as per platform configuration */
-	tgt_cap->wlan_resource_config.max_frag_entries =
-					QDF_MIN(QCA_OL_11AC_TX_MAX_FRAGS,
+	cfg->max_frag_entries =	QDF_MIN(QCA_OL_11AC_TX_MAX_FRAGS,
 					target_if_get_max_frag_entry(tgt_hdl));
+	target_if_set_max_frag_entry(tgt_hdl, cfg->max_frag_entries);
 
-	target_if_set_max_frag_entry(tgt_hdl,
-			tgt_cap->wlan_resource_config.max_frag_entries);
-
-	/* Update no. of maxWoWFilters depending on BPF service */
-	if (wmi_service_enabled(wma_handle->wmi_handle,
-				   wmi_service_bpf_offload))
-		tgt_cap->wlan_resource_config.num_wow_filters =
-					WMA_STA_WOW_DEFAULT_PTRN_MAX;
+	cfg->num_wow_filters = ucfg_pmo_get_num_wow_filters(psoc);
+	cfg->bpf_instruction_size = ucfg_pmo_get_apf_instruction_size(psoc);
 }
 
 /**
@@ -5655,7 +5645,7 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info,
 	wma_set_component_caps(wma_handle->psoc);
 
 	target_cap.wlan_resource_config = tgt_hdl->info.wlan_res_cfg;
-	wma_update_fw_config(wma_handle, &target_cap, tgt_hdl);
+	wma_update_fw_config(wma_handle->psoc, tgt_hdl);
 	qdf_mem_copy(wma_handle->wmi_service_bitmap,
 		     service_bitmap,
 		     sizeof(wma_handle->wmi_service_bitmap));