Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     3)  * This is the new netlink-based wireless configuration interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     5)  * Copyright 2006-2010	Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     6)  * Copyright 2013-2014  Intel Mobile Communications GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     7)  * Copyright 2015-2017	Intel Deutschland GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     8)  * Copyright (C) 2018-2021 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    11) #include <linux/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    15) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    16) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    17) #include <linux/ieee80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    18) #include <linux/nl80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    19) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    20) #include <linux/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    21) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    22) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    23) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    24) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    25) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    26) #include <net/cfg80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    27) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    28) #include <net/inet_connection_sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    29) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    30) #include "nl80211.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    31) #include "reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    32) #include "rdev-ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    34) static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    35) 				   struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    36) 				   struct cfg80211_crypto_settings *settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    37) 				   int cipher_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    39) /* the netlink family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    40) static struct genl_family nl80211_fam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    42) /* multicast groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    43) enum nl80211_multicast_groups {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    44) 	NL80211_MCGRP_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    45) 	NL80211_MCGRP_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    46) 	NL80211_MCGRP_REGULATORY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    47) 	NL80211_MCGRP_MLME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    48) 	NL80211_MCGRP_VENDOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    49) 	NL80211_MCGRP_NAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    50) 	NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    53) static const struct genl_multicast_group nl80211_mcgrps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    54) 	[NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    55) 	[NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    56) 	[NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    57) 	[NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    58) 	[NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    59) 	[NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    60) #ifdef CONFIG_NL80211_TESTMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    61) 	[NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    62) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    65) /* returns ERR_PTR values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    66) static struct wireless_dev *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    67) __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    69) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    70) 	struct wireless_dev *result = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    71) 	bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    72) 	bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    73) 	u64 wdev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    74) 	int wiphy_idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    75) 	int ifidx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    77) 	ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    79) 	if (!have_ifidx && !have_wdev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    80) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    82) 	if (have_ifidx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    83) 		ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    84) 	if (have_wdev_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    85) 		wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    86) 		wiphy_idx = wdev_id >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    89) 	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    90) 		struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    92) 		if (wiphy_net(&rdev->wiphy) != netns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    93) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    95) 		if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    96) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    98) 		list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    99) 			if (have_ifidx && wdev->netdev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   100) 			    wdev->netdev->ifindex == ifidx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   101) 				result = wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   102) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   103) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   104) 			if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   105) 				result = wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   106) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   107) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   108) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   110) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   111) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   114) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   115) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   116) 	return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   119) static struct cfg80211_registered_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   120) __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   122) 	struct cfg80211_registered_device *rdev = NULL, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   123) 	struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   125) 	ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   127) 	if (!attrs[NL80211_ATTR_WIPHY] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   128) 	    !attrs[NL80211_ATTR_IFINDEX] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   129) 	    !attrs[NL80211_ATTR_WDEV])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   130) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   132) 	if (attrs[NL80211_ATTR_WIPHY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   133) 		rdev = cfg80211_rdev_by_wiphy_idx(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   134) 				nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   136) 	if (attrs[NL80211_ATTR_WDEV]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   137) 		u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   138) 		struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   139) 		bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   141) 		tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   142) 		if (tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   143) 			/* make sure wdev exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   144) 			list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   145) 				if (wdev->identifier != (u32)wdev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   146) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   147) 				found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   148) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   149) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   151) 			if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   152) 				tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   154) 			if (rdev && tmp != rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   155) 				return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   156) 			rdev = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   157) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   158) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   160) 	if (attrs[NL80211_ATTR_IFINDEX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   161) 		int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   163) 		netdev = __dev_get_by_index(netns, ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   164) 		if (netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   165) 			if (netdev->ieee80211_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   166) 				tmp = wiphy_to_rdev(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   167) 					netdev->ieee80211_ptr->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   168) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   169) 				tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   171) 			/* not wireless device -- return error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   172) 			if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   173) 				return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   175) 			/* mismatch -- return error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   176) 			if (rdev && tmp != rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   177) 				return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   179) 			rdev = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   180) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   181) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   183) 	if (!rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   184) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   186) 	if (netns != wiphy_net(&rdev->wiphy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   187) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   189) 	return rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   193)  * This function returns a pointer to the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   194)  * that the genl_info item that is passed refers to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   195)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   196)  * The result of this can be a PTR_ERR and hence must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   197)  * be checked with IS_ERR() for errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   198)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   199) static struct cfg80211_registered_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   200) cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   202) 	return __cfg80211_rdev_from_attrs(netns, info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   205) static int validate_beacon_head(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   206) 				struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   208) 	const u8 *data = nla_data(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   209) 	unsigned int len = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   210) 	const struct element *elem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   211) 	const struct ieee80211_mgmt *mgmt = (void *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   212) 	unsigned int fixedlen, hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   213) 	bool s1g_bcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   215) 	if (len < offsetofend(typeof(*mgmt), frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   216) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   218) 	s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   219) 	if (s1g_bcn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   220) 		fixedlen = offsetof(struct ieee80211_ext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   221) 				    u.s1g_beacon.variable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   222) 		hdrlen = offsetof(struct ieee80211_ext, u.s1g_beacon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   223) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   224) 		fixedlen = offsetof(struct ieee80211_mgmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   225) 				    u.beacon.variable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   226) 		hdrlen = offsetof(struct ieee80211_mgmt, u.beacon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   229) 	if (len < fixedlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   230) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   232) 	if (ieee80211_hdrlen(mgmt->frame_control) != hdrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   233) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   235) 	data += fixedlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   236) 	len -= fixedlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   238) 	for_each_element(elem, data, len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   239) 		/* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   242) 	if (for_each_element_completed(elem, data, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   243) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   245) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   246) 	NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   247) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   250) static int validate_ie_attr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   251) 			    struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   253) 	const u8 *data = nla_data(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   254) 	unsigned int len = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   255) 	const struct element *elem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   257) 	for_each_element(elem, data, len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   258) 		/* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   261) 	if (for_each_element_completed(elem, data, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   262) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   264) 	NL_SET_ERR_MSG_ATTR(extack, attr, "malformed information elements");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   265) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   268) /* policy for the attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   269) static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   271) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   272) nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   273) 	[NL80211_FTM_RESP_ATTR_ENABLED] = { .type = NLA_FLAG, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   274) 	[NL80211_FTM_RESP_ATTR_LCI] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   275) 					.len = U8_MAX },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   276) 	[NL80211_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   277) 					     .len = U8_MAX },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   280) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   281) nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   282) 	[NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   283) 	[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   284) 	[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   285) 		NLA_POLICY_MAX(NLA_U8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   286) 	[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   287) 	[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   288) 		NLA_POLICY_MAX(NLA_U8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   289) 	[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   290) 		NLA_POLICY_MAX(NLA_U8, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   291) 	[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   292) 	[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   293) 	[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   294) 	[NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   295) 	[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   296) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   298) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   299) nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   300) 	[NL80211_PMSR_TYPE_FTM] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   301) 		NLA_POLICY_NESTED(nl80211_pmsr_ftm_req_attr_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   304) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   305) nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   306) 	[NL80211_PMSR_REQ_ATTR_DATA] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   307) 		NLA_POLICY_NESTED(nl80211_pmsr_req_data_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   308) 	[NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   309) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   311) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   312) nl80211_psmr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   313) 	[NL80211_PMSR_PEER_ATTR_ADDR] = NLA_POLICY_ETH_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   314) 	[NL80211_PMSR_PEER_ATTR_CHAN] = NLA_POLICY_NESTED(nl80211_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   315) 	[NL80211_PMSR_PEER_ATTR_REQ] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   316) 		NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   317) 	[NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   320) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   321) nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   322) 	[NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   323) 	[NL80211_PMSR_ATTR_REPORT_AP_TSF] = { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   324) 	[NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   325) 	[NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   326) 	[NL80211_PMSR_ATTR_PEERS] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   327) 		NLA_POLICY_NESTED_ARRAY(nl80211_psmr_peer_attr_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   328) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   330) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   331) he_obss_pd_policy[NL80211_HE_OBSS_PD_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   332) 	[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   333) 		NLA_POLICY_RANGE(NLA_U8, 1, 20),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   334) 	[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   335) 		NLA_POLICY_RANGE(NLA_U8, 1, 20),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   336) 	[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   337) 		NLA_POLICY_RANGE(NLA_U8, 1, 20),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   338) 	[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   339) 		NLA_POLICY_EXACT_LEN(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   340) 	[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   341) 		NLA_POLICY_EXACT_LEN(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   342) 	[NL80211_HE_OBSS_PD_ATTR_SR_CTRL] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   345) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   346) he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   347) 	[NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   348) 	[NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   349) 	[NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   352) static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   353) 	[NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   354) 				    .len = NL80211_MAX_SUPP_RATES },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   355) 	[NL80211_TXRATE_HT] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   356) 				.len = NL80211_MAX_SUPP_HT_RATES },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   357) 	[NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   358) 	[NL80211_TXRATE_GI] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   359) 	[NL80211_TXRATE_HE] = NLA_POLICY_EXACT_LEN(sizeof(struct nl80211_txrate_he)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   360) 	[NL80211_TXRATE_HE_GI] =  NLA_POLICY_RANGE(NLA_U8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   361) 						   NL80211_RATE_INFO_HE_GI_0_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   362) 						   NL80211_RATE_INFO_HE_GI_3_2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   363) 	[NL80211_TXRATE_HE_LTF] = NLA_POLICY_RANGE(NLA_U8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   364) 						   NL80211_RATE_INFO_HE_1XLTF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   365) 						   NL80211_RATE_INFO_HE_4XLTF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   366) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   368) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   369) nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   370) 	[NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   371) 	[NL80211_TID_CONFIG_ATTR_PEER_SUPP] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   372) 	[NL80211_TID_CONFIG_ATTR_OVERRIDE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   373) 	[NL80211_TID_CONFIG_ATTR_TIDS] = NLA_POLICY_RANGE(NLA_U16, 1, 0xff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   374) 	[NL80211_TID_CONFIG_ATTR_NOACK] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   375) 			NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   376) 	[NL80211_TID_CONFIG_ATTR_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   377) 	[NL80211_TID_CONFIG_ATTR_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   378) 	[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   379) 			NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   380) 	[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   381) 			NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   382) 	[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   383) 			NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   384) 	[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   385) 			NLA_POLICY_MAX(NLA_U8, NL80211_TX_RATE_FIXED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   386) 	[NL80211_TID_CONFIG_ATTR_TX_RATE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   387) 			NLA_POLICY_NESTED(nl80211_txattr_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   390) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   391) nl80211_fils_discovery_policy[NL80211_FILS_DISCOVERY_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   392) 	[NL80211_FILS_DISCOVERY_ATTR_INT_MIN] = NLA_POLICY_MAX(NLA_U32, 10000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   393) 	[NL80211_FILS_DISCOVERY_ATTR_INT_MAX] = NLA_POLICY_MAX(NLA_U32, 10000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   394) 	NLA_POLICY_RANGE(NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   395) 			 NL80211_FILS_DISCOVERY_TMPL_MIN_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   396) 			 IEEE80211_MAX_DATA_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   397) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   399) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   400) nl80211_unsol_bcast_probe_resp_policy[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   401) 	[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] = NLA_POLICY_MAX(NLA_U32, 20),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   402) 	[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   403) 						       .len = IEEE80211_MAX_DATA_LEN }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   404) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   406) static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   407) 	[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   408) 	[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   409) 	[NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   410) 				      .len = 20-1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   411) 	[NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   413) 	[NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   414) 	[NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   415) 	[NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   416) 						NL80211_EDMG_CHANNELS_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   417) 						NL80211_EDMG_CHANNELS_MAX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   418) 	[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   419) 						NL80211_EDMG_BW_CONFIG_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   420) 						NL80211_EDMG_BW_CONFIG_MAX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   422) 	[NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   423) 	[NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   424) 	[NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   425) 	[NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   427) 	[NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   428) 	[NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   429) 	[NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   430) 	[NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   431) 	[NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   432) 	[NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   434) 	[NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   435) 	[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   436) 	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   438) 	[NL80211_ATTR_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   439) 	[NL80211_ATTR_PREV_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   441) 	[NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   442) 	[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   443) 				    .len = WLAN_MAX_KEY_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   444) 	[NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   445) 	[NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   446) 	[NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   447) 	[NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   448) 	[NL80211_ATTR_KEY_TYPE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   449) 		NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   451) 	[NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   452) 	[NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   453) 	[NL80211_ATTR_BEACON_HEAD] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   454) 		NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   455) 				       IEEE80211_MAX_DATA_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   456) 	[NL80211_ATTR_BEACON_TAIL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   457) 		NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   458) 				       IEEE80211_MAX_DATA_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   459) 	[NL80211_ATTR_STA_AID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   460) 		NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   461) 	[NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   462) 	[NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   463) 	[NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   464) 					       .len = NL80211_MAX_SUPP_RATES },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   465) 	[NL80211_ATTR_STA_PLINK_ACTION] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   466) 		NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   467) 	[NL80211_ATTR_STA_TX_POWER_SETTING] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   468) 		NLA_POLICY_RANGE(NLA_U8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   469) 				 NL80211_TX_POWER_AUTOMATIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   470) 				 NL80211_TX_POWER_FIXED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   471) 	[NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   472) 	[NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   473) 	[NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   474) 	[NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   475) 				   .len = IEEE80211_MAX_MESH_ID_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   476) 	[NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   478) 	/* allow 3 for NUL-termination, we used to declare this NLA_STRING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   479) 	[NL80211_ATTR_REG_ALPHA2] = NLA_POLICY_RANGE(NLA_BINARY, 2, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   480) 	[NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   482) 	[NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   483) 	[NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   484) 	[NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   485) 	[NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   486) 					   .len = NL80211_MAX_SUPP_RATES },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   487) 	[NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   489) 	[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   490) 	[NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   492) 	[NL80211_ATTR_HT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_HT_CAPABILITY_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   494) 	[NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   495) 	[NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   496) 						   validate_ie_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   497) 						   IEEE80211_MAX_DATA_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   498) 	[NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   499) 	[NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   501) 	[NL80211_ATTR_SSID] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   502) 				.len = IEEE80211_MAX_SSID_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   503) 	[NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   504) 	[NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   505) 	[NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   506) 	[NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   507) 	[NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   508) 						  NL80211_MFP_NO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   509) 						  NL80211_MFP_OPTIONAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   510) 	[NL80211_ATTR_STA_FLAGS2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   511) 		.len = sizeof(struct nl80211_sta_flag_update),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   512) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   513) 	[NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   514) 	[NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   515) 	[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   516) 	[NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   517) 	[NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   518) 	[NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   519) 	[NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   520) 	[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   521) 	[NL80211_ATTR_PID] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   522) 	[NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   523) 	[NL80211_ATTR_PMKID] = NLA_POLICY_EXACT_LEN_WARN(WLAN_PMKID_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   524) 	[NL80211_ATTR_DURATION] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   525) 	[NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   526) 	[NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   527) 	[NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   528) 				 .len = IEEE80211_MAX_DATA_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   529) 	[NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   530) 	[NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   531) 						   NL80211_PS_DISABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   532) 						   NL80211_PS_ENABLED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   533) 	[NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   534) 	[NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   535) 	[NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   536) 	[NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   537) 	[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   538) 	[NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   539) 	[NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   540) 	[NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   541) 	[NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   542) 	[NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   543) 	[NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   544) 	[NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   545) 	[NL80211_ATTR_STA_PLINK_STATE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   546) 		NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   547) 	[NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   548) 	[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   549) 	[NL80211_ATTR_MESH_PEER_AID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   550) 		NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   551) 	[NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   552) 	[NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   553) 	[NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   554) 	[NL80211_ATTR_HIDDEN_SSID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   555) 		NLA_POLICY_RANGE(NLA_U32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   556) 				 NL80211_HIDDEN_SSID_NOT_IN_USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   557) 				 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   558) 	[NL80211_ATTR_IE_PROBE_RESP] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   559) 		NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   560) 				       IEEE80211_MAX_DATA_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   561) 	[NL80211_ATTR_IE_ASSOC_RESP] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   562) 		NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   563) 				       IEEE80211_MAX_DATA_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   564) 	[NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   565) 	[NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   566) 	[NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   567) 	[NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   568) 	[NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   569) 	[NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   570) 	[NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   571) 	[NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   572) 	[NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   573) 	[NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   574) 	[NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   575) 				      .len = IEEE80211_MAX_DATA_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   576) 	[NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   577) 	[NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   578) 	[NL80211_ATTR_HT_CAPABILITY_MASK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   579) 		.len = NL80211_HT_CAPABILITY_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   580) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   581) 	[NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   582) 	[NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   583) 	[NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   584) 	[NL80211_ATTR_WDEV] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   585) 	[NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   587) 	/* need to include at least Auth Transaction and Status Code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   588) 	[NL80211_ATTR_AUTH_DATA] = NLA_POLICY_MIN_LEN(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   590) 	[NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   591) 	[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   592) 	[NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   593) 	[NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   594) 	[NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   595) 		NLA_POLICY_RANGE(NLA_U32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   596) 				 NL80211_MESH_POWER_UNKNOWN + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   597) 				 NL80211_MESH_POWER_MAX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   598) 	[NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   599) 	[NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   600) 	[NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   601) 	[NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   602) 	[NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   603) 	[NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   604) 	[NL80211_ATTR_VHT_CAPABILITY_MASK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   605) 		.len = NL80211_VHT_CAPABILITY_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   606) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   607) 	[NL80211_ATTR_MDID] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   608) 	[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   609) 				  .len = IEEE80211_MAX_DATA_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   610) 	[NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   611) 	[NL80211_ATTR_MAX_CRIT_PROT_DURATION] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   612) 		NLA_POLICY_MAX(NLA_U16, NL80211_CRIT_PROTO_MAX_DURATION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   613) 	[NL80211_ATTR_PEER_AID] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   614) 		NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   615) 	[NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   616) 	[NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   617) 	[NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   618) 	[NL80211_ATTR_CNTDWN_OFFS_BEACON] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   619) 	[NL80211_ATTR_CNTDWN_OFFS_PRESP] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   620) 	[NL80211_ATTR_STA_SUPPORTED_CHANNELS] = NLA_POLICY_MIN_LEN(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   621) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   622) 	 * The value of the Length field of the Supported Operating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   623) 	 * Classes element is between 2 and 253.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   624) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   625) 	[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   626) 		NLA_POLICY_RANGE(NLA_BINARY, 2, 253),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   627) 	[NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   628) 	[NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   629) 	[NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   630) 	[NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   631) 	[NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   632) 	[NL80211_ATTR_QOS_MAP] = NLA_POLICY_RANGE(NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   633) 						  IEEE80211_QOS_MAP_LEN_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   634) 						  IEEE80211_QOS_MAP_LEN_MAX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   635) 	[NL80211_ATTR_MAC_HINT] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   636) 	[NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   637) 	[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   638) 	[NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   639) 	[NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   640) 	[NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   641) 	[NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   642) 	[NL80211_ATTR_USER_PRIO] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   643) 		NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   644) 	[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   645) 	[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   646) 	[NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   647) 	[NL80211_ATTR_MAC_MASK] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   648) 	[NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   649) 	[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   650) 	[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   651) 	[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   652) 	[NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   653) 	[NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   654) 	[NL80211_ATTR_STA_SUPPORT_P2P_PS] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   655) 		NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   656) 	[NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   657) 		.len = VHT_MUMIMO_GROUPS_DATA_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   658) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   659) 	[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   660) 	[NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   661) 	[NL80211_ATTR_BANDS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   662) 	[NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   663) 	[NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   664) 				    .len = FILS_MAX_KEK_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   665) 	[NL80211_ATTR_FILS_NONCES] = NLA_POLICY_EXACT_LEN_WARN(2 * FILS_NONCE_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   666) 	[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   667) 	[NL80211_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   668) 	[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   669) 	[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   670) 		.len = sizeof(struct nl80211_bss_select_rssi_adjust)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   671) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   672) 	[NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   673) 	[NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   674) 					     .len = FILS_ERP_MAX_USERNAME_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   675) 	[NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   676) 					  .len = FILS_ERP_MAX_REALM_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   677) 	[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   678) 	[NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   679) 					.len = FILS_ERP_MAX_RRK_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   680) 	[NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   681) 	[NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   682) 	[NL80211_ATTR_PMKR0_NAME] = NLA_POLICY_EXACT_LEN(WLAN_PMK_NAME_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   683) 	[NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   684) 	[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   686) 	[NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   687) 	[NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   688) 	[NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   689) 	[NL80211_ATTR_HE_CAPABILITY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   690) 		NLA_POLICY_RANGE(NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   691) 				 NL80211_HE_MIN_CAPABILITY_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   692) 				 NL80211_HE_MAX_CAPABILITY_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   693) 	[NL80211_ATTR_FTM_RESPONDER] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   694) 		NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   695) 	[NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   696) 	[NL80211_ATTR_PEER_MEASUREMENTS] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   697) 		NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   698) 	[NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   699) 	[NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   700) 					.len = SAE_PASSWORD_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   701) 	[NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   702) 	[NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   703) 	[NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   704) 	[NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   705) 	[NL80211_ATTR_TID_CONFIG] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   706) 		NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   707) 	[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   708) 	[NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   709) 	[NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   710) 	[NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   711) 	[NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   712) 	[NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   713) 	[NL80211_ATTR_HE_6GHZ_CAPABILITY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   714) 		NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   715) 	[NL80211_ATTR_FILS_DISCOVERY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   716) 		NLA_POLICY_NESTED(nl80211_fils_discovery_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   717) 	[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   718) 		NLA_POLICY_NESTED(nl80211_unsol_bcast_probe_resp_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   719) 	[NL80211_ATTR_S1G_CAPABILITY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   720) 		NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   721) 	[NL80211_ATTR_S1G_CAPABILITY_MASK] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   722) 		NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   723) 	[NL80211_ATTR_SAE_PWE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   724) 		NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   725) 				 NL80211_SAE_PWE_BOTH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   726) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   728) /* policy for the key attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   729) static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   730) 	[NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   731) 	[NL80211_KEY_IDX] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   732) 	[NL80211_KEY_CIPHER] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   733) 	[NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   734) 	[NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   735) 	[NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   736) 	[NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   737) 	[NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   738) 	[NL80211_KEY_MODE] = NLA_POLICY_RANGE(NLA_U8, 0, NL80211_KEY_SET_TX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   739) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   741) /* policy for the key default flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   742) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   743) nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   744) 	[NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   745) 	[NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   746) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   748) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   749) /* policy for WoWLAN attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   750) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   751) nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   752) 	[NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   753) 	[NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   754) 	[NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   755) 	[NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   756) 	[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   757) 	[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   758) 	[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   759) 	[NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   760) 	[NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   761) 	[NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   762) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   764) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   765) nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   766) 	[NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   767) 	[NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   768) 	[NL80211_WOWLAN_TCP_DST_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   769) 	[NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   770) 	[NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   771) 	[NL80211_WOWLAN_TCP_DATA_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   772) 	[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   773) 		.len = sizeof(struct nl80211_wowlan_tcp_data_seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   774) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   775) 	[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   776) 		.len = sizeof(struct nl80211_wowlan_tcp_data_token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   777) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   778) 	[NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   779) 	[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   780) 	[NL80211_WOWLAN_TCP_WAKE_MASK] = NLA_POLICY_MIN_LEN(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   781) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   782) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   784) /* policy for coalesce rule attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   785) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   786) nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   787) 	[NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   788) 	[NL80211_ATTR_COALESCE_RULE_CONDITION] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   789) 		NLA_POLICY_RANGE(NLA_U32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   790) 				 NL80211_COALESCE_CONDITION_MATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   791) 				 NL80211_COALESCE_CONDITION_NO_MATCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   792) 	[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   793) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   795) /* policy for GTK rekey offload attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   796) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   797) nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   798) 	[NL80211_REKEY_DATA_KEK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   799) 		.type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   800) 		.len = NL80211_KEK_EXT_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   801) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   802) 	[NL80211_REKEY_DATA_KCK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   803) 		.type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   804) 		.len = NL80211_KCK_EXT_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   805) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   806) 	[NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN(NL80211_REPLAY_CTR_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   807) 	[NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   808) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   810) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   811) nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   812) 	[NL80211_BAND_2GHZ] = { .type = NLA_S32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   813) 	[NL80211_BAND_5GHZ] = { .type = NLA_S32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   814) 	[NL80211_BAND_6GHZ] = { .type = NLA_S32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   815) 	[NL80211_BAND_60GHZ] = { .type = NLA_S32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   816) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   818) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   819) nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   820) 	[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   821) 						 .len = IEEE80211_MAX_SSID_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   822) 	[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   823) 	[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   824) 	[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   825) 		NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   828) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   829) nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   830) 	[NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   831) 	[NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   832) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   834) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   835) nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   836) 	[NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   837) 	[NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   838) 	[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   839) 		.len = sizeof(struct nl80211_bss_select_rssi_adjust)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   840) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   841) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   843) /* policy for NAN function attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   844) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   845) nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   846) 	[NL80211_NAN_FUNC_TYPE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   847) 		NLA_POLICY_MAX(NLA_U8, NL80211_NAN_FUNC_MAX_TYPE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   848) 	[NL80211_NAN_FUNC_SERVICE_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   849) 				    .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   850) 	[NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   851) 	[NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   852) 	[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   853) 	[NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   854) 	[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   855) 	[NL80211_NAN_FUNC_FOLLOW_UP_DEST] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   856) 	[NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   857) 	[NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   858) 	[NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   859) 			.len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   860) 	[NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   861) 	[NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   862) 	[NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   863) 	[NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   864) 	[NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   865) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   867) /* policy for Service Response Filter attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   868) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   869) nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   870) 	[NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   871) 	[NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   872) 				 .len =  NL80211_NAN_FUNC_SRF_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   873) 	[NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   874) 	[NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   875) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   877) /* policy for packet pattern attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   878) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   879) nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   880) 	[NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   881) 	[NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   882) 	[NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   883) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   885) int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   886) 			      struct cfg80211_registered_device **rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   887) 			      struct wireless_dev **wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   889) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   891) 	if (!cb->args[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   892) 		struct nlattr **attrbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   894) 		attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   895) 				  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   896) 		if (!attrbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   897) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   899) 		err = nlmsg_parse_deprecated(cb->nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   900) 					     GENL_HDRLEN + nl80211_fam.hdrsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   901) 					     attrbuf, nl80211_fam.maxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   902) 					     nl80211_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   903) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   904) 			kfree(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   905) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   906) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   908) 		*wdev = __cfg80211_wdev_from_attrs(sock_net(cb->skb->sk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   909) 						   attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   910) 		kfree(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   911) 		if (IS_ERR(*wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   912) 			return PTR_ERR(*wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   913) 		*rdev = wiphy_to_rdev((*wdev)->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   914) 		/* 0 is the first index - add 1 to parse only once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   915) 		cb->args[0] = (*rdev)->wiphy_idx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   916) 		cb->args[1] = (*wdev)->identifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   917) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   918) 		/* subtract the 1 again here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   919) 		struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   920) 		struct wireless_dev *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   922) 		if (!wiphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   923) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   924) 		*rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   925) 		*wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   927) 		list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   928) 			if (tmp->identifier == cb->args[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   929) 				*wdev = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   930) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   931) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   932) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   934) 		if (!*wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   935) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   936) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   938) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   941) /* message building helper */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   942) void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   943) 		     int flags, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   945) 	/* since there is no private header just add the generic one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   946) 	return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   949) static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   950) 				     const struct ieee80211_reg_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   952) 	int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   953) 	struct nlattr *nl_wmm_rules =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   954) 		nla_nest_start_noflag(msg, NL80211_FREQUENCY_ATTR_WMM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   956) 	if (!nl_wmm_rules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   957) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   959) 	for (j = 0; j < IEEE80211_NUM_ACS; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   960) 		struct nlattr *nl_wmm_rule = nla_nest_start_noflag(msg, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   962) 		if (!nl_wmm_rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   963) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   965) 		if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   966) 				rule->wmm_rule.client[j].cw_min) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   967) 		    nla_put_u16(msg, NL80211_WMMR_CW_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   968) 				rule->wmm_rule.client[j].cw_max) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   969) 		    nla_put_u8(msg, NL80211_WMMR_AIFSN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   970) 			       rule->wmm_rule.client[j].aifsn) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   971) 		    nla_put_u16(msg, NL80211_WMMR_TXOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   972) 			        rule->wmm_rule.client[j].cot))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   973) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   975) 		nla_nest_end(msg, nl_wmm_rule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   977) 	nla_nest_end(msg, nl_wmm_rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   979) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   981) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   982) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   985) static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   986) 				   struct ieee80211_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   987) 				   bool large)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   989) 	/* Some channels must be completely excluded from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   990) 	 * list to protect old user-space tools from breaking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   991) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   992) 	if (!large && chan->flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   993) 	    (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   994) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   995) 	if (!large && chan->freq_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   996) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   998) 	if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   999) 			chan->center_freq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1000) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1002) 	if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1003) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1005) 	if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1006) 	    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1007) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1008) 	if (chan->flags & IEEE80211_CHAN_NO_IR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1009) 		if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1010) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1011) 		if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1012) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1013) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1014) 	if (chan->flags & IEEE80211_CHAN_RADAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1015) 		if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1016) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1017) 		if (large) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1018) 			u32 time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1020) 			time = elapsed_jiffies_msecs(chan->dfs_state_entered);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1022) 			if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1023) 					chan->dfs_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1024) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1025) 			if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1026) 					time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1027) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1028) 			if (nla_put_u32(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1029) 					NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1030) 					chan->dfs_cac_ms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1031) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1032) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1033) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1035) 	if (large) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1036) 		if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1037) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1038) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1039) 		if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1040) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1041) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1042) 		if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1043) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1044) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1045) 		if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1046) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1047) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1048) 		if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1049) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1050) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1051) 		if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1052) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1053) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1054) 		if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1055) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1056) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1057) 		if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1058) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1059) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1060) 		if ((chan->flags & IEEE80211_CHAN_NO_HE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1061) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1062) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1063) 		if ((chan->flags & IEEE80211_CHAN_1MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1064) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_1MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1065) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1066) 		if ((chan->flags & IEEE80211_CHAN_2MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1067) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_2MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1068) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1069) 		if ((chan->flags & IEEE80211_CHAN_4MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1070) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_4MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1071) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1072) 		if ((chan->flags & IEEE80211_CHAN_8MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1073) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_8MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1074) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1075) 		if ((chan->flags & IEEE80211_CHAN_16MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1076) 		    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_16MHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1077) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1078) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1080) 	if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1081) 			DBM_TO_MBM(chan->max_power)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1082) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1084) 	if (large) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1085) 		const struct ieee80211_reg_rule *rule =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1086) 			freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1088) 		if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1089) 			if (nl80211_msg_put_wmm_rules(msg, rule))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1090) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1091) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1092) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1094) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1096)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1097) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1100) static bool nl80211_put_txq_stats(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1101) 				  struct cfg80211_txq_stats *txqstats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1102) 				  int attrtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1104) 	struct nlattr *txqattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1106) #define PUT_TXQVAL_U32(attr, memb) do {					  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1107) 	if (txqstats->filled & BIT(NL80211_TXQ_STATS_ ## attr) &&	  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1108) 	    nla_put_u32(msg, NL80211_TXQ_STATS_ ## attr, txqstats->memb)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1109) 		return false;						  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1110) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1112) 	txqattr = nla_nest_start_noflag(msg, attrtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1113) 	if (!txqattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1114) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1116) 	PUT_TXQVAL_U32(BACKLOG_BYTES, backlog_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1117) 	PUT_TXQVAL_U32(BACKLOG_PACKETS, backlog_packets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1118) 	PUT_TXQVAL_U32(FLOWS, flows);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1119) 	PUT_TXQVAL_U32(DROPS, drops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1120) 	PUT_TXQVAL_U32(ECN_MARKS, ecn_marks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1121) 	PUT_TXQVAL_U32(OVERLIMIT, overlimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1122) 	PUT_TXQVAL_U32(OVERMEMORY, overmemory);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1123) 	PUT_TXQVAL_U32(COLLISIONS, collisions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1124) 	PUT_TXQVAL_U32(TX_BYTES, tx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1125) 	PUT_TXQVAL_U32(TX_PACKETS, tx_packets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1126) 	PUT_TXQVAL_U32(MAX_FLOWS, max_flows);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1127) 	nla_nest_end(msg, txqattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1129) #undef PUT_TXQVAL_U32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1130) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1133) /* netlink command implementations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1135) struct key_parse {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1136) 	struct key_params p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1137) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1138) 	int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1139) 	bool def, defmgmt, defbeacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1140) 	bool def_uni, def_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1143) static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1144) 				 struct key_parse *k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1146) 	struct nlattr *tb[NL80211_KEY_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1147) 	int err = nla_parse_nested_deprecated(tb, NL80211_KEY_MAX, key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1148) 					      nl80211_key_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1149) 					      info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1150) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1151) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1153) 	k->def = !!tb[NL80211_KEY_DEFAULT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1154) 	k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1155) 	k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1157) 	if (k->def) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1158) 		k->def_uni = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1159) 		k->def_multi = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1161) 	if (k->defmgmt || k->defbeacon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1162) 		k->def_multi = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1164) 	if (tb[NL80211_KEY_IDX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1165) 		k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1167) 	if (tb[NL80211_KEY_DATA]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1168) 		k->p.key = nla_data(tb[NL80211_KEY_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1169) 		k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1172) 	if (tb[NL80211_KEY_SEQ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1173) 		k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1174) 		k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1177) 	if (tb[NL80211_KEY_CIPHER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1178) 		k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1180) 	if (tb[NL80211_KEY_TYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1181) 		k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1183) 	if (tb[NL80211_KEY_DEFAULT_TYPES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1184) 		struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1186) 		err = nla_parse_nested_deprecated(kdt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1187) 						  NUM_NL80211_KEY_DEFAULT_TYPES - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1188) 						  tb[NL80211_KEY_DEFAULT_TYPES],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1189) 						  nl80211_key_default_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1190) 						  info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1191) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1192) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1194) 		k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1195) 		k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1198) 	if (tb[NL80211_KEY_MODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1199) 		k->p.mode = nla_get_u8(tb[NL80211_KEY_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1201) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1204) static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1206) 	if (info->attrs[NL80211_ATTR_KEY_DATA]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1207) 		k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1208) 		k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1211) 	if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1212) 		k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1213) 		k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1216) 	if (info->attrs[NL80211_ATTR_KEY_IDX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1217) 		k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1219) 	if (info->attrs[NL80211_ATTR_KEY_CIPHER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1220) 		k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1222) 	k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1223) 	k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1225) 	if (k->def) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1226) 		k->def_uni = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1227) 		k->def_multi = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1229) 	if (k->defmgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1230) 		k->def_multi = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1232) 	if (info->attrs[NL80211_ATTR_KEY_TYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1233) 		k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1235) 	if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1236) 		struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1237) 		int err = nla_parse_nested_deprecated(kdt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1238) 						      NUM_NL80211_KEY_DEFAULT_TYPES - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1239) 						      info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1240) 						      nl80211_key_default_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1241) 						      info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1242) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1243) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1245) 		k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1246) 		k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1249) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1252) static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1254) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1256) 	memset(k, 0, sizeof(*k));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1257) 	k->idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1258) 	k->type = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1260) 	if (info->attrs[NL80211_ATTR_KEY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1261) 		err = nl80211_parse_key_new(info, info->attrs[NL80211_ATTR_KEY], k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1262) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1263) 		err = nl80211_parse_key_old(info, k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1265) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1266) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1268) 	if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1269) 	    (k->defbeacon ? 1 : 0) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1270) 		GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1271) 				 "key with multiple default flags is invalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1272) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1273) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1275) 	if (k->defmgmt || k->defbeacon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1276) 		if (k->def_uni || !k->def_multi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1277) 			GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1278) 					 "defmgmt/defbeacon key must be mcast");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1279) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1280) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1283) 	if (k->idx != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1284) 		if (k->defmgmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1285) 			if (k->idx < 4 || k->idx > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1286) 				GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1287) 						 "defmgmt key idx not 4 or 5");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1288) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1289) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1290) 		} else if (k->defbeacon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1291) 			if (k->idx < 6 || k->idx > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1292) 				GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1293) 						 "defbeacon key idx not 6 or 7");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1294) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1295) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1296) 		} else if (k->def) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1297) 			if (k->idx < 0 || k->idx > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1298) 				GENL_SET_ERR_MSG(info, "def key idx not 0-3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1299) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1300) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1301) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1302) 			if (k->idx < 0 || k->idx > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1303) 				GENL_SET_ERR_MSG(info, "key idx not 0-7");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1304) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1305) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1306) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1309) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1312) static struct cfg80211_cached_keys *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1313) nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1314) 		       struct genl_info *info, bool *no_ht)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1316) 	struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1317) 	struct key_parse parse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1318) 	struct nlattr *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1319) 	struct cfg80211_cached_keys *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1320) 	int rem, err, def = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1321) 	bool have_key = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1323) 	nla_for_each_nested(key, keys, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1324) 		have_key = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1325) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1326) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1328) 	if (!have_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1329) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1331) 	result = kzalloc(sizeof(*result), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1332) 	if (!result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1333) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1335) 	result->def = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1337) 	nla_for_each_nested(key, keys, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1338) 		memset(&parse, 0, sizeof(parse));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1339) 		parse.idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1341) 		err = nl80211_parse_key_new(info, key, &parse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1342) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1343) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1344) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1345) 		if (!parse.p.key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1346) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1347) 		if (parse.idx < 0 || parse.idx > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1348) 			GENL_SET_ERR_MSG(info, "key index out of range [0-3]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1349) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1350) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1351) 		if (parse.def) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1352) 			if (def) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1353) 				GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1354) 						 "only one key can be default");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1355) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1356) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1357) 			def = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1358) 			result->def = parse.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1359) 			if (!parse.def_uni || !parse.def_multi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1360) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1361) 		} else if (parse.defmgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1362) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1363) 		err = cfg80211_validate_key_settings(rdev, &parse.p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1364) 						     parse.idx, false, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1365) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1366) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1367) 		if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1368) 		    parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1369) 			GENL_SET_ERR_MSG(info, "connect key must be WEP");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1370) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1371) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1372) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1373) 		result->params[parse.idx].cipher = parse.p.cipher;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1374) 		result->params[parse.idx].key_len = parse.p.key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1375) 		result->params[parse.idx].key = result->data[parse.idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1376) 		memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1378) 		/* must be WEP key if we got here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1379) 		if (no_ht)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1380) 			*no_ht = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1383) 	if (result->def < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1384) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1385) 		GENL_SET_ERR_MSG(info, "need a default/TX key");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1386) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1389) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1390)  error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1391) 	kfree(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1392) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1395) static int nl80211_key_allowed(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1397) 	ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1399) 	switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1400) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1401) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1402) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1403) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1404) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1405) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1406) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1407) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1408) 		if (!wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1409) 			return -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1410) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1411) 	case NL80211_IFTYPE_UNSPECIFIED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1412) 	case NL80211_IFTYPE_OCB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1413) 	case NL80211_IFTYPE_MONITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1414) 	case NL80211_IFTYPE_NAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1415) 	case NL80211_IFTYPE_P2P_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1416) 	case NL80211_IFTYPE_WDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1417) 	case NUM_NL80211_IFTYPES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1418) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1421) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1424) static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1425) 							u32 freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1427) 	struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1429) 	chan = ieee80211_get_channel_khz(wiphy, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1430) 	if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1431) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1432) 	return chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1435) static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1437) 	struct nlattr *nl_modes = nla_nest_start_noflag(msg, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1438) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1440) 	if (!nl_modes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1441) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1443) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1444) 	while (ifmodes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1445) 		if ((ifmodes & 1) && nla_put_flag(msg, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1446) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1447) 		ifmodes >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1448) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1451) 	nla_nest_end(msg, nl_modes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1452) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1454) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1455) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1458) static int nl80211_put_iface_combinations(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1459) 					  struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1460) 					  bool large)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1462) 	struct nlattr *nl_combis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1463) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1465) 	nl_combis = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1466) 					  NL80211_ATTR_INTERFACE_COMBINATIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1467) 	if (!nl_combis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1468) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1470) 	for (i = 0; i < wiphy->n_iface_combinations; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1471) 		const struct ieee80211_iface_combination *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1472) 		struct nlattr *nl_combi, *nl_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1474) 		c = &wiphy->iface_combinations[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1476) 		nl_combi = nla_nest_start_noflag(msg, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1477) 		if (!nl_combi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1478) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1480) 		nl_limits = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1481) 						  NL80211_IFACE_COMB_LIMITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1482) 		if (!nl_limits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1483) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1485) 		for (j = 0; j < c->n_limits; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1486) 			struct nlattr *nl_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1488) 			nl_limit = nla_nest_start_noflag(msg, j + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1489) 			if (!nl_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1490) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1491) 			if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1492) 					c->limits[j].max))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1493) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1494) 			if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1495) 						c->limits[j].types))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1496) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1497) 			nla_nest_end(msg, nl_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1498) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1500) 		nla_nest_end(msg, nl_limits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1502) 		if (c->beacon_int_infra_match &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1503) 		    nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1504) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1505) 		if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1506) 				c->num_different_channels) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1507) 		    nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1508) 				c->max_interfaces))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1509) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1510) 		if (large &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1511) 		    (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1512) 				c->radar_detect_widths) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1513) 		     nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1514) 				c->radar_detect_regions)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1515) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1516) 		if (c->beacon_int_min_gcd &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1517) 		    nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1518) 				c->beacon_int_min_gcd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1519) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1521) 		nla_nest_end(msg, nl_combi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1524) 	nla_nest_end(msg, nl_combis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1526) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1527) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1528) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1531) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1532) static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1533) 					struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1535) 	const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1536) 	struct nlattr *nl_tcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1538) 	if (!tcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1539) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1541) 	nl_tcp = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1542) 				       NL80211_WOWLAN_TRIG_TCP_CONNECTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1543) 	if (!nl_tcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1544) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1546) 	if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1547) 			tcp->data_payload_max))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1548) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1550) 	if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1551) 			tcp->data_payload_max))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1552) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1554) 	if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1555) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1557) 	if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1558) 				sizeof(*tcp->tok), tcp->tok))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1559) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1561) 	if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1562) 			tcp->data_interval_max))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1563) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1565) 	if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1566) 			tcp->wake_payload_max))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1567) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1569) 	nla_nest_end(msg, nl_tcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1570) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1573) static int nl80211_send_wowlan(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1574) 			       struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1575) 			       bool large)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1577) 	struct nlattr *nl_wowlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1579) 	if (!rdev->wiphy.wowlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1580) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1582) 	nl_wowlan = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1583) 					  NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1584) 	if (!nl_wowlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1585) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1587) 	if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1588) 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1589) 	    ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1590) 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1591) 	    ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1592) 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1593) 	    ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1594) 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1595) 	    ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1596) 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1597) 	    ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1598) 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1599) 	    ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1600) 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1601) 	    ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1602) 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1603) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1605) 	if (rdev->wiphy.wowlan->n_patterns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1606) 		struct nl80211_pattern_support pat = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1607) 			.max_patterns = rdev->wiphy.wowlan->n_patterns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1608) 			.min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1609) 			.max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1610) 			.max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1611) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1613) 		if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1614) 			    sizeof(pat), &pat))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1615) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1616) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1618) 	if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1619) 	    nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1620) 			rdev->wiphy.wowlan->max_nd_match_sets))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1621) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1623) 	if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1624) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1626) 	nla_nest_end(msg, nl_wowlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1628) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1630) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1632) static int nl80211_send_coalesce(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1633) 				 struct cfg80211_registered_device *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1635) 	struct nl80211_coalesce_rule_support rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1637) 	if (!rdev->wiphy.coalesce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1638) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1640) 	rule.max_rules = rdev->wiphy.coalesce->n_rules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1641) 	rule.max_delay = rdev->wiphy.coalesce->max_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1642) 	rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1643) 	rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1644) 	rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1645) 	rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1647) 	if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1648) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1650) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1653) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1654) nl80211_send_iftype_data(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1655) 			 const struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1656) 			 const struct ieee80211_sband_iftype_data *iftdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1658) 	const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1660) 	if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1661) 				iftdata->types_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1662) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1664) 	if (he_cap->has_he) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1665) 		if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1666) 			    sizeof(he_cap->he_cap_elem.mac_cap_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1667) 			    he_cap->he_cap_elem.mac_cap_info) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1668) 		    nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1669) 			    sizeof(he_cap->he_cap_elem.phy_cap_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1670) 			    he_cap->he_cap_elem.phy_cap_info) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1671) 		    nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1672) 			    sizeof(he_cap->he_mcs_nss_supp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1673) 			    &he_cap->he_mcs_nss_supp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1674) 		    nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1675) 			    sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1676) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1679) 	if (sband->band == NL80211_BAND_6GHZ &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1680) 	    nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1681) 		    sizeof(iftdata->he_6ghz_capa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1682) 		    &iftdata->he_6ghz_capa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1683) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1685) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1688) static int nl80211_send_band_rateinfo(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1689) 				      struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1690) 				      bool large)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1692) 	struct nlattr *nl_rates, *nl_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1693) 	struct ieee80211_rate *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1694) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1696) 	/* add HT info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1697) 	if (sband->ht_cap.ht_supported &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1698) 	    (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1699) 		     sizeof(sband->ht_cap.mcs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1700) 		     &sband->ht_cap.mcs) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1701) 	     nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1702) 			 sband->ht_cap.cap) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1703) 	     nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1704) 			sband->ht_cap.ampdu_factor) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1705) 	     nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1706) 			sband->ht_cap.ampdu_density)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1707) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1709) 	/* add VHT info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1710) 	if (sband->vht_cap.vht_supported &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1711) 	    (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1712) 		     sizeof(sband->vht_cap.vht_mcs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1713) 		     &sband->vht_cap.vht_mcs) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1714) 	     nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1715) 			 sband->vht_cap.cap)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1716) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1718) 	if (large && sband->n_iftype_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1719) 		struct nlattr *nl_iftype_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1720) 			nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1721) 					      NL80211_BAND_ATTR_IFTYPE_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1722) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1724) 		if (!nl_iftype_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1725) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1727) 		for (i = 0; i < sband->n_iftype_data; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1728) 			struct nlattr *iftdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1730) 			iftdata = nla_nest_start_noflag(msg, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1731) 			if (!iftdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1732) 				return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1734) 			err = nl80211_send_iftype_data(msg, sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1735) 						       &sband->iftype_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1736) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1737) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1739) 			nla_nest_end(msg, iftdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1740) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1742) 		nla_nest_end(msg, nl_iftype_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1745) 	/* add EDMG info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1746) 	if (large && sband->edmg_cap.channels &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1747) 	    (nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1748) 		       sband->edmg_cap.channels) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1749) 	    nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_BW_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1750) 		       sband->edmg_cap.bw_config)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1752) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1754) 	/* add bitrates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1755) 	nl_rates = nla_nest_start_noflag(msg, NL80211_BAND_ATTR_RATES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1756) 	if (!nl_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1757) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1759) 	for (i = 0; i < sband->n_bitrates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1760) 		nl_rate = nla_nest_start_noflag(msg, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1761) 		if (!nl_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1762) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1764) 		rate = &sband->bitrates[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1765) 		if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1766) 				rate->bitrate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1767) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1768) 		if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1769) 		    nla_put_flag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1770) 				 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1771) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1773) 		nla_nest_end(msg, nl_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1774) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1776) 	nla_nest_end(msg, nl_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1778) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1781) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1782) nl80211_send_mgmt_stypes(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1783) 			 const struct ieee80211_txrx_stypes *mgmt_stypes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1785) 	u16 stypes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1786) 	struct nlattr *nl_ftypes, *nl_ifs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1787) 	enum nl80211_iftype ift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1788) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1790) 	if (!mgmt_stypes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1791) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1793) 	nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_TX_FRAME_TYPES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1794) 	if (!nl_ifs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1795) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1797) 	for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1798) 		nl_ftypes = nla_nest_start_noflag(msg, ift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1799) 		if (!nl_ftypes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1800) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1801) 		i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1802) 		stypes = mgmt_stypes[ift].tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1803) 		while (stypes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1804) 			if ((stypes & 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1805) 			    nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1806) 					(i << 4) | IEEE80211_FTYPE_MGMT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1807) 				return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1808) 			stypes >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1809) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1810) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1811) 		nla_nest_end(msg, nl_ftypes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1812) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1814) 	nla_nest_end(msg, nl_ifs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1816) 	nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_RX_FRAME_TYPES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1817) 	if (!nl_ifs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1818) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1820) 	for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1821) 		nl_ftypes = nla_nest_start_noflag(msg, ift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1822) 		if (!nl_ftypes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1823) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1824) 		i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1825) 		stypes = mgmt_stypes[ift].rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1826) 		while (stypes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1827) 			if ((stypes & 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1828) 			    nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1829) 					(i << 4) | IEEE80211_FTYPE_MGMT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1830) 				return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1831) 			stypes >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1832) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1833) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1834) 		nla_nest_end(msg, nl_ftypes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1836) 	nla_nest_end(msg, nl_ifs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1838) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1841) #define CMD(op, n)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1842) 	 do {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1843) 		if (rdev->ops->op) {					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1844) 			i++;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1845) 			if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) 	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1846) 				goto nla_put_failure;			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1847) 		}							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1848) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1850) static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1851) 					struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1853) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1855) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1856) 	 * do *NOT* add anything into this function, new things need to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1857) 	 * advertised only to new versions of userspace that can deal with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1858) 	 * the split (and they can't possibly care about new features...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1859) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1860) 	CMD(add_virtual_intf, NEW_INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1861) 	CMD(change_virtual_intf, SET_INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1862) 	CMD(add_key, NEW_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1863) 	CMD(start_ap, START_AP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1864) 	CMD(add_station, NEW_STATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1865) 	CMD(add_mpath, NEW_MPATH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1866) 	CMD(update_mesh_config, SET_MESH_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1867) 	CMD(change_bss, SET_BSS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1868) 	CMD(auth, AUTHENTICATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1869) 	CMD(assoc, ASSOCIATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1870) 	CMD(deauth, DEAUTHENTICATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1871) 	CMD(disassoc, DISASSOCIATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1872) 	CMD(join_ibss, JOIN_IBSS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1873) 	CMD(join_mesh, JOIN_MESH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1874) 	CMD(set_pmksa, SET_PMKSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1875) 	CMD(del_pmksa, DEL_PMKSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1876) 	CMD(flush_pmksa, FLUSH_PMKSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1877) 	if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1878) 		CMD(remain_on_channel, REMAIN_ON_CHANNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1879) 	CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1880) 	CMD(mgmt_tx, FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1881) 	CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1882) 	if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1883) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1884) 		if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1885) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1886) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1887) 	if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1888) 	    rdev->ops->join_mesh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1889) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1890) 		if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1891) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1892) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1893) 	CMD(set_wds_peer, SET_WDS_PEER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1894) 	if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1895) 		CMD(tdls_mgmt, TDLS_MGMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1896) 		CMD(tdls_oper, TDLS_OPER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1897) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1898) 	if (rdev->wiphy.max_sched_scan_reqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1899) 		CMD(sched_scan_start, START_SCHED_SCAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1900) 	CMD(probe_client, PROBE_CLIENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1901) 	CMD(set_noack_map, SET_NOACK_MAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1902) 	if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1903) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1904) 		if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1905) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1906) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1907) 	CMD(start_p2p_device, START_P2P_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1908) 	CMD(set_mcast_rate, SET_MCAST_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1909) #ifdef CONFIG_NL80211_TESTMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1910) 	CMD(testmode_cmd, TESTMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1911) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1913) 	if (rdev->ops->connect || rdev->ops->auth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1914) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1915) 		if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1916) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1917) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1919) 	if (rdev->ops->disconnect || rdev->ops->deauth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1920) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1921) 		if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1922) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1923) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1925) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1926)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1927) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1930) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1931) nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1932) 			   struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1934) 	struct nlattr *ftm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1936) 	if (!cap->ftm.supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1937) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1939) 	ftm = nla_nest_start_noflag(msg, NL80211_PMSR_TYPE_FTM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1940) 	if (!ftm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1941) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1943) 	if (cap->ftm.asap && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_ASAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1944) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1945) 	if (cap->ftm.non_asap &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1946) 	    nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1947) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1948) 	if (cap->ftm.request_lci &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1949) 	    nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1950) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1951) 	if (cap->ftm.request_civicloc &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1952) 	    nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1953) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1954) 	if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1955) 			cap->ftm.preambles))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1956) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1957) 	if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1958) 			cap->ftm.bandwidths))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1959) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1960) 	if (cap->ftm.max_bursts_exponent >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1961) 	    nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1962) 			cap->ftm.max_bursts_exponent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1963) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1964) 	if (cap->ftm.max_ftms_per_burst &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1965) 	    nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1966) 			cap->ftm.max_ftms_per_burst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1967) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1968) 	if (cap->ftm.trigger_based &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1969) 	    nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1970) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1971) 	if (cap->ftm.non_trigger_based &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1972) 	    nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1973) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1975) 	nla_nest_end(msg, ftm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1976) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1979) static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1980) 				  struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1982) 	const struct cfg80211_pmsr_capabilities *cap = rdev->wiphy.pmsr_capa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1983) 	struct nlattr *pmsr, *caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1985) 	if (!cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1986) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1988) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1989) 	 * we don't need to clean up anything here since the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1990) 	 * will genlmsg_cancel() if we fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1991) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1993) 	pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1994) 	if (!pmsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1995) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1997) 	if (nla_put_u32(msg, NL80211_PMSR_ATTR_MAX_PEERS, cap->max_peers))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1998) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2000) 	if (cap->report_ap_tsf &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2001) 	    nla_put_flag(msg, NL80211_PMSR_ATTR_REPORT_AP_TSF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2002) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2004) 	if (cap->randomize_mac_addr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2005) 	    nla_put_flag(msg, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2006) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2008) 	caps = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_TYPE_CAPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2009) 	if (!caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2010) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2012) 	if (nl80211_send_pmsr_ftm_capa(cap, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2013) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2015) 	nla_nest_end(msg, caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2016) 	nla_nest_end(msg, pmsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2018) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2021) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2022) nl80211_put_iftype_akm_suites(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2023) 			      struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2025) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2026) 	struct nlattr *nested, *nested_akms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2027) 	const struct wiphy_iftype_akm_suites *iftype_akms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2029) 	if (!rdev->wiphy.num_iftype_akm_suites ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2030) 	    !rdev->wiphy.iftype_akm_suites)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2031) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2033) 	nested = nla_nest_start(msg, NL80211_ATTR_IFTYPE_AKM_SUITES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2034) 	if (!nested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2035) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2037) 	for (i = 0; i < rdev->wiphy.num_iftype_akm_suites; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2038) 		nested_akms = nla_nest_start(msg, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2039) 		if (!nested_akms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2040) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2042) 		iftype_akms = &rdev->wiphy.iftype_akm_suites[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2044) 		if (nl80211_put_iftypes(msg, NL80211_IFTYPE_AKM_ATTR_IFTYPES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2045) 					iftype_akms->iftypes_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2046) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2048) 		if (nla_put(msg, NL80211_IFTYPE_AKM_ATTR_SUITES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2049) 			    sizeof(u32) * iftype_akms->n_akm_suites,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2050) 			    iftype_akms->akm_suites)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2051) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2052) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2053) 		nla_nest_end(msg, nested_akms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2054) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2056) 	nla_nest_end(msg, nested);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2058) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2061) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2062) nl80211_put_tid_config_support(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2063) 			       struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2065) 	struct nlattr *supp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2067) 	if (!rdev->wiphy.tid_config_support.vif &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2068) 	    !rdev->wiphy.tid_config_support.peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2069) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2071) 	supp = nla_nest_start(msg, NL80211_ATTR_TID_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2072) 	if (!supp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2073) 		return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2075) 	if (rdev->wiphy.tid_config_support.vif &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2076) 	    nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_VIF_SUPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2077) 			      rdev->wiphy.tid_config_support.vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2078) 			      NL80211_TID_CONFIG_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2079) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2081) 	if (rdev->wiphy.tid_config_support.peer &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2082) 	    nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_PEER_SUPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2083) 			      rdev->wiphy.tid_config_support.peer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2084) 			      NL80211_TID_CONFIG_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2085) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2087) 	/* for now we just use the same value ... makes more sense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2088) 	if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2089) 		       rdev->wiphy.tid_config_support.max_retry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2090) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2091) 	if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_LONG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2092) 		       rdev->wiphy.tid_config_support.max_retry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2093) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2095) 	nla_nest_end(msg, supp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2097) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2098) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2099) 	nla_nest_cancel(msg, supp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2100) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2103) struct nl80211_dump_wiphy_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2104) 	s64 filter_wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2105) 	long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2106) 	long split_start, band_start, chan_start, capa_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2107) 	bool split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2110) static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2111) 			      enum nl80211_commands cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2112) 			      struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2113) 			      int flags, struct nl80211_dump_wiphy_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2115) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2116) 	struct nlattr *nl_bands, *nl_band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2117) 	struct nlattr *nl_freqs, *nl_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2118) 	struct nlattr *nl_cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2119) 	enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2120) 	struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2121) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2122) 	const struct ieee80211_txrx_stypes *mgmt_stypes =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2123) 				rdev->wiphy.mgmt_stypes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2124) 	u32 features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2126) 	hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2127) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2128) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2130) 	if (WARN_ON(!state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2131) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2133) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2134) 	    nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2135) 			   wiphy_name(&rdev->wiphy)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2136) 	    nla_put_u32(msg, NL80211_ATTR_GENERATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2137) 			cfg80211_rdev_list_generation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2138) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2140) 	if (cmd != NL80211_CMD_NEW_WIPHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2141) 		goto finish;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2143) 	switch (state->split_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2144) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2145) 		if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2146) 			       rdev->wiphy.retry_short) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2147) 		    nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2148) 			       rdev->wiphy.retry_long) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2149) 		    nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2150) 				rdev->wiphy.frag_threshold) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2151) 		    nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2152) 				rdev->wiphy.rts_threshold) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2153) 		    nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2154) 			       rdev->wiphy.coverage_class) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2155) 		    nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2156) 			       rdev->wiphy.max_scan_ssids) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2157) 		    nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2158) 			       rdev->wiphy.max_sched_scan_ssids) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2159) 		    nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2160) 				rdev->wiphy.max_scan_ie_len) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2161) 		    nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2162) 				rdev->wiphy.max_sched_scan_ie_len) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2163) 		    nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2164) 			       rdev->wiphy.max_match_sets))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2165) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2167) 		if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2168) 		    nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2169) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2170) 		if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2171) 		    nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2172) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2173) 		if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2174) 		    nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2175) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2176) 		if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2177) 		    nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2178) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2179) 		if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2180) 		    nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2181) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2182) 		if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2183) 		    nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2184) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2185) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2186) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2187) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2188) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2189) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2190) 		if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2191) 			    sizeof(u32) * rdev->wiphy.n_cipher_suites,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2192) 			    rdev->wiphy.cipher_suites))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2193) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2195) 		if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2196) 			       rdev->wiphy.max_num_pmkids))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2197) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2199) 		if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2200) 		    nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2201) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2203) 		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2204) 				rdev->wiphy.available_antennas_tx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2205) 		    nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2206) 				rdev->wiphy.available_antennas_rx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2207) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2209) 		if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2210) 		    nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2211) 				rdev->wiphy.probe_resp_offload))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2212) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2214) 		if ((rdev->wiphy.available_antennas_tx ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2215) 		     rdev->wiphy.available_antennas_rx) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2216) 		    rdev->ops->get_antenna) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2217) 			u32 tx_ant = 0, rx_ant = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2218) 			int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2220) 			res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2221) 			if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2222) 				if (nla_put_u32(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2223) 						NL80211_ATTR_WIPHY_ANTENNA_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2224) 						tx_ant) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2225) 				    nla_put_u32(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2226) 						NL80211_ATTR_WIPHY_ANTENNA_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2227) 						rx_ant))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2228) 					goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2229) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2230) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2232) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2233) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2234) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2235) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2236) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2237) 		if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2238) 					rdev->wiphy.interface_modes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2239) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2240) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2241) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2242) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2243) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2244) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2245) 		nl_bands = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2246) 						 NL80211_ATTR_WIPHY_BANDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2247) 		if (!nl_bands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2248) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2250) 		for (band = state->band_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2251) 		     band < NUM_NL80211_BANDS; band++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2252) 			struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2254) 			/* omit higher bands for ancient software */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2255) 			if (band > NL80211_BAND_5GHZ && !state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2256) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2258) 			sband = rdev->wiphy.bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2260) 			if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2261) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2263) 			nl_band = nla_nest_start_noflag(msg, band);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2264) 			if (!nl_band)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2265) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2267) 			switch (state->chan_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2268) 			case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2269) 				if (nl80211_send_band_rateinfo(msg, sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2270) 							       state->split))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2271) 					goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2272) 				state->chan_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2273) 				if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2274) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2275) 				fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2276) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2277) 				/* add frequencies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2278) 				nl_freqs = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2279) 								 NL80211_BAND_ATTR_FREQS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2280) 				if (!nl_freqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2281) 					goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2283) 				for (i = state->chan_start - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2284) 				     i < sband->n_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2285) 				     i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2286) 					nl_freq = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2287) 									i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2288) 					if (!nl_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2289) 						goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2291) 					chan = &sband->channels[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2293) 					if (nl80211_msg_put_channel(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2294) 							msg, &rdev->wiphy, chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2295) 							state->split))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2296) 						goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2298) 					nla_nest_end(msg, nl_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2299) 					if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2300) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2301) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2302) 				if (i < sband->n_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2303) 					state->chan_start = i + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2304) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2305) 					state->chan_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2306) 				nla_nest_end(msg, nl_freqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2307) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2309) 			nla_nest_end(msg, nl_band);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2311) 			if (state->split) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2312) 				/* start again here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2313) 				if (state->chan_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2314) 					band--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2315) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2316) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2317) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2318) 		nla_nest_end(msg, nl_bands);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2320) 		if (band < NUM_NL80211_BANDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2321) 			state->band_start = band + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2322) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2323) 			state->band_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2325) 		/* if bands & channels are done, continue outside */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2326) 		if (state->band_start == 0 && state->chan_start == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2327) 			state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2328) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2329) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2330) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2331) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2332) 		nl_cmds = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2333) 						NL80211_ATTR_SUPPORTED_COMMANDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2334) 		if (!nl_cmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2335) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2337) 		i = nl80211_add_commands_unsplit(rdev, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2338) 		if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2339) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2340) 		if (state->split) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2341) 			CMD(crit_proto_start, CRIT_PROTOCOL_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2342) 			CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2343) 			if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2344) 				CMD(channel_switch, CHANNEL_SWITCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2345) 			CMD(set_qos_map, SET_QOS_MAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2346) 			if (rdev->wiphy.features &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2347) 					NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2348) 				CMD(add_tx_ts, ADD_TX_TS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2349) 			CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2350) 			CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2351) 			CMD(update_ft_ies, UPDATE_FT_IES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2352) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2353) #undef CMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2355) 		nla_nest_end(msg, nl_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2356) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2357) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2358) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2359) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2360) 	case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2361) 		if (rdev->ops->remain_on_channel &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2362) 		    (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2363) 		    nla_put_u32(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2364) 				NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2365) 				rdev->wiphy.max_remain_on_channel_duration))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2366) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2368) 		if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2369) 		    nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2370) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2372) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2373) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2374) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2375) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2376) 	case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2377) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2378) 		if (nl80211_send_wowlan(msg, rdev, state->split))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2379) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2380) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2381) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2382) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2383) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2384) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2385) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2386) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2387) 	case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2388) 		if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2389) 					rdev->wiphy.software_iftypes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2390) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2392) 		if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2393) 						   state->split))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2394) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2396) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2397) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2398) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2399) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2400) 	case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2401) 		if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2402) 		    nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2403) 				rdev->wiphy.ap_sme_capa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2404) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2406) 		features = rdev->wiphy.features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2407) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2408) 		 * We can only add the per-channel limit information if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2409) 		 * dump is split, otherwise it makes it too big. Therefore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2410) 		 * only advertise it in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2411) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2412) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2413) 			features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2414) 		if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2415) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2417) 		if (rdev->wiphy.ht_capa_mod_mask &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2418) 		    nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2419) 			    sizeof(*rdev->wiphy.ht_capa_mod_mask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2420) 			    rdev->wiphy.ht_capa_mod_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2421) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2423) 		if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2424) 		    rdev->wiphy.max_acl_mac_addrs &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2425) 		    nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2426) 				rdev->wiphy.max_acl_mac_addrs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2427) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2429) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2430) 		 * Any information below this point is only available to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2431) 		 * applications that can deal with it being split. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2432) 		 * helps ensure that newly added capabilities don't break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2433) 		 * older tools by overrunning their buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2434) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2435) 		 * We still increment split_start so that in the split
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2436) 		 * case we'll continue with more data in the next round,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2437) 		 * but break unconditionally so unsplit data stops here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2438) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2439) 		if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2440) 			state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2441) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2442) 			state->split_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2443) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2444) 	case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2445) 		if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2446) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2448) 		if (nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2449) 				rdev->wiphy.max_sched_scan_plans) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2450) 		    nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2451) 				rdev->wiphy.max_sched_scan_plan_interval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2452) 		    nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2453) 				rdev->wiphy.max_sched_scan_plan_iterations))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2454) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2456) 		if (rdev->wiphy.extended_capabilities &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2457) 		    (nla_put(msg, NL80211_ATTR_EXT_CAPA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2458) 			     rdev->wiphy.extended_capabilities_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2459) 			     rdev->wiphy.extended_capabilities) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2460) 		     nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2461) 			     rdev->wiphy.extended_capabilities_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2462) 			     rdev->wiphy.extended_capabilities_mask)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2463) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2465) 		if (rdev->wiphy.vht_capa_mod_mask &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2466) 		    nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2467) 			    sizeof(*rdev->wiphy.vht_capa_mod_mask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2468) 			    rdev->wiphy.vht_capa_mod_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2469) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2471) 		if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2472) 			    rdev->wiphy.perm_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2473) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2475) 		if (!is_zero_ether_addr(rdev->wiphy.addr_mask) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2476) 		    nla_put(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2477) 			    rdev->wiphy.addr_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2478) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2480) 		if (rdev->wiphy.n_addresses > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2481) 			void *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2483) 			attr = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2484) 			if (!attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2485) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2487) 			for (i = 0; i < rdev->wiphy.n_addresses; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2488) 				if (nla_put(msg, i + 1, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2489) 					    rdev->wiphy.addresses[i].addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2490) 					goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2492) 			nla_nest_end(msg, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2493) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2495) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2496) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2497) 	case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2498) 		if (nl80211_send_coalesce(msg, rdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2499) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2501) 		if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2502) 		    (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2503) 		     nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2504) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2506) 		if (rdev->wiphy.max_ap_assoc_sta &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2507) 		    nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2508) 				rdev->wiphy.max_ap_assoc_sta))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2509) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2511) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2512) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2513) 	case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2514) 		if (rdev->wiphy.n_vendor_commands) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2515) 			const struct nl80211_vendor_cmd_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2516) 			struct nlattr *nested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2518) 			nested = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2519) 						       NL80211_ATTR_VENDOR_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2520) 			if (!nested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2521) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2523) 			for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2524) 				info = &rdev->wiphy.vendor_commands[i].info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2525) 				if (nla_put(msg, i + 1, sizeof(*info), info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2526) 					goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2527) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2528) 			nla_nest_end(msg, nested);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2529) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2531) 		if (rdev->wiphy.n_vendor_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2532) 			const struct nl80211_vendor_cmd_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2533) 			struct nlattr *nested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2535) 			nested = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2536) 						       NL80211_ATTR_VENDOR_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2537) 			if (!nested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2538) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2540) 			for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2541) 				info = &rdev->wiphy.vendor_events[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2542) 				if (nla_put(msg, i + 1, sizeof(*info), info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2543) 					goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2544) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2545) 			nla_nest_end(msg, nested);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2546) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2547) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2548) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2549) 	case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2550) 		if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2551) 		    nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2552) 			       rdev->wiphy.max_num_csa_counters))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2553) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2555) 		if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2556) 		    nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2557) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2559) 		if (rdev->wiphy.max_sched_scan_reqs &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2560) 		    nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2561) 				rdev->wiphy.max_sched_scan_reqs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2562) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2564) 		if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2565) 			    sizeof(rdev->wiphy.ext_features),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2566) 			    rdev->wiphy.ext_features))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2567) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2569) 		if (rdev->wiphy.bss_select_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2570) 			struct nlattr *nested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2571) 			u32 bss_select_support = rdev->wiphy.bss_select_support;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2573) 			nested = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2574) 						       NL80211_ATTR_BSS_SELECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2575) 			if (!nested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2576) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2578) 			i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2579) 			while (bss_select_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2580) 				if ((bss_select_support & 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2581) 				    nla_put_flag(msg, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2582) 					goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2583) 				i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2584) 				bss_select_support >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2585) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2586) 			nla_nest_end(msg, nested);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2587) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2589) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2590) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2591) 	case 13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2592) 		if (rdev->wiphy.num_iftype_ext_capab &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2593) 		    rdev->wiphy.iftype_ext_capab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2594) 			struct nlattr *nested_ext_capab, *nested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2596) 			nested = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2597) 						       NL80211_ATTR_IFTYPE_EXT_CAPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2598) 			if (!nested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2599) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2601) 			for (i = state->capa_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2602) 			     i < rdev->wiphy.num_iftype_ext_capab; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2603) 				const struct wiphy_iftype_ext_capab *capab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2605) 				capab = &rdev->wiphy.iftype_ext_capab[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2607) 				nested_ext_capab = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2608) 									 i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2609) 				if (!nested_ext_capab ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2610) 				    nla_put_u32(msg, NL80211_ATTR_IFTYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2611) 						capab->iftype) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2612) 				    nla_put(msg, NL80211_ATTR_EXT_CAPA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2613) 					    capab->extended_capabilities_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2614) 					    capab->extended_capabilities) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2615) 				    nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2616) 					    capab->extended_capabilities_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2617) 					    capab->extended_capabilities_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2618) 					goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2620) 				nla_nest_end(msg, nested_ext_capab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2621) 				if (state->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2622) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2623) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2624) 			nla_nest_end(msg, nested);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2625) 			if (i < rdev->wiphy.num_iftype_ext_capab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2626) 				state->capa_start = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2627) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2628) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2629) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2631) 		if (nla_put_u32(msg, NL80211_ATTR_BANDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2632) 				rdev->wiphy.nan_supported_bands))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2633) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2635) 		if (wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2636) 					    NL80211_EXT_FEATURE_TXQS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2637) 			struct cfg80211_txq_stats txqstats = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2638) 			int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2640) 			res = rdev_get_txq_stats(rdev, NULL, &txqstats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2641) 			if (!res &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2642) 			    !nl80211_put_txq_stats(msg, &txqstats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2643) 						   NL80211_ATTR_TXQ_STATS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2644) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2646) 			if (nla_put_u32(msg, NL80211_ATTR_TXQ_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2647) 					rdev->wiphy.txq_limit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2648) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2649) 			if (nla_put_u32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2650) 					rdev->wiphy.txq_memory_limit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2651) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2652) 			if (nla_put_u32(msg, NL80211_ATTR_TXQ_QUANTUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2653) 					rdev->wiphy.txq_quantum))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2654) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2655) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2657) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2658) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2659) 	case 14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2660) 		if (nl80211_send_pmsr_capa(rdev, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2661) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2663) 		state->split_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2664) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2665) 	case 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2666) 		if (rdev->wiphy.akm_suites &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2667) 		    nla_put(msg, NL80211_ATTR_AKM_SUITES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2668) 			    sizeof(u32) * rdev->wiphy.n_akm_suites,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2669) 			    rdev->wiphy.akm_suites))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2670) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2672) 		if (nl80211_put_iftype_akm_suites(rdev, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2673) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2675) 		if (nl80211_put_tid_config_support(rdev, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2676) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2678) 		/* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2679) 		state->split_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2680) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2682)  finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2683) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2684) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2686)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2687) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2688) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2691) static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2692) 				    struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2693) 				    struct nl80211_dump_wiphy_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2695) 	struct nlattr **tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2696) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2698) 	if (!tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2699) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2701) 	ret = nlmsg_parse_deprecated(cb->nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2702) 				     GENL_HDRLEN + nl80211_fam.hdrsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2703) 				     tb, nl80211_fam.maxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2704) 				     nl80211_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2705) 	/* ignore parse errors for backward compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2706) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2707) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2708) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2709) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2711) 	state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2712) 	if (tb[NL80211_ATTR_WIPHY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2713) 		state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2714) 	if (tb[NL80211_ATTR_WDEV])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2715) 		state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2716) 	if (tb[NL80211_ATTR_IFINDEX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2717) 		struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2718) 		struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2719) 		int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2721) 		netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2722) 		if (!netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2723) 			ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2724) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2725) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2726) 		if (netdev->ieee80211_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2727) 			rdev = wiphy_to_rdev(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2728) 				netdev->ieee80211_ptr->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2729) 			state->filter_wiphy = rdev->wiphy_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2730) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2731) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2733) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2734) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2735) 	kfree(tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2736) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2739) static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2741) 	int idx = 0, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2742) 	struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2743) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2745) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2746) 	if (!state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2747) 		state = kzalloc(sizeof(*state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2748) 		if (!state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2749) 			rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2750) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2751) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2752) 		state->filter_wiphy = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2753) 		ret = nl80211_dump_wiphy_parse(skb, cb, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2754) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2755) 			kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2756) 			rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2757) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2758) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2759) 		cb->args[0] = (long)state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2762) 	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2763) 		if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2764) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2765) 		if (++idx <= state->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2766) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2767) 		if (state->filter_wiphy != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2768) 		    state->filter_wiphy != rdev->wiphy_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2769) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2770) 		/* attempt to fit multiple wiphy data chunks into the skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2771) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2772) 			ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2773) 						 skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2774) 						 NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2775) 						 cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2776) 						 NLM_F_MULTI, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2777) 			if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2778) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2779) 				 * If sending the wiphy data didn't fit (ENOBUFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2780) 				 * or EMSGSIZE returned), this SKB is still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2781) 				 * empty (so it's not too big because another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2782) 				 * wiphy dataset is already in the skb) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2783) 				 * we've not tried to adjust the dump allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2784) 				 * yet ... then adjust the alloc size to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2785) 				 * bigger, and return 1 but with the empty skb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2786) 				 * This results in an empty message being RX'ed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2787) 				 * in userspace, but that is ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2788) 				 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2789) 				 * We can then retry with the larger buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2790) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2791) 				if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2792) 				    !skb->len && !state->split &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2793) 				    cb->min_dump_alloc < 4096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2794) 					cb->min_dump_alloc = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2795) 					state->split_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2796) 					rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2797) 					return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2798) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2799) 				idx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2800) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2801) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2802) 		} while (state->split_start > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2803) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2804) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2805) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2807) 	state->start = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2809) 	return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2812) static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2814) 	kfree((void *)cb->args[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2815) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2818) static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2820) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2821) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2822) 	struct nl80211_dump_wiphy_state state = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2824) 	msg = nlmsg_new(4096, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2825) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2826) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2828) 	if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2829) 			       info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2830) 			       &state) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2831) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2832) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2835) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2838) static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2839) 	[NL80211_TXQ_ATTR_QUEUE]		= { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2840) 	[NL80211_TXQ_ATTR_TXOP]			= { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2841) 	[NL80211_TXQ_ATTR_CWMIN]		= { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2842) 	[NL80211_TXQ_ATTR_CWMAX]		= { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2843) 	[NL80211_TXQ_ATTR_AIFS]			= { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2844) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2846) static int parse_txq_params(struct nlattr *tb[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2847) 			    struct ieee80211_txq_params *txq_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2849) 	u8 ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2851) 	if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2852) 	    !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2853) 	    !tb[NL80211_TXQ_ATTR_AIFS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2854) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2856) 	ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2857) 	txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2858) 	txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2859) 	txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2860) 	txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2862) 	if (ac >= NL80211_NUM_ACS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2863) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2864) 	txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2865) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2868) static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2870) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2871) 	 * You can only set the channel explicitly for WDS interfaces,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2872) 	 * all others have their channel managed via their respective
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2873) 	 * "establish a connection" command (connect, join, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2874) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2875) 	 * For AP/GO and mesh mode, the channel can be set with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2876) 	 * channel userspace API, but is only stored and passed to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2877) 	 * low-level driver when the AP starts or the mesh is joined.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2878) 	 * This is for backward compatibility, userspace can also give
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2879) 	 * the channel in the start-ap or join-mesh commands instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2880) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2881) 	 * Monitors are special as they are normally slaved to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2882) 	 * whatever else is going on, so they have their own special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2883) 	 * operation to set the monitor channel if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2884) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2885) 	return !wdev ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2886) 		wdev->iftype == NL80211_IFTYPE_AP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2887) 		wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2888) 		wdev->iftype == NL80211_IFTYPE_MONITOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2889) 		wdev->iftype == NL80211_IFTYPE_P2P_GO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2892) int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2893) 			  struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2894) 			  struct cfg80211_chan_def *chandef)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2896) 	struct netlink_ext_ack *extack = info->extack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2897) 	struct nlattr **attrs = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2898) 	u32 control_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2900) 	if (!attrs[NL80211_ATTR_WIPHY_FREQ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2901) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2903) 	control_freq = MHZ_TO_KHZ(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2904) 			nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2905) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2906) 		control_freq +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2907) 		    nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2909) 	memset(chandef, 0, sizeof(*chandef));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2910) 	chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2911) 	chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2912) 	chandef->center_freq1 = KHZ_TO_MHZ(control_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2913) 	chandef->freq1_offset = control_freq % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2914) 	chandef->center_freq2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2916) 	/* Primary channel not allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2917) 	if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2918) 		NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2919) 				    "Channel is disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2920) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2921) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2923) 	if (attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2924) 		enum nl80211_channel_type chantype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2926) 		chantype = nla_get_u32(attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2928) 		switch (chantype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2929) 		case NL80211_CHAN_NO_HT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2930) 		case NL80211_CHAN_HT20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2931) 		case NL80211_CHAN_HT40PLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2932) 		case NL80211_CHAN_HT40MINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2933) 			cfg80211_chandef_create(chandef, chandef->chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2934) 						chantype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2935) 			/* user input for center_freq is incorrect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2936) 			if (attrs[NL80211_ATTR_CENTER_FREQ1] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2937) 			    chandef->center_freq1 != nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2938) 				NL_SET_ERR_MSG_ATTR(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2939) 						    attrs[NL80211_ATTR_CENTER_FREQ1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2940) 						    "bad center frequency 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2941) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2942) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2943) 			/* center_freq2 must be zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2944) 			if (attrs[NL80211_ATTR_CENTER_FREQ2] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2945) 			    nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2946) 				NL_SET_ERR_MSG_ATTR(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2947) 						    attrs[NL80211_ATTR_CENTER_FREQ2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2948) 						    "center frequency 2 can't be used");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2949) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2950) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2951) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2952) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2953) 			NL_SET_ERR_MSG_ATTR(extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2954) 					    attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2955) 					    "invalid channel type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2956) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2957) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2958) 	} else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2959) 		chandef->width =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2960) 			nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2961) 		if (attrs[NL80211_ATTR_CENTER_FREQ1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2962) 			chandef->center_freq1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2963) 				nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2964) 			if (attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2965) 				chandef->freq1_offset = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2966) 				      attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2967) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2968) 				chandef->freq1_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2969) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2970) 		if (attrs[NL80211_ATTR_CENTER_FREQ2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2971) 			chandef->center_freq2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2972) 				nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2973) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2975) 	if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2976) 		chandef->edmg.channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2977) 		      nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2979) 		if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2980) 			chandef->edmg.bw_config =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2981) 		     nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2982) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2983) 		chandef->edmg.bw_config = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2984) 		chandef->edmg.channels = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2985) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2987) 	if (!cfg80211_chandef_valid(chandef)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2988) 		NL_SET_ERR_MSG(extack, "invalid channel definition");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2989) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2990) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2992) 	if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2993) 				     IEEE80211_CHAN_DISABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2994) 		NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2995) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2996) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2998) 	if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2999) 	     chandef->width == NL80211_CHAN_WIDTH_10) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3000) 	    !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3001) 		NL_SET_ERR_MSG(extack, "5/10 MHz not supported");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3002) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3003) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3005) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3008) static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3009) 				 struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3010) 				 struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3012) 	struct cfg80211_chan_def chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3013) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3014) 	enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3015) 	struct wireless_dev *wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3017) 	if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3018) 		wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3019) 	if (!nl80211_can_set_dev_channel(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3020) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3021) 	if (wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3022) 		iftype = wdev->iftype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3024) 	result = nl80211_parse_chandef(rdev, info, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3025) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3026) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3028) 	switch (iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3029) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3030) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3031) 		if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3032) 						   iftype)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3033) 			result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3034) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3035) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3036) 		if (wdev->beacon_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3037) 			if (!dev || !rdev->ops->set_ap_chanwidth ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3038) 			    !(rdev->wiphy.features &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3039) 			      NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3040) 				result = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3041) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3042) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3044) 			/* Only allow dynamic channel width changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3045) 			if (chandef.chan != wdev->preset_chandef.chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3046) 				result = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3047) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3048) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3049) 			result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3050) 			if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3051) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3052) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3053) 		wdev->preset_chandef = chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3054) 		result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3055) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3056) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3057) 		result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3058) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3059) 	case NL80211_IFTYPE_MONITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3060) 		result = cfg80211_set_monitor_channel(rdev, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3061) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3062) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3063) 		result = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3064) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3066) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3069) static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3071) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3072) 	struct net_device *netdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3074) 	return __nl80211_set_channel(rdev, netdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3077) static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3079) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3080) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3081) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3082) 	const u8 *bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3084) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3085) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3087) 	if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3088) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3090) 	if (!rdev->ops->set_wds_peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3091) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3093) 	if (wdev->iftype != NL80211_IFTYPE_WDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3094) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3096) 	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3097) 	return rdev_set_wds_peer(rdev, dev, bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3100) static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3102) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3103) 	struct net_device *netdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3104) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3105) 	int result = 0, rem_txq_params = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3106) 	struct nlattr *nl_txq_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3107) 	u32 changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3108) 	u8 retry_short = 0, retry_long = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3109) 	u32 frag_threshold = 0, rts_threshold = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3110) 	u8 coverage_class = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3111) 	u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3113) 	ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3115) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3116) 	 * Try to find the wiphy and netdev. Normally this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3117) 	 * function shouldn't need the netdev, but this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3118) 	 * done for backward compatibility -- previously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3119) 	 * setting the channel was done per wiphy, but now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3120) 	 * it is per netdev. Previous userland like hostapd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3121) 	 * also passed a netdev to set_wiphy, so that it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3122) 	 * possible to let that go to the right netdev!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3123) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3125) 	if (info->attrs[NL80211_ATTR_IFINDEX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3126) 		int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3128) 		netdev = __dev_get_by_index(genl_info_net(info), ifindex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3129) 		if (netdev && netdev->ieee80211_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3130) 			rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3131) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3132) 			netdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3133) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3135) 	if (!netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3136) 		rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3137) 						  info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3138) 		if (IS_ERR(rdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3139) 			return PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3140) 		wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3141) 		netdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3142) 		result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3143) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3144) 		wdev = netdev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3146) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3147) 	 * end workaround code, by now the rdev is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3148) 	 * and locked, and wdev may or may not be NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3149) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3151) 	if (info->attrs[NL80211_ATTR_WIPHY_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3152) 		result = cfg80211_dev_rename(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3153) 			rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3155) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3156) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3158) 	if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3159) 		struct ieee80211_txq_params txq_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3160) 		struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3162) 		if (!rdev->ops->set_txq_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3163) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3165) 		if (!netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3166) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3168) 		if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3169) 		    netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3170) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3172) 		if (!netif_running(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3173) 			return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3175) 		nla_for_each_nested(nl_txq_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3176) 				    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3177) 				    rem_txq_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3178) 			result = nla_parse_nested_deprecated(tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3179) 							     NL80211_TXQ_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3180) 							     nl_txq_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3181) 							     txq_params_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3182) 							     info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3183) 			if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3184) 				return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3185) 			result = parse_txq_params(tb, &txq_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3186) 			if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3187) 				return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3189) 			result = rdev_set_txq_params(rdev, netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3190) 						     &txq_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3191) 			if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3192) 				return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3193) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3196) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3197) 		result = __nl80211_set_channel(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3198) 			rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3199) 			nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3200) 			info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3201) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3202) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3203) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3205) 	if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3206) 		struct wireless_dev *txp_wdev = wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3207) 		enum nl80211_tx_power_setting type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3208) 		int idx, mbm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3210) 		if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3211) 			txp_wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3213) 		if (!rdev->ops->set_tx_power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3214) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3216) 		idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3217) 		type = nla_get_u32(info->attrs[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3219) 		if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3220) 		    (type != NL80211_TX_POWER_AUTOMATIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3221) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3223) 		if (type != NL80211_TX_POWER_AUTOMATIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3224) 			idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3225) 			mbm = nla_get_u32(info->attrs[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3226) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3228) 		result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3229) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3230) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3233) 	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3234) 	    info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3235) 		u32 tx_ant, rx_ant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3237) 		if ((!rdev->wiphy.available_antennas_tx &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3238) 		     !rdev->wiphy.available_antennas_rx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3239) 		    !rdev->ops->set_antenna)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3240) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3242) 		tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3243) 		rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3245) 		/* reject antenna configurations which don't match the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3246) 		 * available antenna masks, except for the "all" mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3247) 		if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3248) 		    (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3249) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3251) 		tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3252) 		rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3254) 		result = rdev_set_antenna(rdev, tx_ant, rx_ant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3255) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3256) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3259) 	changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3261) 	if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3262) 		retry_short = nla_get_u8(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3263) 			info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3265) 		changed |= WIPHY_PARAM_RETRY_SHORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3268) 	if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3269) 		retry_long = nla_get_u8(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3270) 			info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3272) 		changed |= WIPHY_PARAM_RETRY_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3273) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3275) 	if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3276) 		frag_threshold = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3277) 			info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3278) 		if (frag_threshold < 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3279) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3281) 		if (frag_threshold != (u32) -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3282) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3283) 			 * Fragments (apart from the last one) are required to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3284) 			 * have even length. Make the fragmentation code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3285) 			 * simpler by stripping LSB should someone try to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3286) 			 * odd threshold value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3287) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3288) 			frag_threshold &= ~0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3289) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3290) 		changed |= WIPHY_PARAM_FRAG_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3291) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3293) 	if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3294) 		rts_threshold = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3295) 			info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3296) 		changed |= WIPHY_PARAM_RTS_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3299) 	if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3300) 		if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3301) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3303) 		coverage_class = nla_get_u8(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3304) 			info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3305) 		changed |= WIPHY_PARAM_COVERAGE_CLASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3306) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3308) 	if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3309) 		if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3310) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3312) 		changed |= WIPHY_PARAM_DYN_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3315) 	if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3316) 		if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3317) 					     NL80211_EXT_FEATURE_TXQS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3318) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3319) 		txq_limit = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3320) 			info->attrs[NL80211_ATTR_TXQ_LIMIT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3321) 		changed |= WIPHY_PARAM_TXQ_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3324) 	if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3325) 		if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3326) 					     NL80211_EXT_FEATURE_TXQS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3327) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3328) 		txq_memory_limit = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3329) 			info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3330) 		changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3333) 	if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3334) 		if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3335) 					     NL80211_EXT_FEATURE_TXQS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3336) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3337) 		txq_quantum = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3338) 			info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3339) 		changed |= WIPHY_PARAM_TXQ_QUANTUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3342) 	if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3343) 		u8 old_retry_short, old_retry_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3344) 		u32 old_frag_threshold, old_rts_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3345) 		u8 old_coverage_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3346) 		u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3348) 		if (!rdev->ops->set_wiphy_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3349) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3351) 		old_retry_short = rdev->wiphy.retry_short;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3352) 		old_retry_long = rdev->wiphy.retry_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3353) 		old_frag_threshold = rdev->wiphy.frag_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3354) 		old_rts_threshold = rdev->wiphy.rts_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3355) 		old_coverage_class = rdev->wiphy.coverage_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3356) 		old_txq_limit = rdev->wiphy.txq_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3357) 		old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3358) 		old_txq_quantum = rdev->wiphy.txq_quantum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3360) 		if (changed & WIPHY_PARAM_RETRY_SHORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3361) 			rdev->wiphy.retry_short = retry_short;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3362) 		if (changed & WIPHY_PARAM_RETRY_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3363) 			rdev->wiphy.retry_long = retry_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3364) 		if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3365) 			rdev->wiphy.frag_threshold = frag_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3366) 		if (changed & WIPHY_PARAM_RTS_THRESHOLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3367) 			rdev->wiphy.rts_threshold = rts_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3368) 		if (changed & WIPHY_PARAM_COVERAGE_CLASS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3369) 			rdev->wiphy.coverage_class = coverage_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3370) 		if (changed & WIPHY_PARAM_TXQ_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3371) 			rdev->wiphy.txq_limit = txq_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3372) 		if (changed & WIPHY_PARAM_TXQ_MEMORY_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3373) 			rdev->wiphy.txq_memory_limit = txq_memory_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3374) 		if (changed & WIPHY_PARAM_TXQ_QUANTUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3375) 			rdev->wiphy.txq_quantum = txq_quantum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3377) 		result = rdev_set_wiphy_params(rdev, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3378) 		if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3379) 			rdev->wiphy.retry_short = old_retry_short;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3380) 			rdev->wiphy.retry_long = old_retry_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3381) 			rdev->wiphy.frag_threshold = old_frag_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3382) 			rdev->wiphy.rts_threshold = old_rts_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3383) 			rdev->wiphy.coverage_class = old_coverage_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3384) 			rdev->wiphy.txq_limit = old_txq_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3385) 			rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3386) 			rdev->wiphy.txq_quantum = old_txq_quantum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3387) 			return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3388) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3390) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3393) static int nl80211_send_chandef(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3394) 				const struct cfg80211_chan_def *chandef)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3396) 	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3397) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3399) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3400) 			chandef->chan->center_freq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3401) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3402) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3403) 			chandef->chan->freq_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3404) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3405) 	switch (chandef->width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3406) 	case NL80211_CHAN_WIDTH_20_NOHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3407) 	case NL80211_CHAN_WIDTH_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3408) 	case NL80211_CHAN_WIDTH_40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3409) 		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3410) 				cfg80211_get_chandef_type(chandef)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3411) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3412) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3413) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3414) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3416) 	if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3417) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3418) 	if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3419) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3420) 	if (chandef->center_freq2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3421) 	    nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3422) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3423) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3426) static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3427) 			      struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3428) 			      struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3429) 			      enum nl80211_commands cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3431) 	struct net_device *dev = wdev->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3432) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3434) 	WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3435) 		cmd != NL80211_CMD_DEL_INTERFACE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3436) 		cmd != NL80211_CMD_SET_INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3438) 	hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3439) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3440) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3442) 	if (dev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3443) 	    (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3444) 	     nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3445) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3447) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3448) 	    nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3449) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3450) 			      NL80211_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3451) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3452) 	    nla_put_u32(msg, NL80211_ATTR_GENERATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3453) 			rdev->devlist_generation ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3454) 			(cfg80211_rdev_list_generation << 2)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3455) 	    nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3456) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3458) 	if (rdev->ops->get_channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3459) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3460) 		struct cfg80211_chan_def chandef = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3462) 		ret = rdev_get_channel(rdev, wdev, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3463) 		if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3464) 			if (nl80211_send_chandef(msg, &chandef))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3465) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3466) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3469) 	if (rdev->ops->get_tx_power) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3470) 		int dbm, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3472) 		ret = rdev_get_tx_power(rdev, wdev, &dbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3473) 		if (ret == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3474) 		    nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3475) 				DBM_TO_MBM(dbm)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3476) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3477) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3479) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3480) 	switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3481) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3482) 		if (wdev->ssid_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3483) 		    nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3484) 			goto nla_put_failure_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3485) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3486) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3487) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3488) 	case NL80211_IFTYPE_ADHOC: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3489) 		const u8 *ssid_ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3490) 		if (!wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3491) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3492) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3493) 		ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3494) 					       WLAN_EID_SSID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3495) 		if (ssid_ie &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3496) 		    nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3497) 			goto nla_put_failure_rcu_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3498) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3499) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3500) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3501) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3502) 		/* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3503) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3504) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3505) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3507) 	if (rdev->ops->get_txq_stats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3508) 		struct cfg80211_txq_stats txqstats = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3509) 		int ret = rdev_get_txq_stats(rdev, wdev, &txqstats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3511) 		if (ret == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3512) 		    !nl80211_put_txq_stats(msg, &txqstats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3513) 					   NL80211_ATTR_TXQ_STATS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3514) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3517) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3518) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3520)  nla_put_failure_rcu_locked:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3521) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3522)  nla_put_failure_locked:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3523) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3524)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3525) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3526) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3529) static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3531) 	int wp_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3532) 	int if_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3533) 	int wp_start = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3534) 	int if_start = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3535) 	int filter_wiphy = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3536) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3537) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3538) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3540) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3541) 	if (!cb->args[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3542) 		struct nl80211_dump_wiphy_state state = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3543) 			.filter_wiphy = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3544) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3546) 		ret = nl80211_dump_wiphy_parse(skb, cb, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3547) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3548) 			goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3550) 		filter_wiphy = state.filter_wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3552) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3553) 		 * if filtering, set cb->args[2] to +1 since 0 is the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3554) 		 * value needed to determine that parsing is necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3555) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3556) 		if (filter_wiphy >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3557) 			cb->args[2] = filter_wiphy + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3558) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3559) 			cb->args[2] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3560) 	} else if (cb->args[2] > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3561) 		filter_wiphy = cb->args[2] - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3564) 	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3565) 		if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3566) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3567) 		if (wp_idx < wp_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3568) 			wp_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3569) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3570) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3572) 		if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3573) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3575) 		if_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3577) 		list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3578) 			if (if_idx < if_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3579) 				if_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3580) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3581) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3582) 			if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3583) 					       cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3584) 					       rdev, wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3585) 					       NL80211_CMD_NEW_INTERFACE) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3586) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3587) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3588) 			if_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3589) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3591) 		wp_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3593)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3594) 	cb->args[0] = wp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3595) 	cb->args[1] = if_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3597) 	ret = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3598)  out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3599) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3601) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3604) static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3606) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3607) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3608) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3610) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3611) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3612) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3614) 	if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3615) 			       rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3616) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3617) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3620) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3623) static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3624) 	[NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3625) 	[NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3626) 	[NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3627) 	[NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3628) 	[NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3629) 	[NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3632) static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3634) 	struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3635) 	int flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3637) 	*mntrflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3639) 	if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3640) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3642) 	if (nla_parse_nested_deprecated(flags, NL80211_MNTR_FLAG_MAX, nla, mntr_flags_policy, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3643) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3645) 	for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3646) 		if (flags[flag])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3647) 			*mntrflags |= (1<<flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3649) 	*mntrflags |= MONITOR_FLAG_CHANGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3651) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3654) static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3655) 				     enum nl80211_iftype type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3656) 				     struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3657) 				     struct vif_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3659) 	bool change = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3660) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3662) 	if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3663) 		if (type != NL80211_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3664) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3666) 		err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3667) 					  &params->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3668) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3669) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3671) 		change = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3674) 	if (params->flags & MONITOR_FLAG_ACTIVE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3675) 	    !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3676) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3678) 	if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3679) 		const u8 *mumimo_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3680) 		u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3682) 		if (type != NL80211_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3683) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3685) 		if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3686) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3688) 		mumimo_groups =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3689) 			nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3691) 		/* bits 0 and 63 are reserved and must be zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3692) 		if ((mumimo_groups[0] & BIT(0)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3693) 		    (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3694) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3696) 		params->vht_mumimo_groups = mumimo_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3697) 		change = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3700) 	if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3701) 		u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3703) 		if (type != NL80211_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3704) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3706) 		if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3707) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3709) 		params->vht_mumimo_follow_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3710) 			nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3711) 		change = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3714) 	return change ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3717) static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3718) 			       struct net_device *netdev, u8 use_4addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3719) 			       enum nl80211_iftype iftype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3721) 	if (!use_4addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3722) 		if (netdev && netif_is_bridge_port(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3723) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3724) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3725) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3727) 	switch (iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3728) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3729) 		if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3730) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3731) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3732) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3733) 		if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3734) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3735) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3736) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3737) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3740) 	return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3743) static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3745) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3746) 	struct vif_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3747) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3748) 	enum nl80211_iftype otype, ntype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3749) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3750) 	bool change = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3752) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3754) 	otype = ntype = dev->ieee80211_ptr->iftype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3756) 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3757) 		ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3758) 		if (otype != ntype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3759) 			change = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3762) 	if (info->attrs[NL80211_ATTR_MESH_ID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3763) 		struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3765) 		if (ntype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3766) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3767) 		if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3768) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3770) 		wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3771) 		BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3772) 			     IEEE80211_MAX_MESH_ID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3773) 		wdev->mesh_id_up_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3774) 			nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3775) 		memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3776) 		       wdev->mesh_id_up_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3777) 		wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3778) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3780) 	if (info->attrs[NL80211_ATTR_4ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3781) 		params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3782) 		change = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3783) 		err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3784) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3785) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3786) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3787) 		params.use_4addr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3788) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3790) 	err = nl80211_parse_mon_options(rdev, ntype, info, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3791) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3792) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3793) 	if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3794) 		change = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3796) 	if (change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3797) 		err = cfg80211_change_iface(rdev, dev, ntype, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3798) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3799) 		err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3801) 	if (!err && params.use_4addr != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3802) 		dev->ieee80211_ptr->use_4addr = params.use_4addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3804) 	if (change && !err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3805) 		struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3807) 		nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3808) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3810) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3813) static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3815) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3816) 	struct vif_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3817) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3818) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3819) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3820) 	enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3822) 	/* to avoid failing a new interface creation due to pending removal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3823) 	cfg80211_destroy_ifaces(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3825) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3827) 	if (!info->attrs[NL80211_ATTR_IFNAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3828) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3830) 	if (info->attrs[NL80211_ATTR_IFTYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3831) 		type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3833) 	if (!rdev->ops->add_virtual_intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3834) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3836) 	if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3837) 	     rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3838) 	    info->attrs[NL80211_ATTR_MAC]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3839) 		nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3840) 			   ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3841) 		if (!is_valid_ether_addr(params.macaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3842) 			return -EADDRNOTAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3843) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3845) 	if (info->attrs[NL80211_ATTR_4ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3846) 		params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3847) 		err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3848) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3849) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3852) 	if (!cfg80211_iftype_allowed(&rdev->wiphy, type, params.use_4addr, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3853) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3855) 	err = nl80211_parse_mon_options(rdev, type, info, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3856) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3857) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3859) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3860) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3861) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3863) 	wdev = rdev_add_virtual_intf(rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3864) 				nla_data(info->attrs[NL80211_ATTR_IFNAME]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3865) 				NET_NAME_USER, type, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3866) 	if (WARN_ON(!wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3867) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3868) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3869) 	} else if (IS_ERR(wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3870) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3871) 		return PTR_ERR(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3872) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3874) 	if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3875) 		wdev->owner_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3877) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3878) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3879) 		if (!info->attrs[NL80211_ATTR_MESH_ID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3880) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3881) 		wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3882) 		BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3883) 			     IEEE80211_MAX_MESH_ID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3884) 		wdev->mesh_id_up_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3885) 			nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3886) 		memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3887) 		       wdev->mesh_id_up_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3888) 		wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3889) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3890) 	case NL80211_IFTYPE_NAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3891) 	case NL80211_IFTYPE_P2P_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3892) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3893) 		 * P2P Device and NAN do not have a netdev, so don't go
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3894) 		 * through the netdev notifier and must be added here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3895) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3896) 		cfg80211_init_wdev(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3897) 		cfg80211_register_wdev(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3898) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3899) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3900) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3901) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3903) 	if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3904) 			       rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3905) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3906) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3907) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3909) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3912) static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3914) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3915) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3917) 	if (!rdev->ops->del_virtual_intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3918) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3920) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3921) 	 * If we remove a wireless device without a netdev then clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3922) 	 * user_ptr[1] so that nl80211_post_doit won't dereference it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3923) 	 * to check if it needs to do dev_put(). Otherwise it crashes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3924) 	 * since the wdev has been freed, unlike with a netdev where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3925) 	 * we need the dev_put() for the netdev to really be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3926) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3927) 	if (!wdev->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3928) 		info->user_ptr[1] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3930) 	return rdev_del_virtual_intf(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3933) static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3935) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3936) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3937) 	u16 noack_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3939) 	if (!info->attrs[NL80211_ATTR_NOACK_MAP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3940) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3942) 	if (!rdev->ops->set_noack_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3943) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3945) 	noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3947) 	return rdev_set_noack_map(rdev, dev, noack_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3950) struct get_key_cookie {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3951) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3952) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3953) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3954) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3956) static void get_key_callback(void *c, struct key_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3958) 	struct nlattr *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3959) 	struct get_key_cookie *cookie = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3961) 	if ((params->key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3962) 	     nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3963) 		     params->key_len, params->key)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3964) 	    (params->seq &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3965) 	     nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3966) 		     params->seq_len, params->seq)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3967) 	    (params->cipher &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3968) 	     nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3969) 			 params->cipher)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3970) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3972) 	key = nla_nest_start_noflag(cookie->msg, NL80211_ATTR_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3973) 	if (!key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3974) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3976) 	if ((params->key &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3977) 	     nla_put(cookie->msg, NL80211_KEY_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3978) 		     params->key_len, params->key)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3979) 	    (params->seq &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3980) 	     nla_put(cookie->msg, NL80211_KEY_SEQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3981) 		     params->seq_len, params->seq)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3982) 	    (params->cipher &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3983) 	     nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3984) 			 params->cipher)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3985) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3987) 	if (nla_put_u8(cookie->msg, NL80211_KEY_IDX, cookie->idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3988) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3990) 	nla_nest_end(cookie->msg, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3992) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3993)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3994) 	cookie->error = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3997) static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3999) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4000) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4001) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4002) 	u8 key_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4003) 	const u8 *mac_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4004) 	bool pairwise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4005) 	struct get_key_cookie cookie = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4006) 		.error = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4007) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4008) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4009) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4010) 	bool bigtk_support = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4012) 	if (wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4013) 				    NL80211_EXT_FEATURE_BEACON_PROTECTION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4014) 		bigtk_support = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4016) 	if ((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4017) 	     dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4018) 	    wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4019) 				    NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4020) 		bigtk_support = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4022) 	if (info->attrs[NL80211_ATTR_KEY_IDX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4023) 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4025) 		if (key_idx >= 6 && key_idx <= 7 && !bigtk_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4026) 			GENL_SET_ERR_MSG(info, "BIGTK not supported");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4027) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4028) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4029) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4031) 	if (info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4032) 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4034) 	pairwise = !!mac_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4035) 	if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4036) 		u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4038) 		if (kt != NL80211_KEYTYPE_GROUP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4039) 		    kt != NL80211_KEYTYPE_PAIRWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4040) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4041) 		pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4042) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4044) 	if (!rdev->ops->get_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4045) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4047) 	if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4048) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4050) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4051) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4052) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4054) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4055) 			     NL80211_CMD_NEW_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4056) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4057) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4059) 	cookie.msg = msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4060) 	cookie.idx = key_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4062) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4063) 	    nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4064) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4065) 	if (mac_addr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4066) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4067) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4069) 	err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4070) 			   get_key_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4072) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4073) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4075) 	if (cookie.error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4076) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4078) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4079) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4081)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4082) 	err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4083)  free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4084) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4085) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4088) static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4090) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4091) 	struct key_parse key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4092) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4093) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4095) 	err = nl80211_parse_key(info, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4096) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4097) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4099) 	if (key.idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4100) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4102) 	/* Only support setting default key and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4103) 	 * Extended Key ID action NL80211_KEY_SET_TX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4104) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4105) 	if (!key.def && !key.defmgmt && !key.defbeacon &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4106) 	    !(key.p.mode == NL80211_KEY_SET_TX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4107) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4109) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4111) 	if (key.def) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4112) 		if (!rdev->ops->set_default_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4113) 			err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4114) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4115) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4117) 		err = nl80211_key_allowed(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4118) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4119) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4121) 		err = rdev_set_default_key(rdev, dev, key.idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4122) 						 key.def_uni, key.def_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4124) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4125) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4127) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4128) 		dev->ieee80211_ptr->wext.default_key = key.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4129) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4130) 	} else if (key.defmgmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4131) 		if (key.def_uni || !key.def_multi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4132) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4133) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4134) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4136) 		if (!rdev->ops->set_default_mgmt_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4137) 			err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4138) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4139) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4141) 		err = nl80211_key_allowed(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4142) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4143) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4145) 		err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4146) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4147) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4149) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4150) 		dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4151) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4152) 	} else if (key.defbeacon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4153) 		if (key.def_uni || !key.def_multi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4154) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4155) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4156) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4158) 		if (!rdev->ops->set_default_beacon_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4159) 			err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4160) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4161) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4163) 		err = nl80211_key_allowed(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4164) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4165) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4167) 		err = rdev_set_default_beacon_key(rdev, dev, key.idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4168) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4169) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4170) 	} else if (key.p.mode == NL80211_KEY_SET_TX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4171) 		   wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4172) 					   NL80211_EXT_FEATURE_EXT_KEY_ID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4173) 		u8 *mac_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4175) 		if (info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4176) 			mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4178) 		if (!mac_addr || key.idx < 0 || key.idx > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4179) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4180) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4181) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4183) 		err = rdev_add_key(rdev, dev, key.idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4184) 				   NL80211_KEYTYPE_PAIRWISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4185) 				   mac_addr, &key.p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4186) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4187) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4189)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4190) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4192) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4195) static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4197) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4198) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4199) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4200) 	struct key_parse key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4201) 	const u8 *mac_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4203) 	err = nl80211_parse_key(info, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4204) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4205) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4207) 	if (!key.p.key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4208) 		GENL_SET_ERR_MSG(info, "no key");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4209) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4212) 	if (info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4213) 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4215) 	if (key.type == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4216) 		if (mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4217) 			key.type = NL80211_KEYTYPE_PAIRWISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4218) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4219) 			key.type = NL80211_KEYTYPE_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4222) 	/* for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4223) 	if (key.type != NL80211_KEYTYPE_PAIRWISE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4224) 	    key.type != NL80211_KEYTYPE_GROUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4225) 		GENL_SET_ERR_MSG(info, "key type not pairwise or group");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4226) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4229) 	if (key.type == NL80211_KEYTYPE_GROUP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4230) 	    info->attrs[NL80211_ATTR_VLAN_ID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4231) 		key.p.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4233) 	if (!rdev->ops->add_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4234) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4236) 	if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4237) 					   key.type == NL80211_KEYTYPE_PAIRWISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4238) 					   mac_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4239) 		GENL_SET_ERR_MSG(info, "key setting validation failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4240) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4243) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4244) 	err = nl80211_key_allowed(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4245) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4246) 		GENL_SET_ERR_MSG(info, "key not allowed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4247) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4248) 		err = rdev_add_key(rdev, dev, key.idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4249) 				   key.type == NL80211_KEYTYPE_PAIRWISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4250) 				    mac_addr, &key.p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4251) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4252) 			GENL_SET_ERR_MSG(info, "key addition failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4253) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4254) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4256) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4259) static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4261) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4262) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4263) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4264) 	u8 *mac_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4265) 	struct key_parse key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4267) 	err = nl80211_parse_key(info, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4268) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4269) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4271) 	if (info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4272) 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4274) 	if (key.type == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4275) 		if (mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4276) 			key.type = NL80211_KEYTYPE_PAIRWISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4277) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4278) 			key.type = NL80211_KEYTYPE_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4281) 	/* for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4282) 	if (key.type != NL80211_KEYTYPE_PAIRWISE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4283) 	    key.type != NL80211_KEYTYPE_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4284) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4286) 	if (!cfg80211_valid_key_idx(rdev, key.idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4287) 				    key.type == NL80211_KEYTYPE_PAIRWISE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4288) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4290) 	if (!rdev->ops->del_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4291) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4293) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4294) 	err = nl80211_key_allowed(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4296) 	if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4297) 	    !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4298) 		err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4300) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4301) 		err = rdev_del_key(rdev, dev, key.idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4302) 				   key.type == NL80211_KEYTYPE_PAIRWISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4303) 				   mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4305) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4306) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4307) 		if (key.idx == dev->ieee80211_ptr->wext.default_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4308) 			dev->ieee80211_ptr->wext.default_key = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4309) 		else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4310) 			dev->ieee80211_ptr->wext.default_mgmt_key = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4312) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4313) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4315) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4318) /* This function returns an error or the number of nested attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4319) static int validate_acl_mac_addrs(struct nlattr *nl_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4321) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4322) 	int n_entries = 0, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4324) 	nla_for_each_nested(attr, nl_attr, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4325) 		if (nla_len(attr) != ETH_ALEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4326) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4328) 		n_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4329) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4331) 	return n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4335)  * This function parses ACL information and allocates memory for ACL data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4336)  * On successful return, the calling function is responsible to free the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4337)  * ACL buffer returned by this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4338)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4339) static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4340) 						struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4342) 	enum nl80211_acl_policy acl_policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4343) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4344) 	struct cfg80211_acl_data *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4345) 	int i = 0, n_entries, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4347) 	if (!wiphy->max_acl_mac_addrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4348) 		return ERR_PTR(-EOPNOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4350) 	if (!info->attrs[NL80211_ATTR_ACL_POLICY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4351) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4353) 	acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4354) 	if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4355) 	    acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4356) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4358) 	if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4359) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4361) 	n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4362) 	if (n_entries < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4363) 		return ERR_PTR(n_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4365) 	if (n_entries > wiphy->max_acl_mac_addrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4366) 		return ERR_PTR(-ENOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4368) 	acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4369) 	if (!acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4370) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4372) 	nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4373) 		memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4374) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4375) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4377) 	acl->n_acl_entries = n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4378) 	acl->acl_policy = acl_policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4380) 	return acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4383) static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4385) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4386) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4387) 	struct cfg80211_acl_data *acl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4388) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4390) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4391) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4392) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4394) 	if (!dev->ieee80211_ptr->beacon_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4395) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4397) 	acl = parse_acl_data(&rdev->wiphy, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4398) 	if (IS_ERR(acl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4399) 		return PTR_ERR(acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4401) 	err = rdev_set_mac_acl(rdev, dev, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4403) 	kfree(acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4405) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4408) static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4409) 			   u8 *rates, u8 rates_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4411) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4412) 	u32 mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4414) 	for (i = 0; i < rates_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4415) 		int rate = (rates[i] & 0x7f) * 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4416) 		int ridx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4418) 		for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4419) 			struct ieee80211_rate *srate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4420) 				&sband->bitrates[ridx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4421) 			if (rate == srate->bitrate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4422) 				mask |= 1 << ridx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4423) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4424) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4425) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4426) 		if (ridx == sband->n_bitrates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4427) 			return 0; /* rate not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4430) 	return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4433) static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4434) 			       u8 *rates, u8 rates_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4435) 			       u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4437) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4439) 	memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4441) 	for (i = 0; i < rates_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4442) 		int ridx, rbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4444) 		ridx = rates[i] / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4445) 		rbit = BIT(rates[i] % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4447) 		/* check validity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4448) 		if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4449) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4451) 		/* check availability */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4452) 		ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4453) 		if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4454) 			mcs[ridx] |= rbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4455) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4456) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4459) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4462) static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4464) 	u16 mcs_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4466) 	switch (vht_mcs_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4467) 	case IEEE80211_VHT_MCS_NOT_SUPPORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4468) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4469) 	case IEEE80211_VHT_MCS_SUPPORT_0_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4470) 		mcs_mask = 0x00FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4471) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4472) 	case IEEE80211_VHT_MCS_SUPPORT_0_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4473) 		mcs_mask = 0x01FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4474) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4475) 	case IEEE80211_VHT_MCS_SUPPORT_0_9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4476) 		mcs_mask = 0x03FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4477) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4478) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4479) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4482) 	return mcs_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4485) static void vht_build_mcs_mask(u16 vht_mcs_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4486) 			       u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4488) 	u8 nss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4490) 	for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4491) 		vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4492) 		vht_mcs_map >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4496) static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4497) 			     struct nl80211_txrate_vht *txrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4498) 			     u16 mcs[NL80211_VHT_NSS_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4500) 	u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4501) 	u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4502) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4504) 	if (!sband->vht_cap.vht_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4505) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4507) 	memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4509) 	/* Build vht_mcs_mask from VHT capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4510) 	vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4512) 	for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4513) 		if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4514) 			mcs[i] = txrate->mcs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4515) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4516) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4519) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4522) static u16 he_mcs_map_to_mcs_mask(u8 he_mcs_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4524) 	switch (he_mcs_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4525) 	case IEEE80211_HE_MCS_NOT_SUPPORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4526) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4527) 	case IEEE80211_HE_MCS_SUPPORT_0_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4528) 		return 0x00FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4529) 	case IEEE80211_HE_MCS_SUPPORT_0_9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4530) 		return 0x03FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4531) 	case IEEE80211_HE_MCS_SUPPORT_0_11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4532) 		return 0xFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4533) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4534) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4536) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4539) static void he_build_mcs_mask(u16 he_mcs_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4540) 			      u16 he_mcs_mask[NL80211_HE_NSS_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4542) 	u8 nss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4544) 	for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4545) 		he_mcs_mask[nss] = he_mcs_map_to_mcs_mask(he_mcs_map & 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4546) 		he_mcs_map >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4550) static u16 he_get_txmcsmap(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4551) 			   const struct ieee80211_sta_he_cap *he_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4553) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4554) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4555) 	__le16	tx_mcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4557) 	switch (wdev->chandef.width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4558) 	case NL80211_CHAN_WIDTH_80P80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4559) 		tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80p80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4560) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4561) 	case NL80211_CHAN_WIDTH_160:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4562) 		tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4563) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4564) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4565) 		tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4566) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4567) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4568) 	return le16_to_cpu(tx_mcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4571) static bool he_set_mcs_mask(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4572) 			    struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4573) 			    struct ieee80211_supported_band *sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4574) 			    struct nl80211_txrate_he *txrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4575) 			    u16 mcs[NL80211_HE_NSS_MAX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4577) 	const struct ieee80211_sta_he_cap *he_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4578) 	u16 tx_mcs_mask[NL80211_HE_NSS_MAX] = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4579) 	u16 tx_mcs_map = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4580) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4582) 	he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4583) 	if (!he_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4584) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4586) 	memset(mcs, 0, sizeof(u16) * NL80211_HE_NSS_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4588) 	tx_mcs_map = he_get_txmcsmap(info, he_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4590) 	/* Build he_mcs_mask from HE capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4591) 	he_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4593) 	for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4594) 		if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4595) 			mcs[i] = txrate->mcs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4596) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4597) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4598) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4600) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4603) static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4604) 					 struct nlattr *attrs[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4605) 					 enum nl80211_attrs attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4606) 					 struct cfg80211_bitrate_mask *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4607) 					 struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4609) 	struct nlattr *tb[NL80211_TXRATE_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4610) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4611) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4612) 	int rem, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4613) 	struct nlattr *tx_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4614) 	struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4615) 	u16 vht_tx_mcs_map, he_tx_mcs_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4617) 	memset(mask, 0, sizeof(*mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4618) 	/* Default to all rates enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4619) 	for (i = 0; i < NUM_NL80211_BANDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4620) 		const struct ieee80211_sta_he_cap *he_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4622) 		sband = rdev->wiphy.bands[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4624) 		if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4625) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4627) 		mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4628) 		memcpy(mask->control[i].ht_mcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4629) 		       sband->ht_cap.mcs.rx_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4630) 		       sizeof(mask->control[i].ht_mcs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4632) 		if (sband->vht_cap.vht_supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4633) 			vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4634) 			vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4635) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4637) 		he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4638) 		if (!he_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4639) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4641) 		he_tx_mcs_map = he_get_txmcsmap(info, he_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4642) 		he_build_mcs_mask(he_tx_mcs_map, mask->control[i].he_mcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4644) 		mask->control[i].he_gi = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4645) 		mask->control[i].he_ltf = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4646) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4648) 	/* if no rates are given set it back to the defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4649) 	if (!attrs[attr])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4650) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4652) 	/* The nested attribute uses enum nl80211_band as the index. This maps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4653) 	 * directly to the enum nl80211_band values used in cfg80211.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4654) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4655) 	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4656) 	nla_for_each_nested(tx_rates, attrs[attr], rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4657) 		enum nl80211_band band = nla_type(tx_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4658) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4660) 		if (band < 0 || band >= NUM_NL80211_BANDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4661) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4662) 		sband = rdev->wiphy.bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4663) 		if (sband == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4664) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4665) 		err = nla_parse_nested_deprecated(tb, NL80211_TXRATE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4666) 						  tx_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4667) 						  nl80211_txattr_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4668) 						  info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4669) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4670) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4671) 		if (tb[NL80211_TXRATE_LEGACY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4672) 			mask->control[band].legacy = rateset_to_mask(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4673) 				sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4674) 				nla_data(tb[NL80211_TXRATE_LEGACY]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4675) 				nla_len(tb[NL80211_TXRATE_LEGACY]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4676) 			if ((mask->control[band].legacy == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4677) 			    nla_len(tb[NL80211_TXRATE_LEGACY]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4678) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4679) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4680) 		if (tb[NL80211_TXRATE_HT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4681) 			if (!ht_rateset_to_mask(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4682) 					sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4683) 					nla_data(tb[NL80211_TXRATE_HT]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4684) 					nla_len(tb[NL80211_TXRATE_HT]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4685) 					mask->control[band].ht_mcs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4686) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4687) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4688) 		if (tb[NL80211_TXRATE_VHT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4689) 			if (!vht_set_mcs_mask(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4690) 					sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4691) 					nla_data(tb[NL80211_TXRATE_VHT]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4692) 					mask->control[band].vht_mcs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4693) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4694) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4695) 		if (tb[NL80211_TXRATE_GI]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4696) 			mask->control[band].gi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4697) 				nla_get_u8(tb[NL80211_TXRATE_GI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4698) 			if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4699) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4700) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4701) 		if (tb[NL80211_TXRATE_HE] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4702) 		    !he_set_mcs_mask(info, wdev, sband,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4703) 				     nla_data(tb[NL80211_TXRATE_HE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4704) 				     mask->control[band].he_mcs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4705) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4706) 		if (tb[NL80211_TXRATE_HE_GI])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4707) 			mask->control[band].he_gi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4708) 				nla_get_u8(tb[NL80211_TXRATE_HE_GI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4709) 		if (tb[NL80211_TXRATE_HE_LTF])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4710) 			mask->control[band].he_ltf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4711) 				nla_get_u8(tb[NL80211_TXRATE_HE_LTF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4713) 		if (mask->control[band].legacy == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4714) 			/* don't allow empty legacy rates if HT, VHT or HE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4715) 			 * are not even supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4716) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4717) 			if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4718) 			      rdev->wiphy.bands[band]->vht_cap.vht_supported ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4719) 			      ieee80211_get_he_iftype_cap(sband, wdev->iftype)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4720) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4722) 			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4723) 				if (mask->control[band].ht_mcs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4724) 					goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4726) 			for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4727) 				if (mask->control[band].vht_mcs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4728) 					goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4730) 			for (i = 0; i < NL80211_HE_NSS_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4731) 				if (mask->control[band].he_mcs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4732) 					goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4734) 			/* legacy and mcs rates may not be both empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4735) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4736) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4739) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4740) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4743) static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4744) 				   enum nl80211_band band,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4745) 				   struct cfg80211_bitrate_mask *beacon_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4747) 	u32 count_ht, count_vht, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4748) 	u32 rate = beacon_rate->control[band].legacy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4750) 	/* Allow only one rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4751) 	if (hweight32(rate) > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4752) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4754) 	count_ht = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4755) 	for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4756) 		if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4757) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4758) 		} else if (beacon_rate->control[band].ht_mcs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4759) 			count_ht++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4760) 			if (count_ht > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4761) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4762) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4763) 		if (count_ht && rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4764) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4765) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4767) 	count_vht = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4768) 	for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4769) 		if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4770) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4771) 		} else if (beacon_rate->control[band].vht_mcs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4772) 			count_vht++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4773) 			if (count_vht > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4774) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4775) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4776) 		if (count_vht && rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4777) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4778) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4780) 	if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4781) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4783) 	if (rate &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4784) 	    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4785) 				     NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4786) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4787) 	if (count_ht &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4788) 	    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4789) 				     NL80211_EXT_FEATURE_BEACON_RATE_HT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4790) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4791) 	if (count_vht &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4792) 	    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4793) 				     NL80211_EXT_FEATURE_BEACON_RATE_VHT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4794) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4796) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4799) static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4800) 				struct nlattr *attrs[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4801) 				struct cfg80211_beacon_data *bcn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4803) 	bool haveinfo = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4804) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4806) 	memset(bcn, 0, sizeof(*bcn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4808) 	if (attrs[NL80211_ATTR_BEACON_HEAD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4809) 		bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4810) 		bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4811) 		if (!bcn->head_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4812) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4813) 		haveinfo = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4814) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4816) 	if (attrs[NL80211_ATTR_BEACON_TAIL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4817) 		bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4818) 		bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4819) 		haveinfo = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4820) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4822) 	if (!haveinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4823) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4825) 	if (attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4826) 		bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4827) 		bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4828) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4830) 	if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4831) 		bcn->proberesp_ies =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4832) 			nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4833) 		bcn->proberesp_ies_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4834) 			nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4837) 	if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4838) 		bcn->assocresp_ies =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4839) 			nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4840) 		bcn->assocresp_ies_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4841) 			nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4842) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4844) 	if (attrs[NL80211_ATTR_PROBE_RESP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4845) 		bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4846) 		bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4847) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4849) 	if (attrs[NL80211_ATTR_FTM_RESPONDER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4850) 		struct nlattr *tb[NL80211_FTM_RESP_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4852) 		err = nla_parse_nested_deprecated(tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4853) 						  NL80211_FTM_RESP_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4854) 						  attrs[NL80211_ATTR_FTM_RESPONDER],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4855) 						  NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4856) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4857) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4859) 		if (tb[NL80211_FTM_RESP_ATTR_ENABLED] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4860) 		    wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4861) 					    NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4862) 			bcn->ftm_responder = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4863) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4864) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4866) 		if (tb[NL80211_FTM_RESP_ATTR_LCI]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4867) 			bcn->lci = nla_data(tb[NL80211_FTM_RESP_ATTR_LCI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4868) 			bcn->lci_len = nla_len(tb[NL80211_FTM_RESP_ATTR_LCI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4869) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4871) 		if (tb[NL80211_FTM_RESP_ATTR_CIVICLOC]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4872) 			bcn->civicloc = nla_data(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4873) 			bcn->civicloc_len = nla_len(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4874) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4875) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4876) 		bcn->ftm_responder = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4877) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4879) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4882) static int nl80211_parse_he_obss_pd(struct nlattr *attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4883) 				    struct ieee80211_he_obss_pd *he_obss_pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4885) 	struct nlattr *tb[NL80211_HE_OBSS_PD_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4886) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4888) 	err = nla_parse_nested(tb, NL80211_HE_OBSS_PD_ATTR_MAX, attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4889) 			       he_obss_pd_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4890) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4891) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4893) 	if (!tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4894) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4896) 	he_obss_pd->sr_ctrl = nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4898) 	if (tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4899) 		he_obss_pd->min_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4900) 			nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4901) 	if (tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4902) 		he_obss_pd->max_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4903) 			nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4904) 	if (tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4905) 		he_obss_pd->non_srg_max_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4906) 			nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4908) 	if (he_obss_pd->min_offset > he_obss_pd->max_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4909) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4911) 	if (tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4912) 		memcpy(he_obss_pd->bss_color_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4913) 		       nla_data(tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4914) 		       sizeof(he_obss_pd->bss_color_bitmap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4916) 	if (tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4917) 		memcpy(he_obss_pd->partial_bssid_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4918) 		       nla_data(tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4919) 		       sizeof(he_obss_pd->partial_bssid_bitmap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4921) 	he_obss_pd->enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4923) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4926) static int nl80211_parse_he_bss_color(struct nlattr *attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4927) 				      struct cfg80211_he_bss_color *he_bss_color)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4929) 	struct nlattr *tb[NL80211_HE_BSS_COLOR_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4930) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4932) 	err = nla_parse_nested(tb, NL80211_HE_BSS_COLOR_ATTR_MAX, attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4933) 			       he_bss_color_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4934) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4935) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4937) 	if (!tb[NL80211_HE_BSS_COLOR_ATTR_COLOR])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4938) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4940) 	he_bss_color->color =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4941) 		nla_get_u8(tb[NL80211_HE_BSS_COLOR_ATTR_COLOR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4942) 	he_bss_color->enabled =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4943) 		!nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4944) 	he_bss_color->partial =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4945) 		nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4947) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4950) static int nl80211_parse_fils_discovery(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4951) 					struct nlattr *attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4952) 					struct cfg80211_ap_settings *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4954) 	struct nlattr *tb[NL80211_FILS_DISCOVERY_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4955) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4956) 	struct cfg80211_fils_discovery *fd = &params->fils_discovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4958) 	if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4959) 				     NL80211_EXT_FEATURE_FILS_DISCOVERY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4960) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4962) 	ret = nla_parse_nested(tb, NL80211_FILS_DISCOVERY_ATTR_MAX, attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4963) 			       NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4964) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4965) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4967) 	if (!tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4968) 	    !tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4969) 	    !tb[NL80211_FILS_DISCOVERY_ATTR_TMPL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4970) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4972) 	fd->tmpl_len = nla_len(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4973) 	fd->tmpl = nla_data(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4974) 	fd->min_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4975) 	fd->max_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4977) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4980) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4981) nl80211_parse_unsol_bcast_probe_resp(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4982) 				     struct nlattr *attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4983) 				     struct cfg80211_ap_settings *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4985) 	struct nlattr *tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4986) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4987) 	struct cfg80211_unsol_bcast_probe_resp *presp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4988) 					&params->unsol_bcast_probe_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4990) 	if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4991) 				     NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4992) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4994) 	ret = nla_parse_nested(tb, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4995) 			       attrs, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4996) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4997) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4999) 	if (!tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5000) 	    !tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5001) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5003) 	presp->tmpl = nla_data(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5004) 	presp->tmpl_len = nla_len(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5005) 	presp->interval = nla_get_u32(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5006) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5009) static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5010) 					    const u8 *rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5012) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5014) 	if (!rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5015) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5017) 	for (i = 0; i < rates[1]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5018) 		if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5019) 			params->ht_required = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5020) 		if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5021) 			params->vht_required = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5022) 		if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HE_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5023) 			params->he_required = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5024) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5027) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5028)  * Since the nl80211 API didn't include, from the beginning, attributes about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5029)  * HT/VHT requirements/capabilities, we parse them out of the IEs for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5030)  * benefit of drivers that rebuild IEs in the firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5031)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5032) static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5034) 	const struct cfg80211_beacon_data *bcn = &params->beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5035) 	size_t ies_len = bcn->tail_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5036) 	const u8 *ies = bcn->tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5037) 	const u8 *rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5038) 	const u8 *cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5040) 	rates = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5041) 	nl80211_check_ap_rate_selectors(params, rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5043) 	rates = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5044) 	nl80211_check_ap_rate_selectors(params, rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5046) 	cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5047) 	if (cap && cap[1] >= sizeof(*params->ht_cap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5048) 		params->ht_cap = (void *)(cap + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5049) 	cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5050) 	if (cap && cap[1] >= sizeof(*params->vht_cap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5051) 		params->vht_cap = (void *)(cap + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5052) 	cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5053) 	if (cap && cap[1] >= sizeof(*params->he_cap) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5054) 		params->he_cap = (void *)(cap + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5055) 	cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION, ies, ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5056) 	if (cap && cap[1] >= sizeof(*params->he_oper) + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5057) 		params->he_oper = (void *)(cap + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5060) static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5061) 				   struct cfg80211_ap_settings *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5063) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5064) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5066) 	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5067) 		if (wdev->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5068) 		    wdev->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5069) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5071) 		if (!wdev->preset_chandef.chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5072) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5074) 		params->chandef = wdev->preset_chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5075) 		ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5076) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5077) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5079) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5082) static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5083) 				    enum nl80211_auth_type auth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5084) 				    enum nl80211_commands cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5086) 	if (auth_type > NL80211_AUTHTYPE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5087) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5089) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5090) 	case NL80211_CMD_AUTHENTICATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5091) 		if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5092) 		    auth_type == NL80211_AUTHTYPE_SAE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5093) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5094) 		if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5095) 					     NL80211_EXT_FEATURE_FILS_STA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5096) 		    (auth_type == NL80211_AUTHTYPE_FILS_SK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5097) 		     auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5098) 		     auth_type == NL80211_AUTHTYPE_FILS_PK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5099) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5100) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5101) 	case NL80211_CMD_CONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5102) 		if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5103) 		    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5104) 					     NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5105) 		    auth_type == NL80211_AUTHTYPE_SAE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5106) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5108) 		/* FILS with SK PFS or PK not supported yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5109) 		if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5110) 		    auth_type == NL80211_AUTHTYPE_FILS_PK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5111) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5112) 		if (!wiphy_ext_feature_isset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5113) 			    &rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5114) 			    NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5115) 		    auth_type == NL80211_AUTHTYPE_FILS_SK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5116) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5117) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5118) 	case NL80211_CMD_START_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5119) 		if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5120) 					     NL80211_EXT_FEATURE_SAE_OFFLOAD_AP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5121) 		    auth_type == NL80211_AUTHTYPE_SAE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5122) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5123) 		/* FILS not supported yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5124) 		if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5125) 		    auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5126) 		    auth_type == NL80211_AUTHTYPE_FILS_PK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5127) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5128) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5129) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5130) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5134) static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5136) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5137) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5138) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5139) 	struct cfg80211_ap_settings params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5140) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5142) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5143) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5144) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5146) 	if (!rdev->ops->start_ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5147) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5149) 	if (wdev->beacon_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5150) 		return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5152) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5154) 	/* these are required for START_AP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5155) 	if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5156) 	    !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5157) 	    !info->attrs[NL80211_ATTR_BEACON_HEAD])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5158) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5160) 	err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5161) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5162) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5164) 	params.beacon_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5165) 		nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5166) 	params.dtim_period =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5167) 		nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5169) 	err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5170) 					   params.beacon_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5171) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5172) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5174) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5175) 	 * In theory, some of these attributes should be required here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5176) 	 * but since they were not used when the command was originally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5177) 	 * added, keep them optional for old user space programs to let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5178) 	 * them continue to work with drivers that do not need the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5179) 	 * additional information -- drivers must check!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5180) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5181) 	if (info->attrs[NL80211_ATTR_SSID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5182) 		params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5183) 		params.ssid_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5184) 			nla_len(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5185) 		if (params.ssid_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5186) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5189) 	if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5190) 		params.hidden_ssid = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5191) 			info->attrs[NL80211_ATTR_HIDDEN_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5193) 	params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5195) 	if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5196) 		params.auth_type = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5197) 			info->attrs[NL80211_ATTR_AUTH_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5198) 		if (!nl80211_valid_auth_type(rdev, params.auth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5199) 					     NL80211_CMD_START_AP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5200) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5201) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5202) 		params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5204) 	err = nl80211_crypto_settings(rdev, info, &params.crypto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5205) 				      NL80211_MAX_NR_CIPHER_SUITES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5206) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5207) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5209) 	if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5210) 		if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5211) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5212) 		params.inactivity_timeout = nla_get_u16(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5213) 			info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5216) 	if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5217) 		if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5218) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5219) 		params.p2p_ctwindow =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5220) 			nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5221) 		if (params.p2p_ctwindow != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5222) 		    !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5223) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5226) 	if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5227) 		u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5229) 		if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5230) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5231) 		tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5232) 		params.p2p_opp_ps = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5233) 		if (params.p2p_opp_ps != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5234) 		    !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5235) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5238) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5239) 		err = nl80211_parse_chandef(rdev, info, &params.chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5240) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5241) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5242) 	} else if (wdev->preset_chandef.chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5243) 		params.chandef = wdev->preset_chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5244) 	} else if (!nl80211_get_ap_channel(rdev, &params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5245) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5247) 	if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5248) 					   wdev->iftype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5249) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5251) 	if (info->attrs[NL80211_ATTR_TX_RATES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5252) 		err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5253) 						    NL80211_ATTR_TX_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5254) 						    &params.beacon_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5255) 						    dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5256) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5257) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5259) 		err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5260) 					      &params.beacon_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5261) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5262) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5265) 	if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5266) 		params.smps_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5267) 			nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5268) 		switch (params.smps_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5269) 		case NL80211_SMPS_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5270) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5271) 		case NL80211_SMPS_STATIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5272) 			if (!(rdev->wiphy.features &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5273) 			      NL80211_FEATURE_STATIC_SMPS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5274) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5275) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5276) 		case NL80211_SMPS_DYNAMIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5277) 			if (!(rdev->wiphy.features &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5278) 			      NL80211_FEATURE_DYNAMIC_SMPS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5279) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5280) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5281) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5282) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5283) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5284) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5285) 		params.smps_mode = NL80211_SMPS_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5286) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5288) 	params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5289) 	if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5290) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5292) 	if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5293) 		params.acl = parse_acl_data(&rdev->wiphy, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5294) 		if (IS_ERR(params.acl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5295) 			return PTR_ERR(params.acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5298) 	params.twt_responder =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5299) 		    nla_get_flag(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5301) 	if (info->attrs[NL80211_ATTR_HE_OBSS_PD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5302) 		err = nl80211_parse_he_obss_pd(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5303) 					info->attrs[NL80211_ATTR_HE_OBSS_PD],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5304) 					&params.he_obss_pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5305) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5306) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5309) 	if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5310) 		err = nl80211_parse_he_bss_color(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5311) 					info->attrs[NL80211_ATTR_HE_BSS_COLOR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5312) 					&params.he_bss_color);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5313) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5314) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5317) 	if (info->attrs[NL80211_ATTR_FILS_DISCOVERY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5318) 		err = nl80211_parse_fils_discovery(rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5319) 						   info->attrs[NL80211_ATTR_FILS_DISCOVERY],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5320) 						   &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5321) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5322) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5325) 	if (info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5326) 		err = nl80211_parse_unsol_bcast_probe_resp(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5327) 			rdev, info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5328) 			&params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5329) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5330) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5333) 	nl80211_calculate_ap_params(&params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5335) 	if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5336) 		params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5338) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5339) 	err = rdev_start_ap(rdev, dev, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5340) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5341) 		wdev->preset_chandef = params.chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5342) 		wdev->beacon_interval = params.beacon_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5343) 		wdev->chandef = params.chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5344) 		wdev->ssid_len = params.ssid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5345) 		memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5347) 		if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5348) 			wdev->conn_owner_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5350) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5352) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5353) 	kfree(params.acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5355) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5358) static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5360) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5361) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5362) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5363) 	struct cfg80211_beacon_data params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5364) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5366) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5367) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5368) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5370) 	if (!rdev->ops->change_beacon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5371) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5373) 	if (!wdev->beacon_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5374) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5376) 	err = nl80211_parse_beacon(rdev, info->attrs, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5377) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5378) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5380) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5381) 	err = rdev_change_beacon(rdev, dev, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5382) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5384) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5387) static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5389) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5390) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5392) 	return cfg80211_stop_ap(rdev, dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5395) static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5396) 	[NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5397) 	[NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5398) 	[NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5399) 	[NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5400) 	[NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5401) 	[NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5402) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5404) static int parse_station_flags(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5405) 			       enum nl80211_iftype iftype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5406) 			       struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5408) 	struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5409) 	struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5410) 	int flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5412) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5413) 	 * Try parsing the new attribute first so userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5414) 	 * can specify both for older kernels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5415) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5416) 	nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5417) 	if (nla) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5418) 		struct nl80211_sta_flag_update *sta_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5420) 		sta_flags = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5421) 		params->sta_flags_mask = sta_flags->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5422) 		params->sta_flags_set = sta_flags->set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5423) 		params->sta_flags_set &= params->sta_flags_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5424) 		if ((params->sta_flags_mask |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5425) 		     params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5426) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5427) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5430) 	/* if present, parse the old attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5432) 	nla = info->attrs[NL80211_ATTR_STA_FLAGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5433) 	if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5434) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5436) 	if (nla_parse_nested_deprecated(flags, NL80211_STA_FLAG_MAX, nla, sta_flags_policy, info->extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5437) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5439) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5440) 	 * Only allow certain flags for interface types so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5441) 	 * other attributes are silently ignored. Remember that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5442) 	 * this is backward compatibility code with old userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5443) 	 * and shouldn't be hit in other cases anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5444) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5445) 	switch (iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5446) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5447) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5448) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5449) 		params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5450) 					 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5451) 					 BIT(NL80211_STA_FLAG_WME) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5452) 					 BIT(NL80211_STA_FLAG_MFP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5453) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5454) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5455) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5456) 		params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5457) 					 BIT(NL80211_STA_FLAG_TDLS_PEER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5458) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5459) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5460) 		params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5461) 					 BIT(NL80211_STA_FLAG_MFP) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5462) 					 BIT(NL80211_STA_FLAG_AUTHORIZED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5463) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5464) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5465) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5466) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5468) 	for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5469) 		if (flags[flag]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5470) 			params->sta_flags_set |= (1<<flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5472) 			/* no longer support new API additions in old API */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5473) 			if (flag > NL80211_STA_FLAG_MAX_OLD_API)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5474) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5475) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5478) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5481) bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5483) 	struct nlattr *rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5484) 	u32 bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5485) 	u16 bitrate_compat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5486) 	enum nl80211_rate_info rate_flg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5488) 	rate = nla_nest_start_noflag(msg, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5489) 	if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5490) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5492) 	/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5493) 	bitrate = cfg80211_calculate_bitrate(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5494) 	/* report 16-bit bitrate only if we can */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5495) 	bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5496) 	if (bitrate > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5497) 	    nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5498) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5499) 	if (bitrate_compat > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5500) 	    nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5501) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5503) 	switch (info->bw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5504) 	case RATE_INFO_BW_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5505) 		rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5506) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5507) 	case RATE_INFO_BW_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5508) 		rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5509) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5510) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5511) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5512) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5513) 	case RATE_INFO_BW_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5514) 		rate_flg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5515) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5516) 	case RATE_INFO_BW_40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5517) 		rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5518) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5519) 	case RATE_INFO_BW_80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5520) 		rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5521) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5522) 	case RATE_INFO_BW_160:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5523) 		rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5524) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5525) 	case RATE_INFO_BW_HE_RU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5526) 		rate_flg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5527) 		WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5530) 	if (rate_flg && nla_put_flag(msg, rate_flg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5531) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5533) 	if (info->flags & RATE_INFO_FLAGS_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5534) 		if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5535) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5536) 		if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5537) 		    nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5538) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5539) 	} else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5540) 		if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5541) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5542) 		if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5543) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5544) 		if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5545) 		    nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5546) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5547) 	} else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5548) 		if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5549) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5550) 		if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5551) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5552) 		if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5553) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5554) 		if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5555) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5556) 		if (info->bw == RATE_INFO_BW_HE_RU &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5557) 		    nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5558) 			       info->he_ru_alloc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5559) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5562) 	nla_nest_end(msg, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5563) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5566) static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5567) 			       int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5569) 	void *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5570) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5572) 	if (!mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5573) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5575) 	attr = nla_nest_start_noflag(msg, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5576) 	if (!attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5577) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5579) 	for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5580) 		if (!(mask & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5581) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5583) 		if (nla_put_u8(msg, i, signal[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5584) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5587) 	nla_nest_end(msg, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5589) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5592) static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5593) 				u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5594) 				struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5595) 				struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5596) 				const u8 *mac_addr, struct station_info *sinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5598) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5599) 	struct nlattr *sinfoattr, *bss_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5601) 	hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5602) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5603) 		cfg80211_sinfo_release_content(sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5604) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5605) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5607) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5608) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5609) 	    nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5610) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5612) 	sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5613) 	if (!sinfoattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5614) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5616) #define PUT_SINFO(attr, memb, type) do {				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5617) 	BUILD_BUG_ON(sizeof(type) == sizeof(u64));			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5618) 	if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) &&	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5619) 	    nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5620) 			     sinfo->memb))				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5621) 		goto nla_put_failure;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5622) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5623) #define PUT_SINFO_U64(attr, memb) do {					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5624) 	if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) &&	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5625) 	    nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5626) 			      sinfo->memb, NL80211_STA_INFO_PAD))	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5627) 		goto nla_put_failure;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5628) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5630) 	PUT_SINFO(CONNECTED_TIME, connected_time, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5631) 	PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5632) 	PUT_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5634) 	if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5635) 			     BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5636) 	    nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5637) 			(u32)sinfo->rx_bytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5638) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5640) 	if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5641) 			     BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5642) 	    nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5643) 			(u32)sinfo->tx_bytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5644) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5646) 	PUT_SINFO_U64(RX_BYTES64, rx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5647) 	PUT_SINFO_U64(TX_BYTES64, tx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5648) 	PUT_SINFO(LLID, llid, u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5649) 	PUT_SINFO(PLID, plid, u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5650) 	PUT_SINFO(PLINK_STATE, plink_state, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5651) 	PUT_SINFO_U64(RX_DURATION, rx_duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5652) 	PUT_SINFO_U64(TX_DURATION, tx_duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5654) 	if (wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5655) 				    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5656) 		PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5658) 	switch (rdev->wiphy.signal_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5659) 	case CFG80211_SIGNAL_TYPE_MBM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5660) 		PUT_SINFO(SIGNAL, signal, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5661) 		PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5662) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5663) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5664) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5665) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5666) 	if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5667) 		if (!nl80211_put_signal(msg, sinfo->chains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5668) 					sinfo->chain_signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5669) 					NL80211_STA_INFO_CHAIN_SIGNAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5670) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5671) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5672) 	if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5673) 		if (!nl80211_put_signal(msg, sinfo->chains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5674) 					sinfo->chain_signal_avg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5675) 					NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5676) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5678) 	if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5679) 		if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5680) 					  NL80211_STA_INFO_TX_BITRATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5681) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5683) 	if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5684) 		if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5685) 					  NL80211_STA_INFO_RX_BITRATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5686) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5689) 	PUT_SINFO(RX_PACKETS, rx_packets, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5690) 	PUT_SINFO(TX_PACKETS, tx_packets, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5691) 	PUT_SINFO(TX_RETRIES, tx_retries, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5692) 	PUT_SINFO(TX_FAILED, tx_failed, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5693) 	PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5694) 	PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5695) 	PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5696) 	PUT_SINFO(LOCAL_PM, local_pm, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5697) 	PUT_SINFO(PEER_PM, peer_pm, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5698) 	PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5699) 	PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5700) 	PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5702) 	if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5703) 		bss_param = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5704) 						  NL80211_STA_INFO_BSS_PARAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5705) 		if (!bss_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5706) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5708) 		if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5709) 		     nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5710) 		    ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5711) 		     nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5712) 		    ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5713) 		     nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5714) 		    nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5715) 			       sinfo->bss_param.dtim_period) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5716) 		    nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5717) 				sinfo->bss_param.beacon_interval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5718) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5720) 		nla_nest_end(msg, bss_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5722) 	if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5723) 	    nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5724) 		    sizeof(struct nl80211_sta_flag_update),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5725) 		    &sinfo->sta_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5726) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5728) 	PUT_SINFO_U64(T_OFFSET, t_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5729) 	PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5730) 	PUT_SINFO_U64(BEACON_RX, rx_beacon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5731) 	PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5732) 	PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5733) 	PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5734) 	if (wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5735) 				    NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5736) 		PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5737) 		PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5740) #undef PUT_SINFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5741) #undef PUT_SINFO_U64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5743) 	if (sinfo->pertid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5744) 		struct nlattr *tidsattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5745) 		int tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5747) 		tidsattr = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5748) 						 NL80211_STA_INFO_TID_STATS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5749) 		if (!tidsattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5750) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5752) 		for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5753) 			struct cfg80211_tid_stats *tidstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5754) 			struct nlattr *tidattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5756) 			tidstats = &sinfo->pertid[tid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5758) 			if (!tidstats->filled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5759) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5761) 			tidattr = nla_nest_start_noflag(msg, tid + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5762) 			if (!tidattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5763) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5765) #define PUT_TIDVAL_U64(attr, memb) do {					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5766) 	if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) &&	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5767) 	    nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5768) 			      tidstats->memb, NL80211_TID_STATS_PAD))	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5769) 		goto nla_put_failure;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5770) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5772) 			PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5773) 			PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5774) 			PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5775) 			PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5777) #undef PUT_TIDVAL_U64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5778) 			if ((tidstats->filled &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5779) 			     BIT(NL80211_TID_STATS_TXQ_STATS)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5780) 			    !nl80211_put_txq_stats(msg, &tidstats->txq_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5781) 						   NL80211_TID_STATS_TXQ_STATS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5782) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5784) 			nla_nest_end(msg, tidattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5785) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5787) 		nla_nest_end(msg, tidsattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5788) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5790) 	nla_nest_end(msg, sinfoattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5792) 	if (sinfo->assoc_req_ies_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5793) 	    nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5794) 		    sinfo->assoc_req_ies))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5795) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5797) 	cfg80211_sinfo_release_content(sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5798) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5799) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5801)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5802) 	cfg80211_sinfo_release_content(sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5803) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5804) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5807) static int nl80211_dump_station(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5808) 				struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5810) 	struct station_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5811) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5812) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5813) 	u8 mac_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5814) 	int sta_idx = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5815) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5817) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5818) 	err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5819) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5820) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5822) 	if (!wdev->netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5823) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5824) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5825) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5827) 	if (!rdev->ops->dump_station) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5828) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5829) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5830) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5832) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5833) 		memset(&sinfo, 0, sizeof(sinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5834) 		err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5835) 					mac_addr, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5836) 		if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5837) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5838) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5839) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5841) 		if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5842) 				NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5843) 				cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5844) 				rdev, wdev->netdev, mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5845) 				&sinfo) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5846) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5848) 		sta_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5849) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5851)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5852) 	cb->args[2] = sta_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5853) 	err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5854)  out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5855) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5857) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5860) static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5862) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5863) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5864) 	struct station_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5865) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5866) 	u8 *mac_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5867) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5869) 	memset(&sinfo, 0, sizeof(sinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5871) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5872) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5874) 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5876) 	if (!rdev->ops->get_station)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5877) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5879) 	err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5880) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5881) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5883) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5884) 	if (!msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5885) 		cfg80211_sinfo_release_content(&sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5886) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5887) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5889) 	if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5890) 				 info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5891) 				 rdev, dev, mac_addr, &sinfo) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5892) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5893) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5896) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5899) int cfg80211_check_station_change(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5900) 				  struct station_parameters *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5901) 				  enum cfg80211_station_type statype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5903) 	if (params->listen_interval != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5904) 	    statype != CFG80211_STA_AP_CLIENT_UNASSOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5905) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5907) 	if (params->support_p2p_ps != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5908) 	    statype != CFG80211_STA_AP_CLIENT_UNASSOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5909) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5911) 	if (params->aid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5912) 	    !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5913) 	    statype != CFG80211_STA_AP_CLIENT_UNASSOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5914) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5916) 	/* When you run into this, adjust the code below for the new flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5917) 	BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5919) 	switch (statype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5920) 	case CFG80211_STA_MESH_PEER_KERNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5921) 	case CFG80211_STA_MESH_PEER_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5922) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5923) 		 * No ignoring the TDLS flag here -- the userspace mesh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5924) 		 * code doesn't have the bug of including TDLS in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5925) 		 * mask everywhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5926) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5927) 		if (params->sta_flags_mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5928) 				~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5929) 				  BIT(NL80211_STA_FLAG_MFP) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5930) 				  BIT(NL80211_STA_FLAG_AUTHORIZED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5931) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5932) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5933) 	case CFG80211_STA_TDLS_PEER_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5934) 	case CFG80211_STA_TDLS_PEER_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5935) 		if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5936) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5937) 		/* ignore since it can't change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5938) 		params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5939) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5940) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5941) 		/* disallow mesh-specific things */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5942) 		if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5943) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5944) 		if (params->local_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5945) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5946) 		if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5947) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5948) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5950) 	if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5951) 	    statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5952) 		/* TDLS can't be set, ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5953) 		if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5954) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5955) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5956) 		 * ... but don't bother the driver with it. This works around
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5957) 		 * a hostapd/wpa_supplicant issue -- it always includes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5958) 		 * TLDS_PEER flag in the mask even for AP mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5959) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5960) 		params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5961) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5963) 	if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5964) 	    statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5965) 		/* reject other things that can't change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5966) 		if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5967) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5968) 		if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5969) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5970) 		if (params->supported_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5971) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5972) 		if (params->ext_capab || params->ht_capa || params->vht_capa ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5973) 		    params->he_capa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5974) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5975) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5977) 	if (statype != CFG80211_STA_AP_CLIENT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5978) 	    statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5979) 		if (params->vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5980) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5981) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5983) 	switch (statype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5984) 	case CFG80211_STA_AP_MLME_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5985) 		/* Use this only for authorizing/unauthorizing a station */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5986) 		if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5987) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5988) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5989) 	case CFG80211_STA_AP_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5990) 	case CFG80211_STA_AP_CLIENT_UNASSOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5991) 		/* accept only the listed bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5992) 		if (params->sta_flags_mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5993) 				~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5994) 				  BIT(NL80211_STA_FLAG_AUTHENTICATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5995) 				  BIT(NL80211_STA_FLAG_ASSOCIATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5996) 				  BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5997) 				  BIT(NL80211_STA_FLAG_WME) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5998) 				  BIT(NL80211_STA_FLAG_MFP)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5999) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6001) 		/* but authenticated/associated only if driver handles it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6002) 		if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6003) 		    params->sta_flags_mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6004) 				(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6005) 				 BIT(NL80211_STA_FLAG_ASSOCIATED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6006) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6007) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6008) 	case CFG80211_STA_IBSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6009) 	case CFG80211_STA_AP_STA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6010) 		/* reject any changes other than AUTHORIZED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6011) 		if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6012) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6013) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6014) 	case CFG80211_STA_TDLS_PEER_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6015) 		/* reject any changes other than AUTHORIZED or WME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6016) 		if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6017) 					       BIT(NL80211_STA_FLAG_WME)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6018) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6019) 		/* force (at least) rates when authorizing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6020) 		if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6021) 		    !params->supported_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6022) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6023) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6024) 	case CFG80211_STA_TDLS_PEER_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6025) 		/* reject any changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6026) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6027) 	case CFG80211_STA_MESH_PEER_KERNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6028) 		if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6029) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6030) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6031) 	case CFG80211_STA_MESH_PEER_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6032) 		if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6033) 		    params->plink_action != NL80211_PLINK_ACTION_BLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6034) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6035) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6036) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6038) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6039) 	 * Older kernel versions ignored this attribute entirely, so don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6040) 	 * reject attempts to update it but mark it as unused instead so the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6041) 	 * driver won't look at the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6042) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6043) 	if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6044) 	    statype != CFG80211_STA_TDLS_PEER_SETUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6045) 		params->opmode_notif_used = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6047) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6049) EXPORT_SYMBOL(cfg80211_check_station_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6051) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6052)  * Get vlan interface making sure it is running and on the right wiphy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6053)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6054) static struct net_device *get_vlan(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6055) 				   struct cfg80211_registered_device *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6057) 	struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6058) 	struct net_device *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6059) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6061) 	if (!vlanattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6062) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6064) 	v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6065) 	if (!v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6066) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6068) 	if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6069) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6070) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6071) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6073) 	if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6074) 	    v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6075) 	    v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6076) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6077) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6078) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6080) 	if (!netif_running(v)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6081) 		ret = -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6082) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6083) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6085) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6086)  error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6087) 	dev_put(v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6088) 	return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6091) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6092) nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6093) 	[NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6094) 	[NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6095) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6097) static int nl80211_parse_sta_wme(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6098) 				 struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6100) 	struct nlattr *tb[NL80211_STA_WME_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6101) 	struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6102) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6104) 	/* parse WME attributes if present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6105) 	if (!info->attrs[NL80211_ATTR_STA_WME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6106) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6108) 	nla = info->attrs[NL80211_ATTR_STA_WME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6109) 	err = nla_parse_nested_deprecated(tb, NL80211_STA_WME_MAX, nla,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6110) 					  nl80211_sta_wme_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6111) 					  info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6112) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6113) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6115) 	if (tb[NL80211_STA_WME_UAPSD_QUEUES])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6116) 		params->uapsd_queues = nla_get_u8(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6117) 			tb[NL80211_STA_WME_UAPSD_QUEUES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6118) 	if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6119) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6121) 	if (tb[NL80211_STA_WME_MAX_SP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6122) 		params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6124) 	if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6125) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6127) 	params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6129) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6132) static int nl80211_parse_sta_channel_info(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6133) 				      struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6135) 	if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6136) 		params->supported_channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6137) 		     nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6138) 		params->supported_channels_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6139) 		     nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6140) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6141) 		 * Need to include at least one (first channel, number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6142) 		 * channels) tuple for each subband (checked in policy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6143) 		 * and must have proper tuples for the rest of the data as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6144) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6145) 		if (params->supported_channels_len % 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6146) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6149) 	if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6150) 		params->supported_oper_classes =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6151) 		 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6152) 		params->supported_oper_classes_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6153) 		  nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6155) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6158) static int nl80211_set_station_tdls(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6159) 				    struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6161) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6162) 	/* Dummy STA entry gets updated once the peer capabilities are known */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6163) 	if (info->attrs[NL80211_ATTR_PEER_AID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6164) 		params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6165) 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6166) 		params->ht_capa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6167) 			nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6168) 	if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6169) 		params->vht_capa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6170) 			nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6171) 	if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6172) 		params->he_capa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6173) 			nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6174) 		params->he_capa_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6175) 			nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6178) 	err = nl80211_parse_sta_channel_info(info, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6179) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6180) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6182) 	return nl80211_parse_sta_wme(info, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6185) static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6186) 					     struct station_parameters *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6188) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6189) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6191) 	if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6192) 		if (!rdev->ops->set_tx_power ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6193) 		    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6194) 					 NL80211_EXT_FEATURE_STA_TX_PWR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6195) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6197) 		idx = NL80211_ATTR_STA_TX_POWER_SETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6198) 		params->txpwr.type = nla_get_u8(info->attrs[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6200) 		if (params->txpwr.type == NL80211_TX_POWER_LIMITED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6201) 			idx = NL80211_ATTR_STA_TX_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6203) 			if (info->attrs[idx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6204) 				params->txpwr.power =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6205) 					nla_get_s16(info->attrs[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6206) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6207) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6208) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6209) 		params->sta_modify_mask |= STATION_PARAM_APPLY_STA_TXPOWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6212) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6215) static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6217) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6218) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6219) 	struct station_parameters params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6220) 	u8 *mac_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6221) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6223) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6225) 	if (!rdev->ops->change_station)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6226) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6228) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6229) 	 * AID and listen_interval properties can be set only for unassociated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6230) 	 * station. Include these parameters here and will check them in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6231) 	 * cfg80211_check_station_change().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6232) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6233) 	if (info->attrs[NL80211_ATTR_STA_AID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6234) 		params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6236) 	if (info->attrs[NL80211_ATTR_VLAN_ID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6237) 		params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6239) 	if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6240) 		params.listen_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6241) 		     nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6242) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6243) 		params.listen_interval = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6245) 	if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6246) 		params.support_p2p_ps =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6247) 			nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6248) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6249) 		params.support_p2p_ps = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6251) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6252) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6254) 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6256) 	if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6257) 		params.supported_rates =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6258) 			nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6259) 		params.supported_rates_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6260) 			nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6263) 	if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6264) 		params.capability =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6265) 			nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6266) 		params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6269) 	if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6270) 		params.ext_capab =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6271) 			nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6272) 		params.ext_capab_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6273) 			nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6276) 	if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6277) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6279) 	if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6280) 		params.plink_action =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6281) 			nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6283) 	if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6284) 		params.plink_state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6285) 			nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6286) 		if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6287) 			params.peer_aid = nla_get_u16(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6288) 				info->attrs[NL80211_ATTR_MESH_PEER_AID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6289) 		params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6292) 	if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6293) 		params.local_pm = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6294) 			info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6296) 	if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6297) 		params.opmode_notif_used = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6298) 		params.opmode_notif =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6299) 			nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6300) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6302) 	if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6303) 		params.he_6ghz_capa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6304) 			nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6306) 	if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6307) 		params.airtime_weight =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6308) 			nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6310) 	if (params.airtime_weight &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6311) 	    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6312) 				     NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6313) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6315) 	err = nl80211_parse_sta_txpower_setting(info, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6316) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6317) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6319) 	/* Include parameters for TDLS peer (will check later) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6320) 	err = nl80211_set_station_tdls(info, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6321) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6322) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6324) 	params.vlan = get_vlan(info, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6325) 	if (IS_ERR(params.vlan))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6326) 		return PTR_ERR(params.vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6328) 	switch (dev->ieee80211_ptr->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6329) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6330) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6331) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6332) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6333) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6334) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6335) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6336) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6337) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6338) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6339) 		goto out_put_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6342) 	/* driver will call cfg80211_check_station_change() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6343) 	err = rdev_change_station(rdev, dev, mac_addr, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6345)  out_put_vlan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6346) 	if (params.vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6347) 		dev_put(params.vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6349) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6352) static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6354) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6355) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6356) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6357) 	struct station_parameters params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6358) 	u8 *mac_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6359) 	u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6360) 			 BIT(NL80211_STA_FLAG_ASSOCIATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6362) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6364) 	if (!rdev->ops->add_station)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6365) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6367) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6368) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6370) 	if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6371) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6373) 	if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6374) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6376) 	if (!info->attrs[NL80211_ATTR_STA_AID] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6377) 	    !info->attrs[NL80211_ATTR_PEER_AID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6378) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6380) 	mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6381) 	params.supported_rates =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6382) 		nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6383) 	params.supported_rates_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6384) 		nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6385) 	params.listen_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6386) 		nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6388) 	if (info->attrs[NL80211_ATTR_VLAN_ID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6389) 		params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6391) 	if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6392) 		params.support_p2p_ps =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6393) 			nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6394) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6395) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6396) 		 * if not specified, assume it's supported for P2P GO interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6397) 		 * and is NOT supported for AP interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6398) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6399) 		params.support_p2p_ps =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6400) 			dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6403) 	if (info->attrs[NL80211_ATTR_PEER_AID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6404) 		params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6405) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6406) 		params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6408) 	if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6409) 		params.capability =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6410) 			nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6411) 		params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6414) 	if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6415) 		params.ext_capab =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6416) 			nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6417) 		params.ext_capab_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6418) 			nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6421) 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6422) 		params.ht_capa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6423) 			nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6425) 	if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6426) 		params.vht_capa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6427) 			nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6429) 	if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6430) 		params.he_capa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6431) 			nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6432) 		params.he_capa_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6433) 			nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6434) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6436) 	if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6437) 		params.he_6ghz_capa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6438) 			nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6440) 	if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6441) 		params.opmode_notif_used = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6442) 		params.opmode_notif =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6443) 			nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6446) 	if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6447) 		params.plink_action =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6448) 			nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6450) 	if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6451) 		params.airtime_weight =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6452) 			nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6454) 	if (params.airtime_weight &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6455) 	    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6456) 				     NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6457) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6459) 	err = nl80211_parse_sta_txpower_setting(info, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6460) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6461) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6463) 	err = nl80211_parse_sta_channel_info(info, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6464) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6465) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6467) 	err = nl80211_parse_sta_wme(info, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6468) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6469) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6471) 	if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6472) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6474) 	/* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6475) 	 * as userspace might just pass through the capabilities from the IEs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6476) 	 * directly, rather than enforcing this restriction and returning an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6477) 	 * error in this case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6478) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6479) 	if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6480) 		params.ht_capa = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6481) 		params.vht_capa = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6483) 		/* HE requires WME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6484) 		if (params.he_capa_len || params.he_6ghz_capa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6485) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6486) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6488) 	/* Ensure that HT/VHT capabilities are not set for 6 GHz HE STA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6489) 	if (params.he_6ghz_capa && (params.ht_capa || params.vht_capa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6490) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6492) 	/* When you run into this, adjust the code below for the new flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6493) 	BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6495) 	switch (dev->ieee80211_ptr->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6496) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6497) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6498) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6499) 		/* ignore WME attributes if iface/sta is not capable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6500) 		if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6501) 		    !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6502) 			params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6504) 		/* TDLS peers cannot be added */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6505) 		if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6506) 		    info->attrs[NL80211_ATTR_PEER_AID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6507) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6508) 		/* but don't bother the driver with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6509) 		params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6511) 		/* allow authenticated/associated only if driver handles it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6512) 		if (!(rdev->wiphy.features &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6513) 				NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6514) 		    params.sta_flags_mask & auth_assoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6515) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6517) 		/* Older userspace, or userspace wanting to be compatible with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6518) 		 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6519) 		 * and assoc flags in the mask, but assumes the station will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6520) 		 * added as associated anyway since this was the required driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6521) 		 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6522) 		 * introduced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6523) 		 * In order to not bother drivers with this quirk in the API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6524) 		 * set the flags in both the mask and set for new stations in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6525) 		 * this case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6526) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6527) 		if (!(params.sta_flags_mask & auth_assoc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6528) 			params.sta_flags_mask |= auth_assoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6529) 			params.sta_flags_set |= auth_assoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6530) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6532) 		/* must be last in here for error handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6533) 		params.vlan = get_vlan(info, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6534) 		if (IS_ERR(params.vlan))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6535) 			return PTR_ERR(params.vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6536) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6537) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6538) 		/* ignore uAPSD data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6539) 		params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6541) 		/* associated is disallowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6542) 		if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6543) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6544) 		/* TDLS peers cannot be added */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6545) 		if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6546) 		    info->attrs[NL80211_ATTR_PEER_AID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6547) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6548) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6549) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6550) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6551) 		/* ignore uAPSD data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6552) 		params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6554) 		/* these are disallowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6555) 		if (params.sta_flags_mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6556) 				(BIT(NL80211_STA_FLAG_ASSOCIATED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6557) 				 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6558) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6559) 		/* Only TDLS peers can be added */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6560) 		if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6561) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6562) 		/* Can only add if TDLS ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6563) 		if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6564) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6565) 		/* ... with external setup is supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6566) 		if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6567) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6568) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6569) 		 * Older wpa_supplicant versions always mark the TDLS peer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6570) 		 * as authorized, but it shouldn't yet be.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6571) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6572) 		params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6573) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6574) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6575) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6576) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6578) 	/* be aware of params.vlan when changing code here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6580) 	err = rdev_add_station(rdev, dev, mac_addr, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6582) 	if (params.vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6583) 		dev_put(params.vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6584) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6587) static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6589) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6590) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6591) 	struct station_del_parameters params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6593) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6595) 	if (info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6596) 		params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6598) 	switch (dev->ieee80211_ptr->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6599) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6600) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6601) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6602) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6603) 		/* always accept these */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6604) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6605) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6606) 		/* conditionally accept */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6607) 		if (wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6608) 					    NL80211_EXT_FEATURE_DEL_IBSS_STA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6609) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6610) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6611) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6612) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6615) 	if (!rdev->ops->del_station)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6616) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6618) 	if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6619) 		params.subtype =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6620) 			nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6621) 		if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6622) 		    params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6623) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6624) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6625) 		/* Default to Deauthentication frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6626) 		params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6629) 	if (info->attrs[NL80211_ATTR_REASON_CODE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6630) 		params.reason_code =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6631) 			nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6632) 		if (params.reason_code == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6633) 			return -EINVAL; /* 0 is reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6634) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6635) 		/* Default to reason code 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6636) 		params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6639) 	return rdev_del_station(rdev, dev, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6642) static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6643) 				int flags, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6644) 				u8 *dst, u8 *next_hop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6645) 				struct mpath_info *pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6647) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6648) 	struct nlattr *pinfoattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6650) 	hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6651) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6652) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6654) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6655) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6656) 	    nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6657) 	    nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6658) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6660) 	pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MPATH_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6661) 	if (!pinfoattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6662) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6663) 	if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6664) 	    nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6665) 			pinfo->frame_qlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6666) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6667) 	if (((pinfo->filled & MPATH_INFO_SN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6668) 	     nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6669) 	    ((pinfo->filled & MPATH_INFO_METRIC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6670) 	     nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6671) 			 pinfo->metric)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6672) 	    ((pinfo->filled & MPATH_INFO_EXPTIME) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6673) 	     nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6674) 			 pinfo->exptime)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6675) 	    ((pinfo->filled & MPATH_INFO_FLAGS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6676) 	     nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6677) 			pinfo->flags)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6678) 	    ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6679) 	     nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6680) 			 pinfo->discovery_timeout)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6681) 	    ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6682) 	     nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6683) 			pinfo->discovery_retries)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6684) 	    ((pinfo->filled & MPATH_INFO_HOP_COUNT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6685) 	     nla_put_u8(msg, NL80211_MPATH_INFO_HOP_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6686) 			pinfo->hop_count)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6687) 	    ((pinfo->filled & MPATH_INFO_PATH_CHANGE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6688) 	     nla_put_u32(msg, NL80211_MPATH_INFO_PATH_CHANGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6689) 			 pinfo->path_change_count)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6690) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6692) 	nla_nest_end(msg, pinfoattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6694) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6695) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6697)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6698) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6699) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6702) static int nl80211_dump_mpath(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6703) 			      struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6705) 	struct mpath_info pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6706) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6707) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6708) 	u8 dst[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6709) 	u8 next_hop[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6710) 	int path_idx = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6711) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6713) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6714) 	err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6715) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6716) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6718) 	if (!rdev->ops->dump_mpath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6719) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6720) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6723) 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6724) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6725) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6728) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6729) 		err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6730) 				      next_hop, &pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6731) 		if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6732) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6733) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6734) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6736) 		if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6737) 				       cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6738) 				       wdev->netdev, dst, next_hop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6739) 				       &pinfo) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6740) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6742) 		path_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6745)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6746) 	cb->args[2] = path_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6747) 	err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6748)  out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6749) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6750) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6753) static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6755) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6756) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6757) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6758) 	struct mpath_info pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6759) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6760) 	u8 *dst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6761) 	u8 next_hop[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6763) 	memset(&pinfo, 0, sizeof(pinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6765) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6766) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6768) 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6770) 	if (!rdev->ops->get_mpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6771) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6773) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6774) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6776) 	err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6777) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6778) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6780) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6781) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6782) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6784) 	if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6785) 				 dev, dst, next_hop, &pinfo) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6786) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6787) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6788) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6790) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6793) static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6795) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6796) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6797) 	u8 *dst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6798) 	u8 *next_hop = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6800) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6801) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6803) 	if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6804) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6806) 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6807) 	next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6809) 	if (!rdev->ops->change_mpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6810) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6812) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6813) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6815) 	return rdev_change_mpath(rdev, dev, dst, next_hop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6818) static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6820) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6821) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6822) 	u8 *dst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6823) 	u8 *next_hop = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6825) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6826) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6828) 	if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6829) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6831) 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6832) 	next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6834) 	if (!rdev->ops->add_mpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6835) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6837) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6838) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6840) 	return rdev_add_mpath(rdev, dev, dst, next_hop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6843) static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6845) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6846) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6847) 	u8 *dst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6849) 	if (info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6850) 		dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6852) 	if (!rdev->ops->del_mpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6853) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6855) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6856) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6858) 	return rdev_del_mpath(rdev, dev, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6861) static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6863) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6864) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6865) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6866) 	struct mpath_info pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6867) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6868) 	u8 *dst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6869) 	u8 mpp[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6871) 	memset(&pinfo, 0, sizeof(pinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6873) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6874) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6876) 	dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6878) 	if (!rdev->ops->get_mpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6879) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6881) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6882) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6884) 	err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6885) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6886) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6888) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6889) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6890) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6892) 	if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6893) 			       dev, dst, mpp, &pinfo) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6894) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6895) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6898) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6901) static int nl80211_dump_mpp(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6902) 			    struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6904) 	struct mpath_info pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6905) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6906) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6907) 	u8 dst[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6908) 	u8 mpp[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6909) 	int path_idx = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6910) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6912) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6913) 	err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6914) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6915) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6917) 	if (!rdev->ops->dump_mpp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6918) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6919) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6920) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6922) 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6923) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6924) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6927) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6928) 		err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6929) 				    mpp, &pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6930) 		if (err == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6931) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6932) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6933) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6935) 		if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6936) 				       cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6937) 				       wdev->netdev, dst, mpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6938) 				       &pinfo) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6939) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6941) 		path_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6942) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6944)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6945) 	cb->args[2] = path_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6946) 	err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6947)  out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6948) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6949) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6952) static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6954) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6955) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6956) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6957) 	struct bss_parameters params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6958) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6960) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6961) 	/* default to not changing parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6962) 	params.use_cts_prot = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6963) 	params.use_short_preamble = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6964) 	params.use_short_slot_time = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6965) 	params.ap_isolate = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6966) 	params.ht_opmode = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6967) 	params.p2p_ctwindow = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6968) 	params.p2p_opp_ps = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6970) 	if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6971) 		params.use_cts_prot =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6972) 		    nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6973) 	if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6974) 		params.use_short_preamble =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6975) 		    nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6976) 	if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6977) 		params.use_short_slot_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6978) 		    nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6979) 	if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6980) 		params.basic_rates =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6981) 			nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6982) 		params.basic_rates_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6983) 			nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6984) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6985) 	if (info->attrs[NL80211_ATTR_AP_ISOLATE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6986) 		params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6987) 	if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6988) 		params.ht_opmode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6989) 			nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6991) 	if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6992) 		if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6993) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6994) 		params.p2p_ctwindow =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6995) 			nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6996) 		if (params.p2p_ctwindow != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6997) 		    !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6998) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6999) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7001) 	if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7002) 		u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7004) 		if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7005) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7006) 		tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7007) 		params.p2p_opp_ps = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7008) 		if (params.p2p_opp_ps &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7009) 		    !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7010) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7011) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7013) 	if (!rdev->ops->change_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7014) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7016) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7017) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7018) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7020) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7021) 	err = rdev_change_bss(rdev, dev, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7022) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7024) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7027) static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7029) 	char *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7030) 	bool is_indoor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7031) 	enum nl80211_user_reg_hint_type user_reg_hint_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7032) 	u32 owner_nlportid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7034) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7035) 	 * You should only get this when cfg80211 hasn't yet initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7036) 	 * completely when built-in to the kernel right between the time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7037) 	 * window between nl80211_init() and regulatory_init(), if that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7038) 	 * even possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7039) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7040) 	if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7041) 		return -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7043) 	if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7044) 		user_reg_hint_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7045) 		  nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7046) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7047) 		user_reg_hint_type = NL80211_USER_REG_HINT_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7049) 	switch (user_reg_hint_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7050) 	case NL80211_USER_REG_HINT_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7051) 	case NL80211_USER_REG_HINT_CELL_BASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7052) 		if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7053) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7055) 		data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7056) 		return regulatory_hint_user(data, user_reg_hint_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7057) 	case NL80211_USER_REG_HINT_INDOOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7058) 		if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7059) 			owner_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7060) 			is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7061) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7062) 			owner_nlportid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7063) 			is_indoor = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7064) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7066) 		return regulatory_hint_indoor(is_indoor, owner_nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7067) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7068) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7069) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7072) static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7074) 	return reg_reload_regdb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7077) static int nl80211_get_mesh_config(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7078) 				   struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7080) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7081) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7082) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7083) 	struct mesh_config cur_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7084) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7085) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7086) 	struct nlattr *pinfoattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7087) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7089) 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7090) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7092) 	if (!rdev->ops->get_mesh_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7093) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7095) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7096) 	/* If not connected, get default parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7097) 	if (!wdev->mesh_id_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7098) 		memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7099) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7100) 		err = rdev_get_mesh_config(rdev, dev, &cur_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7101) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7103) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7104) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7106) 	/* Draw up a netlink message to send back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7107) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7108) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7109) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7110) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7111) 			     NL80211_CMD_GET_MESH_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7112) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7113) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7114) 	pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MESH_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7115) 	if (!pinfoattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7116) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7117) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7118) 	    nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7119) 			cur_params.dot11MeshRetryTimeout) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7120) 	    nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7121) 			cur_params.dot11MeshConfirmTimeout) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7122) 	    nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7123) 			cur_params.dot11MeshHoldingTimeout) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7124) 	    nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7125) 			cur_params.dot11MeshMaxPeerLinks) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7126) 	    nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7127) 		       cur_params.dot11MeshMaxRetries) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7128) 	    nla_put_u8(msg, NL80211_MESHCONF_TTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7129) 		       cur_params.dot11MeshTTL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7130) 	    nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7131) 		       cur_params.element_ttl) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7132) 	    nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7133) 		       cur_params.auto_open_plinks) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7134) 	    nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7135) 			cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7136) 	    nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7137) 		       cur_params.dot11MeshHWMPmaxPREQretries) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7138) 	    nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7139) 			cur_params.path_refresh_time) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7140) 	    nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7141) 			cur_params.min_discovery_timeout) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7142) 	    nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7143) 			cur_params.dot11MeshHWMPactivePathTimeout) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7144) 	    nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7145) 			cur_params.dot11MeshHWMPpreqMinInterval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7146) 	    nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7147) 			cur_params.dot11MeshHWMPperrMinInterval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7148) 	    nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7149) 			cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7150) 	    nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7151) 		       cur_params.dot11MeshHWMPRootMode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7152) 	    nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7153) 			cur_params.dot11MeshHWMPRannInterval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7154) 	    nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7155) 		       cur_params.dot11MeshGateAnnouncementProtocol) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7156) 	    nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7157) 		       cur_params.dot11MeshForwarding) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7158) 	    nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7159) 			cur_params.rssi_threshold) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7160) 	    nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7161) 			cur_params.ht_opmode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7162) 	    nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7163) 			cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7164) 	    nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7165) 			cur_params.dot11MeshHWMProotInterval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7166) 	    nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7167) 			cur_params.dot11MeshHWMPconfirmationInterval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7168) 	    nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7169) 			cur_params.power_mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7170) 	    nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7171) 			cur_params.dot11MeshAwakeWindowDuration) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7172) 	    nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7173) 			cur_params.plink_timeout) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7174) 	    nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7175) 		       cur_params.dot11MeshConnectedToMeshGate) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7176) 	    nla_put_u8(msg, NL80211_MESHCONF_NOLEARN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7177) 		       cur_params.dot11MeshNolearn) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7178) 	    nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_AS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7179) 		       cur_params.dot11MeshConnectedToAuthServer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7180) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7181) 	nla_nest_end(msg, pinfoattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7182) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7183) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7185)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7186)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7187) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7188) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7191) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7192) nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7193) 	[NL80211_MESHCONF_RETRY_TIMEOUT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7194) 		NLA_POLICY_RANGE(NLA_U16, 1, 255),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7195) 	[NL80211_MESHCONF_CONFIRM_TIMEOUT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7196) 		NLA_POLICY_RANGE(NLA_U16, 1, 255),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7197) 	[NL80211_MESHCONF_HOLDING_TIMEOUT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7198) 		NLA_POLICY_RANGE(NLA_U16, 1, 255),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7199) 	[NL80211_MESHCONF_MAX_PEER_LINKS] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7200) 		NLA_POLICY_RANGE(NLA_U16, 0, 255),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7201) 	[NL80211_MESHCONF_MAX_RETRIES] = NLA_POLICY_MAX(NLA_U8, 16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7202) 	[NL80211_MESHCONF_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7203) 	[NL80211_MESHCONF_ELEMENT_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7204) 	[NL80211_MESHCONF_AUTO_OPEN_PLINKS] = NLA_POLICY_MAX(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7205) 	[NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7206) 		NLA_POLICY_RANGE(NLA_U32, 1, 255),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7207) 	[NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7208) 	[NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7209) 	[NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = NLA_POLICY_MIN(NLA_U16, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7210) 	[NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7211) 	[NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7212) 		NLA_POLICY_MIN(NLA_U16, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7213) 	[NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7214) 		NLA_POLICY_MIN(NLA_U16, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7215) 	[NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7216) 		NLA_POLICY_MIN(NLA_U16, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7217) 	[NL80211_MESHCONF_HWMP_ROOTMODE] = NLA_POLICY_MAX(NLA_U8, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7218) 	[NL80211_MESHCONF_HWMP_RANN_INTERVAL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7219) 		NLA_POLICY_MIN(NLA_U16, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7220) 	[NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = NLA_POLICY_MAX(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7221) 	[NL80211_MESHCONF_FORWARDING] = NLA_POLICY_MAX(NLA_U8, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7222) 	[NL80211_MESHCONF_RSSI_THRESHOLD] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7223) 		NLA_POLICY_RANGE(NLA_S32, -255, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7224) 	[NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7225) 	[NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7226) 	[NL80211_MESHCONF_HWMP_ROOT_INTERVAL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7227) 		NLA_POLICY_MIN(NLA_U16, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7228) 	[NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7229) 		NLA_POLICY_MIN(NLA_U16, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7230) 	[NL80211_MESHCONF_POWER_MODE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7231) 		NLA_POLICY_RANGE(NLA_U32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7232) 				 NL80211_MESH_POWER_ACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7233) 				 NL80211_MESH_POWER_MAX),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7234) 	[NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7235) 	[NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7236) 	[NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7237) 	[NL80211_MESHCONF_NOLEARN] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7238) 	[NL80211_MESHCONF_CONNECTED_TO_AS] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7241) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7242) 	nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7243) 	[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7244) 	[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7245) 	[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7246) 	[NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7247) 	[NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7248) 	[NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7249) 	[NL80211_MESH_SETUP_IE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7250) 		NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7251) 				       IEEE80211_MAX_DATA_LEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7252) 	[NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7255) static int nl80211_parse_mesh_config(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7256) 				     struct mesh_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7257) 				     u32 *mask_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7259) 	struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7260) 	u32 mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7261) 	u16 ht_opmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7263) #define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7264) do {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7265) 	if (tb[attr]) {							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7266) 		cfg->param = fn(tb[attr]);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7267) 		mask |= BIT((attr) - 1);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7268) 	}								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7269) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7271) 	if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7272) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7273) 	if (nla_parse_nested_deprecated(tb, NL80211_MESHCONF_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_CONFIG], nl80211_meshconf_params_policy, info->extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7274) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7276) 	/* This makes sure that there aren't more than 32 mesh config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7277) 	 * parameters (otherwise our bitfield scheme would not work.) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7278) 	BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7280) 	/* Fill in the params struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7281) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7282) 				  NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7283) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7284) 				  NL80211_MESHCONF_CONFIRM_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7285) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7286) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7287) 				  NL80211_MESHCONF_HOLDING_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7288) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7289) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7290) 				  NL80211_MESHCONF_MAX_PEER_LINKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7291) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7292) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7293) 				  NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7294) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7295) 				  NL80211_MESHCONF_TTL, nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7296) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7297) 				  NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7298) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7299) 				  NL80211_MESHCONF_AUTO_OPEN_PLINKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7300) 				  nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7301) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7302) 				  mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7303) 				  NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7304) 				  nla_get_u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7305) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7306) 				  NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7307) 				  nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7308) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7309) 				  NL80211_MESHCONF_PATH_REFRESH_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7310) 				  nla_get_u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7311) 	if (mask & BIT(NL80211_MESHCONF_PATH_REFRESH_TIME) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7312) 	    (cfg->path_refresh_time < 1 || cfg->path_refresh_time > 65535))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7313) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7314) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7315) 				  NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7316) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7317) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7318) 				  mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7319) 				  NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7320) 				  nla_get_u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7321) 	if (mask & BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7322) 	    (cfg->dot11MeshHWMPactivePathTimeout < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7323) 	     cfg->dot11MeshHWMPactivePathTimeout > 65535))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7324) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7325) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7326) 				  NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7327) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7328) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7329) 				  NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7330) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7331) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7332) 				  dot11MeshHWMPnetDiameterTraversalTime, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7333) 				  NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7334) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7335) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7336) 				  NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7337) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7338) 				  NL80211_MESHCONF_HWMP_RANN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7339) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7340) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshGateAnnouncementProtocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7341) 				  mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7342) 				  nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7343) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7344) 				  NL80211_MESHCONF_FORWARDING, nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7345) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7346) 				  NL80211_MESHCONF_RSSI_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7347) 				  nla_get_s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7348) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7349) 				  NL80211_MESHCONF_CONNECTED_TO_GATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7350) 				  nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7351) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToAuthServer, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7352) 				  NL80211_MESHCONF_CONNECTED_TO_AS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7353) 				  nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7354) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7355) 	 * Check HT operation mode based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7356) 	 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7357) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7358) 	if (tb[NL80211_MESHCONF_HT_OPMODE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7359) 		ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7361) 		if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7362) 				  IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7363) 				  IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7364) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7366) 		/* NON_HT_STA bit is reserved, but some programs set it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7367) 		ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7369) 		cfg->ht_opmode = ht_opmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7370) 		mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7371) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7372) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7373) 				  dot11MeshHWMPactivePathToRootTimeout, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7374) 				  NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7375) 				  nla_get_u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7376) 	if (mask & BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7377) 	    (cfg->dot11MeshHWMPactivePathToRootTimeout < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7378) 	     cfg->dot11MeshHWMPactivePathToRootTimeout > 65535))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7379) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7380) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7381) 				  NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7382) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7383) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPconfirmationInterval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7384) 				  mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7385) 				  NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7386) 				  nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7387) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7388) 				  NL80211_MESHCONF_POWER_MODE, nla_get_u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7389) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7390) 				  NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7391) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7392) 				  NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7393) 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNolearn, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7394) 				  NL80211_MESHCONF_NOLEARN, nla_get_u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7395) 	if (mask_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7396) 		*mask_out = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7398) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7400) #undef FILL_IN_MESH_PARAM_IF_SET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7403) static int nl80211_parse_mesh_setup(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7404) 				     struct mesh_setup *setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7406) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7407) 	struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7409) 	if (!info->attrs[NL80211_ATTR_MESH_SETUP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7410) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7411) 	if (nla_parse_nested_deprecated(tb, NL80211_MESH_SETUP_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_SETUP], nl80211_mesh_setup_params_policy, info->extack))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7412) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7414) 	if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7415) 		setup->sync_method =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7416) 		(nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7417) 		 IEEE80211_SYNC_METHOD_VENDOR :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7418) 		 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7420) 	if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7421) 		setup->path_sel_proto =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7422) 		(nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7423) 		 IEEE80211_PATH_PROTOCOL_VENDOR :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7424) 		 IEEE80211_PATH_PROTOCOL_HWMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7426) 	if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7427) 		setup->path_metric =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7428) 		(nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7429) 		 IEEE80211_PATH_METRIC_VENDOR :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7430) 		 IEEE80211_PATH_METRIC_AIRTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7432) 	if (tb[NL80211_MESH_SETUP_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7433) 		struct nlattr *ieattr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7434) 			tb[NL80211_MESH_SETUP_IE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7435) 		setup->ie = nla_data(ieattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7436) 		setup->ie_len = nla_len(ieattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7438) 	if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7439) 	    !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7440) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7441) 	setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7442) 	setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7443) 	setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7444) 	if (setup->is_secure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7445) 		setup->user_mpm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7447) 	if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7448) 		if (!setup->user_mpm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7449) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7450) 		setup->auth_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7451) 			nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7452) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7454) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7457) static int nl80211_update_mesh_config(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7458) 				      struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7460) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7461) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7462) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7463) 	struct mesh_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7464) 	u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7465) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7467) 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7468) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7470) 	if (!rdev->ops->update_mesh_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7471) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7473) 	err = nl80211_parse_mesh_config(info, &cfg, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7474) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7475) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7477) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7478) 	if (!wdev->mesh_id_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7479) 		err = -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7481) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7482) 		err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7484) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7486) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7489) static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7490) 			      struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7492) 	struct nlattr *nl_reg_rules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7493) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7495) 	if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7496) 	    (regdom->dfs_region &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7497) 	     nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7498) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7500) 	nl_reg_rules = nla_nest_start_noflag(msg, NL80211_ATTR_REG_RULES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7501) 	if (!nl_reg_rules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7502) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7504) 	for (i = 0; i < regdom->n_reg_rules; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7505) 		struct nlattr *nl_reg_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7506) 		const struct ieee80211_reg_rule *reg_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7507) 		const struct ieee80211_freq_range *freq_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7508) 		const struct ieee80211_power_rule *power_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7509) 		unsigned int max_bandwidth_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7511) 		reg_rule = &regdom->reg_rules[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7512) 		freq_range = &reg_rule->freq_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7513) 		power_rule = &reg_rule->power_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7515) 		nl_reg_rule = nla_nest_start_noflag(msg, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7516) 		if (!nl_reg_rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7517) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7519) 		max_bandwidth_khz = freq_range->max_bandwidth_khz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7520) 		if (!max_bandwidth_khz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7521) 			max_bandwidth_khz = reg_get_max_bandwidth(regdom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7522) 								  reg_rule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7524) 		if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7525) 				reg_rule->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7526) 		    nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7527) 				freq_range->start_freq_khz) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7528) 		    nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7529) 				freq_range->end_freq_khz) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7530) 		    nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7531) 				max_bandwidth_khz) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7532) 		    nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7533) 				power_rule->max_antenna_gain) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7534) 		    nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7535) 				power_rule->max_eirp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7536) 		    nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7537) 				reg_rule->dfs_cac_ms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7538) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7540) 		nla_nest_end(msg, nl_reg_rule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7543) 	nla_nest_end(msg, nl_reg_rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7544) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7546) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7547) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7550) static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7552) 	const struct ieee80211_regdomain *regdom = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7553) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7554) 	struct wiphy *wiphy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7555) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7556) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7558) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7559) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7560) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7562) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7563) 			     NL80211_CMD_GET_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7564) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7565) 		goto put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7567) 	if (info->attrs[NL80211_ATTR_WIPHY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7568) 		bool self_managed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7570) 		rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7571) 		if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7572) 			nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7573) 			return PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7574) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7576) 		wiphy = &rdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7577) 		self_managed = wiphy->regulatory_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7578) 			       REGULATORY_WIPHY_SELF_MANAGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7579) 		regdom = get_wiphy_regdom(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7581) 		/* a self-managed-reg device must have a private regdom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7582) 		if (WARN_ON(!regdom && self_managed)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7583) 			nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7584) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7585) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7587) 		if (regdom &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7588) 		    nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7589) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7590) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7592) 	if (!wiphy && reg_last_request_cell_base() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7593) 	    nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7594) 			NL80211_USER_REG_HINT_CELL_BASE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7595) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7597) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7599) 	if (!regdom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7600) 		regdom = rcu_dereference(cfg80211_regdomain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7602) 	if (nl80211_put_regdom(regdom, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7603) 		goto nla_put_failure_rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7605) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7607) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7608) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7610) nla_put_failure_rcu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7611) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7612) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7613) put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7614) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7615) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7618) static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7619) 			       u32 seq, int flags, struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7620) 			       const struct ieee80211_regdomain *regdom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7622) 	void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7623) 				   NL80211_CMD_GET_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7625) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7626) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7628) 	genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7630) 	if (nl80211_put_regdom(regdom, msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7631) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7633) 	if (!wiphy && reg_last_request_cell_base() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7634) 	    nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7635) 			NL80211_USER_REG_HINT_CELL_BASE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7636) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7638) 	if (wiphy &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7639) 	    nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7640) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7642) 	if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7643) 	    nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7644) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7646) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7647) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7649) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7650) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7651) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7654) static int nl80211_get_reg_dump(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7655) 				struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7657) 	const struct ieee80211_regdomain *regdom = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7658) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7659) 	int err, reg_idx, start = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7661) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7663) 	if (cfg80211_regdomain && start == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7664) 		err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7665) 					  NLM_F_MULTI, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7666) 					  rtnl_dereference(cfg80211_regdomain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7667) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7668) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7669) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7671) 	/* the global regdom is idx 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7672) 	reg_idx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7673) 	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7674) 		regdom = get_wiphy_regdom(&rdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7675) 		if (!regdom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7676) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7678) 		if (++reg_idx <= start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7679) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7681) 		err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7682) 					  NLM_F_MULTI, &rdev->wiphy, regdom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7683) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7684) 			reg_idx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7685) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7686) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7689) 	cb->args[2] = reg_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7690) 	err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7691) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7692) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7693) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7696) #ifdef CONFIG_CFG80211_CRDA_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7697) static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7698) 	[NL80211_ATTR_REG_RULE_FLAGS]		= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7699) 	[NL80211_ATTR_FREQ_RANGE_START]		= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7700) 	[NL80211_ATTR_FREQ_RANGE_END]		= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7701) 	[NL80211_ATTR_FREQ_RANGE_MAX_BW]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7702) 	[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7703) 	[NL80211_ATTR_POWER_RULE_MAX_EIRP]	= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7704) 	[NL80211_ATTR_DFS_CAC_TIME]		= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7705) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7707) static int parse_reg_rule(struct nlattr *tb[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7708) 	struct ieee80211_reg_rule *reg_rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7710) 	struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7711) 	struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7713) 	if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7714) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7715) 	if (!tb[NL80211_ATTR_FREQ_RANGE_START])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7716) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7717) 	if (!tb[NL80211_ATTR_FREQ_RANGE_END])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7718) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7719) 	if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7720) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7721) 	if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7722) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7724) 	reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7726) 	freq_range->start_freq_khz =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7727) 		nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7728) 	freq_range->end_freq_khz =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7729) 		nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7730) 	freq_range->max_bandwidth_khz =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7731) 		nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7733) 	power_rule->max_eirp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7734) 		nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7736) 	if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7737) 		power_rule->max_antenna_gain =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7738) 			nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7740) 	if (tb[NL80211_ATTR_DFS_CAC_TIME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7741) 		reg_rule->dfs_cac_ms =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7742) 			nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7744) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7747) static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7749) 	struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7750) 	struct nlattr *nl_reg_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7751) 	char *alpha2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7752) 	int rem_reg_rules, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7753) 	u32 num_rules = 0, rule_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7754) 	enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7755) 	struct ieee80211_regdomain *rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7757) 	if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7758) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7760) 	if (!info->attrs[NL80211_ATTR_REG_RULES])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7761) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7763) 	alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7765) 	if (info->attrs[NL80211_ATTR_DFS_REGION])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7766) 		dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7768) 	nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7769) 			    rem_reg_rules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7770) 		num_rules++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7771) 		if (num_rules > NL80211_MAX_SUPP_REG_RULES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7772) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7773) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7775) 	if (!reg_is_valid_request(alpha2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7776) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7778) 	rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7779) 	if (!rd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7780) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7782) 	rd->n_reg_rules = num_rules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7783) 	rd->alpha2[0] = alpha2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7784) 	rd->alpha2[1] = alpha2[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7786) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7787) 	 * Disable DFS master mode if the DFS region was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7788) 	 * not supported or known on this kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7789) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7790) 	if (reg_supported_dfs_region(dfs_region))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7791) 		rd->dfs_region = dfs_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7793) 	nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7794) 			    rem_reg_rules) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7795) 		r = nla_parse_nested_deprecated(tb, NL80211_REG_RULE_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7796) 						nl_reg_rule, reg_rule_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7797) 						info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7798) 		if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7799) 			goto bad_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7800) 		r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7801) 		if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7802) 			goto bad_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7804) 		rule_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7806) 		if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7807) 			r = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7808) 			goto bad_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7809) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7812) 	/* set_regdom takes ownership of rd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7813) 	return set_regdom(rd, REGD_SOURCE_CRDA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7814)  bad_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7815) 	kfree(rd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7816) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7818) #endif /* CONFIG_CFG80211_CRDA_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7820) static int validate_scan_freqs(struct nlattr *freqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7822) 	struct nlattr *attr1, *attr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7823) 	int n_channels = 0, tmp1, tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7825) 	nla_for_each_nested(attr1, freqs, tmp1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7826) 		if (nla_len(attr1) != sizeof(u32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7827) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7829) 	nla_for_each_nested(attr1, freqs, tmp1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7830) 		n_channels++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7831) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7832) 		 * Some hardware has a limited channel list for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7833) 		 * scanning, and it is pretty much nonsensical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7834) 		 * to scan for a channel twice, so disallow that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7835) 		 * and don't require drivers to check that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7836) 		 * channel list they get isn't longer than what
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7837) 		 * they can scan, as long as they can scan all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7838) 		 * the channels they registered at once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7839) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7840) 		nla_for_each_nested(attr2, freqs, tmp2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7841) 			if (attr1 != attr2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7842) 			    nla_get_u32(attr1) == nla_get_u32(attr2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7843) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7846) 	return n_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7849) static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7851) 	return b < NUM_NL80211_BANDS && wiphy->bands[b];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7854) static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7855) 			    struct cfg80211_bss_selection *bss_select)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7857) 	struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7858) 	struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7859) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7860) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7861) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7863) 	/* only process one nested attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7864) 	nest = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7865) 	if (!nla_ok(nest, nla_len(nest)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7866) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7868) 	err = nla_parse_nested_deprecated(attr, NL80211_BSS_SELECT_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7869) 					  nest, nl80211_bss_select_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7870) 					  NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7871) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7872) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7874) 	/* only one attribute may be given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7875) 	for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7876) 		if (attr[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7877) 			if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7878) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7879) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7880) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7881) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7883) 	bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7885) 	if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7886) 		bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7888) 	if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7889) 		bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7890) 		bss_select->param.band_pref =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7891) 			nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7892) 		if (!is_band_valid(wiphy, bss_select->param.band_pref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7893) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7896) 	if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7897) 		struct nl80211_bss_select_rssi_adjust *adj_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7899) 		adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7900) 		bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7901) 		bss_select->param.adjust.band = adj_param->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7902) 		bss_select->param.adjust.delta = adj_param->delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7903) 		if (!is_band_valid(wiphy, bss_select->param.adjust.band))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7904) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7907) 	/* user-space did not provide behaviour attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7908) 	if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7909) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7911) 	if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7912) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7914) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7917) int nl80211_parse_random_mac(struct nlattr **attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7918) 			     u8 *mac_addr, u8 *mac_addr_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7920) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7922) 	if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7923) 		eth_zero_addr(mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7924) 		eth_zero_addr(mac_addr_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7925) 		mac_addr[0] = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7926) 		mac_addr_mask[0] = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7928) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7929) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7931) 	/* need both or none */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7932) 	if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7933) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7935) 	memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7936) 	memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7938) 	/* don't allow or configure an mcast address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7939) 	if (!is_multicast_ether_addr(mac_addr_mask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7940) 	    is_multicast_ether_addr(mac_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7941) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7943) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7944) 	 * allow users to pass a MAC address that has bits set outside
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7945) 	 * of the mask, but don't bother drivers with having to deal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7946) 	 * with such bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7947) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7948) 	for (i = 0; i < ETH_ALEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7949) 		mac_addr[i] &= mac_addr_mask[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7951) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7954) static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7956) 	ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7958) 	if (!cfg80211_beaconing_iface_active(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7959) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7961) 	if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7962) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7964) 	return regulatory_pre_cac_allowed(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7967) static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7968) 				    enum nl80211_ext_feature_index feat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7970) 	if (!(flags & flag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7971) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7972) 	if (wiphy_ext_feature_isset(wiphy, feat))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7973) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7974) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7977) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7978) nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7979) 			 void *request, struct nlattr **attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7980) 			 bool is_sched_scan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7982) 	u8 *mac_addr, *mac_addr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7983) 	u32 *flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7984) 	enum nl80211_feature_flags randomness_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7986) 	if (!attrs[NL80211_ATTR_SCAN_FLAGS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7987) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7989) 	if (is_sched_scan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7990) 		struct cfg80211_sched_scan_request *req = request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7992) 		randomness_flag = wdev ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7993) 				  NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7994) 				  NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7995) 		flags = &req->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7996) 		mac_addr = req->mac_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7997) 		mac_addr_mask = req->mac_addr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7998) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7999) 		struct cfg80211_scan_request *req = request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8001) 		randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8002) 		flags = &req->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8003) 		mac_addr = req->mac_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8004) 		mac_addr_mask = req->mac_addr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8005) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8007) 	*flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8009) 	if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8010) 	     !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8011) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8012) 				     NL80211_SCAN_FLAG_LOW_SPAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8013) 				     NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8014) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8015) 				     NL80211_SCAN_FLAG_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8016) 				     NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8017) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8018) 				     NL80211_SCAN_FLAG_HIGH_ACCURACY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8019) 				     NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8020) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8021) 				     NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8022) 				     NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8023) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8024) 				     NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8025) 				     NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8026) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8027) 				     NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8028) 				     NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8029) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8030) 				     NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8031) 				     NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8032) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8033) 				     NL80211_SCAN_FLAG_RANDOM_SN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8034) 				     NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8035) 	    !nl80211_check_scan_feat(wiphy, *flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8036) 				     NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8037) 				     NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8038) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8040) 	if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8041) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8043) 		if (!(wiphy->features & randomness_flag) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8044) 		    (wdev && wdev->current_bss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8045) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8047) 		err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8048) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8049) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8050) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8052) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8055) static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8057) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8058) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8059) 	struct cfg80211_scan_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8060) 	struct nlattr *scan_freqs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8061) 	bool scan_freqs_khz = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8062) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8063) 	struct wiphy *wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8064) 	int err, tmp, n_ssids = 0, n_channels, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8065) 	size_t ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8067) 	wiphy = &rdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8069) 	if (wdev->iftype == NL80211_IFTYPE_NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8070) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8072) 	if (!rdev->ops->scan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8073) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8075) 	if (rdev->scan_req || rdev->scan_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8076) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8078) 	if (info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8079) 		if (!wiphy_ext_feature_isset(wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8080) 					     NL80211_EXT_FEATURE_SCAN_FREQ_KHZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8081) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8082) 		scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8083) 		scan_freqs_khz = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8084) 	} else if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8085) 		scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8087) 	if (scan_freqs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8088) 		n_channels = validate_scan_freqs(scan_freqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8089) 		if (!n_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8090) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8091) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8092) 		n_channels = ieee80211_get_num_supported_channels(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8093) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8095) 	if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8096) 		nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8097) 			n_ssids++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8099) 	if (n_ssids > wiphy->max_scan_ssids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8100) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8102) 	if (info->attrs[NL80211_ATTR_IE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8103) 		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8104) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8105) 		ie_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8107) 	if (ie_len > wiphy->max_scan_ie_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8108) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8110) 	request = kzalloc(sizeof(*request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8111) 			+ sizeof(*request->ssids) * n_ssids
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8112) 			+ sizeof(*request->channels) * n_channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8113) 			+ ie_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8114) 	if (!request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8115) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8117) 	if (n_ssids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8118) 		request->ssids = (void *)&request->channels[n_channels];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8119) 	request->n_ssids = n_ssids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8120) 	if (ie_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8121) 		if (n_ssids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8122) 			request->ie = (void *)(request->ssids + n_ssids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8123) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8124) 			request->ie = (void *)(request->channels + n_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8127) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8128) 	if (scan_freqs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8129) 		/* user specified, bail out if channel not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8130) 		nla_for_each_nested(attr, scan_freqs, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8131) 			struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8132) 			int freq = nla_get_u32(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8134) 			if (!scan_freqs_khz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8135) 				freq = MHZ_TO_KHZ(freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8137) 			chan = ieee80211_get_channel_khz(wiphy, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8138) 			if (!chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8139) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8140) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8141) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8143) 			/* ignore disabled channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8144) 			if (chan->flags & IEEE80211_CHAN_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8145) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8147) 			request->channels[i] = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8148) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8149) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8150) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8151) 		enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8153) 		/* all channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8154) 		for (band = 0; band < NUM_NL80211_BANDS; band++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8155) 			int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8157) 			if (!wiphy->bands[band])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8158) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8159) 			for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8160) 				struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8162) 				chan = &wiphy->bands[band]->channels[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8164) 				if (chan->flags & IEEE80211_CHAN_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8165) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8167) 				request->channels[i] = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8168) 				i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8169) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8170) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8173) 	if (!i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8174) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8175) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8178) 	request->n_channels = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8180) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8181) 	if (!cfg80211_off_channel_oper_allowed(wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8182) 		struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8184) 		if (request->n_channels != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8185) 			wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8186) 			err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8187) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8188) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8190) 		chan = request->channels[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8191) 		if (chan->center_freq != wdev->chandef.chan->center_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8192) 			wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8193) 			err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8194) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8195) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8197) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8199) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8200) 	if (n_ssids) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8201) 		nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8202) 			if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8203) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8204) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8205) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8206) 			request->ssids[i].ssid_len = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8207) 			memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8208) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8209) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8212) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8213) 		request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8214) 		memcpy((void *)request->ie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8215) 		       nla_data(info->attrs[NL80211_ATTR_IE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8216) 		       request->ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8219) 	for (i = 0; i < NUM_NL80211_BANDS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8220) 		if (wiphy->bands[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8221) 			request->rates[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8222) 				(1 << wiphy->bands[i]->n_bitrates) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8224) 	if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8225) 		nla_for_each_nested(attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8226) 				    info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8227) 				    tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8228) 			enum nl80211_band band = nla_type(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8230) 			if (band < 0 || band >= NUM_NL80211_BANDS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8231) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8232) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8233) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8235) 			if (!wiphy->bands[band])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8236) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8238) 			err = ieee80211_get_ratemask(wiphy->bands[band],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8239) 						     nla_data(attr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8240) 						     nla_len(attr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8241) 						     &request->rates[band]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8242) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8243) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8244) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8247) 	if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8248) 		if (!wiphy_ext_feature_isset(wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8249) 					NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8250) 			err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8251) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8252) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8254) 		request->duration =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8255) 			nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8256) 		request->duration_mandatory =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8257) 			nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8258) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8260) 	err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8261) 				       false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8262) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8263) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8265) 	request->no_cck =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8266) 		nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8268) 	/* Initial implementation used NL80211_ATTR_MAC to set the specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8269) 	 * BSSID to scan for. This was problematic because that same attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8270) 	 * was already used for another purpose (local random MAC address). The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8271) 	 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8272) 	 * compatibility with older userspace components, also use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8273) 	 * NL80211_ATTR_MAC value here if it can be determined to be used for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8274) 	 * the specific BSSID use case instead of the random MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8275) 	 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8276) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8277) 	if (info->attrs[NL80211_ATTR_BSSID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8278) 		memcpy(request->bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8279) 		       nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8280) 	else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8281) 		 info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8282) 		memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8283) 		       ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8284) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8285) 		eth_broadcast_addr(request->bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8287) 	request->wdev = wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8288) 	request->wiphy = &rdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8289) 	request->scan_start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8291) 	rdev->scan_req = request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8292) 	err = cfg80211_scan(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8294) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8295) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8297) 	nl80211_send_scan_start(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8298) 	if (wdev->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8299) 		dev_hold(wdev->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8301) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8303)  out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8304) 	rdev->scan_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8305) 	kfree(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8307) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8310) static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8312) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8313) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8315) 	if (!rdev->ops->abort_scan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8316) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8318) 	if (rdev->scan_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8319) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8321) 	if (!rdev->scan_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8322) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8324) 	rdev_abort_scan(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8325) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8328) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8329) nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8330) 			       struct cfg80211_sched_scan_request *request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8331) 			       struct nlattr **attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8333) 	int tmp, err, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8334) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8336) 	if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8337) 		u32 interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8339) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8340) 		 * If scan plans are not specified,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8341) 		 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8342) 		 * case one scan plan will be set with the specified scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8343) 		 * interval and infinite number of iterations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8344) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8345) 		interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8346) 		if (!interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8347) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8349) 		request->scan_plans[0].interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8350) 			DIV_ROUND_UP(interval, MSEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8351) 		if (!request->scan_plans[0].interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8352) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8354) 		if (request->scan_plans[0].interval >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8355) 		    wiphy->max_sched_scan_plan_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8356) 			request->scan_plans[0].interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8357) 				wiphy->max_sched_scan_plan_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8359) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8360) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8362) 	nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8363) 		struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8365) 		if (WARN_ON(i >= n_plans))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8366) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8368) 		err = nla_parse_nested_deprecated(plan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8369) 						  NL80211_SCHED_SCAN_PLAN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8370) 						  attr, nl80211_plan_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8371) 						  NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8372) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8373) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8375) 		if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8376) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8378) 		request->scan_plans[i].interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8379) 			nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8380) 		if (!request->scan_plans[i].interval ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8381) 		    request->scan_plans[i].interval >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8382) 		    wiphy->max_sched_scan_plan_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8383) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8385) 		if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8386) 			request->scan_plans[i].iterations =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8387) 				nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8388) 			if (!request->scan_plans[i].iterations ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8389) 			    (request->scan_plans[i].iterations >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8390) 			     wiphy->max_sched_scan_plan_iterations))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8391) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8392) 		} else if (i < n_plans - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8393) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8394) 			 * All scan plans but the last one must specify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8395) 			 * a finite number of iterations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8396) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8397) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8398) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8400) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8403) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8404) 	 * The last scan plan must not specify the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8405) 	 * iterations, it is supposed to run infinitely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8406) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8407) 	if (request->scan_plans[n_plans - 1].iterations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8408) 		return  -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8410) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8413) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8414) nl80211_parse_sched_scan_per_band_rssi(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8415) 				       struct cfg80211_match_set *match_sets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8416) 				       struct nlattr *tb_band_rssi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8417) 				       s32 rssi_thold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8419) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8420) 	int i, tmp, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8422) 	if (!wiphy_ext_feature_isset(wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8423) 		    NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8424) 		if (tb_band_rssi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8425) 			ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8426) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8427) 			for (i = 0; i < NUM_NL80211_BANDS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8428) 				match_sets->per_band_rssi_thold[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8429) 					NL80211_SCAN_RSSI_THOLD_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8430) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8433) 	for (i = 0; i < NUM_NL80211_BANDS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8434) 		match_sets->per_band_rssi_thold[i] = rssi_thold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8436) 	nla_for_each_nested(attr, tb_band_rssi, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8437) 		enum nl80211_band band = nla_type(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8439) 		if (band < 0 || band >= NUM_NL80211_BANDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8440) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8442) 		match_sets->per_band_rssi_thold[band] =	nla_get_s32(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8443) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8445) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8448) static struct cfg80211_sched_scan_request *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8449) nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8450) 			 struct nlattr **attrs, int max_match_sets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8452) 	struct cfg80211_sched_scan_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8453) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8454) 	int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8455) 	enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8456) 	size_t ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8457) 	struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8458) 	s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8460) 	if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8461) 		n_channels = validate_scan_freqs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8462) 				attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8463) 		if (!n_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8464) 			return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8465) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8466) 		n_channels = ieee80211_get_num_supported_channels(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8469) 	if (attrs[NL80211_ATTR_SCAN_SSIDS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8470) 		nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8471) 				    tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8472) 			n_ssids++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8474) 	if (n_ssids > wiphy->max_sched_scan_ssids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8475) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8477) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8478) 	 * First, count the number of 'real' matchsets. Due to an issue with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8479) 	 * the old implementation, matchsets containing only the RSSI attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8480) 	 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8481) 	 * RSSI for all matchsets, rather than their own matchset for reporting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8482) 	 * all APs with a strong RSSI. This is needed to be compatible with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8483) 	 * older userspace that treated a matchset with only the RSSI as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8484) 	 * global RSSI for all other matchsets - if there are other matchsets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8485) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8486) 	if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8487) 		nla_for_each_nested(attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8488) 				    attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8489) 				    tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8490) 			struct nlattr *rssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8492) 			err = nla_parse_nested_deprecated(tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8493) 							  NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8494) 							  attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8495) 							  nl80211_match_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8496) 							  NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8497) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8498) 				return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8500) 			/* SSID and BSSID are mutually exclusive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8501) 			if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8502) 			    tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8503) 				return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8505) 			/* add other standalone attributes here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8506) 			if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8507) 			    tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8508) 				n_match_sets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8509) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8510) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8511) 			rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8512) 			if (rssi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8513) 				default_match_rssi = nla_get_s32(rssi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8514) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8517) 	/* However, if there's no other matchset, add the RSSI one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8518) 	if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8519) 		n_match_sets = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8521) 	if (n_match_sets > max_match_sets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8522) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8524) 	if (attrs[NL80211_ATTR_IE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8525) 		ie_len = nla_len(attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8526) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8527) 		ie_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8529) 	if (ie_len > wiphy->max_sched_scan_ie_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8530) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8532) 	if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8533) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8534) 		 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8535) 		 * each scan plan already specifies its own interval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8536) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8537) 		if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8538) 			return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8540) 		nla_for_each_nested(attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8541) 				    attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8542) 			n_plans++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8543) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8544) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8545) 		 * The scan interval attribute is kept for backward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8546) 		 * compatibility. If no scan plans are specified and sched scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8547) 		 * interval is specified, one scan plan will be set with this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8548) 		 * scan interval and infinite number of iterations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8549) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8550) 		if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8551) 			return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8553) 		n_plans = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8556) 	if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8557) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8559) 	if (!wiphy_ext_feature_isset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8560) 		    wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8561) 	    (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8562) 	     attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8563) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8565) 	request = kzalloc(sizeof(*request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8566) 			+ sizeof(*request->ssids) * n_ssids
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8567) 			+ sizeof(*request->match_sets) * n_match_sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8568) 			+ sizeof(*request->scan_plans) * n_plans
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8569) 			+ sizeof(*request->channels) * n_channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8570) 			+ ie_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8571) 	if (!request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8572) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8574) 	if (n_ssids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8575) 		request->ssids = (void *)&request->channels[n_channels];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8576) 	request->n_ssids = n_ssids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8577) 	if (ie_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8578) 		if (n_ssids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8579) 			request->ie = (void *)(request->ssids + n_ssids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8580) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8581) 			request->ie = (void *)(request->channels + n_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8582) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8584) 	if (n_match_sets) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8585) 		if (request->ie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8586) 			request->match_sets = (void *)(request->ie + ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8587) 		else if (n_ssids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8588) 			request->match_sets =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8589) 				(void *)(request->ssids + n_ssids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8590) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8591) 			request->match_sets =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8592) 				(void *)(request->channels + n_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8593) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8594) 	request->n_match_sets = n_match_sets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8596) 	if (n_match_sets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8597) 		request->scan_plans = (void *)(request->match_sets +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8598) 					       n_match_sets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8599) 	else if (request->ie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8600) 		request->scan_plans = (void *)(request->ie + ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8601) 	else if (n_ssids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8602) 		request->scan_plans = (void *)(request->ssids + n_ssids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8603) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8604) 		request->scan_plans = (void *)(request->channels + n_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8606) 	request->n_scan_plans = n_plans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8608) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8609) 	if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8610) 		/* user specified, bail out if channel not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8611) 		nla_for_each_nested(attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8612) 				    attrs[NL80211_ATTR_SCAN_FREQUENCIES],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8613) 				    tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8614) 			struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8616) 			chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8618) 			if (!chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8619) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8620) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8621) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8623) 			/* ignore disabled channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8624) 			if (chan->flags & IEEE80211_CHAN_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8625) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8627) 			request->channels[i] = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8628) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8629) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8630) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8631) 		/* all channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8632) 		for (band = 0; band < NUM_NL80211_BANDS; band++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8633) 			int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8635) 			if (!wiphy->bands[band])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8636) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8637) 			for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8638) 				struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8640) 				chan = &wiphy->bands[band]->channels[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8642) 				if (chan->flags & IEEE80211_CHAN_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8643) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8645) 				request->channels[i] = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8646) 				i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8647) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8648) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8651) 	if (!i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8652) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8653) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8654) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8656) 	request->n_channels = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8658) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8659) 	if (n_ssids) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8660) 		nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8661) 				    tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8662) 			if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8663) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8664) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8665) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8666) 			request->ssids[i].ssid_len = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8667) 			memcpy(request->ssids[i].ssid, nla_data(attr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8668) 			       nla_len(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8669) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8670) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8671) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8673) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8674) 	if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8675) 		nla_for_each_nested(attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8676) 				    attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8677) 				    tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8678) 			struct nlattr *ssid, *bssid, *rssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8680) 			err = nla_parse_nested_deprecated(tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8681) 							  NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8682) 							  attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8683) 							  nl80211_match_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8684) 							  NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8685) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8686) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8687) 			ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8688) 			bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8690) 			if (!ssid && !bssid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8691) 				i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8692) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8693) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8695) 			if (WARN_ON(i >= n_match_sets)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8696) 				/* this indicates a programming error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8697) 				 * the loop above should have verified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8698) 				 * things properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8699) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8700) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8701) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8702) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8704) 			if (ssid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8705) 				memcpy(request->match_sets[i].ssid.ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8706) 				       nla_data(ssid), nla_len(ssid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8707) 				request->match_sets[i].ssid.ssid_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8708) 					nla_len(ssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8709) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8710) 			if (bssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8711) 				memcpy(request->match_sets[i].bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8712) 				       nla_data(bssid), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8714) 			/* special attribute - old implementation w/a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8715) 			request->match_sets[i].rssi_thold = default_match_rssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8716) 			rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8717) 			if (rssi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8718) 				request->match_sets[i].rssi_thold =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8719) 					nla_get_s32(rssi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8721) 			/* Parse per band RSSI attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8722) 			err = nl80211_parse_sched_scan_per_band_rssi(wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8723) 				&request->match_sets[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8724) 				tb[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8725) 				request->match_sets[i].rssi_thold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8726) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8727) 				goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8729) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8730) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8732) 		/* there was no other matchset, so the RSSI one is alone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8733) 		if (i == 0 && n_match_sets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8734) 			request->match_sets[0].rssi_thold = default_match_rssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8736) 		request->min_rssi_thold = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8737) 		for (i = 0; i < n_match_sets; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8738) 			request->min_rssi_thold =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8739) 				min(request->match_sets[i].rssi_thold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8740) 				    request->min_rssi_thold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8741) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8742) 		request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8745) 	if (ie_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8746) 		request->ie_len = ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8747) 		memcpy((void *)request->ie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8748) 		       nla_data(attrs[NL80211_ATTR_IE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8749) 		       request->ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8750) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8752) 	err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8753) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8754) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8756) 	if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8757) 		request->delay =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8758) 			nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8760) 	if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8761) 		request->relative_rssi = nla_get_s8(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8762) 			attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8763) 		request->relative_rssi_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8766) 	if (request->relative_rssi_set &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8767) 	    attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8768) 		struct nl80211_bss_select_rssi_adjust *rssi_adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8770) 		rssi_adjust = nla_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8771) 			attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8772) 		request->rssi_adjust.band = rssi_adjust->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8773) 		request->rssi_adjust.delta = rssi_adjust->delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8774) 		if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8775) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8776) 			goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8777) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8778) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8780) 	err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8781) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8782) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8784) 	request->scan_start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8786) 	return request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8788) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8789) 	kfree(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8790) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8793) static int nl80211_start_sched_scan(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8794) 				    struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8796) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8797) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8798) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8799) 	struct cfg80211_sched_scan_request *sched_scan_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8800) 	bool want_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8801) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8803) 	if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8804) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8806) 	want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8807) 	err = cfg80211_sched_scan_req_possible(rdev, want_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8808) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8809) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8811) 	sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8812) 						  info->attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8813) 						  rdev->wiphy.max_match_sets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8815) 	err = PTR_ERR_OR_ZERO(sched_scan_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8816) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8817) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8819) 	/* leave request id zero for legacy request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8820) 	 * or if driver does not support multi-scheduled scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8821) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8822) 	if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8823) 		sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8825) 	err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8826) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8827) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8829) 	sched_scan_req->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8830) 	sched_scan_req->wiphy = &rdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8832) 	if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8833) 		sched_scan_req->owner_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8835) 	cfg80211_add_sched_scan_req(rdev, sched_scan_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8837) 	nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8838) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8840) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8841) 	kfree(sched_scan_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8842) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8843) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8846) static int nl80211_stop_sched_scan(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8847) 				   struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8849) 	struct cfg80211_sched_scan_request *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8850) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8851) 	u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8853) 	if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8854) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8856) 	if (info->attrs[NL80211_ATTR_COOKIE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8857) 		cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8858) 		return __cfg80211_stop_sched_scan(rdev, cookie, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8859) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8861) 	req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8862) 				     struct cfg80211_sched_scan_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8863) 				     list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8864) 	if (!req || req->reqid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8865) 	    (req->owner_nlportid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8866) 	     req->owner_nlportid != info->snd_portid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8867) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8869) 	return cfg80211_stop_sched_scan_req(rdev, req, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8872) static int nl80211_start_radar_detection(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8873) 					 struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8875) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8876) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8877) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8878) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8879) 	struct cfg80211_chan_def chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8880) 	enum nl80211_dfs_regions dfs_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8881) 	unsigned int cac_time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8882) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8884) 	dfs_region = reg_get_dfs_region(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8885) 	if (dfs_region == NL80211_DFS_UNSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8886) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8888) 	err = nl80211_parse_chandef(rdev, info, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8889) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8890) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8892) 	if (netif_carrier_ok(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8893) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8895) 	if (wdev->cac_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8896) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8898) 	err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8899) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8900) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8902) 	if (err == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8903) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8905) 	if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8906) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8908) 	/* CAC start is offloaded to HW and can't be started manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8909) 	if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8910) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8912) 	if (!rdev->ops->start_radar_detection)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8913) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8915) 	cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8916) 	if (WARN_ON(!cac_time_ms))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8917) 		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8919) 	err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8920) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8921) 		wdev->chandef = chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8922) 		wdev->cac_started = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8923) 		wdev->cac_start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8924) 		wdev->cac_time_ms = cac_time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8926) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8929) static int nl80211_notify_radar_detection(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8930) 					  struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8932) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8933) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8934) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8935) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8936) 	struct cfg80211_chan_def chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8937) 	enum nl80211_dfs_regions dfs_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8938) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8940) 	dfs_region = reg_get_dfs_region(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8941) 	if (dfs_region == NL80211_DFS_UNSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8942) 		GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8943) 				 "DFS Region is not set. Unexpected Radar indication");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8944) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8947) 	err = nl80211_parse_chandef(rdev, info, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8948) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8949) 		GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8950) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8951) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8953) 	err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8954) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8955) 		GENL_SET_ERR_MSG(info, "chandef is invalid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8956) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8959) 	if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8960) 		GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8961) 				 "Unexpected Radar indication for chandef/iftype");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8962) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8963) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8965) 	/* Do not process this notification if radar is already detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8966) 	 * by kernel on this channel, and return success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8967) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8968) 	if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8969) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8971) 	cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8973) 	cfg80211_sched_dfs_chan_update(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8975) 	rdev->radar_chandef = chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8977) 	/* Propagate this notification to other radios as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8978) 	queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8980) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8983) static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8985) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8986) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8987) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8988) 	struct cfg80211_csa_settings params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8989) 	/* csa_attrs is defined static to avoid waste of stack size - this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8990) 	 * function is called under RTNL lock, so this should not be a problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8991) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8992) 	static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8993) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8994) 	bool need_new_beacon = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8995) 	bool need_handle_dfs_flag = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8996) 	int len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8997) 	u32 cs_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8999) 	if (!rdev->ops->channel_switch ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9000) 	    !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9001) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9003) 	switch (dev->ieee80211_ptr->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9004) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9005) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9006) 		need_new_beacon = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9007) 		/* For all modes except AP the handle_dfs flag needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9008) 		 * supplied to tell the kernel that userspace will handle radar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9009) 		 * events when they happen. Otherwise a switch to a channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9010) 		 * requiring DFS will be rejected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9011) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9012) 		need_handle_dfs_flag = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9014) 		/* useless if AP is not running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9015) 		if (!wdev->beacon_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9016) 			return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9017) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9018) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9019) 		if (!wdev->ssid_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9020) 			return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9021) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9022) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9023) 		if (!wdev->mesh_id_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9024) 			return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9025) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9026) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9027) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9028) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9030) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9031) 	params.beacon_csa.ftm_responder = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9033) 	if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9034) 	    !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9035) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9037) 	/* only important for AP, IBSS and mesh create IEs internally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9038) 	if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9039) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9041) 	/* Even though the attribute is u32, the specification says
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9042) 	 * u8, so let's make sure we don't overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9043) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9044) 	cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9045) 	if (cs_count > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9046) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9048) 	params.count = cs_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9050) 	if (!need_new_beacon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9051) 		goto skip_beacons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9053) 	err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9054) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9055) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9057) 	err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9058) 					  info->attrs[NL80211_ATTR_CSA_IES],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9059) 					  nl80211_policy, info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9060) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9061) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9063) 	err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9064) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9065) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9067) 	if (!csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9068) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9070) 	len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9071) 	if (!len || (len % sizeof(u16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9072) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9074) 	params.n_counter_offsets_beacon = len / sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9075) 	if (rdev->wiphy.max_num_csa_counters &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9076) 	    (params.n_counter_offsets_beacon >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9077) 	     rdev->wiphy.max_num_csa_counters))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9078) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9080) 	params.counter_offsets_beacon =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9081) 		nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9083) 	/* sanity checks - counters should fit and be the same */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9084) 	for (i = 0; i < params.n_counter_offsets_beacon; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9085) 		u16 offset = params.counter_offsets_beacon[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9087) 		if (offset >= params.beacon_csa.tail_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9088) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9090) 		if (params.beacon_csa.tail[offset] != params.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9091) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9092) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9094) 	if (csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9095) 		len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9096) 		if (!len || (len % sizeof(u16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9097) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9099) 		params.n_counter_offsets_presp = len / sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9100) 		if (rdev->wiphy.max_num_csa_counters &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9101) 		    (params.n_counter_offsets_presp >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9102) 		     rdev->wiphy.max_num_csa_counters))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9103) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9105) 		params.counter_offsets_presp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9106) 			nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9108) 		/* sanity checks - counters should fit and be the same */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9109) 		for (i = 0; i < params.n_counter_offsets_presp; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9110) 			u16 offset = params.counter_offsets_presp[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9112) 			if (offset >= params.beacon_csa.probe_resp_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9113) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9115) 			if (params.beacon_csa.probe_resp[offset] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9116) 			    params.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9117) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9118) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9119) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9121) skip_beacons:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9122) 	err = nl80211_parse_chandef(rdev, info, &params.chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9123) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9124) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9126) 	if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9127) 					   wdev->iftype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9128) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9130) 	err = cfg80211_chandef_dfs_required(wdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9131) 					    &params.chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9132) 					    wdev->iftype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9133) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9134) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9136) 	if (err > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9137) 		params.radar_required = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9138) 		if (need_handle_dfs_flag &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9139) 		    !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9140) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9141) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9144) 	if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9145) 		params.block_tx = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9147) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9148) 	err = rdev_channel_switch(rdev, dev, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9149) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9151) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9154) static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9155) 			    u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9156) 			    struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9157) 			    struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9158) 			    struct cfg80211_internal_bss *intbss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9160) 	struct cfg80211_bss *res = &intbss->pub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9161) 	const struct cfg80211_bss_ies *ies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9162) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9163) 	struct nlattr *bss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9165) 	ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9167) 	hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9168) 			     NL80211_CMD_NEW_SCAN_RESULTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9169) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9170) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9172) 	genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9174) 	if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9175) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9176) 	if (wdev->netdev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9177) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9178) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9179) 	if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9180) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9181) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9183) 	bss = nla_nest_start_noflag(msg, NL80211_ATTR_BSS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9184) 	if (!bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9185) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9186) 	if ((!is_zero_ether_addr(res->bssid) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9187) 	     nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9188) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9190) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9191) 	/* indicate whether we have probe response data or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9192) 	if (rcu_access_pointer(res->proberesp_ies) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9193) 	    nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9194) 		goto fail_unlock_rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9196) 	/* this pointer prefers to be pointed to probe response data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9197) 	 * but is always valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9198) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9199) 	ies = rcu_dereference(res->ies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9200) 	if (ies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9201) 		if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9202) 				      NL80211_BSS_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9203) 			goto fail_unlock_rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9204) 		if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9205) 					ies->len, ies->data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9206) 			goto fail_unlock_rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9209) 	/* and this pointer is always (unless driver didn't know) beacon data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9210) 	ies = rcu_dereference(res->beacon_ies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9211) 	if (ies && ies->from_beacon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9212) 		if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9213) 				      NL80211_BSS_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9214) 			goto fail_unlock_rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9215) 		if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9216) 					ies->len, ies->data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9217) 			goto fail_unlock_rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9219) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9221) 	if (res->beacon_interval &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9222) 	    nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9223) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9224) 	if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9225) 	    nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9226) 	    nla_put_u32(msg, NL80211_BSS_FREQUENCY_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9227) 			res->channel->freq_offset) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9228) 	    nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9229) 	    nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9230) 			jiffies_to_msecs(jiffies - intbss->ts)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9231) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9233) 	if (intbss->parent_tsf &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9234) 	    (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9235) 			       intbss->parent_tsf, NL80211_BSS_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9236) 	     nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9237) 		     intbss->parent_bssid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9238) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9240) 	if (intbss->ts_boottime &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9241) 	    nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9242) 			      intbss->ts_boottime, NL80211_BSS_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9243) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9245) 	if (!nl80211_put_signal(msg, intbss->pub.chains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9246) 				intbss->pub.chain_signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9247) 				NL80211_BSS_CHAIN_SIGNAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9248) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9250) 	switch (rdev->wiphy.signal_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9251) 	case CFG80211_SIGNAL_TYPE_MBM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9252) 		if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9253) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9254) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9255) 	case CFG80211_SIGNAL_TYPE_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9256) 		if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9257) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9258) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9259) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9260) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9263) 	switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9264) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9265) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9266) 		if (intbss == wdev->current_bss &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9267) 		    nla_put_u32(msg, NL80211_BSS_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9268) 				NL80211_BSS_STATUS_ASSOCIATED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9269) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9270) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9271) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9272) 		if (intbss == wdev->current_bss &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9273) 		    nla_put_u32(msg, NL80211_BSS_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9274) 				NL80211_BSS_STATUS_IBSS_JOINED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9275) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9276) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9277) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9278) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9281) 	nla_nest_end(msg, bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9283) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9284) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9286)  fail_unlock_rcu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9287) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9288)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9289) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9290) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9293) static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9295) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9296) 	struct cfg80211_internal_bss *scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9297) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9298) 	int start = cb->args[2], idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9299) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9301) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9302) 	err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9303) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9304) 		rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9305) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9306) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9308) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9309) 	spin_lock_bh(&rdev->bss_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9311) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9312) 	 * dump_scan will be called multiple times to break up the scan results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9313) 	 * into multiple messages.  It is unlikely that any more bss-es will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9314) 	 * expired after the first call, so only call only call this on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9315) 	 * first dump_scan invocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9316) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9317) 	if (start == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9318) 		cfg80211_bss_expire(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9320) 	cb->seq = rdev->bss_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9322) 	list_for_each_entry(scan, &rdev->bss_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9323) 		if (++idx <= start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9324) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9325) 		if (nl80211_send_bss(skb, cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9326) 				cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9327) 				rdev, wdev, scan) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9328) 			idx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9329) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9330) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9333) 	spin_unlock_bh(&rdev->bss_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9334) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9336) 	cb->args[2] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9337) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9339) 	return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9342) static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9343) 			       int flags, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9344) 			       bool allow_radio_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9345) 			       struct survey_info *survey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9347) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9348) 	struct nlattr *infoattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9350) 	/* skip radio stats if userspace didn't request them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9351) 	if (!survey->channel && !allow_radio_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9352) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9354) 	hdr = nl80211hdr_put(msg, portid, seq, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9355) 			     NL80211_CMD_NEW_SURVEY_RESULTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9356) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9357) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9359) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9360) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9362) 	infoattr = nla_nest_start_noflag(msg, NL80211_ATTR_SURVEY_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9363) 	if (!infoattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9364) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9366) 	if (survey->channel &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9367) 	    nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9368) 			survey->channel->center_freq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9369) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9371) 	if (survey->channel && survey->channel->freq_offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9372) 	    nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9373) 			survey->channel->freq_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9374) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9376) 	if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9377) 	    nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9378) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9379) 	if ((survey->filled & SURVEY_INFO_IN_USE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9380) 	    nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9381) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9382) 	if ((survey->filled & SURVEY_INFO_TIME) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9383) 	    nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9384) 			survey->time, NL80211_SURVEY_INFO_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9385) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9386) 	if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9387) 	    nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9388) 			      survey->time_busy, NL80211_SURVEY_INFO_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9389) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9390) 	if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9391) 	    nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9392) 			      survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9393) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9394) 	if ((survey->filled & SURVEY_INFO_TIME_RX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9395) 	    nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9396) 			      survey->time_rx, NL80211_SURVEY_INFO_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9397) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9398) 	if ((survey->filled & SURVEY_INFO_TIME_TX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9399) 	    nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9400) 			      survey->time_tx, NL80211_SURVEY_INFO_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9401) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9402) 	if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9403) 	    nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9404) 			      survey->time_scan, NL80211_SURVEY_INFO_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9405) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9406) 	if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9407) 	    nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9408) 			      survey->time_bss_rx, NL80211_SURVEY_INFO_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9409) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9411) 	nla_nest_end(msg, infoattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9413) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9414) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9416)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9417) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9418) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9421) static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9423) 	struct nlattr **attrbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9424) 	struct survey_info survey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9425) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9426) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9427) 	int survey_idx = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9428) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9429) 	bool radio_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9431) 	attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9432) 	if (!attrbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9433) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9435) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9436) 	res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9437) 	if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9438) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9440) 	/* prepare_wdev_dump parsed the attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9441) 	radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9443) 	if (!wdev->netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9444) 		res = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9445) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9448) 	if (!rdev->ops->dump_survey) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9449) 		res = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9450) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9453) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9454) 		res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9455) 		if (res == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9456) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9457) 		if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9458) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9460) 		/* don't send disabled channels, but do send non-channel data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9461) 		if (survey.channel &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9462) 		    survey.channel->flags & IEEE80211_CHAN_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9463) 			survey_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9464) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9465) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9467) 		if (nl80211_send_survey(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9468) 				NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9469) 				cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9470) 				wdev->netdev, radio_stats, &survey) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9471) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9472) 		survey_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9475)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9476) 	cb->args[2] = survey_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9477) 	res = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9478)  out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9479) 	kfree(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9480) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9481) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9484) static bool nl80211_valid_wpa_versions(u32 wpa_versions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9486) 	return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9487) 				  NL80211_WPA_VERSION_2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9488) 				  NL80211_WPA_VERSION_3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9491) static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9493) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9494) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9495) 	struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9496) 	const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9497) 	int err, ssid_len, ie_len = 0, auth_data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9498) 	enum nl80211_auth_type auth_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9499) 	struct key_parse key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9500) 	bool local_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9501) 	u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9503) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9504) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9506) 	if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9507) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9509) 	if (!info->attrs[NL80211_ATTR_SSID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9510) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9512) 	if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9513) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9515) 	err = nl80211_parse_key(info, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9516) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9517) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9519) 	if (key.idx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9520) 		if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9521) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9522) 		if (!key.p.key || !key.p.key_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9523) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9524) 		if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9525) 		     key.p.key_len != WLAN_KEY_LEN_WEP40) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9526) 		    (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9527) 		     key.p.key_len != WLAN_KEY_LEN_WEP104))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9528) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9529) 		if (key.idx > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9530) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9531) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9532) 		key.p.key_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9533) 		key.p.key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9536) 	if (key.idx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9537) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9538) 		bool ok = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9540) 		for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9541) 			if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9542) 				ok = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9543) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9544) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9545) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9546) 		if (!ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9547) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9548) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9550) 	if (!rdev->ops->auth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9551) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9553) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9554) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9555) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9557) 	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9558) 	freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9559) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9560) 		freq +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9561) 		    nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9563) 	chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9564) 	if (!chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9565) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9567) 	ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9568) 	ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9570) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9571) 		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9572) 		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9573) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9575) 	auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9576) 	if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9577) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9579) 	if ((auth_type == NL80211_AUTHTYPE_SAE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9580) 	     auth_type == NL80211_AUTHTYPE_FILS_SK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9581) 	     auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9582) 	     auth_type == NL80211_AUTHTYPE_FILS_PK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9583) 	    !info->attrs[NL80211_ATTR_AUTH_DATA])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9584) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9586) 	if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9587) 		if (auth_type != NL80211_AUTHTYPE_SAE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9588) 		    auth_type != NL80211_AUTHTYPE_FILS_SK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9589) 		    auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9590) 		    auth_type != NL80211_AUTHTYPE_FILS_PK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9591) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9592) 		auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9593) 		auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9594) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9596) 	local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9598) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9599) 	 * Since we no longer track auth state, ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9600) 	 * requests to only change local state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9601) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9602) 	if (local_state_change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9603) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9605) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9606) 	err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9607) 				 ssid, ssid_len, ie, ie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9608) 				 key.p.key, key.p.key_len, key.idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9609) 				 auth_data, auth_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9610) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9611) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9614) static int validate_pae_over_nl80211(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9615) 				     struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9617) 	if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9618) 		GENL_SET_ERR_MSG(info, "SOCKET_OWNER not set");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9619) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9622) 	if (!rdev->ops->tx_control_port ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9623) 	    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9624) 				     NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9625) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9627) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9630) static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9631) 				   struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9632) 				   struct cfg80211_crypto_settings *settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9633) 				   int cipher_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9635) 	memset(settings, 0, sizeof(*settings));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9637) 	settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9639) 	if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9640) 		u16 proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9642) 		proto = nla_get_u16(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9643) 			info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9644) 		settings->control_port_ethertype = cpu_to_be16(proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9645) 		if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9646) 		    proto != ETH_P_PAE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9647) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9648) 		if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9649) 			settings->control_port_no_encrypt = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9650) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9651) 		settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9653) 	if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9654) 		int r = validate_pae_over_nl80211(rdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9656) 		if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9657) 			return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9659) 		settings->control_port_over_nl80211 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9661) 		if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9662) 			settings->control_port_no_preauth = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9663) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9665) 	if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9666) 		void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9667) 		int len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9669) 		data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9670) 		len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9671) 		settings->n_ciphers_pairwise = len / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9673) 		if (len % sizeof(u32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9674) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9676) 		if (settings->n_ciphers_pairwise > cipher_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9677) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9679) 		memcpy(settings->ciphers_pairwise, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9681) 		for (i = 0; i < settings->n_ciphers_pairwise; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9682) 			if (!cfg80211_supported_cipher_suite(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9683) 					&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9684) 					settings->ciphers_pairwise[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9685) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9686) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9688) 	if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9689) 		settings->cipher_group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9690) 			nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9691) 		if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9692) 						     settings->cipher_group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9693) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9694) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9696) 	if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9697) 		settings->wpa_versions =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9698) 			nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9699) 		if (!nl80211_valid_wpa_versions(settings->wpa_versions))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9700) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9701) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9703) 	if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9704) 		void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9705) 		int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9707) 		data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9708) 		len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9709) 		settings->n_akm_suites = len / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9711) 		if (len % sizeof(u32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9712) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9714) 		if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9715) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9717) 		memcpy(settings->akm_suites, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9718) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9720) 	if (info->attrs[NL80211_ATTR_PMK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9721) 		if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9722) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9723) 		if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9724) 					     NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9725) 		    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9726) 					     NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9727) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9728) 		settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9731) 	if (info->attrs[NL80211_ATTR_SAE_PASSWORD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9732) 		if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9733) 					     NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9734) 		    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9735) 					     NL80211_EXT_FEATURE_SAE_OFFLOAD_AP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9736) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9737) 		settings->sae_pwd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9738) 			nla_data(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9739) 		settings->sae_pwd_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9740) 			nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9741) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9743) 	if (info->attrs[NL80211_ATTR_SAE_PWE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9744) 		settings->sae_pwe =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9745) 			nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9746) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9747) 		settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9749) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9752) static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9754) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9755) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9756) 	struct ieee80211_channel *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9757) 	struct cfg80211_assoc_request req = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9758) 	const u8 *bssid, *ssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9759) 	int err, ssid_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9760) 	u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9762) 	if (dev->ieee80211_ptr->conn_owner_nlportid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9763) 	    dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9764) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9766) 	if (!info->attrs[NL80211_ATTR_MAC] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9767) 	    !info->attrs[NL80211_ATTR_SSID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9768) 	    !info->attrs[NL80211_ATTR_WIPHY_FREQ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9769) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9771) 	if (!rdev->ops->assoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9772) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9774) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9775) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9776) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9778) 	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9780) 	freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9781) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9782) 		freq +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9783) 		    nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9784) 	chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9785) 	if (!chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9786) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9788) 	ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9789) 	ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9791) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9792) 		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9793) 		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9794) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9796) 	if (info->attrs[NL80211_ATTR_USE_MFP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9797) 		enum nl80211_mfp mfp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9798) 			nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9799) 		if (mfp == NL80211_MFP_REQUIRED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9800) 			req.use_mfp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9801) 		else if (mfp != NL80211_MFP_NO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9802) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9803) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9805) 	if (info->attrs[NL80211_ATTR_PREV_BSSID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9806) 		req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9808) 	if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9809) 		req.flags |= ASSOC_REQ_DISABLE_HT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9811) 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9812) 		memcpy(&req.ht_capa_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9813) 		       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9814) 		       sizeof(req.ht_capa_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9816) 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9817) 		if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9818) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9819) 		memcpy(&req.ht_capa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9820) 		       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9821) 		       sizeof(req.ht_capa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9822) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9824) 	if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9825) 		req.flags |= ASSOC_REQ_DISABLE_VHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9827) 	if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9828) 		memcpy(&req.vht_capa_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9829) 		       nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9830) 		       sizeof(req.vht_capa_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9832) 	if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9833) 		if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9834) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9835) 		memcpy(&req.vht_capa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9836) 		       nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9837) 		       sizeof(req.vht_capa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9840) 	if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9841) 		if (!((rdev->wiphy.features &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9842) 			NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9843) 		       (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9844) 		    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9845) 					     NL80211_EXT_FEATURE_RRM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9846) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9847) 		req.flags |= ASSOC_REQ_USE_RRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9848) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9850) 	if (info->attrs[NL80211_ATTR_FILS_KEK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9851) 		req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9852) 		req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9853) 		if (!info->attrs[NL80211_ATTR_FILS_NONCES])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9854) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9855) 		req.fils_nonces =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9856) 			nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9857) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9859) 	if (info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9860) 		if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9861) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9862) 		memcpy(&req.s1g_capa_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9863) 		       nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9864) 		       sizeof(req.s1g_capa_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9865) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9867) 	if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9868) 		if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9869) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9870) 		memcpy(&req.s1g_capa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9871) 		       nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9872) 		       sizeof(req.s1g_capa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9873) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9875) 	err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9876) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9877) 		wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9879) 		err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9880) 					  ssid, ssid_len, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9882) 		if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9883) 			dev->ieee80211_ptr->conn_owner_nlportid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9884) 				info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9885) 			memcpy(dev->ieee80211_ptr->disconnect_bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9886) 			       bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9887) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9889) 		wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9890) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9892) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9895) static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9897) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9898) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9899) 	const u8 *ie = NULL, *bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9900) 	int ie_len = 0, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9901) 	u16 reason_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9902) 	bool local_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9904) 	if (dev->ieee80211_ptr->conn_owner_nlportid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9905) 	    dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9906) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9908) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9909) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9911) 	if (!info->attrs[NL80211_ATTR_REASON_CODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9912) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9914) 	if (!rdev->ops->deauth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9915) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9917) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9918) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9919) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9921) 	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9923) 	reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9924) 	if (reason_code == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9925) 		/* Reason Code 0 is reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9926) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9927) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9929) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9930) 		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9931) 		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9932) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9934) 	local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9936) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9937) 	err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9938) 				   local_state_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9939) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9940) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9943) static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9945) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9946) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9947) 	const u8 *ie = NULL, *bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9948) 	int ie_len = 0, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9949) 	u16 reason_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9950) 	bool local_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9952) 	if (dev->ieee80211_ptr->conn_owner_nlportid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9953) 	    dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9954) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9956) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9957) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9959) 	if (!info->attrs[NL80211_ATTR_REASON_CODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9960) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9962) 	if (!rdev->ops->disassoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9963) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9965) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9966) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9967) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9969) 	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9971) 	reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9972) 	if (reason_code == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9973) 		/* Reason Code 0 is reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9974) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9975) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9977) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9978) 		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9979) 		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9980) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9982) 	local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9984) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9985) 	err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9986) 				     local_state_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9987) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9988) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9991) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9992) nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9993) 			 int mcast_rate[NUM_NL80211_BANDS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9994) 			 int rateval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9996) 	struct wiphy *wiphy = &rdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9997) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9998) 	int band, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10000) 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10001) 		struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10003) 		sband = wiphy->bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10004) 		if (!sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10005) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10007) 		for (i = 0; i < sband->n_bitrates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10008) 			if (sband->bitrates[i].bitrate == rateval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10009) 				mcast_rate[band] = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10010) 				found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10011) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10012) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10013) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10014) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10016) 	return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10019) static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10021) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10022) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10023) 	struct cfg80211_ibss_params ibss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10024) 	struct wiphy *wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10025) 	struct cfg80211_cached_keys *connkeys = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10026) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10028) 	memset(&ibss, 0, sizeof(ibss));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10030) 	if (!info->attrs[NL80211_ATTR_SSID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10031) 	    !nla_len(info->attrs[NL80211_ATTR_SSID]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10032) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10034) 	ibss.beacon_interval = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10036) 	if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10037) 		ibss.beacon_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10038) 			nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10040) 	err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10041) 					   ibss.beacon_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10042) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10043) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10045) 	if (!rdev->ops->join_ibss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10046) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10048) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10049) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10051) 	wiphy = &rdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10053) 	if (info->attrs[NL80211_ATTR_MAC]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10054) 		ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10056) 		if (!is_valid_ether_addr(ibss.bssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10057) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10058) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10059) 	ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10060) 	ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10062) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10063) 		ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10064) 		ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10065) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10067) 	err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10068) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10069) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10071) 	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10072) 				     NL80211_IFTYPE_ADHOC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10073) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10075) 	switch (ibss.chandef.width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10076) 	case NL80211_CHAN_WIDTH_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10077) 	case NL80211_CHAN_WIDTH_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10078) 	case NL80211_CHAN_WIDTH_20_NOHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10079) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10080) 	case NL80211_CHAN_WIDTH_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10081) 	case NL80211_CHAN_WIDTH_40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10082) 		if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10083) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10084) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10085) 	case NL80211_CHAN_WIDTH_80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10086) 	case NL80211_CHAN_WIDTH_80P80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10087) 	case NL80211_CHAN_WIDTH_160:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10088) 		if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10089) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10090) 		if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10091) 					     NL80211_EXT_FEATURE_VHT_IBSS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10092) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10093) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10094) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10095) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10096) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10098) 	ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10099) 	ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10101) 	if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10102) 		u8 *rates =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10103) 			nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10104) 		int n_rates =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10105) 			nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10106) 		struct ieee80211_supported_band *sband =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10107) 			wiphy->bands[ibss.chandef.chan->band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10109) 		err = ieee80211_get_ratemask(sband, rates, n_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10110) 					     &ibss.basic_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10111) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10112) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10115) 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10116) 		memcpy(&ibss.ht_capa_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10117) 		       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10118) 		       sizeof(ibss.ht_capa_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10120) 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10121) 		if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10122) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10123) 		memcpy(&ibss.ht_capa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10124) 		       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10125) 		       sizeof(ibss.ht_capa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10128) 	if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10129) 	    !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10130) 			nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10131) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10133) 	if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10134) 		bool no_ht = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10136) 		connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10137) 		if (IS_ERR(connkeys))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10138) 			return PTR_ERR(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10140) 		if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10141) 		    no_ht) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10142) 			kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10143) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10144) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10147) 	ibss.control_port =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10148) 		nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10150) 	if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10151) 		int r = validate_pae_over_nl80211(rdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10153) 		if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10154) 			kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10155) 			return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10156) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10158) 		ibss.control_port_over_nl80211 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10161) 	ibss.userspace_handles_dfs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10162) 		nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10164) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10165) 	err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10166) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10167) 		kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10168) 	else if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10169) 		dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10170) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10172) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10175) static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10177) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10178) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10180) 	if (!rdev->ops->leave_ibss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10181) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10183) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10184) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10186) 	return cfg80211_leave_ibss(rdev, dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10189) static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10191) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10192) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10193) 	int mcast_rate[NUM_NL80211_BANDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10194) 	u32 nla_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10195) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10197) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10198) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10199) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10200) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10202) 	if (!rdev->ops->set_mcast_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10203) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10205) 	memset(mcast_rate, 0, sizeof(mcast_rate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10207) 	if (!info->attrs[NL80211_ATTR_MCAST_RATE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10208) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10210) 	nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10211) 	if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10212) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10214) 	err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10216) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10219) static struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10220) __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10221) 			    struct wireless_dev *wdev, int approxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10222) 			    u32 portid, u32 seq, enum nl80211_commands cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10223) 			    enum nl80211_attrs attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10224) 			    const struct nl80211_vendor_cmd_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10225) 			    gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10227) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10228) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10229) 	struct nlattr *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10231) 	skb = nlmsg_new(approxlen + 100, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10232) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10233) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10235) 	hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10236) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10237) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10238) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10239) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10241) 	if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10242) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10244) 	if (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10245) 		if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10246) 				info->vendor_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10247) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10248) 		if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10249) 				info->subcmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10250) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10253) 	if (wdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10254) 		if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10255) 				      wdev_id(wdev), NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10256) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10257) 		if (wdev->netdev &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10258) 		    nla_put_u32(skb, NL80211_ATTR_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10259) 				wdev->netdev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10260) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10263) 	data = nla_nest_start_noflag(skb, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10264) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10265) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10267) 	((void **)skb->cb)[0] = rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10268) 	((void **)skb->cb)[1] = hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10269) 	((void **)skb->cb)[2] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10271) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10273)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10274) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10275) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10278) struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10279) 					   struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10280) 					   enum nl80211_commands cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10281) 					   enum nl80211_attrs attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10282) 					   unsigned int portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10283) 					   int vendor_event_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10284) 					   int approxlen, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10286) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10287) 	const struct nl80211_vendor_cmd_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10289) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10290) 	case NL80211_CMD_TESTMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10291) 		if (WARN_ON(vendor_event_idx != -1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10292) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10293) 		info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10294) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10295) 	case NL80211_CMD_VENDOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10296) 		if (WARN_ON(vendor_event_idx < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10297) 			    vendor_event_idx >= wiphy->n_vendor_events))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10298) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10299) 		info = &wiphy->vendor_events[vendor_event_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10300) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10301) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10302) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10303) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10306) 	return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, portid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10307) 					   cmd, attr, info, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10309) EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10311) void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10313) 	struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10314) 	void *hdr = ((void **)skb->cb)[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10315) 	struct nlmsghdr *nlhdr = nlmsg_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10316) 	struct nlattr *data = ((void **)skb->cb)[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10317) 	enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10319) 	/* clear CB data for netlink core to own from now on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10320) 	memset(skb->cb, 0, sizeof(skb->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10322) 	nla_nest_end(skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10323) 	genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10325) 	if (nlhdr->nlmsg_pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10326) 		genlmsg_unicast(wiphy_net(&rdev->wiphy), skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10327) 				nlhdr->nlmsg_pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10328) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10329) 		if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10330) 			mcgrp = NL80211_MCGRP_VENDOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10332) 		genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10333) 					skb, 0, mcgrp, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10336) EXPORT_SYMBOL(__cfg80211_send_event_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10338) #ifdef CONFIG_NL80211_TESTMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10339) static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10341) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10342) 	struct wireless_dev *wdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10343) 		__cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10344) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10346) 	if (!rdev->ops->testmode_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10347) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10349) 	if (IS_ERR(wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10350) 		err = PTR_ERR(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10351) 		if (err != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10352) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10353) 		wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10354) 	} else if (wdev->wiphy != &rdev->wiphy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10355) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10358) 	if (!info->attrs[NL80211_ATTR_TESTDATA])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10359) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10361) 	rdev->cur_cmd_info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10362) 	err = rdev_testmode_cmd(rdev, wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10363) 				nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10364) 				nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10365) 	rdev->cur_cmd_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10367) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10370) static int nl80211_testmode_dump(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10371) 				 struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10373) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10374) 	struct nlattr **attrbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10375) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10376) 	long phy_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10377) 	void *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10378) 	int data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10380) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10382) 	if (cb->args[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10383) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10384) 		 * 0 is a valid index, but not valid for args[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10385) 		 * so we need to offset by 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10386) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10387) 		phy_idx = cb->args[0] - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10389) 		rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10390) 		if (!rdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10391) 			err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10392) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10393) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10394) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10395) 		attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10396) 				  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10397) 		if (!attrbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10398) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10399) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10400) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10402) 		err = nlmsg_parse_deprecated(cb->nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10403) 					     GENL_HDRLEN + nl80211_fam.hdrsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10404) 					     attrbuf, nl80211_fam.maxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10405) 					     nl80211_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10406) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10407) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10409) 		rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10410) 		if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10411) 			err = PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10412) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10413) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10414) 		phy_idx = rdev->wiphy_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10416) 		if (attrbuf[NL80211_ATTR_TESTDATA])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10417) 			cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10420) 	if (cb->args[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10421) 		data = nla_data((void *)cb->args[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10422) 		data_len = nla_len((void *)cb->args[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10423) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10425) 	if (!rdev->ops->testmode_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10426) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10427) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10430) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10431) 		void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10432) 					   cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10433) 					   NL80211_CMD_TESTMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10434) 		struct nlattr *tmdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10436) 		if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10437) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10439) 		if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10440) 			genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10441) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10442) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10444) 		tmdata = nla_nest_start_noflag(skb, NL80211_ATTR_TESTDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10445) 		if (!tmdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10446) 			genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10447) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10448) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10449) 		err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10450) 		nla_nest_end(skb, tmdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10452) 		if (err == -ENOBUFS || err == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10453) 			genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10454) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10455) 		} else if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10456) 			genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10457) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10458) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10460) 		genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10461) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10463) 	err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10464) 	/* see above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10465) 	cb->args[0] = phy_idx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10466)  out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10467) 	kfree(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10468) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10469) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10471) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10473) static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10475) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10476) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10477) 	struct cfg80211_connect_params connect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10478) 	struct wiphy *wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10479) 	struct cfg80211_cached_keys *connkeys = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10480) 	u32 freq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10481) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10483) 	memset(&connect, 0, sizeof(connect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10485) 	if (!info->attrs[NL80211_ATTR_SSID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10486) 	    !nla_len(info->attrs[NL80211_ATTR_SSID]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10487) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10489) 	if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10490) 		connect.auth_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10491) 			nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10492) 		if (!nl80211_valid_auth_type(rdev, connect.auth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10493) 					     NL80211_CMD_CONNECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10494) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10495) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10496) 		connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10498) 	connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10500) 	if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10501) 	    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10502) 				     NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10503) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10504) 	connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10506) 	err = nl80211_crypto_settings(rdev, info, &connect.crypto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10507) 				      NL80211_MAX_NR_CIPHER_SUITES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10508) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10509) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10511) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10512) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10513) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10515) 	wiphy = &rdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10517) 	connect.bg_scan_period = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10518) 	if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10519) 		(wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10520) 		connect.bg_scan_period =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10521) 			nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10524) 	if (info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10525) 		connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10526) 	else if (info->attrs[NL80211_ATTR_MAC_HINT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10527) 		connect.bssid_hint =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10528) 			nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10529) 	connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10530) 	connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10532) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10533) 		connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10534) 		connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10537) 	if (info->attrs[NL80211_ATTR_USE_MFP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10538) 		connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10539) 		if (connect.mfp == NL80211_MFP_OPTIONAL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10540) 		    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10541) 					     NL80211_EXT_FEATURE_MFP_OPTIONAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10542) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10543) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10544) 		connect.mfp = NL80211_MFP_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10547) 	if (info->attrs[NL80211_ATTR_PREV_BSSID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10548) 		connect.prev_bssid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10549) 			nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10551) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10552) 		freq = MHZ_TO_KHZ(nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10553) 					info->attrs[NL80211_ATTR_WIPHY_FREQ]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10554) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10555) 		freq +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10556) 		    nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10558) 	if (freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10559) 		connect.channel = nl80211_get_valid_chan(wiphy, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10560) 		if (!connect.channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10561) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10562) 	} else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10563) 		freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10564) 		freq = MHZ_TO_KHZ(freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10565) 		connect.channel_hint = nl80211_get_valid_chan(wiphy, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10566) 		if (!connect.channel_hint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10567) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10568) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10570) 	if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10571) 		connect.edmg.channels =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10572) 		      nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10574) 		if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10575) 			connect.edmg.bw_config =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10576) 				nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10579) 	if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10580) 		connkeys = nl80211_parse_connkeys(rdev, info, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10581) 		if (IS_ERR(connkeys))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10582) 			return PTR_ERR(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10583) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10585) 	if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10586) 		connect.flags |= ASSOC_REQ_DISABLE_HT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10588) 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10589) 		memcpy(&connect.ht_capa_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10590) 		       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10591) 		       sizeof(connect.ht_capa_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10593) 	if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10594) 		if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10595) 			kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10596) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10597) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10598) 		memcpy(&connect.ht_capa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10599) 		       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10600) 		       sizeof(connect.ht_capa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10603) 	if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10604) 		connect.flags |= ASSOC_REQ_DISABLE_VHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10606) 	if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10607) 		memcpy(&connect.vht_capa_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10608) 		       nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10609) 		       sizeof(connect.vht_capa_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10611) 	if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10612) 		if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10613) 			kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10614) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10615) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10616) 		memcpy(&connect.vht_capa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10617) 		       nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10618) 		       sizeof(connect.vht_capa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10621) 	if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10622) 		if (!((rdev->wiphy.features &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10623) 			NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10624) 		       (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10625) 		    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10626) 					     NL80211_EXT_FEATURE_RRM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10627) 			kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10628) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10629) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10630) 		connect.flags |= ASSOC_REQ_USE_RRM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10633) 	connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10634) 	if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10635) 		kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10636) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10639) 	if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10640) 		/* bss selection makes no sense if bssid is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10641) 		if (connect.bssid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10642) 			kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10643) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10644) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10646) 		err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10647) 				       wiphy, &connect.bss_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10648) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10649) 			kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10650) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10651) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10652) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10654) 	if (wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10655) 				    NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10656) 	    info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10657) 	    info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10658) 	    info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10659) 	    info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10660) 		connect.fils_erp_username =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10661) 			nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10662) 		connect.fils_erp_username_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10663) 			nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10664) 		connect.fils_erp_realm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10665) 			nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10666) 		connect.fils_erp_realm_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10667) 			nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10668) 		connect.fils_erp_next_seq_num =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10669) 			nla_get_u16(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10670) 			   info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10671) 		connect.fils_erp_rrk =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10672) 			nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10673) 		connect.fils_erp_rrk_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10674) 			nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10675) 	} else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10676) 		   info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10677) 		   info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10678) 		   info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10679) 		kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10680) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10683) 	if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10684) 		if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10685) 			kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10686) 			GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10687) 					 "external auth requires connection ownership");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10688) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10689) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10690) 		connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10691) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10693) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10695) 	err = cfg80211_connect(rdev, dev, &connect, connkeys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10696) 			       connect.prev_bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10697) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10698) 		kfree_sensitive(connkeys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10700) 	if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10701) 		dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10702) 		if (connect.bssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10703) 			memcpy(dev->ieee80211_ptr->disconnect_bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10704) 			       connect.bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10705) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10706) 			eth_zero_addr(dev->ieee80211_ptr->disconnect_bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10709) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10711) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10714) static int nl80211_update_connect_params(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10715) 					 struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10717) 	struct cfg80211_connect_params connect = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10718) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10719) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10720) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10721) 	bool fils_sk_offload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10722) 	u32 auth_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10723) 	u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10724) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10726) 	if (!rdev->ops->update_connect_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10727) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10729) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10730) 		connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10731) 		connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10732) 		changed |= UPDATE_ASSOC_IES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10733) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10735) 	fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10736) 						  NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10738) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10739) 	 * when driver supports fils-sk offload all attributes must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10740) 	 * provided. So the else covers "fils-sk-not-all" and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10741) 	 * "no-fils-sk-any".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10742) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10743) 	if (fils_sk_offload &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10744) 	    info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10745) 	    info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10746) 	    info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10747) 	    info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10748) 		connect.fils_erp_username =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10749) 			nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10750) 		connect.fils_erp_username_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10751) 			nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10752) 		connect.fils_erp_realm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10753) 			nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10754) 		connect.fils_erp_realm_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10755) 			nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10756) 		connect.fils_erp_next_seq_num =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10757) 			nla_get_u16(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10758) 			   info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10759) 		connect.fils_erp_rrk =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10760) 			nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10761) 		connect.fils_erp_rrk_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10762) 			nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10763) 		changed |= UPDATE_FILS_ERP_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10764) 	} else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10765) 		   info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10766) 		   info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10767) 		   info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10768) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10769) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10771) 	if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10772) 		auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10773) 		if (!nl80211_valid_auth_type(rdev, auth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10774) 					     NL80211_CMD_CONNECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10775) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10777) 		if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10778) 		    fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10779) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10781) 		connect.auth_type = auth_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10782) 		changed |= UPDATE_AUTH_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10785) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10786) 	if (!wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10787) 		ret = -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10788) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10789) 		ret = rdev_update_connect_params(rdev, dev, &connect, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10790) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10792) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10795) static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10797) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10798) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10799) 	u16 reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10800) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10802) 	if (dev->ieee80211_ptr->conn_owner_nlportid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10803) 	    dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10804) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10806) 	if (!info->attrs[NL80211_ATTR_REASON_CODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10807) 		reason = WLAN_REASON_DEAUTH_LEAVING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10808) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10809) 		reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10811) 	if (reason == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10812) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10814) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10815) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10816) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10818) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10819) 	ret = cfg80211_disconnect(rdev, dev, reason, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10820) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10821) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10824) static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10826) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10827) 	struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10828) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10830) 	if (info->attrs[NL80211_ATTR_PID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10831) 		u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10833) 		net = get_net_ns_by_pid(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10834) 	} else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10835) 		u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10837) 		net = get_net_ns_by_fd(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10838) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10839) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10840) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10842) 	if (IS_ERR(net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10843) 		return PTR_ERR(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10845) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10847) 	/* check if anything to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10848) 	if (!net_eq(wiphy_net(&rdev->wiphy), net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10849) 		err = cfg80211_switch_netns(rdev, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10851) 	put_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10852) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10855) static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10857) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10858) 	int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10859) 			struct cfg80211_pmksa *pmksa) = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10860) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10861) 	struct cfg80211_pmksa pmksa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10863) 	memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10865) 	if (!info->attrs[NL80211_ATTR_PMKID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10866) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10868) 	pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10870) 	if (info->attrs[NL80211_ATTR_MAC]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10871) 		pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10872) 	} else if (info->attrs[NL80211_ATTR_SSID] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10873) 		   info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10874) 		   (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10875) 		    info->attrs[NL80211_ATTR_PMK])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10876) 		pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10877) 		pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10878) 		pmksa.cache_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10879) 			nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10880) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10881) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10882) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10883) 	if (info->attrs[NL80211_ATTR_PMK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10884) 		pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10885) 		pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10886) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10888) 	if (info->attrs[NL80211_ATTR_PMK_LIFETIME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10889) 		pmksa.pmk_lifetime =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10890) 			nla_get_u32(info->attrs[NL80211_ATTR_PMK_LIFETIME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10892) 	if (info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10893) 		pmksa.pmk_reauth_threshold =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10894) 			nla_get_u8(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10895) 				info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10897) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10898) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10899) 	    !(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10900) 	      wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10901) 				      NL80211_EXT_FEATURE_AP_PMKSA_CACHING)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10902) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10904) 	switch (info->genlhdr->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10905) 	case NL80211_CMD_SET_PMKSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10906) 		rdev_ops = rdev->ops->set_pmksa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10907) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10908) 	case NL80211_CMD_DEL_PMKSA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10909) 		rdev_ops = rdev->ops->del_pmksa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10910) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10911) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10912) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10913) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10914) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10916) 	if (!rdev_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10917) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10919) 	return rdev_ops(&rdev->wiphy, dev, &pmksa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10922) static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10924) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10925) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10927) 	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10928) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10929) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10931) 	if (!rdev->ops->flush_pmksa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10932) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10934) 	return rdev_flush_pmksa(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10937) static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10939) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10940) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10941) 	u8 action_code, dialog_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10942) 	u32 peer_capability = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10943) 	u16 status_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10944) 	u8 *peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10945) 	bool initiator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10947) 	if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10948) 	    !rdev->ops->tdls_mgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10949) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10951) 	if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10952) 	    !info->attrs[NL80211_ATTR_STATUS_CODE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10953) 	    !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10954) 	    !info->attrs[NL80211_ATTR_IE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10955) 	    !info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10956) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10958) 	peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10959) 	action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10960) 	status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10961) 	dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10962) 	initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10963) 	if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10964) 		peer_capability =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10965) 			nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10967) 	return rdev_tdls_mgmt(rdev, dev, peer, action_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10968) 			      dialog_token, status_code, peer_capability,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10969) 			      initiator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10970) 			      nla_data(info->attrs[NL80211_ATTR_IE]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10971) 			      nla_len(info->attrs[NL80211_ATTR_IE]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10974) static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10976) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10977) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10978) 	enum nl80211_tdls_operation operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10979) 	u8 *peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10981) 	if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10982) 	    !rdev->ops->tdls_oper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10983) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10985) 	if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10986) 	    !info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10987) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10989) 	operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10990) 	peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10992) 	return rdev_tdls_oper(rdev, dev, peer, operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10995) static int nl80211_remain_on_channel(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10996) 				     struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10998) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10999) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11000) 	struct cfg80211_chan_def chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11001) 	const struct cfg80211_chan_def *compat_chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11002) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11003) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11004) 	u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11005) 	u32 duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11006) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11008) 	if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11009) 	    !info->attrs[NL80211_ATTR_DURATION])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11010) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11012) 	duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11014) 	if (!rdev->ops->remain_on_channel ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11015) 	    !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11016) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11018) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11019) 	 * We should be on that channel for at least a minimum amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11020) 	 * time (10ms) but no longer than the driver supports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11021) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11022) 	if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11023) 	    duration > rdev->wiphy.max_remain_on_channel_duration)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11024) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11026) 	err = nl80211_parse_chandef(rdev, info, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11027) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11028) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11030) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11031) 	if (!cfg80211_off_channel_oper_allowed(wdev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11032) 	    !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11033) 		compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11034) 							     &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11035) 		if (compat_chandef != &chandef) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11036) 			wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11037) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11038) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11039) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11040) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11042) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11043) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11044) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11046) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11047) 			     NL80211_CMD_REMAIN_ON_CHANNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11048) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11049) 		err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11050) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11051) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11053) 	err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11054) 				     duration, &cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11056) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11057) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11059) 	if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11060) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11061) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11063) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11065) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11067)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11068) 	err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11069)  free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11070) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11071) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11074) static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11075) 					    struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11077) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11078) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11079) 	u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11081) 	if (!info->attrs[NL80211_ATTR_COOKIE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11082) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11084) 	if (!rdev->ops->cancel_remain_on_channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11085) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11087) 	cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11089) 	return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11092) static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11093) 				       struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11095) 	struct cfg80211_bitrate_mask mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11096) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11097) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11098) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11100) 	if (!rdev->ops->set_bitrate_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11101) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11103) 	err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11104) 					    NL80211_ATTR_TX_RATES, &mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11105) 					    dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11106) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11107) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11109) 	return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11112) static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11114) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11115) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11116) 	u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11118) 	if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11119) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11121) 	if (info->attrs[NL80211_ATTR_FRAME_TYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11122) 		frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11124) 	switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11125) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11126) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11127) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11128) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11129) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11130) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11131) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11132) 	case NL80211_IFTYPE_P2P_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11133) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11134) 	case NL80211_IFTYPE_NAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11135) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11136) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11139) 	/* not much point in registering if we can't reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11140) 	if (!rdev->ops->mgmt_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11141) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11143) 	if (info->attrs[NL80211_ATTR_RECEIVE_MULTICAST] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11144) 	    !wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11145) 				     NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11146) 		GENL_SET_ERR_MSG(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11147) 				 "multicast RX registrations are not supported");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11148) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11151) 	return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11152) 					   nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11153) 					   nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11154) 					   info->attrs[NL80211_ATTR_RECEIVE_MULTICAST],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11155) 					   info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11158) static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11160) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11161) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11162) 	struct cfg80211_chan_def chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11163) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11164) 	void *hdr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11165) 	u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11166) 	struct sk_buff *msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11167) 	struct cfg80211_mgmt_tx_params params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11168) 		.dont_wait_for_ack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11169) 			info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11170) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11172) 	if (!info->attrs[NL80211_ATTR_FRAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11173) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11175) 	if (!rdev->ops->mgmt_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11176) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11178) 	switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11179) 	case NL80211_IFTYPE_P2P_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11180) 		if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11181) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11182) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11183) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11184) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11185) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11186) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11187) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11188) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11189) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11190) 	case NL80211_IFTYPE_NAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11191) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11192) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11195) 	if (info->attrs[NL80211_ATTR_DURATION]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11196) 		if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11197) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11198) 		params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11200) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11201) 		 * We should wait on the channel for at least a minimum amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11202) 		 * of time (10ms) but no longer than the driver supports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11203) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11204) 		if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11205) 		    params.wait > rdev->wiphy.max_remain_on_channel_duration)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11206) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11209) 	params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11211) 	if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11212) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11214) 	params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11216) 	/* get the channel if any has been specified, otherwise pass NULL to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11217) 	 * the driver. The latter will use the current one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11218) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11219) 	chandef.chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11220) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11221) 		err = nl80211_parse_chandef(rdev, info, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11222) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11223) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11226) 	if (!chandef.chan && params.offchan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11227) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11229) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11230) 	if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11231) 		wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11232) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11234) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11236) 	params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11237) 	params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11239) 	if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11240) 		int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11241) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11243) 		if (len % sizeof(u16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11244) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11246) 		params.n_csa_offsets = len / sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11247) 		params.csa_offsets =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11248) 			nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11250) 		/* check that all the offsets fit the frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11251) 		for (i = 0; i < params.n_csa_offsets; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11252) 			if (params.csa_offsets[i] >= params.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11253) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11254) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11257) 	if (!params.dont_wait_for_ack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11258) 		msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11259) 		if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11260) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11262) 		hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11263) 				     NL80211_CMD_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11264) 		if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11265) 			err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11266) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11267) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11270) 	params.chan = chandef.chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11271) 	err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11272) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11273) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11275) 	if (msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11276) 		if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11277) 				      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11278) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11280) 		genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11281) 		return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11282) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11284) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11286)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11287) 	err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11288)  free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11289) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11290) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11293) static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11295) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11296) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11297) 	u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11299) 	if (!info->attrs[NL80211_ATTR_COOKIE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11300) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11302) 	if (!rdev->ops->mgmt_tx_cancel_wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11303) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11305) 	switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11306) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11307) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11308) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11309) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11310) 	case NL80211_IFTYPE_AP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11311) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11312) 	case NL80211_IFTYPE_P2P_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11313) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11314) 	case NL80211_IFTYPE_NAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11315) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11316) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11319) 	cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11321) 	return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11324) static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11326) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11327) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11328) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11329) 	u8 ps_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11330) 	bool state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11331) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11333) 	if (!info->attrs[NL80211_ATTR_PS_STATE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11334) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11336) 	ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11338) 	wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11340) 	if (!rdev->ops->set_power_mgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11341) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11343) 	state = (ps_state == NL80211_PS_ENABLED) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11345) 	if (state == wdev->ps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11346) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11348) 	err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11349) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11350) 		wdev->ps = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11351) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11354) static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11356) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11357) 	enum nl80211_ps_state ps_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11358) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11359) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11360) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11361) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11362) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11364) 	wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11366) 	if (!rdev->ops->set_power_mgmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11367) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11369) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11370) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11371) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11373) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11374) 			     NL80211_CMD_GET_POWER_SAVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11375) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11376) 		err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11377) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11380) 	if (wdev->ps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11381) 		ps_state = NL80211_PS_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11382) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11383) 		ps_state = NL80211_PS_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11385) 	if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11386) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11388) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11389) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11391)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11392) 	err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11393)  free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11394) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11395) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11398) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11399) nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11400) 	[NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11401) 	[NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11402) 	[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11403) 	[NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11404) 	[NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11405) 	[NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11406) 	[NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11409) static int nl80211_set_cqm_txe(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11410) 			       u32 rate, u32 pkts, u32 intvl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11412) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11413) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11414) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11416) 	if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11417) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11419) 	if (!rdev->ops->set_cqm_txe_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11420) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11422) 	if (wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11423) 	    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11424) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11426) 	return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11429) static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11430) 				    struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11432) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11433) 	s32 last, low, high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11434) 	u32 hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11435) 	int i, n, low_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11436) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11438) 	/* RSSI reporting disabled? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11439) 	if (!wdev->cqm_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11440) 		return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11442) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11443) 	 * Obtain current RSSI value if possible, if not and no RSSI threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11444) 	 * event has been received yet, we should receive an event after a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11445) 	 * connection is established and enough beacons received to calculate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11446) 	 * the average.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11447) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11448) 	if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11449) 	    rdev->ops->get_station) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11450) 		struct station_info sinfo = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11451) 		u8 *mac_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11453) 		mac_addr = wdev->current_bss->pub.bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11455) 		err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11456) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11457) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11459) 		cfg80211_sinfo_release_content(&sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11460) 		if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11461) 			wdev->cqm_config->last_rssi_event_value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11462) 				(s8) sinfo.rx_beacon_signal_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11465) 	last = wdev->cqm_config->last_rssi_event_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11466) 	hyst = wdev->cqm_config->rssi_hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11467) 	n = wdev->cqm_config->n_rssi_thresholds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11469) 	for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11470) 		i = array_index_nospec(i, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11471) 		if (last < wdev->cqm_config->rssi_thresholds[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11472) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11475) 	low_index = i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11476) 	if (low_index >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11477) 		low_index = array_index_nospec(low_index, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11478) 		low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11479) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11480) 		low = S32_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11482) 	if (i < n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11483) 		i = array_index_nospec(i, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11484) 		high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11485) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11486) 		high = S32_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11489) 	return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11492) static int nl80211_set_cqm_rssi(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11493) 				const s32 *thresholds, int n_thresholds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11494) 				u32 hysteresis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11496) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11497) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11498) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11499) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11500) 	s32 prev = S32_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11502) 	/* Check all values negative and sorted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11503) 	for (i = 0; i < n_thresholds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11504) 		if (thresholds[i] > 0 || thresholds[i] <= prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11505) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11507) 		prev = thresholds[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11508) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11510) 	if (wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11511) 	    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11512) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11514) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11515) 	cfg80211_cqm_config_free(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11516) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11518) 	if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11519) 		if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11520) 			return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11522) 		return rdev_set_cqm_rssi_config(rdev, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11523) 						thresholds[0], hysteresis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11524) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11526) 	if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11527) 				     NL80211_EXT_FEATURE_CQM_RSSI_LIST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11528) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11530) 	if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11531) 		n_thresholds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11533) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11534) 	if (n_thresholds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11535) 		struct cfg80211_cqm_config *cqm_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11537) 		cqm_config = kzalloc(sizeof(struct cfg80211_cqm_config) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11538) 				     n_thresholds * sizeof(s32), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11539) 		if (!cqm_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11540) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11541) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11542) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11544) 		cqm_config->rssi_hyst = hysteresis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11545) 		cqm_config->n_rssi_thresholds = n_thresholds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11546) 		memcpy(cqm_config->rssi_thresholds, thresholds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11547) 		       n_thresholds * sizeof(s32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11549) 		wdev->cqm_config = cqm_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11552) 	err = cfg80211_cqm_rssi_update(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11554) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11555) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11557) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11560) static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11562) 	struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11563) 	struct nlattr *cqm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11564) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11566) 	cqm = info->attrs[NL80211_ATTR_CQM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11567) 	if (!cqm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11568) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11570) 	err = nla_parse_nested_deprecated(attrs, NL80211_ATTR_CQM_MAX, cqm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11571) 					  nl80211_attr_cqm_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11572) 					  info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11573) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11574) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11576) 	if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11577) 	    attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11578) 		const s32 *thresholds =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11579) 			nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11580) 		int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11581) 		u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11583) 		if (len % 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11584) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11586) 		return nl80211_set_cqm_rssi(info, thresholds, len / 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11587) 					    hysteresis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11590) 	if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11591) 	    attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11592) 	    attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11593) 		u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11594) 		u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11595) 		u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11597) 		return nl80211_set_cqm_txe(info, rate, pkts, intvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11598) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11600) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11603) static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11605) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11606) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11607) 	struct ocb_setup setup = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11608) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11610) 	err = nl80211_parse_chandef(rdev, info, &setup.chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11611) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11612) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11614) 	return cfg80211_join_ocb(rdev, dev, &setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11617) static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11619) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11620) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11622) 	return cfg80211_leave_ocb(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11625) static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11627) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11628) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11629) 	struct mesh_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11630) 	struct mesh_setup setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11631) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11633) 	/* start with default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11634) 	memcpy(&cfg, &default_mesh_config, sizeof(cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11635) 	memcpy(&setup, &default_mesh_setup, sizeof(setup));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11637) 	if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11638) 		/* and parse parameters if given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11639) 		err = nl80211_parse_mesh_config(info, &cfg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11640) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11641) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11642) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11644) 	if (!info->attrs[NL80211_ATTR_MESH_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11645) 	    !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11646) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11648) 	setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11649) 	setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11651) 	if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11652) 	    !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11653) 			    nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11654) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11656) 	if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11657) 		setup.beacon_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11658) 			nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11660) 		err = cfg80211_validate_beacon_int(rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11661) 						   NL80211_IFTYPE_MESH_POINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11662) 						   setup.beacon_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11663) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11664) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11665) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11667) 	if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11668) 		setup.dtim_period =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11669) 			nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11670) 		if (setup.dtim_period < 1 || setup.dtim_period > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11671) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11674) 	if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11675) 		/* parse additional setup parameters if given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11676) 		err = nl80211_parse_mesh_setup(info, &setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11677) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11678) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11681) 	if (setup.user_mpm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11682) 		cfg.auto_open_plinks = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11684) 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11685) 		err = nl80211_parse_chandef(rdev, info, &setup.chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11686) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11687) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11688) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11689) 		/* __cfg80211_join_mesh() will sort it out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11690) 		setup.chandef.chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11691) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11693) 	if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11694) 		u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11695) 		int n_rates =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11696) 			nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11697) 		struct ieee80211_supported_band *sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11699) 		if (!setup.chandef.chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11700) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11702) 		sband = rdev->wiphy.bands[setup.chandef.chan->band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11704) 		err = ieee80211_get_ratemask(sband, rates, n_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11705) 					     &setup.basic_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11706) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11707) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11710) 	if (info->attrs[NL80211_ATTR_TX_RATES]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11711) 		err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11712) 						    NL80211_ATTR_TX_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11713) 						    &setup.beacon_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11714) 						    dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11715) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11716) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11718) 		if (!setup.chandef.chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11719) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11721) 		err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11722) 					      &setup.beacon_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11723) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11724) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11725) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11727) 	setup.userspace_handles_dfs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11728) 		nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11730) 	if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11731) 		int r = validate_pae_over_nl80211(rdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11733) 		if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11734) 			return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11736) 		setup.control_port_over_nl80211 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11739) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11740) 	err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11741) 	if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11742) 		dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11743) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11745) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11748) static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11750) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11751) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11753) 	return cfg80211_leave_mesh(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11756) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11757) static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11758) 					struct cfg80211_registered_device *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11760) 	struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11761) 	struct nlattr *nl_pats, *nl_pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11762) 	int i, pat_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11764) 	if (!wowlan->n_patterns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11765) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11767) 	nl_pats = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11768) 	if (!nl_pats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11769) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11771) 	for (i = 0; i < wowlan->n_patterns; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11772) 		nl_pat = nla_nest_start_noflag(msg, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11773) 		if (!nl_pat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11774) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11775) 		pat_len = wowlan->patterns[i].pattern_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11776) 		if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11777) 			    wowlan->patterns[i].mask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11778) 		    nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11779) 			    wowlan->patterns[i].pattern) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11780) 		    nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11781) 				wowlan->patterns[i].pkt_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11782) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11783) 		nla_nest_end(msg, nl_pat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11785) 	nla_nest_end(msg, nl_pats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11787) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11790) static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11791) 				   struct cfg80211_wowlan_tcp *tcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11793) 	struct nlattr *nl_tcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11795) 	if (!tcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11796) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11798) 	nl_tcp = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11799) 				       NL80211_WOWLAN_TRIG_TCP_CONNECTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11800) 	if (!nl_tcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11801) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11803) 	if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11804) 	    nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11805) 	    nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11806) 	    nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11807) 	    nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11808) 	    nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11809) 		    tcp->payload_len, tcp->payload) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11810) 	    nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11811) 			tcp->data_interval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11812) 	    nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11813) 		    tcp->wake_len, tcp->wake_data) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11814) 	    nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11815) 		    DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11816) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11818) 	if (tcp->payload_seq.len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11819) 	    nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11820) 		    sizeof(tcp->payload_seq), &tcp->payload_seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11821) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11823) 	if (tcp->payload_tok.len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11824) 	    nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11825) 		    sizeof(tcp->payload_tok) + tcp->tokens_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11826) 		    &tcp->payload_tok))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11827) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11829) 	nla_nest_end(msg, nl_tcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11831) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11834) static int nl80211_send_wowlan_nd(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11835) 				  struct cfg80211_sched_scan_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11837) 	struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11838) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11840) 	if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11841) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11843) 	nd = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11844) 	if (!nd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11845) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11847) 	if (req->n_scan_plans == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11848) 	    nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11849) 			req->scan_plans[0].interval * 1000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11850) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11852) 	if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11853) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11855) 	if (req->relative_rssi_set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11856) 		struct nl80211_bss_select_rssi_adjust rssi_adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11858) 		if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11859) 			       req->relative_rssi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11860) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11862) 		rssi_adjust.band = req->rssi_adjust.band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11863) 		rssi_adjust.delta = req->rssi_adjust.delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11864) 		if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11865) 			    sizeof(rssi_adjust), &rssi_adjust))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11866) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11867) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11869) 	freqs = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11870) 	if (!freqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11871) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11873) 	for (i = 0; i < req->n_channels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11874) 		if (nla_put_u32(msg, i, req->channels[i]->center_freq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11875) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11876) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11878) 	nla_nest_end(msg, freqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11880) 	if (req->n_match_sets) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11881) 		matches = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11882) 						NL80211_ATTR_SCHED_SCAN_MATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11883) 		if (!matches)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11884) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11886) 		for (i = 0; i < req->n_match_sets; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11887) 			match = nla_nest_start_noflag(msg, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11888) 			if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11889) 				return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11891) 			if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11892) 				    req->match_sets[i].ssid.ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11893) 				    req->match_sets[i].ssid.ssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11894) 				return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11895) 			nla_nest_end(msg, match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11896) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11897) 		nla_nest_end(msg, matches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11898) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11900) 	scan_plans = nla_nest_start_noflag(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11901) 	if (!scan_plans)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11902) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11904) 	for (i = 0; i < req->n_scan_plans; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11905) 		scan_plan = nla_nest_start_noflag(msg, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11906) 		if (!scan_plan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11907) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11909) 		if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11910) 				req->scan_plans[i].interval) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11911) 		    (req->scan_plans[i].iterations &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11912) 		     nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11913) 				 req->scan_plans[i].iterations)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11914) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11915) 		nla_nest_end(msg, scan_plan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11917) 	nla_nest_end(msg, scan_plans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11919) 	nla_nest_end(msg, nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11921) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11924) static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11926) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11927) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11928) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11929) 	u32 size = NLMSG_DEFAULT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11931) 	if (!rdev->wiphy.wowlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11932) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11934) 	if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11935) 		/* adjust size to have room for all the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11936) 		size += rdev->wiphy.wowlan_config->tcp->tokens_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11937) 			rdev->wiphy.wowlan_config->tcp->payload_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11938) 			rdev->wiphy.wowlan_config->tcp->wake_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11939) 			rdev->wiphy.wowlan_config->tcp->wake_len / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11940) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11942) 	msg = nlmsg_new(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11943) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11944) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11946) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11947) 			     NL80211_CMD_GET_WOWLAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11948) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11949) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11951) 	if (rdev->wiphy.wowlan_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11952) 		struct nlattr *nl_wowlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11954) 		nl_wowlan = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11955) 						  NL80211_ATTR_WOWLAN_TRIGGERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11956) 		if (!nl_wowlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11957) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11959) 		if ((rdev->wiphy.wowlan_config->any &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11960) 		     nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11961) 		    (rdev->wiphy.wowlan_config->disconnect &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11962) 		     nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11963) 		    (rdev->wiphy.wowlan_config->magic_pkt &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11964) 		     nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11965) 		    (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11966) 		     nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11967) 		    (rdev->wiphy.wowlan_config->eap_identity_req &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11968) 		     nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11969) 		    (rdev->wiphy.wowlan_config->four_way_handshake &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11970) 		     nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11971) 		    (rdev->wiphy.wowlan_config->rfkill_release &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11972) 		     nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11973) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11975) 		if (nl80211_send_wowlan_patterns(msg, rdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11976) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11978) 		if (nl80211_send_wowlan_tcp(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11979) 					    rdev->wiphy.wowlan_config->tcp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11980) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11982) 		if (nl80211_send_wowlan_nd(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11983) 			    msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11984) 			    rdev->wiphy.wowlan_config->nd_config))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11985) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11987) 		nla_nest_end(msg, nl_wowlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11988) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11990) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11991) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11993) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11994) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11995) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11998) static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11999) 				    struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12000) 				    struct cfg80211_wowlan *trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12002) 	struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12003) 	struct cfg80211_wowlan_tcp *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12004) 	struct nl80211_wowlan_tcp_data_token *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12005) 	struct nl80211_wowlan_tcp_data_seq *seq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12006) 	u32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12007) 	u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12008) 	int err, port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12010) 	if (!rdev->wiphy.wowlan->tcp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12011) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12013) 	err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TCP, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12014) 					  nl80211_wowlan_tcp_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12015) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12016) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12018) 	if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12019) 	    !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12020) 	    !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12021) 	    !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12022) 	    !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12023) 	    !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12024) 	    !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12025) 	    !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12026) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12028) 	data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12029) 	if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12030) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12032) 	if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12033) 			rdev->wiphy.wowlan->tcp->data_interval_max ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12034) 	    nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12035) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12037) 	wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12038) 	if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12039) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12041) 	wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12042) 	if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12043) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12045) 	if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12046) 		u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12048) 		tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12049) 		tokens_size = tokln - sizeof(*tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12051) 		if (!tok->len || tokens_size % tok->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12052) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12053) 		if (!rdev->wiphy.wowlan->tcp->tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12054) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12055) 		if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12056) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12057) 		if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12058) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12059) 		if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12060) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12061) 		if (tok->offset + tok->len > data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12062) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12063) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12065) 	if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12066) 		seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12067) 		if (!rdev->wiphy.wowlan->tcp->seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12068) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12069) 		if (seq->len == 0 || seq->len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12070) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12071) 		if (seq->len + seq->offset > data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12072) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12073) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12075) 	size = sizeof(*cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12076) 	size += data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12077) 	size += wake_size + wake_mask_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12078) 	size += tokens_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12080) 	cfg = kzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12081) 	if (!cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12082) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12083) 	cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12084) 	cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12085) 	memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12086) 	       ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12087) 	if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12088) 		port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12089) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12090) 		port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12091) #ifdef CONFIG_INET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12092) 	/* allocate a socket and port for it and use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12093) 	err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12094) 			    IPPROTO_TCP, &cfg->sock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12095) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12096) 		kfree(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12097) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12098) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12099) 	if (inet_csk_get_port(cfg->sock->sk, port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12100) 		sock_release(cfg->sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12101) 		kfree(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12102) 		return -EADDRINUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12104) 	cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12105) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12106) 	if (!port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12107) 		kfree(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12108) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12110) 	cfg->src_port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12113) 	cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12114) 	cfg->payload_len = data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12115) 	cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12116) 	memcpy((void *)cfg->payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12117) 	       nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12118) 	       data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12119) 	if (seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12120) 		cfg->payload_seq = *seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12121) 	cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12122) 	cfg->wake_len = wake_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12123) 	cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12124) 	memcpy((void *)cfg->wake_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12125) 	       nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12126) 	       wake_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12127) 	cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12128) 			 data_size + wake_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12129) 	memcpy((void *)cfg->wake_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12130) 	       nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12131) 	       wake_mask_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12132) 	if (tok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12133) 		cfg->tokens_size = tokens_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12134) 		memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12137) 	trig->tcp = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12139) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12142) static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12143) 				   const struct wiphy_wowlan_support *wowlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12144) 				   struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12145) 				   struct cfg80211_wowlan *trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12147) 	struct nlattr **tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12148) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12150) 	tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12151) 	if (!tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12152) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12154) 	if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12155) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12156) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12157) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12159) 	err = nla_parse_nested_deprecated(tb, NL80211_ATTR_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12160) 					  nl80211_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12161) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12162) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12164) 	trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12165) 						   wowlan->max_nd_match_sets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12166) 	err = PTR_ERR_OR_ZERO(trig->nd_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12167) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12168) 		trig->nd_config = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12170) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12171) 	kfree(tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12172) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12175) static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12177) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12178) 	struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12179) 	struct cfg80211_wowlan new_triggers = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12180) 	struct cfg80211_wowlan *ntrig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12181) 	const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12182) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12183) 	bool prev_enabled = rdev->wiphy.wowlan_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12184) 	bool regular = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12186) 	if (!wowlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12187) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12189) 	if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12190) 		cfg80211_rdev_free_wowlan(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12191) 		rdev->wiphy.wowlan_config = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12192) 		goto set_wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12195) 	err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TRIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12196) 					  info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12197) 					  nl80211_wowlan_policy, info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12198) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12199) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12201) 	if (tb[NL80211_WOWLAN_TRIG_ANY]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12202) 		if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12203) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12204) 		new_triggers.any = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12207) 	if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12208) 		if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12209) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12210) 		new_triggers.disconnect = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12211) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12214) 	if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12215) 		if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12216) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12217) 		new_triggers.magic_pkt = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12218) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12221) 	if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12222) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12224) 	if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12225) 		if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12226) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12227) 		new_triggers.gtk_rekey_failure = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12228) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12231) 	if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12232) 		if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12233) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12234) 		new_triggers.eap_identity_req = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12235) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12238) 	if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12239) 		if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12240) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12241) 		new_triggers.four_way_handshake = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12242) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12245) 	if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12246) 		if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12247) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12248) 		new_triggers.rfkill_release = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12249) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12252) 	if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12253) 		struct nlattr *pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12254) 		int n_patterns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12255) 		int rem, pat_len, mask_len, pkt_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12256) 		struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12258) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12260) 		nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12261) 				    rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12262) 			n_patterns++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12263) 		if (n_patterns > wowlan->n_patterns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12264) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12266) 		new_triggers.patterns = kcalloc(n_patterns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12267) 						sizeof(new_triggers.patterns[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12268) 						GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12269) 		if (!new_triggers.patterns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12270) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12272) 		new_triggers.n_patterns = n_patterns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12273) 		i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12275) 		nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12276) 				    rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12277) 			u8 *mask_pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12279) 			err = nla_parse_nested_deprecated(pat_tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12280) 							  MAX_NL80211_PKTPAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12281) 							  pat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12282) 							  nl80211_packet_pattern_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12283) 							  info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12284) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12285) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12287) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12288) 			if (!pat_tb[NL80211_PKTPAT_MASK] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12289) 			    !pat_tb[NL80211_PKTPAT_PATTERN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12290) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12291) 			pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12292) 			mask_len = DIV_ROUND_UP(pat_len, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12293) 			if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12294) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12295) 			if (pat_len > wowlan->pattern_max_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12296) 			    pat_len < wowlan->pattern_min_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12297) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12299) 			if (!pat_tb[NL80211_PKTPAT_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12300) 				pkt_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12301) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12302) 				pkt_offset = nla_get_u32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12303) 					pat_tb[NL80211_PKTPAT_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12304) 			if (pkt_offset > wowlan->max_pkt_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12305) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12306) 			new_triggers.patterns[i].pkt_offset = pkt_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12308) 			mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12309) 			if (!mask_pat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12310) 				err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12311) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12312) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12313) 			new_triggers.patterns[i].mask = mask_pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12314) 			memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12315) 			       mask_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12316) 			mask_pat += mask_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12317) 			new_triggers.patterns[i].pattern = mask_pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12318) 			new_triggers.patterns[i].pattern_len = pat_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12319) 			memcpy(mask_pat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12320) 			       nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12321) 			       pat_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12322) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12323) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12324) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12326) 	if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12327) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12328) 		err = nl80211_parse_wowlan_tcp(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12329) 			rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12330) 			&new_triggers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12331) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12332) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12335) 	if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12336) 		regular = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12337) 		err = nl80211_parse_wowlan_nd(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12338) 			rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12339) 			&new_triggers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12340) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12341) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12344) 	/* The 'any' trigger means the device continues operating more or less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12345) 	 * as in its normal operation mode and wakes up the host on most of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12346) 	 * normal interrupts (like packet RX, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12347) 	 * It therefore makes little sense to combine with the more constrained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12348) 	 * wakeup trigger modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12349) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12350) 	if (new_triggers.any && regular) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12351) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12352) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12353) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12355) 	ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12356) 	if (!ntrig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12357) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12358) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12360) 	cfg80211_rdev_free_wowlan(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12361) 	rdev->wiphy.wowlan_config = ntrig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12363)  set_wakeup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12364) 	if (rdev->ops->set_wakeup &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12365) 	    prev_enabled != !!rdev->wiphy.wowlan_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12366) 		rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12368) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12369)  error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12370) 	for (i = 0; i < new_triggers.n_patterns; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12371) 		kfree(new_triggers.patterns[i].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12372) 	kfree(new_triggers.patterns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12373) 	if (new_triggers.tcp && new_triggers.tcp->sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12374) 		sock_release(new_triggers.tcp->sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12375) 	kfree(new_triggers.tcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12376) 	kfree(new_triggers.nd_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12377) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12379) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12381) static int nl80211_send_coalesce_rules(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12382) 				       struct cfg80211_registered_device *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12384) 	struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12385) 	int i, j, pat_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12386) 	struct cfg80211_coalesce_rules *rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12388) 	if (!rdev->coalesce->n_rules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12389) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12391) 	nl_rules = nla_nest_start_noflag(msg, NL80211_ATTR_COALESCE_RULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12392) 	if (!nl_rules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12393) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12395) 	for (i = 0; i < rdev->coalesce->n_rules; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12396) 		nl_rule = nla_nest_start_noflag(msg, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12397) 		if (!nl_rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12398) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12400) 		rule = &rdev->coalesce->rules[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12401) 		if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12402) 				rule->delay))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12403) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12405) 		if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12406) 				rule->condition))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12407) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12409) 		nl_pats = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12410) 						NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12411) 		if (!nl_pats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12412) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12414) 		for (j = 0; j < rule->n_patterns; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12415) 			nl_pat = nla_nest_start_noflag(msg, j + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12416) 			if (!nl_pat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12417) 				return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12418) 			pat_len = rule->patterns[j].pattern_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12419) 			if (nla_put(msg, NL80211_PKTPAT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12420) 				    DIV_ROUND_UP(pat_len, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12421) 				    rule->patterns[j].mask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12422) 			    nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12423) 				    rule->patterns[j].pattern) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12424) 			    nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12425) 					rule->patterns[j].pkt_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12426) 				return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12427) 			nla_nest_end(msg, nl_pat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12428) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12429) 		nla_nest_end(msg, nl_pats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12430) 		nla_nest_end(msg, nl_rule);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12432) 	nla_nest_end(msg, nl_rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12434) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12437) static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12439) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12440) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12441) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12443) 	if (!rdev->wiphy.coalesce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12444) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12446) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12447) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12448) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12450) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12451) 			     NL80211_CMD_GET_COALESCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12452) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12453) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12455) 	if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12456) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12458) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12459) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12461) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12462) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12463) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12466) void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12468) 	struct cfg80211_coalesce *coalesce = rdev->coalesce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12469) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12470) 	struct cfg80211_coalesce_rules *rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12472) 	if (!coalesce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12473) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12475) 	for (i = 0; i < coalesce->n_rules; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12476) 		rule = &coalesce->rules[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12477) 		for (j = 0; j < rule->n_patterns; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12478) 			kfree(rule->patterns[j].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12479) 		kfree(rule->patterns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12481) 	kfree(coalesce->rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12482) 	kfree(coalesce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12483) 	rdev->coalesce = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12486) static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12487) 				       struct nlattr *rule,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12488) 				       struct cfg80211_coalesce_rules *new_rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12490) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12491) 	const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12492) 	struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12493) 	int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12494) 	struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12496) 	err = nla_parse_nested_deprecated(tb, NL80211_ATTR_COALESCE_RULE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12497) 					  rule, nl80211_coalesce_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12498) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12499) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12501) 	if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12502) 		new_rule->delay =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12503) 			nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12504) 	if (new_rule->delay > coalesce->max_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12505) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12507) 	if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12508) 		new_rule->condition =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12509) 			nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12511) 	if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12512) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12514) 	nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12515) 			    rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12516) 		n_patterns++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12517) 	if (n_patterns > coalesce->n_patterns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12518) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12520) 	new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12521) 				     GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12522) 	if (!new_rule->patterns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12523) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12525) 	new_rule->n_patterns = n_patterns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12526) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12528) 	nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12529) 			    rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12530) 		u8 *mask_pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12532) 		err = nla_parse_nested_deprecated(pat_tb, MAX_NL80211_PKTPAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12533) 						  pat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12534) 						  nl80211_packet_pattern_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12535) 						  NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12536) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12537) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12539) 		if (!pat_tb[NL80211_PKTPAT_MASK] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12540) 		    !pat_tb[NL80211_PKTPAT_PATTERN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12541) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12542) 		pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12543) 		mask_len = DIV_ROUND_UP(pat_len, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12544) 		if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12545) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12546) 		if (pat_len > coalesce->pattern_max_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12547) 		    pat_len < coalesce->pattern_min_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12548) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12550) 		if (!pat_tb[NL80211_PKTPAT_OFFSET])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12551) 			pkt_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12552) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12553) 			pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12554) 		if (pkt_offset > coalesce->max_pkt_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12555) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12556) 		new_rule->patterns[i].pkt_offset = pkt_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12558) 		mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12559) 		if (!mask_pat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12560) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12562) 		new_rule->patterns[i].mask = mask_pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12563) 		memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12564) 		       mask_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12566) 		mask_pat += mask_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12567) 		new_rule->patterns[i].pattern = mask_pat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12568) 		new_rule->patterns[i].pattern_len = pat_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12569) 		memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12570) 		       pat_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12571) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12574) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12577) static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12579) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12580) 	const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12581) 	struct cfg80211_coalesce new_coalesce = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12582) 	struct cfg80211_coalesce *n_coalesce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12583) 	int err, rem_rule, n_rules = 0, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12584) 	struct nlattr *rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12585) 	struct cfg80211_coalesce_rules *tmp_rule;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12587) 	if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12588) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12590) 	if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12591) 		cfg80211_rdev_free_coalesce(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12592) 		rdev_set_coalesce(rdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12593) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12594) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12596) 	nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12597) 			    rem_rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12598) 		n_rules++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12599) 	if (n_rules > coalesce->n_rules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12600) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12602) 	new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12603) 				     GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12604) 	if (!new_coalesce.rules)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12605) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12607) 	new_coalesce.n_rules = n_rules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12608) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12610) 	nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12611) 			    rem_rule) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12612) 		err = nl80211_parse_coalesce_rule(rdev, rule,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12613) 						  &new_coalesce.rules[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12614) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12615) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12617) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12620) 	err = rdev_set_coalesce(rdev, &new_coalesce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12621) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12622) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12624) 	n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12625) 	if (!n_coalesce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12626) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12627) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12628) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12629) 	cfg80211_rdev_free_coalesce(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12630) 	rdev->coalesce = n_coalesce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12632) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12633) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12634) 	for (i = 0; i < new_coalesce.n_rules; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12635) 		tmp_rule = &new_coalesce.rules[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12636) 		for (j = 0; j < tmp_rule->n_patterns; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12637) 			kfree(tmp_rule->patterns[j].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12638) 		kfree(tmp_rule->patterns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12640) 	kfree(new_coalesce.rules);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12642) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12645) static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12647) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12648) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12649) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12650) 	struct nlattr *tb[NUM_NL80211_REKEY_DATA];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12651) 	struct cfg80211_gtk_rekey_data rekey_data = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12652) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12654) 	if (!info->attrs[NL80211_ATTR_REKEY_DATA])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12655) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12657) 	err = nla_parse_nested_deprecated(tb, MAX_NL80211_REKEY_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12658) 					  info->attrs[NL80211_ATTR_REKEY_DATA],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12659) 					  nl80211_rekey_policy, info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12660) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12661) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12663) 	if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12664) 	    !tb[NL80211_REKEY_DATA_KCK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12665) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12666) 	if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12667) 	    !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12668) 	      nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12669) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12670) 	if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12671) 	    !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12672) 	      nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12673) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12675) 	rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12676) 	rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12677) 	rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12678) 	rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12679) 	rekey_data.kck_len = nla_len(tb[NL80211_REKEY_DATA_KCK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12680) 	if (tb[NL80211_REKEY_DATA_AKM])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12681) 		rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12683) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12684) 	if (!wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12685) 		err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12686) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12689) 	if (!rdev->ops->set_rekey_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12690) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12691) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12692) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12694) 	err = rdev_set_rekey_data(rdev, dev, &rekey_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12695)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12696) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12697) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12700) static int nl80211_register_unexpected_frame(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12701) 					     struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12703) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12704) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12706) 	if (wdev->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12707) 	    wdev->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12708) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12710) 	if (wdev->ap_unexpected_nlportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12711) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12713) 	wdev->ap_unexpected_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12714) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12717) static int nl80211_probe_client(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12718) 				struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12720) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12721) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12722) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12723) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12724) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12725) 	const u8 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12726) 	u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12727) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12729) 	if (wdev->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12730) 	    wdev->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12731) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12733) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12734) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12736) 	if (!rdev->ops->probe_client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12737) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12739) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12740) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12741) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12743) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12744) 			     NL80211_CMD_PROBE_CLIENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12745) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12746) 		err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12747) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12750) 	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12752) 	err = rdev_probe_client(rdev, dev, addr, &cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12753) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12754) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12756) 	if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12757) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12758) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12760) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12762) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12764)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12765) 	err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12766)  free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12767) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12768) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12771) static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12773) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12774) 	struct cfg80211_beacon_registration *reg, *nreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12775) 	int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12777) 	if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12778) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12780) 	nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12781) 	if (!nreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12782) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12784) 	/* First, check if already registered. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12785) 	spin_lock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12786) 	list_for_each_entry(reg, &rdev->beacon_registrations, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12787) 		if (reg->nlportid == info->snd_portid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12788) 			rv = -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12789) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12790) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12791) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12792) 	/* Add it to the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12793) 	nreg->nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12794) 	list_add(&nreg->list, &rdev->beacon_registrations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12796) 	spin_unlock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12798) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12799) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12800) 	spin_unlock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12801) 	kfree(nreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12802) 	return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12805) static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12807) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12808) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12809) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12811) 	if (!rdev->ops->start_p2p_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12812) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12814) 	if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12815) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12817) 	if (wdev_running(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12818) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12820) 	if (rfkill_blocked(rdev->rfkill))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12821) 		return -ERFKILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12823) 	err = rdev_start_p2p_device(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12824) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12825) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12827) 	wdev->is_running = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12828) 	rdev->opencount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12830) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12833) static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12835) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12836) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12838) 	if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12839) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12841) 	if (!rdev->ops->stop_p2p_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12842) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12844) 	cfg80211_stop_p2p_device(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12846) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12849) static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12851) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12852) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12853) 	struct cfg80211_nan_conf conf = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12854) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12856) 	if (wdev->iftype != NL80211_IFTYPE_NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12857) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12859) 	if (wdev_running(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12860) 		return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12862) 	if (rfkill_blocked(rdev->rfkill))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12863) 		return -ERFKILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12865) 	if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12866) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12868) 	conf.master_pref =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12869) 		nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12871) 	if (info->attrs[NL80211_ATTR_BANDS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12872) 		u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12874) 		if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12875) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12877) 		if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12878) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12880) 		conf.bands = bands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12881) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12883) 	err = rdev_start_nan(rdev, wdev, &conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12884) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12885) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12887) 	wdev->is_running = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12888) 	rdev->opencount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12890) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12893) static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12895) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12896) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12898) 	if (wdev->iftype != NL80211_IFTYPE_NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12899) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12901) 	cfg80211_stop_nan(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12903) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12906) static int validate_nan_filter(struct nlattr *filter_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12908) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12909) 	int len = 0, n_entries = 0, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12911) 	nla_for_each_nested(attr, filter_attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12912) 		len += nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12913) 		n_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12914) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12916) 	if (len >= U8_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12917) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12919) 	return n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12922) static int handle_nan_filter(struct nlattr *attr_filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12923) 			     struct cfg80211_nan_func *func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12924) 			     bool tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12926) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12927) 	int n_entries, rem, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12928) 	struct cfg80211_nan_func_filter *filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12930) 	n_entries = validate_nan_filter(attr_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12931) 	if (n_entries < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12932) 		return n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12934) 	BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12936) 	filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12937) 	if (!filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12938) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12940) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12941) 	nla_for_each_nested(attr, attr_filter, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12942) 		filter[i].filter = nla_memdup(attr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12943) 		if (!filter[i].filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12944) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12946) 		filter[i].len = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12947) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12948) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12949) 	if (tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12950) 		func->num_tx_filters = n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12951) 		func->tx_filters = filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12952) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12953) 		func->num_rx_filters = n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12954) 		func->rx_filters = filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12955) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12957) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12959) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12960) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12961) 	nla_for_each_nested(attr, attr_filter, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12962) 		kfree(filter[i].filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12963) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12964) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12965) 	kfree(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12966) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12969) static int nl80211_nan_add_func(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12970) 				struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12972) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12973) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12974) 	struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12975) 	struct cfg80211_nan_func *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12976) 	struct sk_buff *msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12977) 	void *hdr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12978) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12980) 	if (wdev->iftype != NL80211_IFTYPE_NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12981) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12983) 	if (!wdev_running(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12984) 		return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12986) 	if (!info->attrs[NL80211_ATTR_NAN_FUNC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12987) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12989) 	err = nla_parse_nested_deprecated(tb, NL80211_NAN_FUNC_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12990) 					  info->attrs[NL80211_ATTR_NAN_FUNC],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12991) 					  nl80211_nan_func_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12992) 					  info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12993) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12994) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12996) 	func = kzalloc(sizeof(*func), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12997) 	if (!func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12998) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13000) 	func->cookie = cfg80211_assign_cookie(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13002) 	if (!tb[NL80211_NAN_FUNC_TYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13003) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13004) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13005) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13008) 	func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13010) 	if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13011) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13012) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13013) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13015) 	memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13016) 	       sizeof(func->service_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13018) 	func->close_range =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13019) 		nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13021) 	if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13022) 		func->serv_spec_info_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13023) 			nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13024) 		func->serv_spec_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13025) 			kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13026) 				func->serv_spec_info_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13027) 				GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13028) 		if (!func->serv_spec_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13029) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13030) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13031) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13032) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13034) 	if (tb[NL80211_NAN_FUNC_TTL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13035) 		func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13037) 	switch (func->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13038) 	case NL80211_NAN_FUNC_PUBLISH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13039) 		if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13040) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13041) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13042) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13044) 		func->publish_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13045) 			nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13046) 		func->publish_bcast =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13047) 			nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13049) 		if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13050) 			func->publish_bcast) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13051) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13052) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13053) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13054) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13055) 	case NL80211_NAN_FUNC_SUBSCRIBE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13056) 		func->subscribe_active =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13057) 			nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13058) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13059) 	case NL80211_NAN_FUNC_FOLLOW_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13060) 		if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13061) 		    !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13062) 		    !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13063) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13064) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13065) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13067) 		func->followup_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13068) 			nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13069) 		func->followup_reqid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13070) 			nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13071) 		memcpy(func->followup_dest.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13072) 		       nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13073) 		       sizeof(func->followup_dest.addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13074) 		if (func->ttl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13075) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13076) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13077) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13078) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13079) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13080) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13081) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13084) 	if (tb[NL80211_NAN_FUNC_SRF]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13085) 		struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13087) 		err = nla_parse_nested_deprecated(srf_tb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13088) 						  NL80211_NAN_SRF_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13089) 						  tb[NL80211_NAN_FUNC_SRF],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13090) 						  nl80211_nan_srf_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13091) 						  info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13092) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13093) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13095) 		func->srf_include =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13096) 			nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13098) 		if (srf_tb[NL80211_NAN_SRF_BF]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13099) 			if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13100) 			    !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13101) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13102) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13103) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13105) 			func->srf_bf_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13106) 				nla_len(srf_tb[NL80211_NAN_SRF_BF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13107) 			func->srf_bf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13108) 				kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13109) 					func->srf_bf_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13110) 			if (!func->srf_bf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13111) 				err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13112) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13113) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13115) 			func->srf_bf_idx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13116) 				nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13117) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13118) 			struct nlattr *attr, *mac_attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13119) 				srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13120) 			int n_entries, rem, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13122) 			if (!mac_attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13123) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13124) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13125) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13127) 			n_entries = validate_acl_mac_addrs(mac_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13128) 			if (n_entries <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13129) 				err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13130) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13131) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13133) 			func->srf_num_macs = n_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13134) 			func->srf_macs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13135) 				kcalloc(n_entries, sizeof(*func->srf_macs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13136) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13137) 			if (!func->srf_macs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13138) 				err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13139) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13140) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13142) 			nla_for_each_nested(attr, mac_attr, rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13143) 				memcpy(func->srf_macs[i++].addr, nla_data(attr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13144) 				       sizeof(*func->srf_macs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13145) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13148) 	if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13149) 		err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13150) 					func, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13151) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13152) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13155) 	if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13156) 		err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13157) 					func, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13158) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13159) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13162) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13163) 	if (!msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13164) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13165) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13168) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13169) 			     NL80211_CMD_ADD_NAN_FUNCTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13170) 	/* This can't really happen - we just allocated 4KB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13171) 	if (WARN_ON(!hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13172) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13173) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13176) 	err = rdev_add_nan_func(rdev, wdev, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13177) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13178) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13179) 		cfg80211_free_nan_func(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13180) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13181) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13184) 	/* propagate the instance id and cookie to userspace  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13185) 	if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13186) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13187) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13189) 	func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13190) 	if (!func_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13191) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13193) 	if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13194) 		       func->instance_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13195) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13197) 	nla_nest_end(msg, func_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13199) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13200) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13202) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13203) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13204) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13207) static int nl80211_nan_del_func(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13208) 			       struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13210) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13211) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13212) 	u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13214) 	if (wdev->iftype != NL80211_IFTYPE_NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13215) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13217) 	if (!wdev_running(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13218) 		return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13220) 	if (!info->attrs[NL80211_ATTR_COOKIE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13221) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13223) 	cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13225) 	rdev_del_nan_func(rdev, wdev, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13227) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13230) static int nl80211_nan_change_config(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13231) 				     struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13233) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13234) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13235) 	struct cfg80211_nan_conf conf = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13236) 	u32 changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13238) 	if (wdev->iftype != NL80211_IFTYPE_NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13239) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13241) 	if (!wdev_running(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13242) 		return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13244) 	if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13245) 		conf.master_pref =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13246) 			nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13247) 		if (conf.master_pref <= 1 || conf.master_pref == 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13248) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13250) 		changed |= CFG80211_NAN_CONF_CHANGED_PREF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13253) 	if (info->attrs[NL80211_ATTR_BANDS]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13254) 		u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13256) 		if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13257) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13259) 		if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13260) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13262) 		conf.bands = bands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13263) 		changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13266) 	if (!changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13267) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13269) 	return rdev_nan_change_conf(rdev, wdev, &conf, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13272) void cfg80211_nan_match(struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13273) 			struct cfg80211_nan_match_params *match, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13275) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13276) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13277) 	struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13278) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13279) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13281) 	if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13282) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13284) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13285) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13286) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13288) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13289) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13290) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13291) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13294) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13295) 	    (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13296) 					 wdev->netdev->ifindex)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13297) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13298) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13299) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13301) 	if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13302) 			      NL80211_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13303) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13304) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13306) 	match_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_MATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13307) 	if (!match_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13308) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13310) 	local_func_attr = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13311) 						NL80211_NAN_MATCH_FUNC_LOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13312) 	if (!local_func_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13313) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13315) 	if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13316) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13318) 	nla_nest_end(msg, local_func_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13320) 	peer_func_attr = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13321) 					       NL80211_NAN_MATCH_FUNC_PEER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13322) 	if (!peer_func_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13323) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13325) 	if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13326) 	    nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13327) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13329) 	if (match->info && match->info_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13330) 	    nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13331) 		    match->info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13332) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13334) 	nla_nest_end(msg, peer_func_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13335) 	nla_nest_end(msg, match_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13336) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13338) 	if (!wdev->owner_nlportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13339) 		genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13340) 					msg, 0, NL80211_MCGRP_NAN, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13341) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13342) 		genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13343) 				wdev->owner_nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13345) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13347) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13348) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13350) EXPORT_SYMBOL(cfg80211_nan_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13352) void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13353) 				  u8 inst_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13354) 				  enum nl80211_nan_func_term_reason reason,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13355) 				  u64 cookie, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13357) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13358) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13359) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13360) 	struct nlattr *func_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13361) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13363) 	if (WARN_ON(!inst_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13364) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13366) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13367) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13368) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13370) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13371) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13372) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13373) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13376) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13377) 	    (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13378) 					 wdev->netdev->ifindex)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13379) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13380) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13381) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13383) 	if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13384) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13385) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13387) 	func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13388) 	if (!func_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13389) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13391) 	if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13392) 	    nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13393) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13395) 	nla_nest_end(msg, func_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13396) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13398) 	if (!wdev->owner_nlportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13399) 		genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13400) 					msg, 0, NL80211_MCGRP_NAN, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13401) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13402) 		genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13403) 				wdev->owner_nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13405) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13407) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13408) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13410) EXPORT_SYMBOL(cfg80211_nan_func_terminated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13412) static int nl80211_get_protocol_features(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13413) 					 struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13415) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13416) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13418) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13419) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13420) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13422) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13423) 			     NL80211_CMD_GET_PROTOCOL_FEATURES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13424) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13425) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13427) 	if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13428) 			NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13429) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13431) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13432) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13434)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13435) 	kfree_skb(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13436) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13439) static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13441) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13442) 	struct cfg80211_update_ft_ies_params ft_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13443) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13445) 	if (!rdev->ops->update_ft_ies)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13446) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13448) 	if (!info->attrs[NL80211_ATTR_MDID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13449) 	    !info->attrs[NL80211_ATTR_IE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13450) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13452) 	memset(&ft_params, 0, sizeof(ft_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13453) 	ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13454) 	ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13455) 	ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13457) 	return rdev_update_ft_ies(rdev, dev, &ft_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13460) static int nl80211_crit_protocol_start(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13461) 				       struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13463) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13464) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13465) 	enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13466) 	u16 duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13467) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13469) 	if (!rdev->ops->crit_proto_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13470) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13472) 	if (WARN_ON(!rdev->ops->crit_proto_stop))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13473) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13475) 	if (rdev->crit_proto_nlportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13476) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13478) 	/* determine protocol if provided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13479) 	if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13480) 		proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13482) 	if (proto >= NUM_NL80211_CRIT_PROTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13483) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13485) 	/* timeout must be provided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13486) 	if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13487) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13489) 	duration =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13490) 		nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13492) 	ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13493) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13494) 		rdev->crit_proto_nlportid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13496) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13499) static int nl80211_crit_protocol_stop(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13500) 				      struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13502) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13503) 	struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13505) 	if (!rdev->ops->crit_proto_stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13506) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13508) 	if (rdev->crit_proto_nlportid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13509) 		rdev->crit_proto_nlportid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13510) 		rdev_crit_proto_stop(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13511) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13512) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13515) static int nl80211_vendor_check_policy(const struct wiphy_vendor_command *vcmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13516) 				       struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13517) 				       struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13519) 	if (vcmd->policy == VENDOR_CMD_RAW_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13520) 		if (attr->nla_type & NLA_F_NESTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13521) 			NL_SET_ERR_MSG_ATTR(extack, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13522) 					    "unexpected nested data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13523) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13524) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13526) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13529) 	if (!(attr->nla_type & NLA_F_NESTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13530) 		NL_SET_ERR_MSG_ATTR(extack, attr, "expected nested data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13531) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13534) 	return nla_validate_nested(attr, vcmd->maxattr, vcmd->policy, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13537) static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13539) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13540) 	struct wireless_dev *wdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13541) 		__cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13542) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13543) 	u32 vid, subcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13545) 	if (!rdev->wiphy.vendor_commands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13546) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13548) 	if (IS_ERR(wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13549) 		err = PTR_ERR(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13550) 		if (err != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13551) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13552) 		wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13553) 	} else if (wdev->wiphy != &rdev->wiphy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13554) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13557) 	if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13558) 	    !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13559) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13561) 	vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13562) 	subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13563) 	for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13564) 		const struct wiphy_vendor_command *vcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13565) 		void *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13566) 		int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13568) 		vcmd = &rdev->wiphy.vendor_commands[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13570) 		if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13571) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13573) 		if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13574) 				   WIPHY_VENDOR_CMD_NEED_NETDEV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13575) 			if (!wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13576) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13577) 			if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13578) 			    !wdev->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13579) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13581) 			if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13582) 				if (!wdev_running(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13583) 					return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13584) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13585) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13586) 			wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13587) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13589) 		if (!vcmd->doit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13590) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13592) 		if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13593) 			data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13594) 			len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13596) 			err = nl80211_vendor_check_policy(vcmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13597) 					info->attrs[NL80211_ATTR_VENDOR_DATA],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13598) 					info->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13599) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13600) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13601) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13603) 		rdev->cur_cmd_info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13604) 		err = vcmd->doit(&rdev->wiphy, wdev, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13605) 		rdev->cur_cmd_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13606) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13607) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13609) 	return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13612) static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13613) 				       struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13614) 				       struct cfg80211_registered_device **rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13615) 				       struct wireless_dev **wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13617) 	struct nlattr **attrbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13618) 	u32 vid, subcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13619) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13620) 	int vcmd_idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13621) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13622) 	void *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13623) 	unsigned int data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13625) 	if (cb->args[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13626) 		/* subtract the 1 again here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13627) 		struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13628) 		struct wireless_dev *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13630) 		if (!wiphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13631) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13632) 		*rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13633) 		*wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13635) 		if (cb->args[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13636) 			list_for_each_entry(tmp, &wiphy->wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13637) 				if (tmp->identifier == cb->args[1] - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13638) 					*wdev = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13639) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13640) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13641) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13642) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13644) 		/* keep rtnl locked in successful case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13645) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13646) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13648) 	attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13649) 	if (!attrbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13650) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13652) 	err = nlmsg_parse_deprecated(cb->nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13653) 				     GENL_HDRLEN + nl80211_fam.hdrsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13654) 				     attrbuf, nl80211_fam.maxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13655) 				     nl80211_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13656) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13657) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13659) 	if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13660) 	    !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13661) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13662) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13663) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13665) 	*wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13666) 	if (IS_ERR(*wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13667) 		*wdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13669) 	*rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13670) 	if (IS_ERR(*rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13671) 		err = PTR_ERR(*rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13672) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13675) 	vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13676) 	subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13678) 	for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13679) 		const struct wiphy_vendor_command *vcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13681) 		vcmd = &(*rdev)->wiphy.vendor_commands[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13683) 		if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13684) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13686) 		if (!vcmd->dumpit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13687) 			err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13688) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13689) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13691) 		vcmd_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13692) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13695) 	if (vcmd_idx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13696) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13697) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13700) 	if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13701) 		data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13702) 		data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13704) 		err = nl80211_vendor_check_policy(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13705) 				&(*rdev)->wiphy.vendor_commands[vcmd_idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13706) 				attrbuf[NL80211_ATTR_VENDOR_DATA],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13707) 				cb->extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13708) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13709) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13712) 	/* 0 is the first index - add 1 to parse only once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13713) 	cb->args[0] = (*rdev)->wiphy_idx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13714) 	/* add 1 to know if it was NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13715) 	cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13716) 	cb->args[2] = vcmd_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13717) 	cb->args[3] = (unsigned long)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13718) 	cb->args[4] = data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13720) 	/* keep rtnl locked in successful case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13721) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13722) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13723) 	kfree(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13724) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13727) static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13728) 				   struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13730) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13731) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13732) 	unsigned int vcmd_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13733) 	const struct wiphy_vendor_command *vcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13734) 	void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13735) 	int data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13736) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13737) 	struct nlattr *vendor_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13739) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13740) 	err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13741) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13742) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13744) 	vcmd_idx = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13745) 	data = (void *)cb->args[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13746) 	data_len = cb->args[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13747) 	vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13749) 	if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13750) 			   WIPHY_VENDOR_CMD_NEED_NETDEV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13751) 		if (!wdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13752) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13753) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13754) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13755) 		if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13756) 		    !wdev->netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13757) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13758) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13759) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13761) 		if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13762) 			if (!wdev_running(wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13763) 				err = -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13764) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13765) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13766) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13767) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13769) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13770) 		void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13771) 					   cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13772) 					   NL80211_CMD_VENDOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13773) 		if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13774) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13776) 		if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13777) 		    (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13778) 					       wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13779) 					       NL80211_ATTR_PAD))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13780) 			genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13781) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13782) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13784) 		vendor_data = nla_nest_start_noflag(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13785) 						    NL80211_ATTR_VENDOR_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13786) 		if (!vendor_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13787) 			genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13788) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13789) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13791) 		err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13792) 				   (unsigned long *)&cb->args[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13793) 		nla_nest_end(skb, vendor_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13795) 		if (err == -ENOBUFS || err == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13796) 			genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13797) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13798) 		} else if (err <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13799) 			genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13800) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13801) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13803) 		genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13804) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13806) 	err = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13807)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13808) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13809) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13812) struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13813) 					   enum nl80211_commands cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13814) 					   enum nl80211_attrs attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13815) 					   int approxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13817) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13819) 	if (WARN_ON(!rdev->cur_cmd_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13820) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13822) 	return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13823) 					   rdev->cur_cmd_info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13824) 					   rdev->cur_cmd_info->snd_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13825) 					   cmd, attr, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13827) EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13829) int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13831) 	struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13832) 	void *hdr = ((void **)skb->cb)[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13833) 	struct nlattr *data = ((void **)skb->cb)[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13835) 	/* clear CB data for netlink core to own from now on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13836) 	memset(skb->cb, 0, sizeof(skb->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13838) 	if (WARN_ON(!rdev->cur_cmd_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13839) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13840) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13841) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13843) 	nla_nest_end(skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13844) 	genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13845) 	return genlmsg_reply(skb, rdev->cur_cmd_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13847) EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13849) unsigned int cfg80211_vendor_cmd_get_sender(struct wiphy *wiphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13851) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13853) 	if (WARN_ON(!rdev->cur_cmd_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13854) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13856) 	return rdev->cur_cmd_info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13858) EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_get_sender);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13860) static int nl80211_set_qos_map(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13861) 			       struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13863) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13864) 	struct cfg80211_qos_map *qos_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13865) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13866) 	u8 *pos, len, num_des, des_len, des;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13867) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13869) 	if (!rdev->ops->set_qos_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13870) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13872) 	if (info->attrs[NL80211_ATTR_QOS_MAP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13873) 		pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13874) 		len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13876) 		if (len % 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13877) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13879) 		qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13880) 		if (!qos_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13881) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13883) 		num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13884) 		if (num_des) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13885) 			des_len = num_des *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13886) 				sizeof(struct cfg80211_dscp_exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13887) 			memcpy(qos_map->dscp_exception, pos, des_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13888) 			qos_map->num_des = num_des;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13889) 			for (des = 0; des < num_des; des++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13890) 				if (qos_map->dscp_exception[des].up > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13891) 					kfree(qos_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13892) 					return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13893) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13894) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13895) 			pos += des_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13896) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13897) 		memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13898) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13900) 	wdev_lock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13901) 	ret = nl80211_key_allowed(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13902) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13903) 		ret = rdev_set_qos_map(rdev, dev, qos_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13904) 	wdev_unlock(dev->ieee80211_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13906) 	kfree(qos_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13907) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13910) static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13912) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13913) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13914) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13915) 	const u8 *peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13916) 	u8 tsid, up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13917) 	u16 admitted_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13918) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13920) 	if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13921) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13923) 	if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13924) 	    !info->attrs[NL80211_ATTR_USER_PRIO])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13925) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13927) 	tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13928) 	up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13930) 	/* WMM uses TIDs 0-7 even for TSPEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13931) 	if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13932) 		/* TODO: handle 802.11 TSPEC/admission control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13933) 		 * need more attributes for that (e.g. BA session requirement);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13934) 		 * change the WMM adminssion test above to allow both then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13935) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13936) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13937) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13939) 	peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13941) 	if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13942) 		admitted_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13943) 			nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13944) 		if (!admitted_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13945) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13946) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13948) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13949) 	switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13950) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13951) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13952) 		if (wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13953) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13954) 		err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13955) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13956) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13957) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13958) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13961) 	err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13963)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13964) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13965) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13968) static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13970) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13971) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13972) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13973) 	const u8 *peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13974) 	u8 tsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13975) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13977) 	if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13978) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13980) 	tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13981) 	peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13983) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13984) 	err = rdev_del_tx_ts(rdev, dev, tsid, peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13985) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13987) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13990) static int nl80211_tdls_channel_switch(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13991) 				       struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13993) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13994) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13995) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13996) 	struct cfg80211_chan_def chandef = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13997) 	const u8 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13998) 	u8 oper_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13999) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14001) 	if (!rdev->ops->tdls_channel_switch ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14002) 	    !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14003) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14005) 	switch (dev->ieee80211_ptr->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14006) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14007) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14008) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14009) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14010) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14011) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14013) 	if (!info->attrs[NL80211_ATTR_MAC] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14014) 	    !info->attrs[NL80211_ATTR_OPER_CLASS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14015) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14017) 	err = nl80211_parse_chandef(rdev, info, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14018) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14019) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14021) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14022) 	 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14023) 	 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14024) 	 * specification is not defined for them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14025) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14026) 	if (chandef.chan->band == NL80211_BAND_2GHZ &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14027) 	    chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14028) 	    chandef.width != NL80211_CHAN_WIDTH_20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14029) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14031) 	/* we will be active on the TDLS link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14032) 	if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14033) 					   wdev->iftype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14034) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14036) 	/* don't allow switching to DFS channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14037) 	if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14038) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14040) 	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14041) 	oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14043) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14044) 	err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14045) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14047) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14050) static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14051) 					      struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14053) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14054) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14055) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14056) 	const u8 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14058) 	if (!rdev->ops->tdls_channel_switch ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14059) 	    !rdev->ops->tdls_cancel_channel_switch ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14060) 	    !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14061) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14063) 	switch (dev->ieee80211_ptr->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14064) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14065) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14066) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14067) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14068) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14069) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14071) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14072) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14074) 	addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14076) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14077) 	rdev_tdls_cancel_channel_switch(rdev, dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14078) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14080) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14083) static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14084) 					    struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14086) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14087) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14088) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14089) 	const struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14090) 	bool enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14092) 	if (!rdev->ops->set_multicast_to_unicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14093) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14095) 	if (wdev->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14096) 	    wdev->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14097) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14099) 	nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14100) 	enabled = nla_get_flag(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14102) 	return rdev_set_multicast_to_unicast(rdev, dev, enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14105) static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14107) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14108) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14109) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14110) 	struct cfg80211_pmk_conf pmk_conf = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14111) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14113) 	if (wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14114) 	    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14115) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14117) 	if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14118) 				     NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14119) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14121) 	if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14122) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14124) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14125) 	if (!wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14126) 		ret = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14127) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14130) 	pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14131) 	if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14132) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14133) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14134) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14136) 	pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14137) 	pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14138) 	if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14139) 	    pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14140) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14141) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14144) 	if (info->attrs[NL80211_ATTR_PMKR0_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14145) 		pmk_conf.pmk_r0_name =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14146) 			nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14148) 	ret = rdev_set_pmk(rdev, dev, &pmk_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14149) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14150) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14151) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14154) static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14156) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14157) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14158) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14159) 	const u8 *aa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14160) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14162) 	if (wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14163) 	    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14164) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14166) 	if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14167) 				     NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14168) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14170) 	if (!info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14171) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14173) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14174) 	aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14175) 	ret = rdev_del_pmk(rdev, dev, aa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14176) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14178) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14181) static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14183) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14184) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14185) 	struct cfg80211_external_auth_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14187) 	if (!rdev->ops->external_auth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14188) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14190) 	if (!info->attrs[NL80211_ATTR_SSID] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14191) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14192) 	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14193) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14195) 	if (!info->attrs[NL80211_ATTR_BSSID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14196) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14198) 	if (!info->attrs[NL80211_ATTR_STATUS_CODE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14199) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14201) 	memset(&params, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14203) 	if (info->attrs[NL80211_ATTR_SSID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14204) 		params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14205) 		if (params.ssid.ssid_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14206) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14207) 		memcpy(params.ssid.ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14208) 		       nla_data(info->attrs[NL80211_ATTR_SSID]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14209) 		       params.ssid.ssid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14212) 	memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14213) 	       ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14215) 	params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14217) 	if (info->attrs[NL80211_ATTR_PMKID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14218) 		params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14220) 	return rdev_external_auth(rdev, dev, &params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14223) static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14225) 	bool dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14226) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14227) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14228) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14229) 	const u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14230) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14231) 	u8 *dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14232) 	u16 proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14233) 	bool noencrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14234) 	u64 cookie = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14235) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14237) 	if (!wiphy_ext_feature_isset(&rdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14238) 				     NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14239) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14241) 	if (!rdev->ops->tx_control_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14242) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14244) 	if (!info->attrs[NL80211_ATTR_FRAME] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14245) 	    !info->attrs[NL80211_ATTR_MAC] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14246) 	    !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14247) 		GENL_SET_ERR_MSG(info, "Frame, MAC or ethertype missing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14248) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14251) 	wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14253) 	switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14254) 	case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14255) 	case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14256) 	case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14257) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14258) 	case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14259) 	case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14260) 	case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14261) 		if (wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14262) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14263) 		err = -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14264) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14265) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14266) 		err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14267) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14270) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14272) 	buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14273) 	len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14274) 	dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14275) 	proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14276) 	noencrypt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14277) 		nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14279) 	err = rdev_tx_control_port(rdev, dev, buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14280) 				   dest, cpu_to_be16(proto), noencrypt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14281) 				   dont_wait_for_ack ? NULL : &cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14282) 	if (!err && !dont_wait_for_ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14283) 		nl_set_extack_cookie_u64(info->extack, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14284) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14285)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14286) 	wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14287) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14290) static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14291) 					   struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14293) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14294) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14295) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14296) 	struct cfg80211_ftm_responder_stats ftm_stats = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14297) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14298) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14299) 	struct nlattr *ftm_stats_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14300) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14302) 	if (wdev->iftype != NL80211_IFTYPE_AP || !wdev->beacon_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14303) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14305) 	err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14306) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14307) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14309) 	if (!ftm_stats.filled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14310) 		return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14312) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14313) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14314) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14316) 	hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14317) 			     NL80211_CMD_GET_FTM_RESPONDER_STATS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14318) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14319) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14321) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14322) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14324) 	ftm_stats_attr = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14325) 					       NL80211_ATTR_FTM_RESPONDER_STATS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14326) 	if (!ftm_stats_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14327) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14329) #define SET_FTM(field, name, type)					 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14330) 	do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14331) 	    nla_put_ ## type(msg, NL80211_FTM_STATS_ ## name,		 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14332) 			     ftm_stats.field))				 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14333) 		goto nla_put_failure; } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14334) #define SET_FTM_U64(field, name)					 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14335) 	do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14336) 	    nla_put_u64_64bit(msg, NL80211_FTM_STATS_ ## name,		 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14337) 			      ftm_stats.field, NL80211_FTM_STATS_PAD))	 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14338) 		goto nla_put_failure; } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14340) 	SET_FTM(success_num, SUCCESS_NUM, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14341) 	SET_FTM(partial_num, PARTIAL_NUM, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14342) 	SET_FTM(failed_num, FAILED_NUM, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14343) 	SET_FTM(asap_num, ASAP_NUM, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14344) 	SET_FTM(non_asap_num, NON_ASAP_NUM, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14345) 	SET_FTM_U64(total_duration_ms, TOTAL_DURATION_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14346) 	SET_FTM(unknown_triggers_num, UNKNOWN_TRIGGERS_NUM, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14347) 	SET_FTM(reschedule_requests_num, RESCHEDULE_REQUESTS_NUM, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14348) 	SET_FTM(out_of_window_triggers_num, OUT_OF_WINDOW_TRIGGERS_NUM, u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14349) #undef SET_FTM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14351) 	nla_nest_end(msg, ftm_stats_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14353) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14354) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14356) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14357) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14358) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14361) static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14363) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14364) 	struct cfg80211_update_owe_info owe_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14365) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14367) 	if (!rdev->ops->update_owe_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14368) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14370) 	if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14371) 	    !info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14372) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14374) 	memset(&owe_info, 0, sizeof(owe_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14375) 	owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14376) 	nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14378) 	if (info->attrs[NL80211_ATTR_IE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14379) 		owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14380) 		owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14383) 	return rdev_update_owe_info(rdev, dev, &owe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14386) static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14388) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14389) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14390) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14391) 	struct station_info sinfo = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14392) 	const u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14393) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14394) 	u8 *dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14395) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14397) 	if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14398) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14400) 	if (!info->attrs[NL80211_ATTR_MAC] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14401) 	    !info->attrs[NL80211_ATTR_FRAME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14402) 		GENL_SET_ERR_MSG(info, "Frame or MAC missing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14403) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14404) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14406) 	if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14407) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14409) 	dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14410) 	buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14411) 	len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14413) 	if (len < sizeof(struct ethhdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14414) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14416) 	if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14417) 	    !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14418) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14420) 	err = rdev_get_station(rdev, dev, dest, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14421) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14422) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14424) 	cfg80211_sinfo_release_content(&sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14426) 	return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14429) static int parse_tid_conf(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14430) 			  struct nlattr *attrs[], struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14431) 			  struct cfg80211_tid_cfg *tid_conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14432) 			  struct genl_info *info, const u8 *peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14434) 	struct netlink_ext_ack *extack = info->extack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14435) 	u64 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14436) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14438) 	if (!attrs[NL80211_TID_CONFIG_ATTR_TIDS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14439) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14441) 	tid_conf->config_override =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14442) 			nla_get_flag(attrs[NL80211_TID_CONFIG_ATTR_OVERRIDE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14443) 	tid_conf->tids = nla_get_u16(attrs[NL80211_TID_CONFIG_ATTR_TIDS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14445) 	if (tid_conf->config_override) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14446) 		if (rdev->ops->reset_tid_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14447) 			err = rdev_reset_tid_config(rdev, dev, peer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14448) 						    tid_conf->tids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14449) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14450) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14451) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14452) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14453) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14456) 	if (attrs[NL80211_TID_CONFIG_ATTR_NOACK]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14457) 		tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_NOACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14458) 		tid_conf->noack =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14459) 			nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_NOACK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14462) 	if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14463) 		tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14464) 		tid_conf->retry_short =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14465) 			nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14467) 		if (tid_conf->retry_short > rdev->wiphy.max_data_retry_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14468) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14469) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14471) 	if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14472) 		tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14473) 		tid_conf->retry_long =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14474) 			nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14476) 		if (tid_conf->retry_long > rdev->wiphy.max_data_retry_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14477) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14478) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14480) 	if (attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14481) 		tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14482) 		tid_conf->ampdu =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14483) 			nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14484) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14486) 	if (attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14487) 		tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14488) 		tid_conf->rtscts =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14489) 			nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14490) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14492) 	if (attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14493) 		tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14494) 		tid_conf->amsdu =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14495) 			nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14496) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14498) 	if (attrs[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14499) 		u32 idx = NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE, attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14501) 		tid_conf->txrate_type = nla_get_u8(attrs[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14503) 		if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14504) 			attr = NL80211_TID_CONFIG_ATTR_TX_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14505) 			err = nl80211_parse_tx_bitrate_mask(info, attrs, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14506) 						    &tid_conf->txrate_mask, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14507) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14508) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14510) 			tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14511) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14512) 		tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14515) 	if (peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14516) 		mask = rdev->wiphy.tid_config_support.peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14517) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14518) 		mask = rdev->wiphy.tid_config_support.vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14520) 	if (tid_conf->mask & ~mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14521) 		NL_SET_ERR_MSG(extack, "unsupported TID configuration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14522) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14523) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14525) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14528) static int nl80211_set_tid_config(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14529) 				  struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14531) 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14532) 	struct nlattr *attrs[NL80211_TID_CONFIG_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14533) 	struct net_device *dev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14534) 	struct cfg80211_tid_config *tid_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14535) 	struct nlattr *tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14536) 	int conf_idx = 0, rem_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14537) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14538) 	u32 num_conf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14540) 	if (!info->attrs[NL80211_ATTR_TID_CONFIG])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14541) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14543) 	if (!rdev->ops->set_tid_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14544) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14546) 	nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14547) 			    rem_conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14548) 		num_conf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14550) 	tid_config = kzalloc(struct_size(tid_config, tid_conf, num_conf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14551) 			     GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14552) 	if (!tid_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14553) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14555) 	tid_config->n_tid_conf = num_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14557) 	if (info->attrs[NL80211_ATTR_MAC])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14558) 		tid_config->peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14560) 	nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14561) 			    rem_conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14562) 		ret = nla_parse_nested(attrs, NL80211_TID_CONFIG_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14563) 				       tid, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14565) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14566) 			goto bad_tid_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14568) 		ret = parse_tid_conf(rdev, attrs, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14569) 				     &tid_config->tid_conf[conf_idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14570) 				     info, tid_config->peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14571) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14572) 			goto bad_tid_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14574) 		conf_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14577) 	ret = rdev_set_tid_config(rdev, dev, tid_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14579) bad_tid_conf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14580) 	kfree(tid_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14581) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14584) #define NL80211_FLAG_NEED_WIPHY		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14585) #define NL80211_FLAG_NEED_NETDEV	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14586) #define NL80211_FLAG_NEED_RTNL		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14587) #define NL80211_FLAG_CHECK_NETDEV_UP	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14588) #define NL80211_FLAG_NEED_NETDEV_UP	(NL80211_FLAG_NEED_NETDEV |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14589) 					 NL80211_FLAG_CHECK_NETDEV_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14590) #define NL80211_FLAG_NEED_WDEV		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14591) /* If a netdev is associated, it must be UP, P2P must be started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14592) #define NL80211_FLAG_NEED_WDEV_UP	(NL80211_FLAG_NEED_WDEV |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14593) 					 NL80211_FLAG_CHECK_NETDEV_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14594) #define NL80211_FLAG_CLEAR_SKB		0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14596) static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14597) 			    struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14599) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14600) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14601) 	struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14602) 	bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14604) 	if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14605) 		rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14607) 	if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14608) 		rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14609) 		if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14610) 			if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14611) 				rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14612) 			return PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14613) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14614) 		info->user_ptr[0] = rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14615) 	} else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14616) 		   ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14617) 		ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14619) 		wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14620) 						  info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14621) 		if (IS_ERR(wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14622) 			if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14623) 				rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14624) 			return PTR_ERR(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14625) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14627) 		dev = wdev->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14628) 		rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14630) 		if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14631) 			if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14632) 				if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14633) 					rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14634) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14635) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14637) 			info->user_ptr[1] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14638) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14639) 			info->user_ptr[1] = wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14640) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14642) 		if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14643) 		    !wdev_running(wdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14644) 			if (rtnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14645) 				rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14646) 			return -ENETDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14647) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14649) 		if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14650) 			dev_hold(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14652) 		info->user_ptr[0] = rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14655) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14658) static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14659) 			      struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14661) 	if (info->user_ptr[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14662) 		if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14663) 			struct wireless_dev *wdev = info->user_ptr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14665) 			if (wdev->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14666) 				dev_put(wdev->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14667) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14668) 			dev_put(info->user_ptr[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14669) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14672) 	if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14673) 		rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14675) 	/* If needed, clear the netlink message payload from the SKB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14676) 	 * as it might contain key data that shouldn't stick around on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14677) 	 * the heap after the SKB is freed. The netlink message header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14678) 	 * is still needed for further processing, so leave it intact.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14679) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14680) 	if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14681) 		struct nlmsghdr *nlh = nlmsg_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14683) 		memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14684) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14687) static const struct genl_ops nl80211_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14688) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14689) 		.cmd = NL80211_CMD_GET_WIPHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14690) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14691) 		.doit = nl80211_get_wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14692) 		.dumpit = nl80211_dump_wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14693) 		.done = nl80211_dump_wiphy_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14694) 		/* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14695) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14696) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14697) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14698) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14700) static const struct genl_small_ops nl80211_small_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14701) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14702) 		.cmd = NL80211_CMD_SET_WIPHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14703) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14704) 		.doit = nl80211_set_wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14705) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14706) 		.internal_flags = NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14707) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14708) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14709) 		.cmd = NL80211_CMD_GET_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14710) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14711) 		.doit = nl80211_get_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14712) 		.dumpit = nl80211_dump_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14713) 		/* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14714) 		.internal_flags = NL80211_FLAG_NEED_WDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14715) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14716) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14717) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14718) 		.cmd = NL80211_CMD_SET_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14719) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14720) 		.doit = nl80211_set_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14721) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14722) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14723) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14724) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14725) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14726) 		.cmd = NL80211_CMD_NEW_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14727) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14728) 		.doit = nl80211_new_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14729) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14730) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14731) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14732) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14733) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14734) 		.cmd = NL80211_CMD_DEL_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14735) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14736) 		.doit = nl80211_del_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14737) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14738) 		.internal_flags = NL80211_FLAG_NEED_WDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14739) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14740) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14741) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14742) 		.cmd = NL80211_CMD_GET_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14743) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14744) 		.doit = nl80211_get_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14745) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14746) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14747) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14748) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14749) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14750) 		.cmd = NL80211_CMD_SET_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14751) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14752) 		.doit = nl80211_set_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14753) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14754) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14755) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14756) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14757) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14758) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14759) 		.cmd = NL80211_CMD_NEW_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14760) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14761) 		.doit = nl80211_new_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14762) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14763) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14764) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14765) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14766) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14767) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14768) 		.cmd = NL80211_CMD_DEL_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14769) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14770) 		.doit = nl80211_del_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14771) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14772) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14773) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14774) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14775) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14776) 		.cmd = NL80211_CMD_SET_BEACON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14777) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14778) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14779) 		.doit = nl80211_set_beacon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14780) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14781) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14782) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14783) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14784) 		.cmd = NL80211_CMD_START_AP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14785) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14786) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14787) 		.doit = nl80211_start_ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14788) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14789) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14790) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14791) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14792) 		.cmd = NL80211_CMD_STOP_AP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14793) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14794) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14795) 		.doit = nl80211_stop_ap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14796) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14797) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14798) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14799) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14800) 		.cmd = NL80211_CMD_GET_STATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14801) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14802) 		.doit = nl80211_get_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14803) 		.dumpit = nl80211_dump_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14804) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14805) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14806) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14807) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14808) 		.cmd = NL80211_CMD_SET_STATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14809) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14810) 		.doit = nl80211_set_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14811) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14812) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14813) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14814) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14815) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14816) 		.cmd = NL80211_CMD_NEW_STATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14817) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14818) 		.doit = nl80211_new_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14819) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14820) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14821) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14822) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14823) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14824) 		.cmd = NL80211_CMD_DEL_STATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14825) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14826) 		.doit = nl80211_del_station,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14827) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14828) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14829) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14830) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14831) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14832) 		.cmd = NL80211_CMD_GET_MPATH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14833) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14834) 		.doit = nl80211_get_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14835) 		.dumpit = nl80211_dump_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14836) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14837) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14838) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14839) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14840) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14841) 		.cmd = NL80211_CMD_GET_MPP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14842) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14843) 		.doit = nl80211_get_mpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14844) 		.dumpit = nl80211_dump_mpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14845) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14846) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14847) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14848) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14849) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14850) 		.cmd = NL80211_CMD_SET_MPATH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14851) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14852) 		.doit = nl80211_set_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14853) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14854) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14855) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14856) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14857) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14858) 		.cmd = NL80211_CMD_NEW_MPATH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14859) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14860) 		.doit = nl80211_new_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14861) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14862) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14863) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14864) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14865) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14866) 		.cmd = NL80211_CMD_DEL_MPATH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14867) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14868) 		.doit = nl80211_del_mpath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14869) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14870) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14871) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14872) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14873) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14874) 		.cmd = NL80211_CMD_SET_BSS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14875) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14876) 		.doit = nl80211_set_bss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14877) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14878) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14879) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14880) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14881) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14882) 		.cmd = NL80211_CMD_GET_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14883) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14884) 		.doit = nl80211_get_reg_do,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14885) 		.dumpit = nl80211_get_reg_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14886) 		.internal_flags = NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14887) 		/* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14888) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14889) #ifdef CONFIG_CFG80211_CRDA_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14890) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14891) 		.cmd = NL80211_CMD_SET_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14892) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14893) 		.doit = nl80211_set_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14894) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14895) 		.internal_flags = NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14896) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14897) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14898) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14899) 		.cmd = NL80211_CMD_REQ_SET_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14900) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14901) 		.doit = nl80211_req_set_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14902) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14903) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14904) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14905) 		.cmd = NL80211_CMD_RELOAD_REGDB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14906) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14907) 		.doit = nl80211_reload_regdb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14908) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14909) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14910) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14911) 		.cmd = NL80211_CMD_GET_MESH_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14912) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14913) 		.doit = nl80211_get_mesh_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14914) 		/* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14915) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14916) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14917) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14918) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14919) 		.cmd = NL80211_CMD_SET_MESH_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14920) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14921) 		.doit = nl80211_update_mesh_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14922) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14923) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14924) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14925) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14926) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14927) 		.cmd = NL80211_CMD_TRIGGER_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14928) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14929) 		.doit = nl80211_trigger_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14930) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14931) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14932) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14933) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14934) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14935) 		.cmd = NL80211_CMD_ABORT_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14936) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14937) 		.doit = nl80211_abort_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14938) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14939) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14940) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14941) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14942) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14943) 		.cmd = NL80211_CMD_GET_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14944) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14945) 		.dumpit = nl80211_dump_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14946) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14947) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14948) 		.cmd = NL80211_CMD_START_SCHED_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14949) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14950) 		.doit = nl80211_start_sched_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14951) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14952) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14953) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14954) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14955) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14956) 		.cmd = NL80211_CMD_STOP_SCHED_SCAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14957) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14958) 		.doit = nl80211_stop_sched_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14959) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14960) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14961) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14962) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14963) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14964) 		.cmd = NL80211_CMD_AUTHENTICATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14965) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14966) 		.doit = nl80211_authenticate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14967) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14968) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14969) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14970) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14971) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14972) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14973) 		.cmd = NL80211_CMD_ASSOCIATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14974) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14975) 		.doit = nl80211_associate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14976) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14977) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14978) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14979) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14980) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14981) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14982) 		.cmd = NL80211_CMD_DEAUTHENTICATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14983) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14984) 		.doit = nl80211_deauthenticate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14985) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14986) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14987) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14988) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14989) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14990) 		.cmd = NL80211_CMD_DISASSOCIATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14991) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14992) 		.doit = nl80211_disassociate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14993) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14994) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14995) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14996) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14997) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14998) 		.cmd = NL80211_CMD_JOIN_IBSS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14999) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15000) 		.doit = nl80211_join_ibss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15001) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15002) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15003) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15004) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15005) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15006) 		.cmd = NL80211_CMD_LEAVE_IBSS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15007) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15008) 		.doit = nl80211_leave_ibss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15009) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15010) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15011) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15012) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15013) #ifdef CONFIG_NL80211_TESTMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15014) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15015) 		.cmd = NL80211_CMD_TESTMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15016) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15017) 		.doit = nl80211_testmode_do,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15018) 		.dumpit = nl80211_testmode_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15019) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15020) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15021) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15022) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15023) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15024) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15025) 		.cmd = NL80211_CMD_CONNECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15026) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15027) 		.doit = nl80211_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15028) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15029) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15030) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15031) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15032) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15033) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15034) 		.cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15035) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15036) 		.doit = nl80211_update_connect_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15037) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15038) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15039) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15040) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15041) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15042) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15043) 		.cmd = NL80211_CMD_DISCONNECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15044) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15045) 		.doit = nl80211_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15046) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15047) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15048) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15049) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15050) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15051) 		.cmd = NL80211_CMD_SET_WIPHY_NETNS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15052) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15053) 		.doit = nl80211_wiphy_netns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15054) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15055) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15056) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15057) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15058) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15059) 		.cmd = NL80211_CMD_GET_SURVEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15060) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15061) 		.dumpit = nl80211_dump_survey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15062) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15063) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15064) 		.cmd = NL80211_CMD_SET_PMKSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15065) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15066) 		.doit = nl80211_setdel_pmksa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15067) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15068) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15069) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15070) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15071) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15072) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15073) 		.cmd = NL80211_CMD_DEL_PMKSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15074) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15075) 		.doit = nl80211_setdel_pmksa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15076) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15077) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15078) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15079) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15080) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15081) 		.cmd = NL80211_CMD_FLUSH_PMKSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15082) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15083) 		.doit = nl80211_flush_pmksa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15084) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15085) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15086) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15087) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15088) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15089) 		.cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15090) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15091) 		.doit = nl80211_remain_on_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15092) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15093) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15094) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15095) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15096) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15097) 		.cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15098) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15099) 		.doit = nl80211_cancel_remain_on_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15100) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15101) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15102) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15103) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15104) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15105) 		.cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15106) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15107) 		.doit = nl80211_set_tx_bitrate_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15108) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15109) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15110) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15111) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15112) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15113) 		.cmd = NL80211_CMD_REGISTER_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15114) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15115) 		.doit = nl80211_register_mgmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15116) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15117) 		.internal_flags = NL80211_FLAG_NEED_WDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15118) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15119) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15120) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15121) 		.cmd = NL80211_CMD_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15122) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15123) 		.doit = nl80211_tx_mgmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15124) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15125) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15126) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15127) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15128) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15129) 		.cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15130) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15131) 		.doit = nl80211_tx_mgmt_cancel_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15132) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15133) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15134) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15135) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15136) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15137) 		.cmd = NL80211_CMD_SET_POWER_SAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15138) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15139) 		.doit = nl80211_set_power_save,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15140) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15141) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15142) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15143) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15144) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15145) 		.cmd = NL80211_CMD_GET_POWER_SAVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15146) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15147) 		.doit = nl80211_get_power_save,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15148) 		/* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15149) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15150) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15151) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15152) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15153) 		.cmd = NL80211_CMD_SET_CQM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15154) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15155) 		.doit = nl80211_set_cqm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15156) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15157) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15158) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15159) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15160) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15161) 		.cmd = NL80211_CMD_SET_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15162) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15163) 		.doit = nl80211_set_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15164) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15165) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15166) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15167) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15168) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15169) 		.cmd = NL80211_CMD_SET_WDS_PEER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15170) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15171) 		.doit = nl80211_set_wds_peer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15172) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15173) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15174) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15175) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15176) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15177) 		.cmd = NL80211_CMD_JOIN_MESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15178) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15179) 		.doit = nl80211_join_mesh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15180) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15181) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15182) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15183) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15184) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15185) 		.cmd = NL80211_CMD_LEAVE_MESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15186) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15187) 		.doit = nl80211_leave_mesh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15188) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15189) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15190) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15191) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15192) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15193) 		.cmd = NL80211_CMD_JOIN_OCB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15194) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15195) 		.doit = nl80211_join_ocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15196) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15197) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15198) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15199) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15200) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15201) 		.cmd = NL80211_CMD_LEAVE_OCB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15202) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15203) 		.doit = nl80211_leave_ocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15204) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15205) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15206) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15207) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15208) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15209) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15210) 		.cmd = NL80211_CMD_GET_WOWLAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15211) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15212) 		.doit = nl80211_get_wowlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15213) 		/* can be retrieved by unprivileged users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15214) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15215) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15216) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15217) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15218) 		.cmd = NL80211_CMD_SET_WOWLAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15219) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15220) 		.doit = nl80211_set_wowlan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15221) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15222) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15223) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15224) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15226) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15227) 		.cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15228) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15229) 		.doit = nl80211_set_rekey_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15230) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15231) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15232) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15233) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15234) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15235) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15236) 		.cmd = NL80211_CMD_TDLS_MGMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15237) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15238) 		.doit = nl80211_tdls_mgmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15239) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15240) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15241) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15242) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15243) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15244) 		.cmd = NL80211_CMD_TDLS_OPER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15245) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15246) 		.doit = nl80211_tdls_oper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15247) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15248) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15249) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15250) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15251) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15252) 		.cmd = NL80211_CMD_UNEXPECTED_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15253) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15254) 		.doit = nl80211_register_unexpected_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15255) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15256) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15257) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15258) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15259) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15260) 		.cmd = NL80211_CMD_PROBE_CLIENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15261) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15262) 		.doit = nl80211_probe_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15263) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15264) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15265) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15266) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15267) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15268) 		.cmd = NL80211_CMD_REGISTER_BEACONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15269) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15270) 		.doit = nl80211_register_beacons,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15271) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15272) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15273) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15274) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15275) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15276) 		.cmd = NL80211_CMD_SET_NOACK_MAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15277) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15278) 		.doit = nl80211_set_noack_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15279) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15280) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15281) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15282) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15283) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15284) 		.cmd = NL80211_CMD_START_P2P_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15285) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15286) 		.doit = nl80211_start_p2p_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15287) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15288) 		.internal_flags = NL80211_FLAG_NEED_WDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15289) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15290) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15291) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15292) 		.cmd = NL80211_CMD_STOP_P2P_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15293) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15294) 		.doit = nl80211_stop_p2p_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15295) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15296) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15297) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15298) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15299) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15300) 		.cmd = NL80211_CMD_START_NAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15301) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15302) 		.doit = nl80211_start_nan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15303) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15304) 		.internal_flags = NL80211_FLAG_NEED_WDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15305) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15306) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15307) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15308) 		.cmd = NL80211_CMD_STOP_NAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15309) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15310) 		.doit = nl80211_stop_nan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15311) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15312) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15313) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15314) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15315) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15316) 		.cmd = NL80211_CMD_ADD_NAN_FUNCTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15317) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15318) 		.doit = nl80211_nan_add_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15319) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15320) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15321) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15322) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15323) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15324) 		.cmd = NL80211_CMD_DEL_NAN_FUNCTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15325) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15326) 		.doit = nl80211_nan_del_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15327) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15328) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15329) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15330) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15331) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15332) 		.cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15333) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15334) 		.doit = nl80211_nan_change_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15335) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15336) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15337) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15338) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15339) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15340) 		.cmd = NL80211_CMD_SET_MCAST_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15341) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15342) 		.doit = nl80211_set_mcast_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15343) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15344) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15345) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15346) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15347) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15348) 		.cmd = NL80211_CMD_SET_MAC_ACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15349) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15350) 		.doit = nl80211_set_mac_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15351) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15352) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15353) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15354) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15355) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15356) 		.cmd = NL80211_CMD_RADAR_DETECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15357) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15358) 		.doit = nl80211_start_radar_detection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15359) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15360) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15361) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15362) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15363) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15364) 		.cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15365) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15366) 		.doit = nl80211_get_protocol_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15367) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15368) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15369) 		.cmd = NL80211_CMD_UPDATE_FT_IES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15370) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15371) 		.doit = nl80211_update_ft_ies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15372) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15373) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15374) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15375) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15376) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15377) 		.cmd = NL80211_CMD_CRIT_PROTOCOL_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15378) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15379) 		.doit = nl80211_crit_protocol_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15380) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15381) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15382) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15383) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15384) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15385) 		.cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15386) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15387) 		.doit = nl80211_crit_protocol_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15388) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15389) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15390) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15391) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15392) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15393) 		.cmd = NL80211_CMD_GET_COALESCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15394) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15395) 		.doit = nl80211_get_coalesce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15396) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15397) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15398) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15399) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15400) 		.cmd = NL80211_CMD_SET_COALESCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15401) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15402) 		.doit = nl80211_set_coalesce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15403) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15404) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15405) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15406) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15407) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15408) 		.cmd = NL80211_CMD_CHANNEL_SWITCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15409) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15410) 		.doit = nl80211_channel_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15411) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15412) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15413) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15414) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15415) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15416) 		.cmd = NL80211_CMD_VENDOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15417) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15418) 		.doit = nl80211_vendor_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15419) 		.dumpit = nl80211_vendor_cmd_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15420) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15421) 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15422) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15423) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15424) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15425) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15426) 		.cmd = NL80211_CMD_SET_QOS_MAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15427) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15428) 		.doit = nl80211_set_qos_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15429) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15430) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15431) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15432) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15433) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15434) 		.cmd = NL80211_CMD_ADD_TX_TS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15435) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15436) 		.doit = nl80211_add_tx_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15437) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15438) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15439) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15440) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15441) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15442) 		.cmd = NL80211_CMD_DEL_TX_TS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15443) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15444) 		.doit = nl80211_del_tx_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15445) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15446) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15447) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15448) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15449) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15450) 		.cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15451) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15452) 		.doit = nl80211_tdls_channel_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15453) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15454) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15455) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15456) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15457) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15458) 		.cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15459) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15460) 		.doit = nl80211_tdls_cancel_channel_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15461) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15462) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15463) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15464) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15465) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15466) 		.cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15467) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15468) 		.doit = nl80211_set_multicast_to_unicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15469) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15470) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15471) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15472) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15473) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15474) 		.cmd = NL80211_CMD_SET_PMK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15475) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15476) 		.doit = nl80211_set_pmk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15477) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15478) 				  NL80211_FLAG_NEED_RTNL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15479) 				  NL80211_FLAG_CLEAR_SKB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15480) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15481) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15482) 		.cmd = NL80211_CMD_DEL_PMK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15483) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15484) 		.doit = nl80211_del_pmk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15485) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15486) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15487) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15488) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15489) 		.cmd = NL80211_CMD_EXTERNAL_AUTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15490) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15491) 		.doit = nl80211_external_auth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15492) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15493) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15494) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15495) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15496) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15497) 		.cmd = NL80211_CMD_CONTROL_PORT_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15498) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15499) 		.doit = nl80211_tx_control_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15500) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15501) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15502) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15503) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15504) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15505) 		.cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15506) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15507) 		.doit = nl80211_get_ftm_responder_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15508) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15509) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15510) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15511) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15512) 		.cmd = NL80211_CMD_PEER_MEASUREMENT_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15513) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15514) 		.doit = nl80211_pmsr_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15515) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15516) 		.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15517) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15518) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15519) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15520) 		.cmd = NL80211_CMD_NOTIFY_RADAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15521) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15522) 		.doit = nl80211_notify_radar_detection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15523) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15524) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15525) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15526) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15527) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15528) 		.cmd = NL80211_CMD_UPDATE_OWE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15529) 		.doit = nl80211_update_owe_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15530) 		.flags = GENL_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15531) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15532) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15533) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15534) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15535) 		.cmd = NL80211_CMD_PROBE_MESH_LINK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15536) 		.doit = nl80211_probe_mesh_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15537) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15538) 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15539) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15540) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15541) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15542) 		.cmd = NL80211_CMD_SET_TID_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15543) 		.doit = nl80211_set_tid_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15544) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15545) 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15546) 				  NL80211_FLAG_NEED_RTNL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15547) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15548) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15550) static struct genl_family nl80211_fam __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15551) 	.name = NL80211_GENL_NAME,	/* have users key off the name instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15552) 	.hdrsize = 0,			/* no private header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15553) 	.version = 1,			/* no particular meaning now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15554) 	.maxattr = NL80211_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15555) 	.policy = nl80211_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15556) 	.netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15557) 	.pre_doit = nl80211_pre_doit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15558) 	.post_doit = nl80211_post_doit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15559) 	.module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15560) 	.ops = nl80211_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15561) 	.n_ops = ARRAY_SIZE(nl80211_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15562) 	.small_ops = nl80211_small_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15563) 	.n_small_ops = ARRAY_SIZE(nl80211_small_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15564) 	.mcgrps = nl80211_mcgrps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15565) 	.n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15566) 	.parallel_ops = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15567) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15569) /* notification functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15571) void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15572) 			  enum nl80211_commands cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15574) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15575) 	struct nl80211_dump_wiphy_state state = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15577) 	WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15578) 		cmd != NL80211_CMD_DEL_WIPHY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15580) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15581) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15582) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15584) 	if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15585) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15586) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15587) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15589) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15590) 				NL80211_MCGRP_CONFIG, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15593) void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15594) 				struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15595) 				enum nl80211_commands cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15597) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15599) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15600) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15601) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15603) 	if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, cmd) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15604) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15605) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15606) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15608) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15609) 				NL80211_MCGRP_CONFIG, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15612) static int nl80211_add_scan_req(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15613) 				struct cfg80211_registered_device *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15615) 	struct cfg80211_scan_request *req = rdev->scan_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15616) 	struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15617) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15618) 	struct cfg80211_scan_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15620) 	if (WARN_ON(!req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15621) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15623) 	nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_SSIDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15624) 	if (!nest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15625) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15626) 	for (i = 0; i < req->n_ssids; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15627) 		if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15628) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15630) 	nla_nest_end(msg, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15632) 	if (req->flags & NL80211_SCAN_FLAG_FREQ_KHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15633) 		nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQ_KHZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15634) 		if (!nest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15635) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15636) 		for (i = 0; i < req->n_channels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15637) 			if (nla_put_u32(msg, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15638) 				   ieee80211_channel_to_khz(req->channels[i])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15639) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15640) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15641) 		nla_nest_end(msg, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15642) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15643) 		nest = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15644) 					     NL80211_ATTR_SCAN_FREQUENCIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15645) 		if (!nest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15646) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15647) 		for (i = 0; i < req->n_channels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15648) 			if (nla_put_u32(msg, i, req->channels[i]->center_freq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15649) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15650) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15651) 		nla_nest_end(msg, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15652) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15654) 	if (req->ie &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15655) 	    nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15656) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15658) 	if (req->flags &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15659) 	    nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15660) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15662) 	info = rdev->int_scan_req ? &rdev->int_scan_req->info :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15663) 		&rdev->scan_req->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15664) 	if (info->scan_start_tsf &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15665) 	    (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15666) 			       info->scan_start_tsf, NL80211_BSS_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15667) 	     nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15668) 		     info->tsf_bssid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15669) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15671) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15672)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15673) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15676) static int nl80211_prep_scan_msg(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15677) 				 struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15678) 				 struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15679) 				 u32 portid, u32 seq, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15680) 				 u32 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15682) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15684) 	hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15685) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15686) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15688) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15689) 	    (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15690) 					 wdev->netdev->ifindex)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15691) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15692) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15693) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15695) 	/* ignore errors and send incomplete event anyway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15696) 	nl80211_add_scan_req(msg, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15698) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15699) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15701)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15702) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15703) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15706) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15707) nl80211_prep_sched_scan_msg(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15708) 			    struct cfg80211_sched_scan_request *req, u32 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15710) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15712) 	hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15713) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15714) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15716) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15717) 			wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15718) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15719) 	    nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15720) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15721) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15723) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15724) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15726)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15727) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15728) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15731) void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15732) 			     struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15734) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15736) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15737) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15738) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15740) 	if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15741) 				  NL80211_CMD_TRIGGER_SCAN) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15742) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15743) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15744) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15746) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15747) 				NL80211_MCGRP_SCAN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15750) struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15751) 				       struct wireless_dev *wdev, bool aborted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15753) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15755) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15756) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15757) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15759) 	if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15760) 				  aborted ? NL80211_CMD_SCAN_ABORTED :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15761) 					    NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15762) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15763) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15766) 	return msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15769) /* send message created by nl80211_build_scan_msg() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15770) void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15771) 			   struct sk_buff *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15773) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15774) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15776) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15777) 				NL80211_MCGRP_SCAN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15780) void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15782) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15784) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15785) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15786) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15788) 	if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15789) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15790) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15791) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15793) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15794) 				NL80211_MCGRP_SCAN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15797) static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15798) 					  struct regulatory_request *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15800) 	/* Userspace can always count this one always being set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15801) 	if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15802) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15804) 	if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15805) 		if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15806) 			       NL80211_REGDOM_TYPE_WORLD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15807) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15808) 	} else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15809) 		if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15810) 			       NL80211_REGDOM_TYPE_CUSTOM_WORLD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15811) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15812) 	} else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15813) 		   request->intersect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15814) 		if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15815) 			       NL80211_REGDOM_TYPE_INTERSECTION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15816) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15817) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15818) 		if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15819) 			       NL80211_REGDOM_TYPE_COUNTRY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15820) 		    nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15821) 				   request->alpha2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15822) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15823) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15825) 	if (request->wiphy_idx != WIPHY_IDX_INVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15826) 		struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15828) 		if (wiphy &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15829) 		    nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15830) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15832) 		if (wiphy &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15833) 		    wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15834) 		    nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15835) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15836) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15838) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15840) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15841) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15844) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15845)  * This can happen on global regulatory changes or device specific settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15846)  * based on custom regulatory domains.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15847)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15848) void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15849) 				     struct regulatory_request *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15851) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15852) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15854) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15855) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15856) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15858) 	hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15859) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15860) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15862) 	if (!nl80211_reg_change_event_fill(msg, request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15863) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15865) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15867) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15868) 	genlmsg_multicast_allns(&nl80211_fam, msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15869) 				NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15870) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15872) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15874) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15875) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15878) static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15879) 				    struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15880) 				    const u8 *buf, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15881) 				    enum nl80211_commands cmd, gfp_t gfp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15882) 				    int uapsd_queues, const u8 *req_ies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15883) 				    size_t req_ies_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15885) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15886) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15888) 	msg = nlmsg_new(100 + len + req_ies_len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15889) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15890) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15892) 	hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15893) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15894) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15895) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15898) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15899) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15900) 	    nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15901) 	    (req_ies &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15902) 	     nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15903) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15905) 	if (uapsd_queues >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15906) 		struct nlattr *nla_wmm =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15907) 			nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15908) 		if (!nla_wmm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15909) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15911) 		if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15912) 			       uapsd_queues))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15913) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15915) 		nla_nest_end(msg, nla_wmm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15918) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15920) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15921) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15922) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15924)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15925) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15928) void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15929) 			  struct net_device *netdev, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15930) 			  size_t len, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15932) 	nl80211_send_mlme_event(rdev, netdev, buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15933) 				NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15936) void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15937) 			   struct net_device *netdev, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15938) 			   size_t len, gfp_t gfp, int uapsd_queues,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15939) 			   const u8 *req_ies, size_t req_ies_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15941) 	nl80211_send_mlme_event(rdev, netdev, buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15942) 				NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15943) 				req_ies, req_ies_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15946) void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15947) 			 struct net_device *netdev, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15948) 			 size_t len, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15950) 	nl80211_send_mlme_event(rdev, netdev, buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15951) 				NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15954) void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15955) 			   struct net_device *netdev, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15956) 			   size_t len, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15958) 	nl80211_send_mlme_event(rdev, netdev, buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15959) 				NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15962) void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15963) 				  size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15965) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15966) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15967) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15968) 	const struct ieee80211_mgmt *mgmt = (void *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15969) 	u32 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15971) 	if (WARN_ON(len < 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15972) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15974) 	if (ieee80211_is_deauth(mgmt->frame_control)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15975) 		cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15976) 	} else if (ieee80211_is_disassoc(mgmt->frame_control)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15977) 		cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15978) 	} else if (ieee80211_is_beacon(mgmt->frame_control)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15979) 		if (wdev->unprot_beacon_reported &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15980) 		    elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15981) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15982) 		cmd = NL80211_CMD_UNPROT_BEACON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15983) 		wdev->unprot_beacon_reported = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15984) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15985) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15986) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15988) 	trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15989) 	nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15990) 				NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15992) EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15994) static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15995) 				      struct net_device *netdev, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15996) 				      const u8 *addr, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15998) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15999) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16001) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16002) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16003) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16005) 	hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16006) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16007) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16008) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16009) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16011) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16012) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16013) 	    nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16014) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16015) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16017) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16019) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16020) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16021) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16023)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16024) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16027) void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16028) 			       struct net_device *netdev, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16029) 			       gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16031) 	nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16032) 				  addr, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16035) void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16036) 				struct net_device *netdev, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16037) 				gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16039) 	nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16040) 				  addr, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16043) void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16044) 				 struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16045) 				 struct cfg80211_connect_resp_params *cr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16046) 				 gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16048) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16049) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16051) 	msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16052) 			cr->fils.kek_len + cr->fils.pmk_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16053) 			(cr->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16054) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16055) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16057) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16058) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16059) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16060) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16061) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16063) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16064) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16065) 	    (cr->bssid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16066) 	     nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16067) 	    nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16068) 			cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16069) 			cr->status) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16070) 	    (cr->status < 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16071) 	     (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16072) 	      nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16073) 			  cr->timeout_reason))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16074) 	    (cr->req_ie &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16075) 	     nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16076) 	    (cr->resp_ie &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16077) 	     nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16078) 		     cr->resp_ie)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16079) 	    (cr->fils.update_erp_next_seq_num &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16080) 	     nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16081) 			 cr->fils.erp_next_seq_num)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16082) 	    (cr->status == WLAN_STATUS_SUCCESS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16083) 	     ((cr->fils.kek &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16084) 	       nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils.kek_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16085) 		       cr->fils.kek)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16086) 	      (cr->fils.pmk &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16087) 	       nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16088) 	      (cr->fils.pmkid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16089) 	       nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16090) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16092) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16094) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16095) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16096) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16098)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16099) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16102) void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16103) 			 struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16104) 			 struct cfg80211_roam_info *info, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16106) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16107) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16108) 	const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16110) 	msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16111) 			info->fils.kek_len + info->fils.pmk_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16112) 			(info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16113) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16114) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16116) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16117) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16118) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16119) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16122) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16123) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16124) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16125) 	    (info->req_ie &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16126) 	     nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16127) 		     info->req_ie)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16128) 	    (info->resp_ie &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16129) 	     nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16130) 		     info->resp_ie)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16131) 	    (info->fils.update_erp_next_seq_num &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16132) 	     nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16133) 			 info->fils.erp_next_seq_num)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16134) 	    (info->fils.kek &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16135) 	     nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16136) 		     info->fils.kek)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16137) 	    (info->fils.pmk &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16138) 	     nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16139) 	    (info->fils.pmkid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16140) 	     nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16141) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16143) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16145) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16146) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16147) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16149)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16150) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16153) void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16154) 				  struct net_device *netdev, const u8 *bssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16156) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16157) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16159) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16160) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16161) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16163) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16164) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16165) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16166) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16169) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16170) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16171) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16172) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16174) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16176) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16177) 				NL80211_MCGRP_MLME, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16178) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16180)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16181) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16184) void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16185) 			       struct net_device *netdev, u16 reason,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16186) 			       const u8 *ie, size_t ie_len, bool from_ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16188) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16189) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16191) 	msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16192) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16193) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16195) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16196) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16197) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16198) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16201) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16202) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16203) 	    (reason &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16204) 	     nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16205) 	    (from_ap &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16206) 	     nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16207) 	    (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16208) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16210) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16212) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16213) 				NL80211_MCGRP_MLME, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16214) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16216)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16217) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16220) void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16221) 			     struct net_device *netdev, const u8 *bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16222) 			     gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16224) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16225) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16227) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16228) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16229) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16231) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16232) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16233) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16234) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16237) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16238) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16239) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16240) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16242) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16244) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16245) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16246) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16248)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16249) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16252) void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16253) 					const u8 *ie, u8 ie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16254) 					int sig_dbm, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16256) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16257) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16258) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16259) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16261) 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16262) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16264) 	trace_cfg80211_notify_new_peer_candidate(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16266) 	msg = nlmsg_new(100 + ie_len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16267) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16268) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16270) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16271) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16272) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16273) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16276) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16277) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16278) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16279) 	    (ie_len && ie &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16280) 	     nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16281) 	    (sig_dbm &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16282) 	     nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16283) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16285) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16287) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16288) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16289) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16291)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16292) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16294) EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16296) void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16297) 				 struct net_device *netdev, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16298) 				 enum nl80211_key_type key_type, int key_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16299) 				 const u8 *tsc, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16301) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16302) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16304) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16305) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16306) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16308) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16309) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16310) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16311) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16314) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16315) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16316) 	    (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16317) 	    nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16318) 	    (key_id != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16319) 	     nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16320) 	    (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16321) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16323) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16325) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16326) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16327) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16329)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16330) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16333) void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16334) 				    struct ieee80211_channel *channel_before,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16335) 				    struct ieee80211_channel *channel_after)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16337) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16338) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16339) 	struct nlattr *nl_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16341) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16342) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16343) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16345) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16346) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16347) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16348) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16351) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16352) 	 * Since we are applying the beacon hint to a wiphy we know its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16353) 	 * wiphy_idx is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16354) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16355) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16356) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16358) 	/* Before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16359) 	nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_BEFORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16360) 	if (!nl_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16361) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16363) 	if (nl80211_msg_put_channel(msg, wiphy, channel_before, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16364) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16365) 	nla_nest_end(msg, nl_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16367) 	/* After */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16368) 	nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_AFTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16369) 	if (!nl_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16370) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16372) 	if (nl80211_msg_put_channel(msg, wiphy, channel_after, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16373) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16374) 	nla_nest_end(msg, nl_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16376) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16378) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16379) 	genlmsg_multicast_allns(&nl80211_fam, msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16380) 				NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16381) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16383) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16385) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16386) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16389) static void nl80211_send_remain_on_chan_event(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16390) 	int cmd, struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16391) 	struct wireless_dev *wdev, u64 cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16392) 	struct ieee80211_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16393) 	unsigned int duration, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16395) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16396) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16398) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16399) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16400) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16402) 	hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16403) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16404) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16405) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16408) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16409) 	    (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16410) 					 wdev->netdev->ifindex)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16411) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16412) 			      NL80211_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16413) 	    nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16414) 	    nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16415) 			NL80211_CHAN_NO_HT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16416) 	    nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16417) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16418) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16420) 	if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16421) 	    nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16422) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16424) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16426) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16427) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16428) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16430)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16431) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16434) void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16435) 			       struct ieee80211_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16436) 			       unsigned int duration, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16438) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16439) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16441) 	trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16442) 	nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16443) 					  rdev, wdev, cookie, chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16444) 					  duration, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16446) EXPORT_SYMBOL(cfg80211_ready_on_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16448) void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16449) 					struct ieee80211_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16450) 					gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16452) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16453) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16455) 	trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16456) 	nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16457) 					  rdev, wdev, cookie, chan, 0, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16459) EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16461) void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16462) 					struct ieee80211_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16463) 					gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16465) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16466) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16468) 	trace_cfg80211_tx_mgmt_expired(wdev, cookie, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16469) 	nl80211_send_remain_on_chan_event(NL80211_CMD_FRAME_WAIT_CANCEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16470) 					  rdev, wdev, cookie, chan, 0, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16472) EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16474) void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16475) 		      struct station_info *sinfo, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16477) 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16478) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16479) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16481) 	trace_cfg80211_new_sta(dev, mac_addr, sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16483) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16484) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16485) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16487) 	if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16488) 				 rdev, dev, mac_addr, sinfo) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16489) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16490) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16493) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16494) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16496) EXPORT_SYMBOL(cfg80211_new_sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16498) void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16499) 			    struct station_info *sinfo, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16501) 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16502) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16503) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16504) 	struct station_info empty_sinfo = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16506) 	if (!sinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16507) 		sinfo = &empty_sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16509) 	trace_cfg80211_del_sta(dev, mac_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16511) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16512) 	if (!msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16513) 		cfg80211_sinfo_release_content(sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16514) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16517) 	if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16518) 				 rdev, dev, mac_addr, sinfo) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16519) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16520) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16521) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16523) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16524) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16526) EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16528) void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16529) 			  enum nl80211_connect_failed_reason reason,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16530) 			  gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16532) 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16533) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16534) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16535) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16537) 	msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16538) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16539) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16541) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16542) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16543) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16544) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16547) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16548) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16549) 	    nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16550) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16552) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16554) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16555) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16556) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16558)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16559) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16561) EXPORT_SYMBOL(cfg80211_conn_failed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16563) static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16564) 				       const u8 *addr, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16566) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16567) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16568) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16569) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16570) 	u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16572) 	if (!nlportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16573) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16575) 	msg = nlmsg_new(100, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16576) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16577) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16579) 	hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16580) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16581) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16582) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16583) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16585) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16586) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16587) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16588) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16590) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16591) 	genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16592) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16594)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16595) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16596) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16599) bool cfg80211_rx_spurious_frame(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16600) 				const u8 *addr, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16602) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16603) 	bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16605) 	trace_cfg80211_rx_spurious_frame(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16607) 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16608) 		    wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16609) 		trace_cfg80211_return_bool(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16610) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16611) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16612) 	ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16613) 					 addr, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16614) 	trace_cfg80211_return_bool(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16615) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16617) EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16619) bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16620) 					const u8 *addr, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16622) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16623) 	bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16625) 	trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16627) 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16628) 		    wdev->iftype != NL80211_IFTYPE_P2P_GO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16629) 		    wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16630) 		trace_cfg80211_return_bool(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16631) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16633) 	ret = __nl80211_unexpected_frame(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16634) 					 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16635) 					 addr, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16636) 	trace_cfg80211_return_bool(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16637) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16639) EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16641) int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16642) 		      struct wireless_dev *wdev, u32 nlportid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16643) 		      int freq, int sig_dbm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16644) 		      const u8 *buf, size_t len, u32 flags, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16646) 	struct net_device *netdev = wdev->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16647) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16648) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16650) 	msg = nlmsg_new(100 + len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16651) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16652) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16654) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16655) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16656) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16657) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16658) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16660) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16661) 	    (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16662) 					netdev->ifindex)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16663) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16664) 			      NL80211_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16665) 	    nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(freq)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16666) 	    nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, freq % 1000) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16667) 	    (sig_dbm &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16668) 	     nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16669) 	    nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16670) 	    (flags &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16671) 	     nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16672) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16674) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16676) 	return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16678)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16679) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16680) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16683) static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16684) 				    const u8 *buf, size_t len, bool ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16685) 				    gfp_t gfp, enum nl80211_commands command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16687) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16688) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16689) 	struct net_device *netdev = wdev->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16690) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16691) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16693) 	if (command == NL80211_CMD_FRAME_TX_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16694) 		trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16695) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16696) 		trace_cfg80211_control_port_tx_status(wdev, cookie, ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16698) 	msg = nlmsg_new(100 + len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16699) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16700) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16702) 	hdr = nl80211hdr_put(msg, 0, 0, 0, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16703) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16704) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16705) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16706) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16708) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16709) 	    (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16710) 				   netdev->ifindex)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16711) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16712) 			      NL80211_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16713) 	    nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16714) 	    nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16715) 			      NL80211_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16716) 	    (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16717) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16719) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16721) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16722) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16723) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16725) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16726) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16729) void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16730) 				     const u8 *buf, size_t len, bool ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16731) 				     gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16733) 	nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16734) 				NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16736) EXPORT_SYMBOL(cfg80211_control_port_tx_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16738) void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16739) 			     const u8 *buf, size_t len, bool ack, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16741) 	nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16742) 				NL80211_CMD_FRAME_TX_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16744) EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16746) static int __nl80211_rx_control_port(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16747) 				     struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16748) 				     bool unencrypted, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16750) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16751) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16752) 	struct ethhdr *ehdr = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16753) 	const u8 *addr = ehdr->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16754) 	u16 proto = be16_to_cpu(skb->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16755) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16756) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16757) 	struct nlattr *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16759) 	u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16761) 	if (!nlportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16762) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16764) 	msg = nlmsg_new(100 + skb->len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16765) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16766) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16768) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16769) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16770) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16771) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16772) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16774) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16775) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16776) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16777) 			      NL80211_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16778) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16779) 	    nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16780) 	    (unencrypted && nla_put_flag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16781) 					 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16782) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16784) 	frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16785) 	if (!frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16786) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16788) 	skb_copy_bits(skb, 0, nla_data(frame), skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16789) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16791) 	return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16793)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16794) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16795) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16798) bool cfg80211_rx_control_port(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16799) 			      struct sk_buff *skb, bool unencrypted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16801) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16803) 	trace_cfg80211_rx_control_port(dev, skb, unencrypted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16804) 	ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16805) 	trace_cfg80211_return_bool(ret == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16806) 	return ret == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16808) EXPORT_SYMBOL(cfg80211_rx_control_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16810) static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16811) 					    const char *mac, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16813) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16814) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16815) 	struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16816) 	void **cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16818) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16819) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16821) 	cb = (void **)msg->cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16823) 	cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16824) 	if (!cb[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16825) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16826) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16829) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16830) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16831) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16833) 	if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16834) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16836) 	cb[1] = nla_nest_start_noflag(msg, NL80211_ATTR_CQM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16837) 	if (!cb[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16838) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16840) 	cb[2] = rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16842) 	return msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16843)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16844) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16845) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16848) static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16850) 	void **cb = (void **)msg->cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16851) 	struct cfg80211_registered_device *rdev = cb[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16853) 	nla_nest_end(msg, cb[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16854) 	genlmsg_end(msg, cb[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16856) 	memset(msg->cb, 0, sizeof(msg->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16858) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16859) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16862) void cfg80211_cqm_rssi_notify(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16863) 			      enum nl80211_cqm_rssi_threshold_event rssi_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16864) 			      s32 rssi_level, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16866) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16867) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16868) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16870) 	trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16872) 	if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16873) 		    rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16874) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16876) 	if (wdev->cqm_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16877) 		wdev->cqm_config->last_rssi_event_value = rssi_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16879) 		cfg80211_cqm_rssi_update(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16881) 		if (rssi_level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16882) 			rssi_level = wdev->cqm_config->last_rssi_event_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16883) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16885) 	msg = cfg80211_prepare_cqm(dev, NULL, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16886) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16887) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16889) 	if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16890) 			rssi_event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16891) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16893) 	if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16894) 				      rssi_level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16895) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16897) 	cfg80211_send_cqm(msg, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16899) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16901)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16902) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16904) EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16906) void cfg80211_cqm_txe_notify(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16907) 			     const u8 *peer, u32 num_packets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16908) 			     u32 rate, u32 intvl, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16910) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16912) 	msg = cfg80211_prepare_cqm(dev, peer, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16913) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16914) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16916) 	if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16917) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16919) 	if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16920) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16922) 	if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16923) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16925) 	cfg80211_send_cqm(msg, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16926) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16928)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16929) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16931) EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16933) void cfg80211_cqm_pktloss_notify(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16934) 				 const u8 *peer, u32 num_packets, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16936) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16938) 	trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16940) 	msg = cfg80211_prepare_cqm(dev, peer, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16941) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16942) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16944) 	if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16945) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16947) 	cfg80211_send_cqm(msg, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16948) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16950)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16951) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16953) EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16955) void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16957) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16959) 	msg = cfg80211_prepare_cqm(dev, NULL, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16960) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16961) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16963) 	if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16964) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16966) 	cfg80211_send_cqm(msg, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16967) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16969)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16970) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16972) EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16974) static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16975) 				     struct net_device *netdev, const u8 *bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16976) 				     const u8 *replay_ctr, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16978) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16979) 	struct nlattr *rekey_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16980) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16982) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16983) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16984) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16986) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16987) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16988) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16989) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16990) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16992) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16993) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16994) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16995) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16997) 	rekey_attr = nla_nest_start_noflag(msg, NL80211_ATTR_REKEY_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16998) 	if (!rekey_attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16999) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17001) 	if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17002) 		    NL80211_REPLAY_CTR_LEN, replay_ctr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17003) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17005) 	nla_nest_end(msg, rekey_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17007) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17009) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17010) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17011) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17013)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17014) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17017) void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17018) 			       const u8 *replay_ctr, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17020) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17021) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17022) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17024) 	trace_cfg80211_gtk_rekey_notify(dev, bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17025) 	nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17027) EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17029) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17030) nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17031) 			       struct net_device *netdev, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17032) 			       const u8 *bssid, bool preauth, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17034) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17035) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17036) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17038) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17039) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17040) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17042) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17043) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17044) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17045) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17046) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17048) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17049) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17050) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17052) 	attr = nla_nest_start_noflag(msg, NL80211_ATTR_PMKSA_CANDIDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17053) 	if (!attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17054) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17056) 	if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17057) 	    nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17058) 	    (preauth &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17059) 	     nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17060) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17062) 	nla_nest_end(msg, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17064) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17066) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17067) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17068) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17070)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17071) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17074) void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17075) 				     const u8 *bssid, bool preauth, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17077) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17078) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17079) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17081) 	trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17082) 	nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17084) EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17086) static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17087) 				     struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17088) 				     struct cfg80211_chan_def *chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17089) 				     gfp_t gfp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17090) 				     enum nl80211_commands notif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17091) 				     u8 count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17093) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17094) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17096) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17097) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17098) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17100) 	hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17101) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17102) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17103) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17104) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17106) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17107) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17109) 	if (nl80211_send_chandef(msg, chandef))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17110) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17112) 	if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17113) 	    (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17114) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17116) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17118) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17119) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17120) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17122)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17123) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17126) void cfg80211_ch_switch_notify(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17127) 			       struct cfg80211_chan_def *chandef)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17129) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17130) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17131) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17133) 	ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17135) 	trace_cfg80211_ch_switch_notify(dev, chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17137) 	wdev->chandef = *chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17138) 	wdev->preset_chandef = *chandef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17140) 	if ((wdev->iftype == NL80211_IFTYPE_STATION ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17141) 	     wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17142) 	    !WARN_ON(!wdev->current_bss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17143) 		cfg80211_update_assoc_bss_entry(wdev, chandef->chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17145) 	cfg80211_sched_dfs_chan_update(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17147) 	nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17148) 				 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17150) EXPORT_SYMBOL(cfg80211_ch_switch_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17152) void cfg80211_ch_switch_started_notify(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17153) 				       struct cfg80211_chan_def *chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17154) 				       u8 count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17156) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17157) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17158) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17160) 	trace_cfg80211_ch_switch_started_notify(dev, chandef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17162) 	nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17163) 				 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17165) EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17167) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17168) nl80211_radar_notify(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17169) 		     const struct cfg80211_chan_def *chandef,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17170) 		     enum nl80211_radar_event event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17171) 		     struct net_device *netdev, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17173) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17174) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17176) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17177) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17178) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17180) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17181) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17182) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17183) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17184) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17186) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17187) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17189) 	/* NOP and radar events don't need a netdev parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17190) 	if (netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17191) 		struct wireless_dev *wdev = netdev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17193) 		if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17194) 		    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17195) 				      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17196) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17199) 	if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17200) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17202) 	if (nl80211_send_chandef(msg, chandef))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17203) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17205) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17207) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17208) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17209) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17211)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17212) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17215) void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17216) 				       struct sta_opmode_info *sta_opmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17217) 				       gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17219) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17220) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17221) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17222) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17224) 	if (WARN_ON(!mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17225) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17227) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17228) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17229) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17231) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17232) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17233) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17234) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17237) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17238) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17240) 	if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17241) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17243) 	if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17244) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17246) 	if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17247) 	    nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17248) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17250) 	if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17251) 	    nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17252) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17254) 	if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17255) 	    nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17256) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17258) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17260) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17261) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17263) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17265) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17266) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17268) EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17270) void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17271) 			   u64 cookie, bool acked, s32 ack_signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17272) 			   bool is_valid_ack_signal, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17274) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17275) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17276) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17277) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17279) 	trace_cfg80211_probe_status(dev, addr, cookie, acked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17281) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17283) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17284) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17286) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17287) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17288) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17289) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17292) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17293) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17294) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17295) 	    nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17296) 			      NL80211_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17297) 	    (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17298) 	    (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17299) 						ack_signal)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17300) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17302) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17304) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17305) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17306) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17308)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17309) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17311) EXPORT_SYMBOL(cfg80211_probe_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17313) void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17314) 				     size_t len, int freq, int sig_dbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17316) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17317) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17318) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17319) 	struct cfg80211_beacon_registration *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17321) 	trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17323) 	spin_lock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17324) 	list_for_each_entry(reg, &rdev->beacon_registrations, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17325) 		msg = nlmsg_new(len + 100, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17326) 		if (!msg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17327) 			spin_unlock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17328) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17329) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17331) 		hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17332) 		if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17333) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17335) 		if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17336) 		    (freq &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17337) 		     (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17338) 				  KHZ_TO_MHZ(freq)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17339) 		      nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17340) 				  freq % 1000))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17341) 		    (sig_dbm &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17342) 		     nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17343) 		    nla_put(msg, NL80211_ATTR_FRAME, len, frame))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17344) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17346) 		genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17348) 		genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17350) 	spin_unlock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17351) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17353)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17354) 	spin_unlock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17355) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17357) EXPORT_SYMBOL(cfg80211_report_obss_beacon_khz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17359) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17360) static int cfg80211_net_detect_results(struct sk_buff *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17361) 				       struct cfg80211_wowlan_wakeup *wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17363) 	struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17364) 	struct nlattr *nl_results, *nl_match, *nl_freqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17365) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17367) 	nl_results = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17368) 					   NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17369) 	if (!nl_results)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17370) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17372) 	for (i = 0; i < nd->n_matches; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17373) 		struct cfg80211_wowlan_nd_match *match = nd->matches[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17375) 		nl_match = nla_nest_start_noflag(msg, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17376) 		if (!nl_match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17377) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17379) 		/* The SSID attribute is optional in nl80211, but for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17380) 		 * simplicity reasons it's always present in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17381) 		 * cfg80211 structure.  If a driver can't pass the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17382) 		 * SSID, that needs to be changed.  A zero length SSID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17383) 		 * is still a valid SSID (wildcard), so it cannot be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17384) 		 * used for this purpose.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17385) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17386) 		if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17387) 			    match->ssid.ssid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17388) 			nla_nest_cancel(msg, nl_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17389) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17390) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17392) 		if (match->n_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17393) 			nl_freqs = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17394) 							 NL80211_ATTR_SCAN_FREQUENCIES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17395) 			if (!nl_freqs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17396) 				nla_nest_cancel(msg, nl_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17397) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17398) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17400) 			for (j = 0; j < match->n_channels; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17401) 				if (nla_put_u32(msg, j, match->channels[j])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17402) 					nla_nest_cancel(msg, nl_freqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17403) 					nla_nest_cancel(msg, nl_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17404) 					goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17405) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17406) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17408) 			nla_nest_end(msg, nl_freqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17409) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17411) 		nla_nest_end(msg, nl_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17414) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17415) 	nla_nest_end(msg, nl_results);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17416) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17419) void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17420) 				   struct cfg80211_wowlan_wakeup *wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17421) 				   gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17423) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17424) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17425) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17426) 	int size = 200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17428) 	trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17430) 	if (wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17431) 		size += wakeup->packet_present_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17433) 	msg = nlmsg_new(size, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17434) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17435) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17437) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17438) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17439) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17441) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17442) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17443) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17444) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17446) 	if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17447) 					wdev->netdev->ifindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17448) 		goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17450) 	if (wakeup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17451) 		struct nlattr *reasons;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17453) 		reasons = nla_nest_start_noflag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17454) 						NL80211_ATTR_WOWLAN_TRIGGERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17455) 		if (!reasons)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17456) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17458) 		if (wakeup->disconnect &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17459) 		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17460) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17461) 		if (wakeup->magic_pkt &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17462) 		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17463) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17464) 		if (wakeup->gtk_rekey_failure &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17465) 		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17466) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17467) 		if (wakeup->eap_identity_req &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17468) 		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17469) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17470) 		if (wakeup->four_way_handshake &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17471) 		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17472) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17473) 		if (wakeup->rfkill_release &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17474) 		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17475) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17477) 		if (wakeup->pattern_idx >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17478) 		    nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17479) 				wakeup->pattern_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17480) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17482) 		if (wakeup->tcp_match &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17483) 		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17484) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17486) 		if (wakeup->tcp_connlost &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17487) 		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17488) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17490) 		if (wakeup->tcp_nomoretokens &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17491) 		    nla_put_flag(msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17492) 				 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17493) 			goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17495) 		if (wakeup->packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17496) 			u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17497) 			u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17499) 			if (!wakeup->packet_80211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17500) 				pkt_attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17501) 					NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17502) 				len_attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17503) 					NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17504) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17506) 			if (wakeup->packet_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17507) 			    nla_put_u32(msg, len_attr, wakeup->packet_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17508) 				goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17510) 			if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17511) 				    wakeup->packet))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17512) 				goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17513) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17515) 		if (wakeup->net_detect &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17516) 		    cfg80211_net_detect_results(msg, wakeup))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17517) 				goto free_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17519) 		nla_nest_end(msg, reasons);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17522) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17524) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17525) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17526) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17528)  free_msg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17529) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17531) EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17532) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17534) void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17535) 				enum nl80211_tdls_operation oper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17536) 				u16 reason_code, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17538) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17539) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17540) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17541) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17543) 	trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17544) 					 reason_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17546) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17547) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17548) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17550) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17551) 	if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17552) 		nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17553) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17556) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17557) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17558) 	    nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17559) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17560) 	    (reason_code > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17561) 	     nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17562) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17564) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17566) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17567) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17568) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17570)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17571) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17573) EXPORT_SYMBOL(cfg80211_tdls_oper_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17575) static int nl80211_netlink_notify(struct notifier_block * nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17576) 				  unsigned long state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17577) 				  void *_notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17579) 	struct netlink_notify *notify = _notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17580) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17581) 	struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17582) 	struct cfg80211_beacon_registration *reg, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17584) 	if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17585) 		return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17587) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17589) 	list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17590) 		struct cfg80211_sched_scan_request *sched_scan_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17592) 		list_for_each_entry_rcu(sched_scan_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17593) 					&rdev->sched_scan_req_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17594) 					list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17595) 			if (sched_scan_req->owner_nlportid == notify->portid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17596) 				sched_scan_req->nl_owner_dead = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17597) 				schedule_work(&rdev->sched_scan_stop_wk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17598) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17599) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17601) 		list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17602) 			cfg80211_mlme_unregister_socket(wdev, notify->portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17604) 			if (wdev->owner_nlportid == notify->portid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17605) 				wdev->nl_owner_dead = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17606) 				schedule_work(&rdev->destroy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17607) 			} else if (wdev->conn_owner_nlportid == notify->portid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17608) 				schedule_work(&wdev->disconnect_wk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17609) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17611) 			cfg80211_release_pmsr(wdev, notify->portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17612) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17614) 		spin_lock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17615) 		list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17616) 					 list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17617) 			if (reg->nlportid == notify->portid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17618) 				list_del(&reg->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17619) 				kfree(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17620) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17621) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17622) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17623) 		spin_unlock_bh(&rdev->beacon_registrations_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17624) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17626) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17628) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17629) 	 * It is possible that the user space process that is controlling the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17630) 	 * indoor setting disappeared, so notify the regulatory core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17631) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17632) 	regulatory_netlink_notify(notify->portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17633) 	return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17636) static struct notifier_block nl80211_netlink_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17637) 	.notifier_call = nl80211_netlink_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17638) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17640) void cfg80211_ft_event(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17641) 		       struct cfg80211_ft_event_params *ft_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17643) 	struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17644) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17645) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17646) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17648) 	trace_cfg80211_ft_event(wiphy, netdev, ft_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17650) 	if (!ft_event->target_ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17651) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17653) 	msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17654) 			GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17655) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17656) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17658) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17659) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17660) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17662) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17663) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17664) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17665) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17667) 	if (ft_event->ies &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17668) 	    nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17669) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17670) 	if (ft_event->ric_ies &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17671) 	    nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17672) 		    ft_event->ric_ies))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17673) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17675) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17677) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17678) 				NL80211_MCGRP_MLME, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17679) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17680)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17681) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17683) EXPORT_SYMBOL(cfg80211_ft_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17685) void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17687) 	struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17688) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17689) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17690) 	u32 nlportid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17692) 	rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17693) 	if (!rdev->crit_proto_nlportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17694) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17696) 	nlportid = rdev->crit_proto_nlportid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17697) 	rdev->crit_proto_nlportid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17699) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17700) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17701) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17703) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17704) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17705) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17707) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17708) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17709) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17710) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17712) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17714) 	genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17715) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17717)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17718) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17720) EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17722) void nl80211_send_ap_stopped(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17724) 	struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17725) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17726) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17727) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17729) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17730) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17731) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17733) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17734) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17735) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17737) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17738) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17739) 	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17740) 			      NL80211_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17741) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17743) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17745) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17746) 				NL80211_MCGRP_MLME, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17747) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17748)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17749) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17752) int cfg80211_external_auth_request(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17753) 				   struct cfg80211_external_auth_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17754) 				   gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17756) 	struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17757) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17758) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17759) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17761) 	if (!wdev->conn_owner_nlportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17762) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17764) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17765) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17766) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17768) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17769) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17770) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17772) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17773) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17774) 	    nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17775) 	    nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17776) 			params->action) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17777) 	    nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17778) 	    nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17779) 		    params->ssid.ssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17780) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17782) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17783) 	genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17784) 			wdev->conn_owner_nlportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17785) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17787)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17788) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17789) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17791) EXPORT_SYMBOL(cfg80211_external_auth_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17793) void cfg80211_update_owe_info_event(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17794) 				    struct cfg80211_update_owe_info *owe_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17795) 				    gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17797) 	struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17798) 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17799) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17800) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17802) 	trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17804) 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17805) 	if (!msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17806) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17808) 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17809) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17810) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17812) 	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17813) 	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17814) 	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17815) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17817) 	if (!owe_info->ie_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17818) 	    nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17819) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17821) 	genlmsg_end(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17823) 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17824) 				NL80211_MCGRP_MLME, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17825) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17827) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17828) 	genlmsg_cancel(msg, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17829) 	nlmsg_free(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17831) EXPORT_SYMBOL(cfg80211_update_owe_info_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17833) /* initialisation/exit functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17835) int __init nl80211_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17837) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17839) 	err = genl_register_family(&nl80211_fam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17840) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17841) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17843) 	err = netlink_register_notifier(&nl80211_netlink_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17844) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17845) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17847) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17848)  err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17849) 	genl_unregister_family(&nl80211_fam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17850) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17853) void nl80211_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17855) 	netlink_unregister_notifier(&nl80211_netlink_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17856) 	genl_unregister_family(&nl80211_fam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17857) }