Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65f0b4a8 authored by sheenam monga's avatar sheenam monga Committed by Madan Koyyalamudi
Browse files

qcacld-3.0: Handle command to get usable channels

Handle command to get usable channels for
provided mode, band and con filter.

Change-Id: I20133ea1a93c9153ec7252dcd34a0a160715d8a6
CRs-Fixed: 2946908
parent 4d0d5fe1
Loading
Loading
Loading
Loading
+137 −0
Original line number Diff line number Diff line
@@ -14952,6 +14952,104 @@ nla_policy get_chain_rssi_policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] = {
						 .len = QDF_MAC_ADDR_SIZE},
};
static const struct nla_policy
get_chan_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_INVALID] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH] = {.type = NLA_U32},
	[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK] = {.type = NLA_U32},
};
static const struct nla_policy
get_usable_channel_policy[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX + 1] = {
	[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_INVALID] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK] = {
		.type = NLA_U32
	},
	[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO] = {
		.type = NLA_NESTED
	},
};
/**
 * __wlan_hdd_cfg80211_get_usable_channel() - get chain rssi
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * Return: 0 on success; error number otherwise.
 */
static int __wlan_hdd_cfg80211_get_usable_channel(struct wiphy *wiphy,
						  struct wireless_dev *wdev,
						  const void *data,
						  int data_len)
{
	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
	struct get_usable_chan_req_params req_msg = {0};
	struct get_usable_chan_res_params res_msg[NUM_CHANNELS];
	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX + 1];
	int retval;
	uint32_t count;
	QDF_STATUS status;
	retval = wlan_hdd_validate_context(hdd_ctx);
	if (0 != retval)
		return retval;
	if (wlan_cfg80211_nla_parse(
				tb, QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX,
				data, data_len, get_usable_channel_policy)) {
		hdd_err("Invalid ATTR");
		return -EINVAL;
	}
	if (!tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK]) {
		hdd_err("band mask not present");
		return -EINVAL;
	}
	req_msg.band_mask =
		nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK]);
	if (!tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK]) {
		hdd_err("iface mode mask not present");
		return -EINVAL;
	}
	req_msg.iface_mode_mask = nla_get_u32(
		tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK]);
	if (!tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK]) {
		hdd_err("usable channels filter mask not present");
		return -EINVAL;
	}
	req_msg.filter_mask =
	   nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK]);
	hdd_debug("get usable channel list for band %d mode %d filter %d",
		  req_msg.band_mask, req_msg.iface_mode_mask,
		  req_msg.filter_mask);
	status = wlan_reg_get_usable_channel(hdd_ctx->pdev, req_msg,
					     res_msg, &count);
	if (QDF_STATUS_SUCCESS != status) {
		hdd_err("get usable channel failed %d", status);
		return -EINVAL;
	}
	hdd_debug("usable channel count : %d", count);
	return qdf_status_to_os_return(status);
}
/**
 * __wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi
 * @wiphy: wiphy pointer
@@ -15040,6 +15138,35 @@ static int __wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy,
	return retval;
}
/**
 * wlan_hdd_cfg80211_get_usable_channel() - get chain rssi
 * @wiphy: wiphy pointer
 * @wdev: pointer to struct wireless_dev
 * @data: pointer to incoming NL vendor data
 * @data_len: length of @data
 *
 * Return: 0 on success; error number otherwise.
 */
static int wlan_hdd_cfg80211_get_usable_channel(struct wiphy *wiphy,
						struct wireless_dev *wdev,
						const void *data,
						int data_len)
{
	int errno;
	struct osif_vdev_sync *vdev_sync;
	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
	if (errno)
		return errno;
	errno = __wlan_hdd_cfg80211_get_usable_channel(wiphy, wdev,
						       data, data_len);
	osif_vdev_sync_op_stop(vdev_sync);
	return errno;
}
/**
 * wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi
 * @wiphy: wiphy pointer
@@ -15894,6 +16021,16 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
		vendor_command_policy(get_chain_rssi_policy,
				      QCA_WLAN_VENDOR_ATTR_MAX)
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV |
			WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wlan_hdd_cfg80211_get_usable_channel,
		vendor_command_policy(get_usable_channel_policy,
				      QCA_WLAN_VENDOR_ATTR_MAX)
	},
	FEATURE_ACTIVE_TOS_VENDOR_COMMANDS
	FEATURE_NAN_VENDOR_COMMANDS