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

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

qcacld-3.0: Send response of SUBCMD_USABLE_CHANNELS

Send response of SUBCMD_USABLE_CHANNELS to upper layer.

Change-Id: I3f7d0a9f28fcf60141fec86561524882ce4e3095
CRs-Fixed: 2946928
parent 65f0b4a8
Loading
Loading
Loading
Loading
+119 −0
Original line number Diff line number Diff line
@@ -14981,6 +14981,119 @@ get_usable_channel_policy[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX + 1] = {
	},
};
/**
 * hdd_fill_usable_channels_data() - Fill the data requested by userspace
 * @skb: SK buffer
 * @tb: List of attributes
 * @res_msg: structure of usable channel info
 * @count: no of usable channels
 *
 * Get the data corresponding to the attribute list specified in tb and
 * update the same to skb by populating the same attributes.
 *
 * Return: 0 on success; error number on failure
 */
static int
hdd_fill_usable_channels_data(struct sk_buff *skb, struct nlattr **tb,
			      struct get_usable_chan_res_params *res_msg,
			      int count)
{
	struct nlattr *config;
	uint8_t i = 0;
	config = nla_nest_start(skb,
				QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO);
	if (!config) {
		hdd_err("nla nest start failure");
		return -EINVAL;
	}
	for (i = 0; i < count ; i++) {
		if (!res_msg[i].freq)
			continue;
		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ,
			    res_msg[i].freq);
		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ,
			    res_msg[i].seg0_freq);
		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ,
			    res_msg[i].seg1_freq);
		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH,
			    res_msg[i].bw);
		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK,
			    res_msg[i].iface_mode_mask);
	}
	nla_nest_end(skb, config);
	return 0;
}
/**
 * hdd_get_usable_cahnnel_len() - calculate the length required by skb
 * @count: number of usable channels
 *
 * Find the required length to send usable channel data to upper layer
 *
 * Return: required len
 */
static uint32_t
hdd_get_usable_cahnnel_len(uint32_t count)
{
	uint32_t len = 0;
	struct get_usable_chan_res_params res_msg;
	len = nla_total_size(sizeof(res_msg.freq)) +
		nla_total_size(sizeof(res_msg.seg0_freq)) +
		nla_total_size(sizeof(res_msg.seg1_freq)) +
		nla_total_size(sizeof(res_msg.bw)) +
		nla_total_size(sizeof(res_msg.iface_mode_mask));
	return len * count;
}
/**
 * hdd_send_usable_channel() - Send usable channels as vendor cmd reply
 * @mac_handle: Opaque handle to the MAC context
 * @vdev_id: vdev id
 * @tb: List of attributes
 *
 * Parse the attributes list tb and  get the data corresponding to the
 * attributes specified in tb. Send them as a vendor response.
 *
 * Return: 0 on success; error number on failure
 */
static int
hdd_send_usable_channel(struct hdd_context *hdd_ctx,
			struct get_usable_chan_res_params *res_msg,
			uint32_t count,
			struct nlattr **tb)
{
	struct sk_buff *skb;
	uint32_t skb_len;
	int status;
	skb_len = hdd_get_usable_cahnnel_len(count);
	if (!skb_len) {
		hdd_err("No data requested");
		return -EINVAL;
	}
	skb_len += NLMSG_HDRLEN;
	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, skb_len);
	if (!skb) {
		hdd_info("cfg80211_vendor_cmd_alloc_reply_skb failed");
		return -ENOMEM;
	}
	status = hdd_fill_usable_channels_data(skb, tb, res_msg, count);
	if (status)
		goto fail;
	return cfg80211_vendor_cmd_reply(skb);
fail:
	hdd_err("nla put fail");
	kfree_skb(skb);
	return status;
}
/**
 * __wlan_hdd_cfg80211_get_usable_channel() - get chain rssi
 * @wiphy: wiphy pointer
@@ -15047,6 +15160,12 @@ static int __wlan_hdd_cfg80211_get_usable_channel(struct wiphy *wiphy,
	}
	hdd_debug("usable channel count : %d", count);
	status = hdd_send_usable_channel(hdd_ctx, res_msg, count, tb);
	if (status) {
		hdd_err("failed to send usable_channels");
		return status;
	}
	return qdf_status_to_os_return(status);
}