Эх сурвалжийг харах

qcacld-3.0: Add handler for gateway parameter update request

Add handler for gateway parameter request vendor command. The
request is issued to update the gateway parameters to be used
during subnet detection post roaming.

Change-Id: I848f24b36a1d65a0e8bb8465b2b6f2016cb2224c
CRs-Fixed: 876335
Ravi Joshi 9 жил өмнө
parent
commit
deb5a8d6ff

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

@@ -87,6 +87,8 @@
 
 #include "wlan_hdd_ocb.h"
 
+#include "wlan_hdd_subnet_detect.h"
+
 #define g_mode_rates_size (12)
 #define a_mode_rates_size (8)
 #define GET_IE_LEN_IN_BSS_DESC(lenInBss) (lenInBss + sizeof(lenInBss) - \
@@ -1064,6 +1066,12 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
 		.vendor_id = QCA_NL80211_VENDOR_ID,
 		.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT
 	},
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	[QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX] = {
+		.vendor_id = QCA_NL80211_VENDOR_ID,
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG
+	},
+#endif /*FEATURE_LFR_SUBNET_DETECTION */
 };
 
 /**
@@ -4982,6 +4990,16 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
 				 WIPHY_VENDOR_CMD_NEED_RUNNING,
 		.doit = wlan_hdd_cfg80211_set_ota_test
 	},
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+				WIPHY_VENDOR_CMD_NEED_NETDEV |
+				WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_set_gateway_params
+	},
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
 };
 
 /*

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

@@ -249,6 +249,7 @@ typedef enum {
  * @QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN: venodr scan command
  * @QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE: vendor scan complete
  * @QCA_NL80211_VENDOR_SUBCMD_OTA_TEST: enable OTA test
+ * @QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG: set gateway parameters
  */
 
 enum qca_nl80211_vendor_subcmds {
@@ -350,6 +351,8 @@ enum qca_nl80211_vendor_subcmds {
 
 	/* subcommand to get link properties */
 	QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101,
+	/* LFR Subnet Detection */
+	QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG = 102,
 
 	/* DBS subcommands */
 	QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST = 103,
@@ -420,6 +423,8 @@ enum qca_nl80211_vendor_subcmds {
  * @QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX: vendor scan index
  * @QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX:
  *	vendor scan complete event  index
+ * @QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX:
+ *	update gateway parameters index
  */
 
 enum qca_nl80211_vendor_subcmds_index {
@@ -488,6 +493,7 @@ enum qca_nl80211_vendor_subcmds_index {
 	QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX,
 	QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX,
 	QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX,
+	QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX,
 };
 
 /**
@@ -2165,6 +2171,23 @@ enum qca_vendor_attr_probable_oper_channel {
 	QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_AFTER_LAST - 1
 };
 
+/**
+ * enum qca_wlan_vendor_attr_gw_param_config - gateway param config
+ * @QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_INVALID: Invalid
+ * @QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_GW_MAC_ADDR: gateway mac addr
+ * @QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV4_ADDR: ipv4 addr
+ * @QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV6_ADDR: ipv6 addr
+ */
+enum qca_wlan_vendor_attr_gw_param_config {
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_GW_MAC_ADDR,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV4_ADDR,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV6_ADDR,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX =
+		QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_AFTER_LAST - 1,
+};
+
 /**
  * enum drv_dbs_capability - DBS capability
  * @DRV_DBS_CAPABILITY_DISABLED: DBS disabled

+ 195 - 0
core/hdd/src/wlan_hdd_subnet_detect.c

@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_subnet_detect.c
+ *
+ * WLAN Host Device Driver subnet detect API implementation
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <net/cfg80211.h>
+#include <ani_global.h>
+#include "sme_api.h"
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_subnet_detect.h"
+
+/*
+ * define short names for the global vendor params
+ * used by __wlan_hdd_cfg80211_set_gateway_params()
+ */
+#define PARAM_MAC_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_GW_MAC_ADDR
+#define PARAM_IPV4_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV4_ADDR
+#define PARAM_IPV6_ADDR QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_IPV6_ADDR
+
+static const struct nla_policy
+	policy[QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX + 1] = {
+		[PARAM_MAC_ADDR] = {
+				.type = NLA_BINARY,
+				.len = CDF_MAC_ADDR_SIZE
+		},
+		[PARAM_IPV4_ADDR] = {
+				.type = NLA_BINARY,
+				.len = CDF_IPV4_ADDR_SIZE
+		},
+		[PARAM_IPV6_ADDR] = {
+				.type = NLA_BINARY,
+				.len = CDF_IPV6_ADDR_SIZE
+		}
+};
+
+/**
+ * __wlan_hdd_cfg80211_set_gateway_params() - set gateway params
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Data length
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int __wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+		struct wireless_dev *wdev,
+		const void *data,
+		int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX + 1];
+	struct gateway_param_update_req req = { 0 };
+	int ret;
+	CDF_STATUS status;
+
+	ENTER();
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	/* user may have disabled the feature in INI */
+	if (!hdd_ctx->config->enable_lfr_subnet_detection) {
+		hdd_info("LFR Subnet Detection disabled in INI");
+		return -ENOTSUPP;
+	}
+
+	/* The gateway parameters are only valid in the STA persona
+	 * and only in the connected state.
+	 */
+	if (WLAN_HDD_INFRA_STATION != adapter->device_mode) {
+		hdd_err("Received GW param update for non-STA mode adapter");
+		return -ENOTSUPP;
+	}
+
+	if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
+		hdd_err("Received GW param update in disconnected state!");
+		return -ENOTSUPP;
+	}
+
+	/* Extract NL parameters
+	 * mac_addr:  6 bytes
+	 * ipv4 addr: 4 bytes
+	 * ipv6 addr: 16 bytes
+	 */
+	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GW_PARAM_CONFIG_MAX,
+			data, data_len, policy)) {
+		hdd_err("Invalid ATTR list");
+		return -EINVAL;
+	}
+
+	if (!tb[PARAM_MAC_ADDR]) {
+		hdd_err("request mac addr failed");
+		return -EINVAL;
+	}
+	nla_memcpy(req.gw_mac_addr.bytes, tb[PARAM_MAC_ADDR],
+			CDF_MAC_ADDR_SIZE);
+
+	/* req ipv4_addr_type and ipv6_addr_type are initially false due
+	 * to zeroing the struct
+	 */
+	if (tb[PARAM_IPV4_ADDR]) {
+		nla_memcpy(req.ipv4_addr, tb[PARAM_IPV4_ADDR],
+			CDF_IPV4_ADDR_SIZE);
+		req.ipv4_addr_type = true;
+	}
+
+	if (tb[PARAM_IPV6_ADDR]) {
+		nla_memcpy(&req.ipv6_addr, tb[PARAM_IPV6_ADDR],
+			CDF_IPV6_ADDR_SIZE);
+		req.ipv6_addr_type = true;
+	}
+
+	if (!req.ipv4_addr_type && !req.ipv6_addr_type) {
+		hdd_err("invalid ipv4 or ipv6 gateway address");
+		return -EINVAL;
+	}
+
+	req.max_retries = 3;
+	req.timeout = 100;   /* in milliseconds */
+	req.session_id = adapter->sessionId;
+
+	hdd_info("**** Gateway Parameters: ****");
+	hdd_info("session id: %d", req.session_id);
+	hdd_info("ipv4 addr type: %d", req.ipv4_addr_type);
+	hdd_info("ipv6 addr type: %d", req.ipv6_addr_type);
+	hdd_info("gw mac addr: %pM", req.gw_mac_addr.bytes);
+	hdd_info("ipv4 addr: %pI4", req.ipv4_addr);
+	hdd_info("ipv6 addr: %pI6c", req.ipv6_addr);
+
+	status = sme_gateway_param_update(hdd_ctx->hHal, &req);
+	if (!CDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("sme_gateway_param_update failed(err=%d)", status);
+		ret = -EINVAL;
+	}
+
+	EXIT();
+	return ret;
+}
+
+/**
+ * wlan_hdd_cfg80211_set_gateway_params() - set gateway parameters
+ * @wiphy:    wiphy structure pointer
+ * @wdev:     Wireless device structure pointer
+ * @data:     Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * The API is invoked by the user space to set the gateway parameters
+ * such as mac address and the IP address which is used for detecting
+ * the IP subnet change
+ *
+ * Return: 0 on success; errno on failure
+ */
+int wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+		struct wireless_dev *wdev, const void *data, int data_len)
+{
+	int ret;
+
+	cds_ssr_protect(__func__);
+
+	ret = __wlan_hdd_cfg80211_set_gateway_params(
+				wiphy, wdev, data, data_len);
+	cds_ssr_unprotect(__func__);
+	return ret;
+}
+#undef PARAM_MAC_ADDR
+#undef PARAM_IPV4_ADDR
+#undef PARAM_IPV6_ADDR

+ 44 - 0
core/hdd/src/wlan_hdd_subnet_detect.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __WLAN_HDD_SUBNET_DETECT_H
+#define __WLAN_HDD_SUBNET_DETECT_H
+
+/**
+ * DOC: wlan_hdd_subnet_detect.h
+ *
+ * WLAN Host Device Driver subnet detect API specification
+ */
+
+#ifdef FEATURE_LFR_SUBNET_DETECTION
+struct wiphy;
+struct wireless_dev;
+
+int wlan_hdd_cfg80211_set_gateway_params(struct wiphy *wiphy,
+	struct wireless_dev *wdev, const void *data, int data_len);
+#endif /* FEATURE_LFR_SUBNET_DETECTION */
+#endif /* __WLAN_HDD_SUBNET_DETECT_H */