Loading core/hdd/src/wlan_hdd_cfg80211.c +119 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); } Loading Loading
core/hdd/src/wlan_hdd_cfg80211.c +119 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); } Loading