Procházet zdrojové kódy

qcacld-3.0: Add HAL command support to set NS offload

Propagation from qcacld-2.0 to qcacld-3.0

Add support to enable/disable NS offload to firmware from HAL
vendor command.

As part of this fix when NS offload is set to disable from HAL
command, NS will not be offloaded when wlan goes to suspend state
even if NS offload is enabled in cfg ini.

Change-Id: Iffaaa9be2e62ea03fcbe3e32d2cc654d3e7334f5
CRs-Fixed: 954880
Sravan Kumar Kairam před 8 roky
rodič
revize
fece87f53f

+ 2 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1415,10 +1415,12 @@ struct hdd_context_s {
 	qdf_spinlock_t hdd_scan_req_q_lock;
 	qdf_list_t hdd_scan_req_q;
 	uint8_t miracast_value;
+
 #ifdef WLAN_NS_OFFLOAD
 	/* IPv6 notifier callback for handling NS offload on change in IP */
 	struct notifier_block ipv6_notifier;
 #endif
+	bool ns_offload_enable;
 	/* IPv4 notifier callback for handling ARP offload on change in IP */
 	struct notifier_block ipv4_notifier;
 

+ 81 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -4817,6 +4817,79 @@ fail:
 	return;
 }
 
+static const struct nla_policy
+ns_offload_set_policy[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG] = {.type = NLA_U8},
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_ns_offload() - enable/disable NS offload
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
+			struct wireless_dev *wdev,
+			const void *data, int data_len)
+{
+	int status;
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1];
+	hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+
+	ENTER_DEV(wdev->netdev);
+
+	status = wlan_hdd_validate_context(pHddCtx);
+	if (0 != status)
+		return status;
+	if (!pHddCtx->config->fhostNSOffload) {
+		hdd_err("ND Offload not supported");
+		return -EINVAL;
+	}
+
+	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX,
+			(struct nlattr *)data,
+			data_len, ns_offload_set_policy)) {
+		hdd_err("nla_parse failed");
+		return -EINVAL;
+	}
+
+	if (!tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]) {
+		hdd_err("ND Offload flag attribute not present");
+		return -EINVAL;
+	}
+
+	pHddCtx->ns_offload_enable =
+		nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]);
+
+	return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_ns_offload() - enable/disable NS offload
+ * @wiphy:   pointer to wireless wiphy structure.
+ * @wdev:    pointer to wireless_dev structure.
+ * @data:    Pointer to the data to be passed via vendor interface
+ * @data_len:Length of the data to be passed
+ *
+ * Return:   Return the Success or Failure code.
+ */
+static int wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
+					struct wireless_dev *wdev,
+					const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+	ret = __wlan_hdd_cfg80211_set_ns_offload(wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+
+	return ret;
+}
+
 /** __wlan_hdd_cfg80211_get_preferred_freq_list() - get preferred frequency list
  * @wiphy: Pointer to wireless phy
  * @wdev: Pointer to wireless device
@@ -7402,6 +7475,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
 			WIPHY_VENDOR_CMD_NEED_RUNNING,
 		.doit = wlan_hdd_cfg80211_monitor_rssi
 	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			 WIPHY_VENDOR_CMD_NEED_NETDEV |
+			 WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_ns_offload
+	},
 	{
 		.info.vendor_id = QCA_NL80211_VENDOR_ID,
 		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,

+ 24 - 0
core/hdd/src/wlan_hdd_cfg80211.h

@@ -373,6 +373,9 @@ enum qca_nl80211_vendor_subcmds {
 	QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI = 80,
 	QCA_NL80211_VENDOR_SUBCMD_NDP = 81,
 
+	/* NS Offload enable/disable cmd */
+	QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD = 82,
+
 	QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER = 83,
 
 	QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS = 85,
@@ -2079,6 +2082,27 @@ enum qca_wlan_vendor_attr_link_properties {
 		QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_wlan_vendor_attr_nd_offload - vendor NS offload support
+ *
+ * @QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_INVALID - Invalid
+ * @QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG - Flag to set NS offload
+ * @QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_AFTER_LAST - To keep track of the last enum
+ * @QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX - max value possible for this type
+ *
+ * enum values are used for NL attributes for data used by
+ * QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD sub command.
+ */
+enum qca_wlan_vendor_attr_nd_offload {
+	QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG,
+
+	/* Keep last */
+	QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX =
+		QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_AFTER_LAST - 1,
+};
+
 /**
  * enum qca_wlan_vendor_features - vendor device/driver features
  * @QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD: Device supports key

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

@@ -6055,6 +6055,9 @@ hdd_context_t *hdd_context_create(struct device *dev)
 	hdd_notice("Setting configuredMcastBcastFilter: %d",
 		   hdd_ctx->config->mcastBcastFilterSetting);
 
+	if (hdd_ctx->config->fhostNSOffload)
+		hdd_ctx->ns_offload_enable = true;
+
 	cds_set_fatal_event(hdd_ctx->config->enable_fatal_event);
 
 	hdd_override_ini_config(hdd_ctx);

+ 4 - 2
core/hdd/src/wlan_hdd_power.c

@@ -492,7 +492,8 @@ void __hdd_ipv6_notifier_work_queue(struct work_struct *work)
 	if (eConnectionState_Associated ==
 	     (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState ||
 		ndi_connected)
-		if (pHddCtx->config->fhostNSOffload)
+		if (pHddCtx->config->fhostNSOffload &&
+		    pHddCtx->ns_offload_enable)
 			hdd_conf_ns_offload(pAdapter, true);
 	EXIT();
 }
@@ -557,7 +558,8 @@ void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, bool fenable)
 		hdd_conf_arp_offload(pAdapter, fenable);
 		wlan_hdd_set_mc_addr_list(pAdapter, fenable);
 
-		if (pHddCtx->config->fhostNSOffload)
+		if (pHddCtx->config->fhostNSOffload &&
+		    pHddCtx->ns_offload_enable)
 			hdd_conf_ns_offload(pAdapter, fenable);
 	}
 	EXIT();