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)  * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (c) 2016 - 2017 Intel Deutschland GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (C) 2018 - 2020 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  */
^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)  * TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * - Add TSF sync and fix IBSS beacon transmission by adding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *   competition for "air time" at TBTT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * - RX filtering based on filter configuration (data->rx_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <net/dst.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <net/xfrm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <net/mac80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <net/ieee80211_radiotap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <net/netns/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/rhashtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/virtio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/virtio_ids.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/virtio_config.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include "mac80211_hwsim.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define WARN_QUEUE 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define MAX_QUEUE 200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) MODULE_AUTHOR("Jouni Malinen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) static int radios = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) module_param(radios, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) MODULE_PARM_DESC(radios, "Number of simulated radios");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) static int channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) module_param(channels, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) MODULE_PARM_DESC(channels, "Number of concurrent channels");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) static bool paged_rx = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) module_param(paged_rx, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) MODULE_PARM_DESC(paged_rx, "Use paged SKBs for RX instead of linear ones");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) static bool rctbl = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) module_param(rctbl, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) MODULE_PARM_DESC(rctbl, "Handle rate control table");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) static bool support_p2p_device = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) module_param(support_p2p_device, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) MODULE_PARM_DESC(support_p2p_device, "Support P2P-Device interface type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) static ushort mac_prefix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) module_param(mac_prefix, ushort, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) MODULE_PARM_DESC(mac_prefix, "Second and third most significant octets in MAC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)  * enum hwsim_regtest - the type of regulatory tests we offer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  * These are the different values you can use for the regtest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * module parameter. This is useful to help test world roaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  * and the driver regulatory_hint() call and combinations of these.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * If you want to do specific alpha2 regulatory domain tests simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * use the userspace regulatory request as that will be respected as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  * well without the need of this module parameter. This is designed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  * only for testing the driver regulatory request, world roaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  * and all possible combinations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * @HWSIM_REGTEST_DISABLED: No regulatory tests are performed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  * 	this is the default value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  * @HWSIM_REGTEST_DRIVER_REG_FOLLOW: Used for testing the driver regulatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)  *	hint, only one driver regulatory hint will be sent as such the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88)  * 	secondary radios are expected to follow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89)  * @HWSIM_REGTEST_DRIVER_REG_ALL: Used for testing the driver regulatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90)  * 	request with all radios reporting the same regulatory domain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91)  * @HWSIM_REGTEST_DIFF_COUNTRY: Used for testing the drivers calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92)  * 	different regulatory domains requests. Expected behaviour is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93)  * 	an intersection to occur but each device will still use their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94)  * 	respective regulatory requested domains. Subsequent radios will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)  * 	use the resulting intersection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)  * @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We accomplish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)  *	this by using a custom beacon-capable regulatory domain for the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  *	radio. All other device world roam.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  * @HWSIM_REGTEST_CUSTOM_WORLD: Used for testing the custom world regulatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * 	domain requests. All radios will adhere to this custom world regulatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  * 	domain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)  * @HWSIM_REGTEST_CUSTOM_WORLD_2: Used for testing 2 custom world regulatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  * 	domain requests. The first radio will adhere to the first custom world
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  * 	regulatory domain, the second one to the second custom world regulatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * 	domain. All other devices will world roam.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  * @HWSIM_REGTEST_STRICT_FOLLOW: Used for testing strict regulatory domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  *	settings, only the first radio will send a regulatory domain request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  *	and use strict settings. The rest of the radios are expected to follow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)  * @HWSIM_REGTEST_STRICT_ALL: Used for testing strict regulatory domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110)  *	settings. All radios will adhere to this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)  * @HWSIM_REGTEST_STRICT_AND_DRIVER_REG: Used for testing strict regulatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)  *	domain settings, combined with secondary driver regulatory domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113)  *	settings. The first radio will get a strict regulatory domain setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114)  *	using the first driver regulatory request and the second radio will use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115)  *	non-strict settings using the second driver regulatory request. All
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116)  *	other devices should follow the intersection created between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117)  *	first two.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118)  * @HWSIM_REGTEST_ALL: Used for testing every possible mix. You will need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119)  * 	at least 6 radios for a complete test. We will test in this order:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120)  * 	1 - driver custom world regulatory domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  * 	2 - second custom world regulatory domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  * 	3 - first driver regulatory domain request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)  * 	4 - second driver regulatory domain request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  * 	5 - strict regulatory domain settings using the third driver regulatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  * 	    domain request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  * 	6 and on - should follow the intersection of the 3rd, 4rth and 5th radio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  * 	           regulatory requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) enum hwsim_regtest {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	HWSIM_REGTEST_DISABLED = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	HWSIM_REGTEST_DRIVER_REG_FOLLOW = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	HWSIM_REGTEST_DRIVER_REG_ALL = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	HWSIM_REGTEST_DIFF_COUNTRY = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	HWSIM_REGTEST_WORLD_ROAM = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	HWSIM_REGTEST_CUSTOM_WORLD = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	HWSIM_REGTEST_CUSTOM_WORLD_2 = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	HWSIM_REGTEST_STRICT_FOLLOW = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	HWSIM_REGTEST_STRICT_ALL = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	HWSIM_REGTEST_STRICT_AND_DRIVER_REG = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	HWSIM_REGTEST_ALL = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) /* Set to one of the HWSIM_REGTEST_* values above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) static int regtest = HWSIM_REGTEST_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) module_param(regtest, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) MODULE_PARM_DESC(regtest, "The type of regulatory test we want to run");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) static const char *hwsim_alpha2s[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	"FI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	"AL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	"US",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	"DE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	"JP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	"AL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) static const struct ieee80211_regdomain hwsim_world_regdom_custom_01 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	.n_reg_rules = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	.alpha2 =  "99",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	.reg_rules = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		REG_RULE(2484-10, 2484+10, 40, 0, 20, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		REG_RULE(5150-10, 5240+10, 40, 0, 30, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		REG_RULE(5745-10, 5825+10, 40, 0, 30, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		REG_RULE(5855-10, 5925+10, 40, 0, 33, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	.n_reg_rules = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	.alpha2 =  "99",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	.reg_rules = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		REG_RULE(5725-10, 5850+10, 40, 0, 30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			 NL80211_RRF_NO_IR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		REG_RULE(5855-10, 5925+10, 40, 0, 33, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) static const struct ieee80211_regdomain *hwsim_world_regdom_custom[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	&hwsim_world_regdom_custom_01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	&hwsim_world_regdom_custom_02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) struct hwsim_vif_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	u32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	u8 bssid[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	bool assoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	bool bcn_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	u16 aid;
^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) #define HWSIM_VIF_MAGIC	0x69537748
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) static inline void hwsim_check_magic(struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	WARN(vp->magic != HWSIM_VIF_MAGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	     "Invalid VIF (%p) magic %#x, %pM, %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	     vif, vp->magic, vif->addr, vif->type, vif->p2p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) static inline void hwsim_set_magic(struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	vp->magic = HWSIM_VIF_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) static inline void hwsim_clear_magic(struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	vp->magic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) struct hwsim_sta_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	u32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) #define HWSIM_STA_MAGIC	0x6d537749
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	struct hwsim_sta_priv *sp = (void *)sta->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	WARN_ON(sp->magic != HWSIM_STA_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) static inline void hwsim_set_sta_magic(struct ieee80211_sta *sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	struct hwsim_sta_priv *sp = (void *)sta->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	sp->magic = HWSIM_STA_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) static inline void hwsim_clear_sta_magic(struct ieee80211_sta *sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	struct hwsim_sta_priv *sp = (void *)sta->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	sp->magic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) struct hwsim_chanctx_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	u32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) #define HWSIM_CHANCTX_MAGIC 0x6d53774a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) static inline void hwsim_check_chanctx_magic(struct ieee80211_chanctx_conf *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	struct hwsim_chanctx_priv *cp = (void *)c->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	WARN_ON(cp->magic != HWSIM_CHANCTX_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) static inline void hwsim_set_chanctx_magic(struct ieee80211_chanctx_conf *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	struct hwsim_chanctx_priv *cp = (void *)c->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	cp->magic = HWSIM_CHANCTX_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) static inline void hwsim_clear_chanctx_magic(struct ieee80211_chanctx_conf *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	struct hwsim_chanctx_priv *cp = (void *)c->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	cp->magic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) static unsigned int hwsim_net_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) static DEFINE_IDA(hwsim_netgroup_ida);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) struct hwsim_net {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	int netgroup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	u32 wmediumd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) static inline int hwsim_net_get_netgroup(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	return hwsim_net->netgroup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) static inline int hwsim_net_set_netgroup(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	hwsim_net->netgroup = ida_simple_get(&hwsim_netgroup_ida,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 					     0, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	return hwsim_net->netgroup >= 0 ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) static inline u32 hwsim_net_get_wmediumd(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	return hwsim_net->wmediumd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) static inline void hwsim_net_set_wmediumd(struct net *net, u32 portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	struct hwsim_net *hwsim_net = net_generic(net, hwsim_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	hwsim_net->wmediumd = portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) static struct class *hwsim_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) static struct net_device *hwsim_mon; /* global monitor netdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) #define CHAN2G(_freq)  { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	.band = NL80211_BAND_2GHZ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	.center_freq = (_freq), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	.hw_value = (_freq), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) #define CHAN5G(_freq) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	.band = NL80211_BAND_5GHZ, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	.center_freq = (_freq), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	.hw_value = (_freq), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) static const struct ieee80211_channel hwsim_channels_2ghz[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	CHAN2G(2412), /* Channel 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	CHAN2G(2417), /* Channel 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	CHAN2G(2422), /* Channel 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	CHAN2G(2427), /* Channel 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	CHAN2G(2432), /* Channel 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	CHAN2G(2437), /* Channel 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	CHAN2G(2442), /* Channel 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	CHAN2G(2447), /* Channel 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	CHAN2G(2452), /* Channel 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	CHAN2G(2457), /* Channel 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	CHAN2G(2462), /* Channel 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	CHAN2G(2467), /* Channel 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	CHAN2G(2472), /* Channel 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	CHAN2G(2484), /* Channel 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) static const struct ieee80211_channel hwsim_channels_5ghz[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	CHAN5G(5180), /* Channel 36 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	CHAN5G(5200), /* Channel 40 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	CHAN5G(5220), /* Channel 44 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	CHAN5G(5240), /* Channel 48 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	CHAN5G(5260), /* Channel 52 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	CHAN5G(5280), /* Channel 56 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	CHAN5G(5300), /* Channel 60 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	CHAN5G(5320), /* Channel 64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	CHAN5G(5500), /* Channel 100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	CHAN5G(5520), /* Channel 104 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	CHAN5G(5540), /* Channel 108 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	CHAN5G(5560), /* Channel 112 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	CHAN5G(5580), /* Channel 116 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	CHAN5G(5600), /* Channel 120 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	CHAN5G(5620), /* Channel 124 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	CHAN5G(5640), /* Channel 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	CHAN5G(5660), /* Channel 132 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	CHAN5G(5680), /* Channel 136 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	CHAN5G(5700), /* Channel 140 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	CHAN5G(5745), /* Channel 149 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	CHAN5G(5765), /* Channel 153 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	CHAN5G(5785), /* Channel 157 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	CHAN5G(5805), /* Channel 161 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	CHAN5G(5825), /* Channel 165 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	CHAN5G(5845), /* Channel 169 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	CHAN5G(5855), /* Channel 171 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	CHAN5G(5860), /* Channel 172 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	CHAN5G(5865), /* Channel 173 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	CHAN5G(5870), /* Channel 174 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	CHAN5G(5875), /* Channel 175 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	CHAN5G(5880), /* Channel 176 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	CHAN5G(5885), /* Channel 177 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	CHAN5G(5890), /* Channel 178 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	CHAN5G(5895), /* Channel 179 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	CHAN5G(5900), /* Channel 180 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	CHAN5G(5905), /* Channel 181 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	CHAN5G(5910), /* Channel 182 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	CHAN5G(5915), /* Channel 183 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	CHAN5G(5920), /* Channel 184 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	CHAN5G(5925), /* Channel 185 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) #define NUM_S1G_CHANS_US 51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) static struct ieee80211_channel hwsim_channels_s1g[NUM_S1G_CHANS_US];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) static const struct ieee80211_sta_s1g_cap hwsim_s1g_cap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	.s1g = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	.cap = { S1G_CAP0_SGI_1MHZ | S1G_CAP0_SGI_2MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		 S1G_CAP3_MAX_MPDU_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		 S1G_CAP5_AMPDU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		 S1G_CAP7_DUP_1MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		 S1G_CAP8_TWT_RESPOND | S1G_CAP8_TWT_REQUEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	.nss_mcs = { 0xfc | 1, /* MCS 7 for 1 SS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	/* RX Highest Supported Long GI Data Rate 0:7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		     0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	/* RX Highest Supported Long GI Data Rate 0:7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	/* TX S1G MCS Map 0:6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		     0xfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	/* TX S1G MCS Map :7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	/* TX Highest Supported Long GI Data Rate 0:6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		     0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	/* TX Highest Supported Long GI Data Rate 7:8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	/* Rx Single spatial stream and S1G-MCS Map for 1MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	/* Tx Single spatial stream and S1G-MCS Map for 1MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		     0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) static void hwsim_init_s1g_channels(struct ieee80211_channel *channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	int ch, freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	for (ch = 0; ch < NUM_S1G_CHANS_US; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		freq = 902000 + (ch + 1) * 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		channels[ch].band = NL80211_BAND_S1GHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		channels[ch].center_freq = KHZ_TO_MHZ(freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		channels[ch].freq_offset = freq % 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		channels[ch].hw_value = ch + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) static const struct ieee80211_rate hwsim_rates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	{ .bitrate = 10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	{ .bitrate = 60 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	{ .bitrate = 90 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	{ .bitrate = 120 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	{ .bitrate = 180 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	{ .bitrate = 240 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	{ .bitrate = 360 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	{ .bitrate = 480 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	{ .bitrate = 540 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) static const u32 hwsim_ciphers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	WLAN_CIPHER_SUITE_WEP40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	WLAN_CIPHER_SUITE_WEP104,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	WLAN_CIPHER_SUITE_TKIP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	WLAN_CIPHER_SUITE_CCMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	WLAN_CIPHER_SUITE_CCMP_256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	WLAN_CIPHER_SUITE_GCMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	WLAN_CIPHER_SUITE_GCMP_256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	WLAN_CIPHER_SUITE_AES_CMAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	WLAN_CIPHER_SUITE_BIP_CMAC_256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	WLAN_CIPHER_SUITE_BIP_GMAC_128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	WLAN_CIPHER_SUITE_BIP_GMAC_256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) #define OUI_QCA 0x001374
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) #define QCA_NL80211_SUBCMD_TEST 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) enum qca_nl80211_vendor_subcmds {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	QCA_WLAN_VENDOR_ATTR_TEST = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_TEST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) static const struct nla_policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) hwsim_vendor_test_policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	[QCA_WLAN_VENDOR_ATTR_MAX] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) static int mac80211_hwsim_vendor_cmd_test(struct wiphy *wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 					  struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 					  const void *data, int data_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	err = nla_parse_deprecated(tb, QCA_WLAN_VENDOR_ATTR_MAX, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 				   data_len, hwsim_vendor_test_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	if (!tb[QCA_WLAN_VENDOR_ATTR_TEST])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	val = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_TEST]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	wiphy_dbg(wiphy, "%s: test=%u\n", __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	/* Send a vendor event as a test. Note that this would not normally be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	 * done within a command handler, but rather, based on some other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	 * trigger. For simplicity, this command is used to trigger the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	 * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	 * event_idx = 0 (index in mac80211_hwsim_vendor_commands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	skb = cfg80211_vendor_event_alloc(wiphy, wdev, 100, 0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		/* skb_put() or nla_put() will fill up data within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		 * NL80211_ATTR_VENDOR_DATA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		/* Add vendor data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_TEST, val + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		/* Send the event - this will call nla_nest_end() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		cfg80211_vendor_event(skb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	/* Send a response to the command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	/* skb_put() or nla_put() will fill up data within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	 * NL80211_ATTR_VENDOR_DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_TEST, val + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	return cfg80211_vendor_cmd_reply(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) static struct wiphy_vendor_command mac80211_hwsim_vendor_commands[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		.info = { .vendor_id = OUI_QCA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 			  .subcmd = QCA_NL80211_SUBCMD_TEST },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		.flags = WIPHY_VENDOR_CMD_NEED_NETDEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		.doit = mac80211_hwsim_vendor_cmd_test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		.policy = hwsim_vendor_test_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		.maxattr = QCA_WLAN_VENDOR_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) /* Advertise support vendor specific events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) static const struct nl80211_vendor_cmd_info mac80211_hwsim_vendor_events[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	{ .vendor_id = OUI_QCA, .subcmd = 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) static spinlock_t hwsim_radio_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static LIST_HEAD(hwsim_radios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) static struct rhashtable hwsim_radios_rht;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) static int hwsim_radio_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) static int hwsim_radios_generation = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) static struct platform_driver mac80211_hwsim_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		.name = "mac80211_hwsim",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) struct mac80211_hwsim_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	struct rhash_head rht;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	struct ieee80211_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	struct ieee80211_channel channels_s1g[ARRAY_SIZE(hwsim_channels_s1g)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	struct ieee80211_iface_combination if_combination;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	struct ieee80211_iface_limit if_limits[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	int n_if_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	u32 ciphers[ARRAY_SIZE(hwsim_ciphers)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	struct mac_address addresses[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	struct ieee80211_chanctx_conf *chanctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	int channels, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	bool use_chanctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	bool destroy_on_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	u32 portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	char alpha2[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	const struct ieee80211_regdomain *regd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	struct ieee80211_channel *tmp_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	struct ieee80211_channel *roc_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	u32 roc_duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	struct delayed_work roc_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	struct delayed_work roc_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	struct delayed_work hw_scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	struct cfg80211_scan_request *hw_scan_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	struct ieee80211_vif *hw_scan_vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	int scan_chan_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	u8 scan_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		struct ieee80211_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		unsigned long next_start, start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	} survey_data[ARRAY_SIZE(hwsim_channels_2ghz) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		      ARRAY_SIZE(hwsim_channels_5ghz)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	struct ieee80211_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	u64 beacon_int	/* beacon interval in us */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	unsigned int rx_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	bool started, idle, scanning;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	struct hrtimer beacon_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	enum ps_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	} ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	bool ps_poll_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	struct dentry *debugfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	uintptr_t pending_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	struct sk_buff_head pending;	/* packets pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	 * Only radios in the same group can communicate together (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	 * channel has to match too). Each bit represents a group. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	 * radio can be in more than one group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	u64 group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	/* group shared by radios created in the same netns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	int netgroup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	/* wmediumd portid responsible for netgroup of this radio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	u32 wmediumd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	/* difference between this hw's clock and the real clock, in usecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	s64 tsf_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	s64 bcn_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	/* absolute beacon transmission time. Used to cover up "tx" delay. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	u64 abs_bcn_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	/* Stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	u64 tx_pkts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	u64 rx_pkts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	u64 tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	u64 rx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	u64 tx_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	u64 tx_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) static const struct rhashtable_params hwsim_rht_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	.nelem_hint = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	.automatic_shrinking = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	.key_len = ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	.key_offset = offsetof(struct mac80211_hwsim_data, addresses[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	.head_offset = offsetof(struct mac80211_hwsim_data, rht),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) struct hwsim_radiotap_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	struct ieee80211_radiotap_header hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	__le64 rt_tsft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	u8 rt_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	u8 rt_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	__le16 rt_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	__le16 rt_chbitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) struct hwsim_radiotap_ack_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	struct ieee80211_radiotap_header hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	u8 rt_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	u8 pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	__le16 rt_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	__le16 rt_chbitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) /* MAC80211_HWSIM netlink family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) static struct genl_family hwsim_genl_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) enum hwsim_multicast_groups {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	HWSIM_MCGRP_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) static const struct genl_multicast_group hwsim_mcgrps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	[HWSIM_MCGRP_CONFIG] = { .name = "config", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) /* MAC80211_HWSIM netlink policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	[HWSIM_ATTR_ADDR_RECEIVER] = NLA_POLICY_ETH_ADDR_COMPAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	[HWSIM_ATTR_ADDR_TRANSMITTER] = NLA_POLICY_ETH_ADDR_COMPAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	[HWSIM_ATTR_FRAME] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			       .len = IEEE80211_MAX_DATA_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	[HWSIM_ATTR_FLAGS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	[HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	[HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	[HWSIM_ATTR_TX_INFO] = { .type = NLA_BINARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 				 .len = IEEE80211_TX_MAX_RATES *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 					sizeof(struct hwsim_tx_rate)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	[HWSIM_ATTR_COOKIE] = { .type = NLA_U64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	[HWSIM_ATTR_CHANNELS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	[HWSIM_ATTR_RADIO_ID] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	[HWSIM_ATTR_REG_HINT_ALPHA2] = { .type = NLA_STRING, .len = 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	[HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	[HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	[HWSIM_ATTR_SUPPORT_P2P_DEVICE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	[HWSIM_ATTR_USE_CHANCTX] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	[HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	[HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	[HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	[HWSIM_ATTR_TX_INFO_FLAGS] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	[HWSIM_ATTR_PERM_ADDR] = NLA_POLICY_ETH_ADDR_COMPAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	[HWSIM_ATTR_IFTYPE_SUPPORT] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	[HWSIM_ATTR_CIPHER_SUPPORT] = { .type = NLA_BINARY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) #if IS_REACHABLE(CONFIG_VIRTIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) /* MAC80211_HWSIM virtio queues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) static struct virtqueue *hwsim_vqs[HWSIM_NUM_VQS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) static bool hwsim_virtio_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) static spinlock_t hwsim_virtio_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) static void hwsim_virtio_rx_work(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) static DECLARE_WORK(hwsim_virtio_rx, hwsim_virtio_rx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) static int hwsim_tx_virtio(struct mac80211_hwsim_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			   struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	struct scatterlist sg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	spin_lock_irqsave(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	if (!hwsim_virtio_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	sg_init_one(sg, skb->head, skb_end_offset(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	err = virtqueue_add_outbuf(hwsim_vqs[HWSIM_VQ_TX], sg, 1, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				   GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	virtqueue_kick(hwsim_vqs[HWSIM_VQ_TX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) /* cause a linker error if this ends up being needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) extern int hwsim_tx_virtio(struct mac80211_hwsim_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			   struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) #define hwsim_virtio_enabled false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 				    struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 				    struct ieee80211_channel *chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) /* sysfs attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	struct mac80211_hwsim_data *data = dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	struct ieee80211_pspoll *pspoll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (!vp->assoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	wiphy_dbg(data->hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		  "%s: send PS-Poll to %pM for aid %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		  __func__, vp->bssid, vp->aid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	skb = dev_alloc_skb(sizeof(*pspoll));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	pspoll = skb_put(skb, sizeof(*pspoll));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 					    IEEE80211_STYPE_PSPOLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 					    IEEE80211_FCTL_PM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	memcpy(pspoll->ta, mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	mac80211_hwsim_tx_frame(data->hw, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 				rcu_dereference(vif->chanctx_conf)->def.chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 				struct ieee80211_vif *vif, int ps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	struct ieee80211_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	if (!vp->assoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	wiphy_dbg(data->hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		  "%s: send data::nullfunc to %pM ps=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		  __func__, vp->bssid, ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	skb = dev_alloc_skb(sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	hdr = skb_put(skb, sizeof(*hdr) - ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 					 IEEE80211_STYPE_NULLFUNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 					 IEEE80211_FCTL_TODS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 					 (ps ? IEEE80211_FCTL_PM : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	hdr->duration_id = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	memcpy(hdr->addr2, mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	mac80211_hwsim_tx_frame(data->hw, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 				rcu_dereference(vif->chanctx_conf)->def.chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) }
^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 void hwsim_send_nullfunc_ps(void *dat, u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 				   struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	struct mac80211_hwsim_data *data = dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	hwsim_send_nullfunc(data, mac, vif, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) static void hwsim_send_nullfunc_no_ps(void *dat, u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 				      struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	struct mac80211_hwsim_data *data = dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	hwsim_send_nullfunc(data, mac, vif, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) static int hwsim_fops_ps_read(void *dat, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	struct mac80211_hwsim_data *data = dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	*val = data->ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) static int hwsim_fops_ps_write(void *dat, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	struct mac80211_hwsim_data *data = dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	enum ps_mode old_ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	if (val != PS_DISABLED && val != PS_ENABLED && val != PS_AUTO_POLL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	    val != PS_MANUAL_POLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	if (val == PS_MANUAL_POLL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		if (data->ps != PS_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		ieee80211_iterate_active_interfaces_atomic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 			data->hw, IEEE80211_IFACE_ITER_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			hwsim_send_ps_poll, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	old_ps = data->ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	data->ps = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (old_ps == PS_DISABLED && val != PS_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		ieee80211_iterate_active_interfaces_atomic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			data->hw, IEEE80211_IFACE_ITER_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			hwsim_send_nullfunc_ps, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	} else if (old_ps != PS_DISABLED && val == PS_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		ieee80211_iterate_active_interfaces_atomic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			data->hw, IEEE80211_IFACE_ITER_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 			hwsim_send_nullfunc_no_ps, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) DEFINE_DEBUGFS_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			 "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) static int hwsim_write_simulate_radar(void *dat, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	struct mac80211_hwsim_data *data = dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	ieee80211_radar_detected(data->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) DEFINE_DEBUGFS_ATTRIBUTE(hwsim_simulate_radar, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			 hwsim_write_simulate_radar, "%llu\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) static int hwsim_fops_group_read(void *dat, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	struct mac80211_hwsim_data *data = dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	*val = data->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) static int hwsim_fops_group_write(void *dat, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	struct mac80211_hwsim_data *data = dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	data->group = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) DEFINE_DEBUGFS_ATTRIBUTE(hwsim_fops_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			 hwsim_fops_group_read, hwsim_fops_group_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			 "%llx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 					struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	/* TODO: allow packet injection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) static inline u64 mac80211_hwsim_get_tsf_raw(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	return ktime_to_us(ktime_get_real());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	u64 now = mac80211_hwsim_get_tsf_raw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	return cpu_to_le64(now + data->tsf_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 				  struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	return le64_to_cpu(__mac80211_hwsim_get_tsf(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		struct ieee80211_vif *vif, u64 tsf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	u64 now = mac80211_hwsim_get_tsf(hw, vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	u32 bcn_int = data->beacon_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	u64 delta = abs(tsf - now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	/* adjust after beaconing with new timestamp at old TBTT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	if (tsf > now) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		data->tsf_offset += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		data->bcn_delta = do_div(delta, bcn_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		data->tsf_offset -= delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		data->bcn_delta = -(s64)do_div(delta, bcn_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 				      struct sk_buff *tx_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 				      struct ieee80211_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	struct hwsim_radiotap_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	u16 flags, bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	if (!txrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		bitrate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		bitrate = txrate->bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	if (!netif_running(hwsim_mon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	hdr = skb_push(skb, sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	hdr->hdr.it_pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 					  (1 << IEEE80211_RADIOTAP_RATE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 					  (1 << IEEE80211_RADIOTAP_TSFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 					  (1 << IEEE80211_RADIOTAP_CHANNEL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	hdr->rt_tsft = __mac80211_hwsim_get_tsf(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	hdr->rt_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	hdr->rt_rate = bitrate / 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	hdr->rt_channel = cpu_to_le16(chan->center_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	flags = IEEE80211_CHAN_2GHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	if (txrate && txrate->flags & IEEE80211_RATE_ERP_G)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		flags |= IEEE80211_CHAN_OFDM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		flags |= IEEE80211_CHAN_CCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	hdr->rt_chbitmask = cpu_to_le16(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	skb->dev = hwsim_mon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	skb->ip_summed = CHECKSUM_UNNECESSARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	skb->pkt_type = PACKET_OTHERHOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	skb->protocol = htons(ETH_P_802_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	memset(skb->cb, 0, sizeof(skb->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 				       const u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	struct hwsim_radiotap_ack_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	u16 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	struct ieee80211_hdr *hdr11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	if (!netif_running(hwsim_mon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	skb = dev_alloc_skb(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	hdr = skb_put(skb, sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	hdr->hdr.it_pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 					  (1 << IEEE80211_RADIOTAP_CHANNEL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	hdr->rt_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	hdr->pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	hdr->rt_channel = cpu_to_le16(chan->center_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	flags = IEEE80211_CHAN_2GHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	hdr->rt_chbitmask = cpu_to_le16(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	hdr11 = skb_put(skb, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	hdr11->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 					   IEEE80211_STYPE_ACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	hdr11->duration_id = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	memcpy(hdr11->addr1, addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	skb->dev = hwsim_mon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	skb->ip_summed = CHECKSUM_UNNECESSARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	skb->pkt_type = PACKET_OTHERHOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	skb->protocol = htons(ETH_P_802_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	memset(skb->cb, 0, sizeof(skb->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) struct mac80211_hwsim_addr_match_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	u8 addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	bool ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static void mac80211_hwsim_addr_iter(void *data, u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 				     struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	struct mac80211_hwsim_addr_match_data *md = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	if (memcmp(mac, md->addr, ETH_ALEN) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		md->ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 				      const u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	struct mac80211_hwsim_addr_match_data md = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		.ret = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	if (data->scanning && memcmp(addr, data->scan_addr, ETH_ALEN) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	memcpy(md.addr, addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	ieee80211_iterate_active_interfaces_atomic(data->hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 						   IEEE80211_IFACE_ITER_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 						   mac80211_hwsim_addr_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 						   &md);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	return md.ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			   struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	switch (data->ps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	case PS_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	case PS_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	case PS_AUTO_POLL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		/* TODO: accept (some) Beacons by default and other frames only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		 * if pending PS-Poll has been sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	case PS_MANUAL_POLL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		/* Allow unicast frames to own address if there is a pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		 * PS-Poll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		if (data->ps_poll_pending &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		    mac80211_hwsim_addr_match(data, skb->data + 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			data->ps_poll_pending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int hwsim_unicast_netgroup(struct mac80211_hwsim_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 				  struct sk_buff *skb, int portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	int res = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	for_each_net_rcu(net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		if (data->netgroup == hwsim_net_get_netgroup(net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			res = genlmsg_unicast(net, skb, portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static void mac80211_hwsim_config_mac_nl(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 					 const u8 *addr, bool add)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	u32 _portid = READ_ONCE(data->wmediumd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	void *msg_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	if (!_portid && !hwsim_virtio_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			       add ? HWSIM_CMD_ADD_MAC_ADDR :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 				     HWSIM_CMD_DEL_MAC_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	if (!msg_head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		pr_debug("mac80211_hwsim: problem with msg_head\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 		    ETH_ALEN, data->addresses[1].addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	if (nla_put(skb, HWSIM_ATTR_ADDR_RECEIVER, ETH_ALEN, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	genlmsg_end(skb, msg_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	if (hwsim_virtio_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		hwsim_tx_virtio(data, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		hwsim_unicast_netgroup(data, skb, _portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	u16 result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	if (rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		result |= MAC80211_HWSIM_TX_RC_USE_RTS_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	if (rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		result |= MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		result |= MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	if (rate->flags & IEEE80211_TX_RC_MCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		result |= MAC80211_HWSIM_TX_RC_MCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		result |= MAC80211_HWSIM_TX_RC_GREEN_FIELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		result |= MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	if (rate->flags & IEEE80211_TX_RC_DUP_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		result |= MAC80211_HWSIM_TX_RC_DUP_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		result |= MAC80211_HWSIM_TX_RC_SHORT_GI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	if (rate->flags & IEEE80211_TX_RC_VHT_MCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		result |= MAC80211_HWSIM_TX_RC_VHT_MCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		result |= MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		result |= MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 				       struct sk_buff *my_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 				       int dst_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 				       struct ieee80211_channel *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) my_skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(my_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	void *msg_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	unsigned int hwsim_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	struct hwsim_tx_rate_flag tx_attempts_flags[IEEE80211_TX_MAX_RATES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	uintptr_t cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	if (data->ps != PS_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	/* If the queue contains MAX_QUEUE skb's drop some */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	if (skb_queue_len(&data->pending) >= MAX_QUEUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		/* Droping until WARN_QUEUE level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		while (skb_queue_len(&data->pending) >= WARN_QUEUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			ieee80211_free_txskb(hw, skb_dequeue(&data->pending));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 			data->tx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			       HWSIM_CMD_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (msg_head == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		pr_debug("mac80211_hwsim: problem with msg_head\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		    ETH_ALEN, data->addresses[1].addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	/* We get the skb->data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	if (nla_put(skb, HWSIM_ATTR_FRAME, my_skb->len, my_skb->data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	/* We get the flags for this transmission, and we translate them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	   wmediumd flags  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		hwsim_flags |= HWSIM_TX_CTL_REQ_TX_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		hwsim_flags |= HWSIM_TX_CTL_NO_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	if (nla_put_u32(skb, HWSIM_ATTR_FREQ, channel->center_freq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	/* We get the tx control (rate and retries) info*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		tx_attempts[i].idx = info->status.rates[i].idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		tx_attempts_flags[i].idx = info->status.rates[i].idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		tx_attempts[i].count = info->status.rates[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		tx_attempts_flags[i].flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 				trans_tx_rate_flags_ieee2hwsim(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 						&info->status.rates[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	if (nla_put(skb, HWSIM_ATTR_TX_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		    sizeof(struct hwsim_tx_rate)*IEEE80211_TX_MAX_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		    tx_attempts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	if (nla_put(skb, HWSIM_ATTR_TX_INFO_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		    sizeof(struct hwsim_tx_rate_flag) * IEEE80211_TX_MAX_RATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 		    tx_attempts_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	/* We create a cookie to identify this skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	data->pending_cookie++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	cookie = data->pending_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	info->rate_driver_data[0] = (void *)cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	genlmsg_end(skb, msg_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	if (hwsim_virtio_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		if (hwsim_tx_virtio(data, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 			goto err_free_txskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		if (hwsim_unicast_netgroup(data, skb, dst_portid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 			goto err_free_txskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	/* Enqueue the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	skb_queue_tail(&data->pending, my_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	data->tx_pkts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	data->tx_bytes += my_skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) err_free_txskb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	ieee80211_free_txskb(hw, my_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	data->tx_failed++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) static bool hwsim_chans_compat(struct ieee80211_channel *c1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 			       struct ieee80211_channel *c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	if (!c1 || !c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	return c1->center_freq == c2->center_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) struct tx_iter_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	struct ieee80211_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	bool receive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) static void mac80211_hwsim_tx_iter(void *_data, u8 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 				   struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	struct tx_iter_data *data = _data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	if (!vif->chanctx_conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	if (!hwsim_chans_compat(data->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 				rcu_dereference(vif->chanctx_conf)->def.chan))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	data->receive = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static void mac80211_hwsim_add_vendor_rtap(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	 * To enable this code, #define the HWSIM_RADIOTAP_OUI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	 * e.g. like this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	 * #define HWSIM_RADIOTAP_OUI "\x02\x00\x00"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	 * (but you should use a valid OUI, not that)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	 * If anyone wants to 'donate' a radiotap OUI/subns code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	 * please send a patch removing this #ifdef and changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	 * the values accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) #ifdef HWSIM_RADIOTAP_OUI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	struct ieee80211_vendor_radiotap *rtap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	 * Note that this code requires the headroom in the SKB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	 * that was allocated earlier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	rtap = skb_push(skb, sizeof(*rtap) + 8 + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	rtap->oui[0] = HWSIM_RADIOTAP_OUI[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	rtap->oui[1] = HWSIM_RADIOTAP_OUI[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	rtap->oui[2] = HWSIM_RADIOTAP_OUI[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	rtap->subns = 127;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	 * Radiotap vendor namespaces can (and should) also be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	 * split into fields by using the standard radiotap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	 * presence bitmap mechanism. Use just BIT(0) here for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	 * the presence bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	rtap->present = BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	/* We have 8 bytes of (dummy) data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	rtap->len = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	/* For testing, also require it to be aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	rtap->align = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	/* And also test that padding works, 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	rtap->pad = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	/* push the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	memcpy(rtap->data, "ABCDEFGH", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	/* make sure to clear padding, mac80211 doesn't */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	memset(rtap->data + 8, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	IEEE80211_SKB_RXCB(skb)->flag |= RX_FLAG_RADIOTAP_VENDOR_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 					  struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 					  struct ieee80211_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	struct mac80211_hwsim_data *data = hw->priv, *data2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	bool ack = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	struct ieee80211_rx_status rx_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	u64 now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	memset(&rx_status, 0, sizeof(rx_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	rx_status.flag |= RX_FLAG_MACTIME_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	rx_status.freq = chan->center_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	rx_status.freq_offset = chan->freq_offset ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	rx_status.band = chan->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	if (info->control.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		rx_status.rate_idx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 			ieee80211_rate_get_vht_mcs(&info->control.rates[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		rx_status.nss =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 			ieee80211_rate_get_vht_nss(&info->control.rates[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		rx_status.encoding = RX_ENC_VHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 		rx_status.rate_idx = info->control.rates[0].idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 		if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 			rx_status.encoding = RX_ENC_HT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		rx_status.bw = RATE_INFO_BW_40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	else if (info->control.rates[0].flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		rx_status.bw = RATE_INFO_BW_80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	else if (info->control.rates[0].flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 		rx_status.bw = RATE_INFO_BW_160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 		rx_status.bw = RATE_INFO_BW_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 		rx_status.enc_flags |= RX_ENC_FLAG_SHORT_GI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	/* TODO: simulate real signal strength (and optional packet loss) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	rx_status.signal = -50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	if (info->control.vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		rx_status.signal += info->control.vif->bss_conf.txpower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	if (data->ps != PS_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	/* release the skb's source info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	skb_orphan(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	skb_dst_drop(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	skb->mark = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	skb_ext_reset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	nf_reset_ct(skb);
^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) 	 * Get absolute mactime here so all HWs RX at the "same time", and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	 * absolute TX time for beacon mactime so the timestamp matches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	 * Giving beacons a different mactime than non-beacons looks messy, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	 * it helps the Toffset be exact and a ~10us mactime discrepancy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	 * probably doesn't really matter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	if (ieee80211_is_beacon(hdr->frame_control) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	    ieee80211_is_probe_resp(hdr->frame_control)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		rx_status.boottime_ns = ktime_get_boottime_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		now = data->abs_bcn_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		now = mac80211_hwsim_get_tsf_raw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	/* Copy skb to all enabled radios that are on the current frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	spin_lock(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	list_for_each_entry(data2, &hwsim_radios, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 		struct sk_buff *nskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		struct tx_iter_data tx_iter_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 			.receive = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 			.channel = chan,
^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) 		if (data == data2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		if (!data2->started || (data2->idle && !data2->tmp_chan) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		    !hwsim_ps_rx_ok(data2, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		if (!(data->group & data2->group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		if (data->netgroup != data2->netgroup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		if (!hwsim_chans_compat(chan, data2->tmp_chan) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		    !hwsim_chans_compat(chan, data2->channel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 			ieee80211_iterate_active_interfaces_atomic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 				data2->hw, IEEE80211_IFACE_ITER_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 				mac80211_hwsim_tx_iter, &tx_iter_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 			if (!tx_iter_data.receive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		 * reserve some space for our vendor and the normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		 * radiotap header, since we're copying anyway
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		if (skb->len < PAGE_SIZE && paged_rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 			struct page *page = alloc_page(GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 			if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 			nskb = dev_alloc_skb(128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 			if (!nskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 				__free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 			memcpy(page_address(page), skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 			skb_add_rx_frag(nskb, 0, page, 0, skb->len, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 			nskb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 			if (!nskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		if (mac80211_hwsim_addr_match(data2, hdr->addr1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 			ack = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		rx_status.mactime = now + data2->tsf_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		mac80211_hwsim_add_vendor_rtap(nskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 		data2->rx_pkts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		data2->rx_bytes += nskb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		ieee80211_rx_irqsafe(data2->hw, nskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	spin_unlock(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	return ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 			      struct ieee80211_tx_control *control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 			      struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	struct ieee80211_hdr *hdr = (void *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	struct ieee80211_chanctx_conf *chanctx_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	struct ieee80211_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	bool ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	u32 _portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	if (WARN_ON(skb->len < 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		/* Should not happen; just a sanity check for addr1 use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 		ieee80211_free_txskb(hw, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	if (!data->use_chanctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		channel = data->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	} else if (txi->hw_queue == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		channel = data->tmp_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		chanctx_conf = rcu_dereference(txi->control.vif->chanctx_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		if (chanctx_conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 			channel = chanctx_conf->def.chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 			channel = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	if (WARN(!channel, "TX w/o channel - queue = %d\n", txi->hw_queue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 		ieee80211_free_txskb(hw, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	if (data->idle && !data->tmp_chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		wiphy_dbg(hw->wiphy, "Trying to TX when idle - reject\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		ieee80211_free_txskb(hw, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	if (txi->control.vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		hwsim_check_magic(txi->control.vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	if (control->sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		hwsim_check_sta_magic(control->sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	if (ieee80211_hw_check(hw, SUPPORTS_RC_TABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		ieee80211_get_tx_rates(txi->control.vif, control->sta, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 				       txi->control.rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 				       ARRAY_SIZE(txi->control.rates));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	if (skb->len >= 24 + 8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	    ieee80211_is_probe_resp(hdr->frame_control)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		/* fake header transmission time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		struct ieee80211_mgmt *mgmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		struct ieee80211_rate *txrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		/* TODO: get MCS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 		int bitrate = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 		u64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		mgmt = (struct ieee80211_mgmt *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		txrate = ieee80211_get_tx_rate(hw, txi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		if (txrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 			bitrate = txrate->bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		ts = mac80211_hwsim_get_tsf_raw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		mgmt->u.probe_resp.timestamp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 			cpu_to_le64(ts + data->tsf_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 				    24 * 8 * 10 / bitrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	mac80211_hwsim_monitor_rx(hw, skb, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	/* wmediumd mode check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	_portid = READ_ONCE(data->wmediumd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	if (_portid || hwsim_virtio_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 		return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	/* NO wmediumd detected, perfect medium simulation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	data->tx_pkts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	data->tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	if (ack && skb->len >= 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 		mac80211_hwsim_monitor_ack(channel, hdr->addr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	ieee80211_tx_info_clear_status(txi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	/* frame was transmitted at most favorable rate at first attempt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	txi->control.rates[0].count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	txi->control.rates[1].idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 		txi->flags |= IEEE80211_TX_STAT_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	ieee80211_tx_status_irqsafe(hw, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) static int mac80211_hwsim_start(struct ieee80211_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	wiphy_dbg(hw->wiphy, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	data->started = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	data->started = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	hrtimer_cancel(&data->beacon_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	while (!skb_queue_empty(&data->pending))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		ieee80211_free_txskb(hw, skb_dequeue(&data->pending));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	wiphy_dbg(hw->wiphy, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 					struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	wiphy_dbg(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		  __func__, ieee80211_vif_type_p2p(vif),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		  vif->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	hwsim_set_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	if (vif->type != NL80211_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		mac80211_hwsim_config_mac_nl(hw, vif->addr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	vif->cab_queue = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	vif->hw_queue[IEEE80211_AC_VO] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	vif->hw_queue[IEEE80211_AC_VI] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	vif->hw_queue[IEEE80211_AC_BE] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	vif->hw_queue[IEEE80211_AC_BK] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 					   struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 					   enum nl80211_iftype newtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 					   bool newp2p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	newtype = ieee80211_iftype_p2p(newtype, newp2p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	wiphy_dbg(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		  "%s (old type=%d, new type=%d, mac_addr=%pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		  __func__, ieee80211_vif_type_p2p(vif),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 		    newtype, vif->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	 * interface may change from non-AP to AP in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	 * which case this needs to be set up again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	vif->cab_queue = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) static void mac80211_hwsim_remove_interface(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	struct ieee80211_hw *hw, struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	wiphy_dbg(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		  __func__, ieee80211_vif_type_p2p(vif),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		  vif->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	hwsim_clear_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	if (vif->type != NL80211_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 		mac80211_hwsim_config_mac_nl(hw, vif->addr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 				    struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 				    struct ieee80211_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	u32 _pid = READ_ONCE(data->wmediumd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	if (ieee80211_hw_check(hw, SUPPORTS_RC_TABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		ieee80211_get_tx_rates(txi->control.vif, NULL, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 				       txi->control.rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 				       ARRAY_SIZE(txi->control.rates));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	mac80211_hwsim_monitor_rx(hw, skb, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	if (_pid || hwsim_virtio_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		return mac80211_hwsim_tx_frame_nl(hw, skb, _pid, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	mac80211_hwsim_tx_frame_no_nl(hw, skb, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 				     struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	struct mac80211_hwsim_data *data = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	struct ieee80211_hw *hw = data->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	struct ieee80211_tx_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	struct ieee80211_rate *txrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	struct ieee80211_mgmt *mgmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	/* TODO: get MCS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	int bitrate = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	if (vif->type != NL80211_IFTYPE_AP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	    vif->type != NL80211_IFTYPE_MESH_POINT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	    vif->type != NL80211_IFTYPE_ADHOC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	    vif->type != NL80211_IFTYPE_OCB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	skb = ieee80211_beacon_get(hw, vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	if (ieee80211_hw_check(hw, SUPPORTS_RC_TABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		ieee80211_get_tx_rates(vif, NULL, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 				       info->control.rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 				       ARRAY_SIZE(info->control.rates));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	txrate = ieee80211_get_tx_rate(hw, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	if (txrate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		bitrate = txrate->bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	mgmt = (struct ieee80211_mgmt *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	/* fake header transmission time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	data->abs_bcn_ts = mac80211_hwsim_get_tsf_raw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		struct ieee80211_ext *ext = (void *) mgmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 		ext->u.s1g_beacon.timestamp = cpu_to_le32(data->abs_bcn_ts +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 							  data->tsf_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 							  10 * 8 * 10 /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 							  bitrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 		mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 						       data->tsf_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 						       24 * 8 * 10 /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 						       bitrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	mac80211_hwsim_tx_frame(hw, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 				rcu_dereference(vif->chanctx_conf)->def.chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	while ((skb = ieee80211_get_buffered_bc(hw, vif)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 		mac80211_hwsim_tx_frame(hw, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 				rcu_dereference(vif->chanctx_conf)->def.chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	if (vif->csa_active && ieee80211_beacon_cntdwn_is_complete(vif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		ieee80211_csa_finish(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) static enum hrtimer_restart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) mac80211_hwsim_beacon(struct hrtimer *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	struct mac80211_hwsim_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 		container_of(timer, struct mac80211_hwsim_data, beacon_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	struct ieee80211_hw *hw = data->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	u64 bcn_int = data->beacon_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	if (!data->started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 		return HRTIMER_NORESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	ieee80211_iterate_active_interfaces_atomic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		hw, IEEE80211_IFACE_ITER_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 		mac80211_hwsim_beacon_tx, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	/* beacon at new TBTT + beacon interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	if (data->bcn_delta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 		bcn_int -= data->bcn_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 		data->bcn_delta = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	hrtimer_forward_now(&data->beacon_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 			    ns_to_ktime(bcn_int * NSEC_PER_USEC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	return HRTIMER_RESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) static const char * const hwsim_chanwidths[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	[NL80211_CHAN_WIDTH_5] = "ht5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	[NL80211_CHAN_WIDTH_10] = "ht10",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	[NL80211_CHAN_WIDTH_20_NOHT] = "noht",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	[NL80211_CHAN_WIDTH_20] = "ht20",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	[NL80211_CHAN_WIDTH_40] = "ht40",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	[NL80211_CHAN_WIDTH_80] = "vht80",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	[NL80211_CHAN_WIDTH_80P80] = "vht80p80",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	[NL80211_CHAN_WIDTH_160] = "vht160",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	[NL80211_CHAN_WIDTH_1] = "1MHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	[NL80211_CHAN_WIDTH_2] = "2MHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	[NL80211_CHAN_WIDTH_4] = "4MHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	[NL80211_CHAN_WIDTH_8] = "8MHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	[NL80211_CHAN_WIDTH_16] = "16MHz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	struct ieee80211_conf *conf = &hw->conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	static const char *smps_modes[IEEE80211_SMPS_NUM_MODES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 		[IEEE80211_SMPS_AUTOMATIC] = "auto",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 		[IEEE80211_SMPS_OFF] = "off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 		[IEEE80211_SMPS_STATIC] = "static",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 		[IEEE80211_SMPS_DYNAMIC] = "dynamic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	if (conf->chandef.chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 		wiphy_dbg(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 			  "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 			  __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 			  conf->chandef.chan->center_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 			  conf->chandef.center_freq1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 			  conf->chandef.center_freq2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 			  hwsim_chanwidths[conf->chandef.width],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 			  !!(conf->flags & IEEE80211_CONF_IDLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 			  !!(conf->flags & IEEE80211_CONF_PS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 			  smps_modes[conf->smps_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		wiphy_dbg(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 			  "%s (freq=0 idle=%d ps=%d smps=%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 			  __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 			  !!(conf->flags & IEEE80211_CONF_IDLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 			  !!(conf->flags & IEEE80211_CONF_PS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 			  smps_modes[conf->smps_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	WARN_ON(conf->chandef.chan && data->use_chanctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	mutex_lock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	if (data->scanning && conf->chandef.chan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		for (idx = 0; idx < ARRAY_SIZE(data->survey_data); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 			if (data->survey_data[idx].channel == data->channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 				data->survey_data[idx].start =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 					data->survey_data[idx].next_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 				data->survey_data[idx].end = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 		data->channel = conf->chandef.chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 		for (idx = 0; idx < ARRAY_SIZE(data->survey_data); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 			if (data->survey_data[idx].channel &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 			    data->survey_data[idx].channel != data->channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 			data->survey_data[idx].channel = data->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 			data->survey_data[idx].next_start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 		data->channel = conf->chandef.chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	mutex_unlock(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	if (!data->started || !data->beacon_int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 		hrtimer_cancel(&data->beacon_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	else if (!hrtimer_is_queued(&data->beacon_timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 		u64 tsf = mac80211_hwsim_get_tsf(hw, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 		u32 bcn_int = data->beacon_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 		u64 until_tbtt = bcn_int - do_div(tsf, bcn_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 		hrtimer_start(&data->beacon_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 			      ns_to_ktime(until_tbtt * NSEC_PER_USEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 			      HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 					    unsigned int changed_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 					    unsigned int *total_flags,u64 multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	wiphy_dbg(hw->wiphy, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	data->rx_filter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	if (*total_flags & FIF_ALLMULTI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 		data->rx_filter |= FIF_ALLMULTI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	if (*total_flags & FIF_MCAST_ACTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 		data->rx_filter |= FIF_MCAST_ACTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	*total_flags = data->rx_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) static void mac80211_hwsim_bcn_en_iter(void *data, u8 *mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 				       struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	unsigned int *count = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	if (vp->bcn_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		(*count)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 					    struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 					    struct ieee80211_bss_conf *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 					    u32 changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	struct mac80211_hwsim_data *data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	wiphy_dbg(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		  __func__, changed, vif->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	if (changed & BSS_CHANGED_BSSID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 		wiphy_dbg(hw->wiphy, "%s: BSSID changed: %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 			  __func__, info->bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		memcpy(vp->bssid, info->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	if (changed & BSS_CHANGED_ASSOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 		wiphy_dbg(hw->wiphy, "  ASSOC: assoc=%d aid=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 			  info->assoc, info->aid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 		vp->assoc = info->assoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 		vp->aid = info->aid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 		wiphy_dbg(hw->wiphy, "  BCN EN: %d (BI=%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 			  info->enable_beacon, info->beacon_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 		vp->bcn_en = info->enable_beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 		if (data->started &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 		    !hrtimer_is_queued(&data->beacon_timer) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 		    info->enable_beacon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 			u64 tsf, until_tbtt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 			u32 bcn_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 			data->beacon_int = info->beacon_int * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 			tsf = mac80211_hwsim_get_tsf(hw, vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 			bcn_int = data->beacon_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 			until_tbtt = bcn_int - do_div(tsf, bcn_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 			hrtimer_start(&data->beacon_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 				      ns_to_ktime(until_tbtt * NSEC_PER_USEC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 				      HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		} else if (!info->enable_beacon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 			unsigned int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 			ieee80211_iterate_active_interfaces_atomic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 				data->hw, IEEE80211_IFACE_ITER_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 				mac80211_hwsim_bcn_en_iter, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 			wiphy_dbg(hw->wiphy, "  beaconing vifs remaining: %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 				  count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 			if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 				hrtimer_cancel(&data->beacon_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 				data->beacon_int = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 		wiphy_dbg(hw->wiphy, "  ERP_CTS_PROT: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 			  info->use_cts_prot);
^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) 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 		wiphy_dbg(hw->wiphy, "  ERP_PREAMBLE: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 			  info->use_short_preamble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	if (changed & BSS_CHANGED_ERP_SLOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		wiphy_dbg(hw->wiphy, "  ERP_SLOT: %d\n", info->use_short_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	if (changed & BSS_CHANGED_HT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 		wiphy_dbg(hw->wiphy, "  HT: op_mode=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 			  info->ht_operation_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	if (changed & BSS_CHANGED_BASIC_RATES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 		wiphy_dbg(hw->wiphy, "  BASIC_RATES: 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 			  (unsigned long long) info->basic_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	if (changed & BSS_CHANGED_TXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 		wiphy_dbg(hw->wiphy, "  TX Power: %d dBm\n", info->txpower);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 				  struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 				  struct ieee80211_sta *sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	hwsim_set_sta_magic(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) static int mac80211_hwsim_sta_remove(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 				     struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 				     struct ieee80211_sta *sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	hwsim_clear_sta_magic(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 				      struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 				      enum sta_notify_cmd cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 				      struct ieee80211_sta *sta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	case STA_NOTIFY_SLEEP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	case STA_NOTIFY_AWAKE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 		/* TODO: make good use of these flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 		WARN(1, "Invalid sta notify: %d\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) static int mac80211_hwsim_set_tim(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 				  struct ieee80211_sta *sta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 				  bool set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	hwsim_check_sta_magic(sta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) static int mac80211_hwsim_conf_tx(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	struct ieee80211_vif *vif, u16 queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	const struct ieee80211_tx_queue_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	wiphy_dbg(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 		  "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 		  __func__, queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 		  params->txop, params->cw_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 		  params->cw_max, params->aifs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) static int mac80211_hwsim_get_survey(struct ieee80211_hw *hw, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 				     struct survey_info *survey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	if (idx < 0 || idx >= ARRAY_SIZE(hwsim->survey_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	survey->channel = hwsim->survey_data[idx].channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	if (!survey->channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 		mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	 * Magically conjured dummy values --- this is only ok for simulated hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	 * A real driver which cannot determine real values noise MUST NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	 * report any, especially not a magically conjured ones :-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	survey->filled = SURVEY_INFO_NOISE_DBM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 			 SURVEY_INFO_TIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 			 SURVEY_INFO_TIME_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	survey->noise = -92;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	survey->time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		jiffies_to_msecs(hwsim->survey_data[idx].end -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 				 hwsim->survey_data[idx].start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	/* report 12.5% of channel time is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	survey->time_busy = survey->time/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) #ifdef CONFIG_NL80211_TESTMODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)  * This section contains example code for using netlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)  * attributes with the testmode command in nl80211.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) /* These enums need to be kept in sync with userspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) enum hwsim_testmode_attr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	__HWSIM_TM_ATTR_INVALID	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	HWSIM_TM_ATTR_CMD	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 	HWSIM_TM_ATTR_PS	= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	/* keep last */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 	__HWSIM_TM_ATTR_AFTER_LAST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	HWSIM_TM_ATTR_MAX	= __HWSIM_TM_ATTR_AFTER_LAST - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) enum hwsim_testmode_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 	HWSIM_TM_CMD_SET_PS		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	HWSIM_TM_CMD_GET_PS		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	HWSIM_TM_CMD_STOP_QUEUES	= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	HWSIM_TM_CMD_WAKE_QUEUES	= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	[HWSIM_TM_ATTR_CMD] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	[HWSIM_TM_ATTR_PS] = { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 				       struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 				       void *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	struct nlattr *tb[HWSIM_TM_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	int err, ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	err = nla_parse_deprecated(tb, HWSIM_TM_ATTR_MAX, data, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 				   hwsim_testmode_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	if (!tb[HWSIM_TM_ATTR_CMD])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	switch (nla_get_u32(tb[HWSIM_TM_ATTR_CMD])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	case HWSIM_TM_CMD_SET_PS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		if (!tb[HWSIM_TM_ATTR_PS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 		ps = nla_get_u32(tb[HWSIM_TM_ATTR_PS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 		return hwsim_fops_ps_write(hwsim, ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	case HWSIM_TM_CMD_GET_PS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 						nla_total_size(sizeof(u32)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 		if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		if (nla_put_u32(skb, HWSIM_TM_ATTR_PS, hwsim->ps))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 		return cfg80211_testmode_reply(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	case HWSIM_TM_CMD_STOP_QUEUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 		ieee80211_stop_queues(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	case HWSIM_TM_CMD_WAKE_QUEUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 		ieee80211_wake_queues(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)  nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 				       struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 				       struct ieee80211_ampdu_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 	struct ieee80211_sta *sta = params->sta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	enum ieee80211_ampdu_mlme_action action = params->action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 	u16 tid = params->tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	case IEEE80211_AMPDU_TX_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 		return IEEE80211_AMPDU_TX_START_IMMEDIATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	case IEEE80211_AMPDU_TX_STOP_CONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	case IEEE80211_AMPDU_TX_STOP_FLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	case IEEE80211_AMPDU_TX_OPERATIONAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 	case IEEE80211_AMPDU_RX_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	case IEEE80211_AMPDU_RX_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) static void mac80211_hwsim_flush(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 				 struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 				 u32 queues, bool drop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	/* Not implemented, queues only on kernel side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) static void hw_scan_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	struct mac80211_hwsim_data *hwsim =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 		container_of(work, struct mac80211_hwsim_data, hw_scan.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	struct cfg80211_scan_request *req = hwsim->hw_scan_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	int dwell, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	if (hwsim->scan_chan_idx >= req->n_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 		struct cfg80211_scan_info info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 			.aborted = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 		wiphy_dbg(hwsim->hw->wiphy, "hw scan complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 		ieee80211_scan_completed(hwsim->hw, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 		hwsim->hw_scan_request = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 		hwsim->hw_scan_vif = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 		hwsim->tmp_chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 		mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		mac80211_hwsim_config_mac_nl(hwsim->hw, hwsim->scan_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 					     false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	wiphy_dbg(hwsim->hw->wiphy, "hw scan %d MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 		  req->channels[hwsim->scan_chan_idx]->center_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	if (hwsim->tmp_chan->flags & (IEEE80211_CHAN_NO_IR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 				      IEEE80211_CHAN_RADAR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	    !req->n_ssids) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 		dwell = 120;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 		dwell = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 		/* send probes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 		for (i = 0; i < req->n_ssids; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 			struct sk_buff *probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 			struct ieee80211_mgmt *mgmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 			probe = ieee80211_probereq_get(hwsim->hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 						       hwsim->scan_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 						       req->ssids[i].ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 						       req->ssids[i].ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 						       req->ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 			if (!probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 			mgmt = (struct ieee80211_mgmt *) probe->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 			memcpy(mgmt->da, req->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 			memcpy(mgmt->bssid, req->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 			if (req->ie_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 				skb_put_data(probe, req->ie, req->ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 			if (!ieee80211_tx_prepare_skb(hwsim->hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 						      hwsim->hw_scan_vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 						      probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 						      hwsim->tmp_chan->band,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 						      NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 				kfree_skb(probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 			local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 			mac80211_hwsim_tx_frame(hwsim->hw, probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 						hwsim->tmp_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 			local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 				     msecs_to_jiffies(dwell));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	hwsim->survey_data[hwsim->scan_chan_idx].channel = hwsim->tmp_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	hwsim->survey_data[hwsim->scan_chan_idx].start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	hwsim->survey_data[hwsim->scan_chan_idx].end =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 		jiffies + msecs_to_jiffies(dwell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	hwsim->scan_chan_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 				  struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 				  struct ieee80211_scan_request *hw_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	struct cfg80211_scan_request *req = &hw_req->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 		mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	hwsim->hw_scan_request = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	hwsim->hw_scan_vif = vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	hwsim->scan_chan_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 	if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 		get_random_mask_addr(hwsim->scan_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 				     hw_req->req.mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 				     hw_req->req.mac_addr_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 		memcpy(hwsim->scan_addr, vif->addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	wiphy_dbg(hw->wiphy, "hwsim hw_scan request\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 					  struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	struct cfg80211_scan_info info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 		.aborted = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	wiphy_dbg(hw->wiphy, "hwsim cancel_hw_scan\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	cancel_delayed_work_sync(&hwsim->hw_scan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	ieee80211_scan_completed(hwsim->hw, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	hwsim->tmp_chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	hwsim->hw_scan_request = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	hwsim->hw_scan_vif = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 				   struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 				   const u8 *mac_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	if (hwsim->scanning) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 		pr_debug("two hwsim sw_scans detected!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	pr_debug("hwsim sw_scan request, prepping stuff\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	hwsim->scanning = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 					    struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	pr_debug("hwsim sw_scan_complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	hwsim->scanning = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	eth_zero_addr(hwsim->scan_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) static void hw_roc_start(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	struct mac80211_hwsim_data *hwsim =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 		container_of(work, struct mac80211_hwsim_data, roc_start.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	wiphy_dbg(hwsim->hw->wiphy, "hwsim ROC begins\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	hwsim->tmp_chan = hwsim->roc_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	ieee80211_ready_on_channel(hwsim->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	ieee80211_queue_delayed_work(hwsim->hw, &hwsim->roc_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 				     msecs_to_jiffies(hwsim->roc_duration));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) static void hw_roc_done(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	struct mac80211_hwsim_data *hwsim =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 		container_of(work, struct mac80211_hwsim_data, roc_done.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	ieee80211_remain_on_channel_expired(hwsim->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	hwsim->tmp_chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	wiphy_dbg(hwsim->hw->wiphy, "hwsim ROC expired\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 			      struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 			      struct ieee80211_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 			      int duration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 			      enum ieee80211_roc_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	hwsim->roc_chan = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	hwsim->roc_duration = duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	wiphy_dbg(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 		  chan->center_freq, duration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	ieee80211_queue_delayed_work(hw, &hwsim->roc_start, HZ/50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) static int mac80211_hwsim_croc(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 			       struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	cancel_delayed_work_sync(&hwsim->roc_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	cancel_delayed_work_sync(&hwsim->roc_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	hwsim->tmp_chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	wiphy_dbg(hw->wiphy, "hwsim ROC canceled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 				      struct ieee80211_chanctx_conf *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	hwsim->chanctx = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	hwsim_set_chanctx_magic(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	wiphy_dbg(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		  "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 		  ctx->def.chan->center_freq, ctx->def.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 		  ctx->def.center_freq1, ctx->def.center_freq2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 					  struct ieee80211_chanctx_conf *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	hwsim->chanctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	wiphy_dbg(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		  "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 		  ctx->def.chan->center_freq, ctx->def.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 		  ctx->def.center_freq1, ctx->def.center_freq2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 	hwsim_check_chanctx_magic(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	hwsim_clear_chanctx_magic(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 					  struct ieee80211_chanctx_conf *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 					  u32 changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	struct mac80211_hwsim_data *hwsim = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	mutex_lock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	hwsim->chanctx = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	mutex_unlock(&hwsim->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	hwsim_check_chanctx_magic(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	wiphy_dbg(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		  "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 		  ctx->def.chan->center_freq, ctx->def.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 		  ctx->def.center_freq1, ctx->def.center_freq2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 					     struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 					     struct ieee80211_chanctx_conf *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	hwsim_check_chanctx_magic(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 						struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 						struct ieee80211_chanctx_conf *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	hwsim_check_magic(vif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	hwsim_check_chanctx_magic(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	"tx_pkts_nic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	"tx_bytes_nic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	"rx_pkts_nic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	"rx_bytes_nic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	"d_tx_dropped",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	"d_tx_failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	"d_ps_mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	"d_group",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) #define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) static void mac80211_hwsim_get_et_strings(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 					  struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 					  u32 sset, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	if (sset == ETH_SS_STATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 		memcpy(data, *mac80211_hwsim_gstrings_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 		       sizeof(mac80211_hwsim_gstrings_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) static int mac80211_hwsim_get_et_sset_count(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 					    struct ieee80211_vif *vif, int sset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	if (sset == ETH_SS_STATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		return MAC80211_HWSIM_SSTATS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) static void mac80211_hwsim_get_et_stats(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 					struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 					struct ethtool_stats *stats, u64 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	struct mac80211_hwsim_data *ar = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 	data[i++] = ar->tx_pkts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	data[i++] = ar->tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	data[i++] = ar->rx_pkts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	data[i++] = ar->rx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 	data[i++] = ar->tx_dropped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	data[i++] = ar->tx_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 	data[i++] = ar->ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	data[i++] = ar->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) static int mac80211_hwsim_tx_last_beacon(struct ieee80211_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) #define HWSIM_COMMON_OPS					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	.tx = mac80211_hwsim_tx,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	.start = mac80211_hwsim_start,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	.stop = mac80211_hwsim_stop,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	.add_interface = mac80211_hwsim_add_interface,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	.change_interface = mac80211_hwsim_change_interface,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	.remove_interface = mac80211_hwsim_remove_interface,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	.config = mac80211_hwsim_config,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 	.configure_filter = mac80211_hwsim_configure_filter,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	.bss_info_changed = mac80211_hwsim_bss_info_changed,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	.tx_last_beacon = mac80211_hwsim_tx_last_beacon,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	.sta_add = mac80211_hwsim_sta_add,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	.sta_remove = mac80211_hwsim_sta_remove,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	.sta_notify = mac80211_hwsim_sta_notify,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	.set_tim = mac80211_hwsim_set_tim,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	.conf_tx = mac80211_hwsim_conf_tx,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	.get_survey = mac80211_hwsim_get_survey,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	.ampdu_action = mac80211_hwsim_ampdu_action,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	.flush = mac80211_hwsim_flush,				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	.get_tsf = mac80211_hwsim_get_tsf,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	.set_tsf = mac80211_hwsim_set_tsf,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	.get_et_sset_count = mac80211_hwsim_get_et_sset_count,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 	.get_et_stats = mac80211_hwsim_get_et_stats,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	.get_et_strings = mac80211_hwsim_get_et_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) static const struct ieee80211_ops mac80211_hwsim_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	HWSIM_COMMON_OPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 	.sw_scan_start = mac80211_hwsim_sw_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	.sw_scan_complete = mac80211_hwsim_sw_scan_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) static const struct ieee80211_ops mac80211_hwsim_mchan_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	HWSIM_COMMON_OPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	.hw_scan = mac80211_hwsim_hw_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 	.sw_scan_start = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	.sw_scan_complete = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	.remain_on_channel = mac80211_hwsim_roc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	.cancel_remain_on_channel = mac80211_hwsim_croc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	.add_chanctx = mac80211_hwsim_add_chanctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	.remove_chanctx = mac80211_hwsim_remove_chanctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	.change_chanctx = mac80211_hwsim_change_chanctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	.assign_vif_chanctx = mac80211_hwsim_assign_vif_chanctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	.unassign_vif_chanctx = mac80211_hwsim_unassign_vif_chanctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) struct hwsim_new_radio_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	unsigned int channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	const char *reg_alpha2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	const struct ieee80211_regdomain *regd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	bool reg_strict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	bool p2p_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	bool use_chanctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	bool destroy_on_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	const char *hwname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	bool no_vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	const u8 *perm_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	u32 iftypes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	u32 *ciphers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	u8 n_ciphers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 				   struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	if (info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 		genl_notify(&hwsim_genl_family, mcast_skb, info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 			    HWSIM_MCGRP_CONFIG, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 		genlmsg_multicast(&hwsim_genl_family, mcast_skb, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 				  HWSIM_MCGRP_CONFIG, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) static int append_radio_msg(struct sk_buff *skb, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 			    struct hwsim_new_radio_params *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	ret = nla_put_u32(skb, HWSIM_ATTR_RADIO_ID, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 	if (param->channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 		ret = nla_put_u32(skb, HWSIM_ATTR_CHANNELS, param->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	if (param->reg_alpha2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 		ret = nla_put(skb, HWSIM_ATTR_REG_HINT_ALPHA2, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 			      param->reg_alpha2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	if (param->regd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		for (i = 0; i < ARRAY_SIZE(hwsim_world_regdom_custom); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 			if (hwsim_world_regdom_custom[i] != param->regd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 			ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	if (param->reg_strict) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 		ret = nla_put_flag(skb, HWSIM_ATTR_REG_STRICT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	if (param->p2p_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 		ret = nla_put_flag(skb, HWSIM_ATTR_SUPPORT_P2P_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	if (param->use_chanctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 		ret = nla_put_flag(skb, HWSIM_ATTR_USE_CHANCTX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	if (param->hwname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 		ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 			      strlen(param->hwname), param->hwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) static void hwsim_mcast_new_radio(int id, struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 				  struct hwsim_new_radio_params *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	struct sk_buff *mcast_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 	mcast_skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 	if (!mcast_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 	data = genlmsg_put(mcast_skb, 0, 0, &hwsim_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 			   HWSIM_CMD_NEW_RADIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	if (append_radio_msg(mcast_skb, id, param) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 	genlmsg_end(mcast_skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	hwsim_mcast_config_msg(mcast_skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	nlmsg_free(mcast_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) static const struct ieee80211_sband_iftype_data he_capa_2ghz[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		/* TODO: should we support other types, e.g., P2P?*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 		.types_mask = BIT(NL80211_IFTYPE_STATION) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 			      BIT(NL80211_IFTYPE_AP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 		.he_cap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 			.has_he = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 			.he_cap_elem = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 				.mac_cap_info[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 					IEEE80211_HE_MAC_CAP0_HTC_HE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 				.mac_cap_info[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 					IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 					IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 				.mac_cap_info[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 					IEEE80211_HE_MAC_CAP2_BSR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 					IEEE80211_HE_MAC_CAP2_MU_CASCADING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 					IEEE80211_HE_MAC_CAP2_ACK_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 				.mac_cap_info[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 					IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 					IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 				.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 				.phy_cap_info[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 					IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 					IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 					IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 					IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 				.phy_cap_info[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 					IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 					IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 					IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 					IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 					IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 				/* Leave all the other PHY capability bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 				 * unset, as DCM, beam forming, RU and PPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 				 * threshold information are not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 			.he_mcs_nss_supp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 				.rx_mcs_80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 				.tx_mcs_80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 				.rx_mcs_160 = cpu_to_le16(0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 				.tx_mcs_160 = cpu_to_le16(0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 				.rx_mcs_80p80 = cpu_to_le16(0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 				.tx_mcs_80p80 = cpu_to_le16(0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 		/* TODO: should we support other types, e.g., IBSS?*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 		.types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 		.he_cap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 			.has_he = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 			.he_cap_elem = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 				.mac_cap_info[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 					IEEE80211_HE_MAC_CAP0_HTC_HE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 				.mac_cap_info[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 					IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 				.mac_cap_info[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 					IEEE80211_HE_MAC_CAP2_ACK_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 				.mac_cap_info[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 					IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 					IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 				.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 				.phy_cap_info[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 					IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 					IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 					IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 					IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 				.phy_cap_info[2] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 				/* Leave all the other PHY capability bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 				 * unset, as DCM, beam forming, RU and PPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 				 * threshold information are not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 			.he_mcs_nss_supp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 				.rx_mcs_80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 				.tx_mcs_80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 				.rx_mcs_160 = cpu_to_le16(0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 				.tx_mcs_160 = cpu_to_le16(0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 				.rx_mcs_80p80 = cpu_to_le16(0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 				.tx_mcs_80p80 = cpu_to_le16(0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) static const struct ieee80211_sband_iftype_data he_capa_5ghz[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		/* TODO: should we support other types, e.g., P2P?*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		.types_mask = BIT(NL80211_IFTYPE_STATION) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 			      BIT(NL80211_IFTYPE_AP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 		.he_cap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 			.has_he = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 			.he_cap_elem = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 				.mac_cap_info[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 					IEEE80211_HE_MAC_CAP0_HTC_HE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 				.mac_cap_info[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 					IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 					IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 				.mac_cap_info[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 					IEEE80211_HE_MAC_CAP2_BSR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 					IEEE80211_HE_MAC_CAP2_MU_CASCADING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 					IEEE80211_HE_MAC_CAP2_ACK_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 				.mac_cap_info[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 					IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 					IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 				.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 				.phy_cap_info[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 				.phy_cap_info[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 					IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 					IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 					IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 					IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 				.phy_cap_info[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 					IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 					IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 					IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 					IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 					IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 				/* Leave all the other PHY capability bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 				 * unset, as DCM, beam forming, RU and PPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 				 * threshold information are not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 			.he_mcs_nss_supp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 				.rx_mcs_80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 				.tx_mcs_80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 				.rx_mcs_160 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 				.tx_mcs_160 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 				.rx_mcs_80p80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 				.tx_mcs_80p80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 		/* TODO: should we support other types, e.g., IBSS?*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 		.types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 		.he_cap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 			.has_he = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 			.he_cap_elem = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 				.mac_cap_info[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 					IEEE80211_HE_MAC_CAP0_HTC_HE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 				.mac_cap_info[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 					IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 				.mac_cap_info[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 					IEEE80211_HE_MAC_CAP2_ACK_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 				.mac_cap_info[3] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 					IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 					IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 				.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 				.phy_cap_info[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 				.phy_cap_info[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 					IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 					IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 					IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 					IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 				.phy_cap_info[2] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 				/* Leave all the other PHY capability bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 				 * unset, as DCM, beam forming, RU and PPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 				 * threshold information are not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 			.he_mcs_nss_supp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 				.rx_mcs_80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 				.tx_mcs_80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 				.rx_mcs_160 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 				.tx_mcs_160 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 				.rx_mcs_80p80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 				.tx_mcs_80p80 = cpu_to_le16(0xfffa),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) static void mac80211_hwsim_he_capab(struct ieee80211_supported_band *sband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	u16 n_iftype_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	if (sband->band == NL80211_BAND_2GHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 		n_iftype_data = ARRAY_SIZE(he_capa_2ghz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 		sband->iftype_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 			(struct ieee80211_sband_iftype_data *)he_capa_2ghz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	} else if (sband->band == NL80211_BAND_5GHZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		n_iftype_data = ARRAY_SIZE(he_capa_5ghz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 		sband->iftype_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 			(struct ieee80211_sband_iftype_data *)he_capa_5ghz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 	sband->n_iftype_data = n_iftype_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) #ifdef CONFIG_MAC80211_MESH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) #define HWSIM_MESH_BIT BIT(NL80211_IFTYPE_MESH_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) #define HWSIM_MESH_BIT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) #define HWSIM_DEFAULT_IF_LIMIT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	(BIT(NL80211_IFTYPE_STATION) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 	 BIT(NL80211_IFTYPE_P2P_CLIENT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	 BIT(NL80211_IFTYPE_AP) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 	 BIT(NL80211_IFTYPE_P2P_GO) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	 HWSIM_MESH_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) #define HWSIM_IFTYPE_SUPPORT_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	(BIT(NL80211_IFTYPE_STATION) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	 BIT(NL80211_IFTYPE_AP) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	 BIT(NL80211_IFTYPE_P2P_CLIENT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	 BIT(NL80211_IFTYPE_P2P_GO) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	 BIT(NL80211_IFTYPE_ADHOC) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	 BIT(NL80211_IFTYPE_MESH_POINT) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 	 BIT(NL80211_IFTYPE_OCB))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) static int mac80211_hwsim_new_radio(struct genl_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 				    struct hwsim_new_radio_params *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 	u8 addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 	struct mac80211_hwsim_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 	struct ieee80211_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 	const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 	struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 	int idx, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	int n_limits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	if (WARN_ON(param->channels > 1 && !param->use_chanctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	idx = hwsim_radio_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	if (param->use_chanctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 		ops = &mac80211_hwsim_mchan_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, param->hwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	if (!hw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 		pr_debug("mac80211_hwsim: ieee80211_alloc_hw failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	/* ieee80211_alloc_hw_nm may have used a default name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	param->hwname = wiphy_name(hw->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	if (info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 		net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 		net = &init_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 	wiphy_net_set(hw->wiphy, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 	data = hw->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 	data->hw = hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	data->dev = device_create(hwsim_class, NULL, 0, hw, "hwsim%d", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	if (IS_ERR(data->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 		printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 		       "mac80211_hwsim: device_create failed (%ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 		       PTR_ERR(data->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 		goto failed_drvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	data->dev->driver = &mac80211_hwsim_driver.driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	err = device_bind_driver(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	if (err != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 		pr_debug("mac80211_hwsim: device_bind_driver failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 		       err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 		goto failed_bind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	skb_queue_head_init(&data->pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	SET_IEEE80211_DEV(hw, data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	if (!param->perm_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 		eth_zero_addr(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 		addr[0] = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 		addr[1] = (mac_prefix >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 		addr[2] = mac_prefix & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 		addr[3] = idx >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 		addr[4] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 		memcpy(data->addresses[0].addr, addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 		/* Why need here second address ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 		memcpy(data->addresses[1].addr, addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 		data->addresses[1].addr[0] |= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 		hw->wiphy->n_addresses = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 		hw->wiphy->addresses = data->addresses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 		/* possible address clash is checked at hash table insertion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 		memcpy(data->addresses[0].addr, param->perm_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 		/* compatibility with automatically generated mac addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 		memcpy(data->addresses[1].addr, param->perm_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 		hw->wiphy->n_addresses = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 		hw->wiphy->addresses = data->addresses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 	data->channels = param->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	data->use_chanctx = param->use_chanctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 	data->idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	data->destroy_on_close = param->destroy_on_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	if (info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 		data->portid = info->snd_portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	/* setup interface limits, only on interface types we support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	if (param->iftypes & BIT(NL80211_IFTYPE_ADHOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 		data->if_limits[n_limits].max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		data->if_limits[n_limits].types = BIT(NL80211_IFTYPE_ADHOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 		n_limits++;
^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) 	if (param->iftypes & HWSIM_DEFAULT_IF_LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 		data->if_limits[n_limits].max = 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 		 * For this case, we may only support a subset of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 		 * HWSIM_DEFAULT_IF_LIMIT, therefore we only want to add the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 		 * bits that both param->iftype & HWSIM_DEFAULT_IF_LIMIT have.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 		data->if_limits[n_limits].types =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 					HWSIM_DEFAULT_IF_LIMIT & param->iftypes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 		n_limits++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 	if (param->iftypes & BIT(NL80211_IFTYPE_P2P_DEVICE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 		data->if_limits[n_limits].max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 		data->if_limits[n_limits].types =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 						BIT(NL80211_IFTYPE_P2P_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 		n_limits++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 	if (data->use_chanctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 		hw->wiphy->max_scan_ssids = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 		hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 		hw->wiphy->max_remain_on_channel_duration = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 		data->if_combination.radar_detect_widths = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 		data->if_combination.num_different_channels = data->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 		data->chanctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 		data->if_combination.num_different_channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 		data->if_combination.radar_detect_widths =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 					BIT(NL80211_CHAN_WIDTH_5) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 					BIT(NL80211_CHAN_WIDTH_10) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 					BIT(NL80211_CHAN_WIDTH_20_NOHT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 					BIT(NL80211_CHAN_WIDTH_20) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 					BIT(NL80211_CHAN_WIDTH_40) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 					BIT(NL80211_CHAN_WIDTH_80) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 					BIT(NL80211_CHAN_WIDTH_160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	if (!n_limits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 		goto failed_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	data->if_combination.max_interfaces = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 	for (i = 0; i < n_limits; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 		data->if_combination.max_interfaces +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 			data->if_limits[i].max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 	data->if_combination.n_limits = n_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 	data->if_combination.limits = data->if_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 	 * If we actually were asked to support combinations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	 * advertise them - if there's only a single thing like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	 * only IBSS then don't advertise it as combinations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	if (data->if_combination.max_interfaces > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 		hw->wiphy->iface_combinations = &data->if_combination;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 		hw->wiphy->n_iface_combinations = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 	if (param->ciphers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 		memcpy(data->ciphers, param->ciphers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 		       param->n_ciphers * sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 		hw->wiphy->cipher_suites = data->ciphers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 		hw->wiphy->n_cipher_suites = param->n_ciphers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 	INIT_DELAYED_WORK(&data->roc_start, hw_roc_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 	INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 	hw->queues = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	hw->offchannel_tx_hw_queue = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 	ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	ieee80211_hw_set(hw, CHANCTX_STA_CSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	ieee80211_hw_set(hw, QUEUE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 	ieee80211_hw_set(hw, WANT_MONITOR_VIF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	ieee80211_hw_set(hw, AMPDU_AGGREGATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 	ieee80211_hw_set(hw, MFP_CAPABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	ieee80211_hw_set(hw, SIGNAL_DBM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 	ieee80211_hw_set(hw, SUPPORTS_PS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 	ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	ieee80211_hw_set(hw, PS_NULLFUNC_STACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	ieee80211_hw_set(hw, TDLS_WIDER_BW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	if (rctbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 	ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 			    WIPHY_FLAG_AP_UAPSD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 			    WIPHY_FLAG_SUPPORTS_5_10_MHZ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 			    WIPHY_FLAG_HAS_CHANNEL_SWITCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 			       NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 			       NL80211_FEATURE_STATIC_SMPS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 			       NL80211_FEATURE_DYNAMIC_SMPS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 			       NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 	wiphy_ext_feature_set(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 			      NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 	wiphy_ext_feature_set(hw->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 			      NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 	hw->wiphy->interface_modes = param->iftypes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 	/* ask mac80211 to reserve space for magic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 	hw->vif_data_size = sizeof(struct hwsim_vif_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	hw->sta_data_size = sizeof(struct hwsim_sta_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 	hw->chanctx_data_size = sizeof(struct hwsim_chanctx_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 	memcpy(data->channels_2ghz, hwsim_channels_2ghz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 		sizeof(hwsim_channels_2ghz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 	memcpy(data->channels_5ghz, hwsim_channels_5ghz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 		sizeof(hwsim_channels_5ghz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	memcpy(data->channels_s1g, hwsim_channels_s1g,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 	       sizeof(hwsim_channels_s1g));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 	memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 		struct ieee80211_supported_band *sband = &data->bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 		sband->band = band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 		switch (band) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 		case NL80211_BAND_2GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 			sband->channels = data->channels_2ghz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 			sband->n_channels = ARRAY_SIZE(hwsim_channels_2ghz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 			sband->bitrates = data->rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 			sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		case NL80211_BAND_5GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 			sband->channels = data->channels_5ghz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 			sband->n_channels = ARRAY_SIZE(hwsim_channels_5ghz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 			sband->bitrates = data->rates + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 			sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 			sband->vht_cap.vht_supported = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 			sband->vht_cap.cap =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 				IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 				IEEE80211_VHT_CAP_RXLDPC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 				IEEE80211_VHT_CAP_SHORT_GI_80 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 				IEEE80211_VHT_CAP_SHORT_GI_160 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 				IEEE80211_VHT_CAP_TXSTBC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 				IEEE80211_VHT_CAP_RXSTBC_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 				IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 			sband->vht_cap.vht_mcs.rx_mcs_map =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 				cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 					    IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 					    IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 					    IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 					    IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 					    IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 					    IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 					    IEEE80211_VHT_MCS_SUPPORT_0_9 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 			sband->vht_cap.vht_mcs.tx_mcs_map =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 				sband->vht_cap.vht_mcs.rx_mcs_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 		case NL80211_BAND_S1GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 			memcpy(&sband->s1g_cap, &hwsim_s1g_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 			       sizeof(sband->s1g_cap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 			sband->channels = data->channels_s1g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 			sband->n_channels = ARRAY_SIZE(hwsim_channels_s1g);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 		sband->ht_cap.ht_supported = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 		sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 				    IEEE80211_HT_CAP_GRN_FLD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 				    IEEE80211_HT_CAP_SGI_20 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 				    IEEE80211_HT_CAP_SGI_40 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 				    IEEE80211_HT_CAP_DSSSCCK40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 		sband->ht_cap.ampdu_factor = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		sband->ht_cap.ampdu_density = 0x6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 		memset(&sband->ht_cap.mcs, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 		       sizeof(sband->ht_cap.mcs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 		sband->ht_cap.mcs.rx_mask[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 		sband->ht_cap.mcs.rx_mask[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 		sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 		mac80211_hwsim_he_capab(sband);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 		hw->wiphy->bands[band] = sband;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	/* By default all radios belong to the first group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 	data->group = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 	mutex_init(&data->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	data->netgroup = hwsim_net_get_netgroup(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	data->wmediumd = hwsim_net_get_wmediumd(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 	/* Enable frame retransmissions for lossy channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 	hw->max_rates = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 	hw->max_rate_tries = 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 	hw->wiphy->vendor_commands = mac80211_hwsim_vendor_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	hw->wiphy->n_vendor_commands =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 		ARRAY_SIZE(mac80211_hwsim_vendor_commands);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	hw->wiphy->vendor_events = mac80211_hwsim_vendor_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 	hw->wiphy->n_vendor_events = ARRAY_SIZE(mac80211_hwsim_vendor_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 	if (param->reg_strict)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 		hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 	if (param->regd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 		data->regd = param->regd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 		hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 		wiphy_apply_custom_regulatory(hw->wiphy, param->regd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 		/* give the regulatory workqueue a chance to run */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 		schedule_timeout_interruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 	if (param->no_vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 		ieee80211_hw_set(hw, NO_AUTO_VIF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 	hrtimer_init(&data->beacon_timer, CLOCK_MONOTONIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 		     HRTIMER_MODE_ABS_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 	data->beacon_timer.function = mac80211_hwsim_beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 	err = ieee80211_register_hw(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		pr_debug("mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 		       err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 		goto failed_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 	wiphy_dbg(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 	if (param->reg_alpha2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 		data->alpha2[0] = param->reg_alpha2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 		data->alpha2[1] = param->reg_alpha2[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 		regulatory_hint(hw->wiphy, param->reg_alpha2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 	data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 	debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 	debugfs_create_file("group", 0666, data->debugfs, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 			    &hwsim_fops_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 	if (!data->use_chanctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 		debugfs_create_file("dfs_simulate_radar", 0222,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 				    data->debugfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 				    data, &hwsim_simulate_radar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	err = rhashtable_insert_fast(&hwsim_radios_rht, &data->rht,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 				     hwsim_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 		if (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 			GENL_SET_ERR_MSG(info, "perm addr already present");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 			NL_SET_BAD_ATTR(info->extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 					info->attrs[HWSIM_ATTR_PERM_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 		spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 		goto failed_final_insert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 	list_add_tail(&data->list, &hwsim_radios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	hwsim_radios_generation++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 	hwsim_mcast_new_radio(idx, info, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 	return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) failed_final_insert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 	debugfs_remove_recursive(data->debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 	ieee80211_unregister_hw(data->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) failed_hw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	device_release_driver(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) failed_bind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	device_unregister(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) failed_drvdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	ieee80211_free_hw(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) static void hwsim_mcast_del_radio(int id, const char *hwname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 				  struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	data = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 			   HWSIM_CMD_DEL_RADIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 	ret = nla_put_u32(skb, HWSIM_ATTR_RADIO_ID, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 	ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, strlen(hwname),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 		      hwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	genlmsg_end(skb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 	hwsim_mcast_config_msg(skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 	nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) static void mac80211_hwsim_del_radio(struct mac80211_hwsim_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 				     const char *hwname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 				     struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 	hwsim_mcast_del_radio(data->idx, hwname, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 	debugfs_remove_recursive(data->debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 	ieee80211_unregister_hw(data->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 	device_release_driver(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 	device_unregister(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	ieee80211_free_hw(data->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) static int mac80211_hwsim_get_radio(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 				    struct mac80211_hwsim_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 				    u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 				    struct netlink_callback *cb, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 	struct hwsim_new_radio_params param = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	int res = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 	hdr = genlmsg_put(skb, portid, seq, &hwsim_genl_family, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 			  HWSIM_CMD_GET_RADIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	if (cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 		genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 	if (data->alpha2[0] && data->alpha2[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 		param.reg_alpha2 = data->alpha2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	param.reg_strict = !!(data->hw->wiphy->regulatory_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 					REGULATORY_STRICT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 	param.p2p_device = !!(data->hw->wiphy->interface_modes &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 					BIT(NL80211_IFTYPE_P2P_DEVICE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 	param.use_chanctx = data->use_chanctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 	param.regd = data->regd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 	param.channels = data->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 	param.hwname = wiphy_name(data->hw->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 	res = append_radio_msg(skb, data->idx, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 	genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 	genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) static void mac80211_hwsim_free(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 	struct mac80211_hwsim_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 	while ((data = list_first_entry_or_null(&hwsim_radios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 						struct mac80211_hwsim_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 						list))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 		list_del(&data->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 		spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 		mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 					 NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 		spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 	class_destroy(hwsim_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) static const struct net_device_ops hwsim_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 	.ndo_start_xmit 	= hwsim_mon_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 	.ndo_set_mac_address 	= eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 	.ndo_validate_addr	= eth_validate_addr,
^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) static void hwsim_mon_setup(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 	dev->netdev_ops = &hwsim_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 	dev->needs_free_netdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 	ether_setup(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 	dev->priv_flags |= IFF_NO_QUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 	dev->type = ARPHRD_IEEE80211_RADIOTAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 	eth_zero_addr(dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 	dev->dev_addr[0] = 0x12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 	return rhashtable_lookup_fast(&hwsim_radios_rht,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 				      addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 				      hwsim_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) static void hwsim_register_wmediumd(struct net *net, u32 portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 	struct mac80211_hwsim_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 	hwsim_net_set_wmediumd(net, portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 	list_for_each_entry(data, &hwsim_radios, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 		if (data->netgroup == hwsim_net_get_netgroup(net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 			data->wmediumd = portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 					   struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	struct ieee80211_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 	struct mac80211_hwsim_data *data2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 	struct ieee80211_tx_info *txi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 	struct hwsim_tx_rate *tx_attempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	u64 ret_skb_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 	struct sk_buff *skb, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 	const u8 *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	unsigned int hwsim_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 	    !info->attrs[HWSIM_ATTR_FLAGS] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	    !info->attrs[HWSIM_ATTR_COOKIE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 	    !info->attrs[HWSIM_ATTR_SIGNAL] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	    !info->attrs[HWSIM_ATTR_TX_INFO])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	src = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 	ret_skb_cookie = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	data2 = get_hwsim_data_ref_from_addr(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	if (!data2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 	if (!hwsim_virtio_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 		if (hwsim_net_get_netgroup(genl_info_net(info)) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 		    data2->netgroup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 		if (info->snd_portid != data2->wmediumd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	/* look for the skb matching the cookie passed back from user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	skb_queue_walk_safe(&data2->pending, skb, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 		u64 skb_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 		txi = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 		skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 		if (skb_cookie == ret_skb_cookie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 			skb_unlink(skb, &data2->pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 			break;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 	/* not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	/* Tx info received because the frame was broadcasted on user space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 	 so we get all the necessary info: tx attempts and skb control buff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	tx_attempts = (struct hwsim_tx_rate *)nla_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 		       info->attrs[HWSIM_ATTR_TX_INFO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 	/* now send back TX status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 	txi = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 	ieee80211_tx_info_clear_status(txi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 		txi->status.rates[i].idx = tx_attempts[i].idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 		txi->status.rates[i].count = tx_attempts[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 	txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 	if (!(hwsim_flags & HWSIM_TX_CTL_NO_ACK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 	   (hwsim_flags & HWSIM_TX_STAT_ACK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 		if (skb->len >= 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 			hdr = (struct ieee80211_hdr *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 			mac80211_hwsim_monitor_ack(data2->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 						   hdr->addr2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 		txi->flags |= IEEE80211_TX_STAT_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	if (hwsim_flags & HWSIM_TX_CTL_NO_ACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 		txi->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 	ieee80211_tx_status_irqsafe(data2->hw, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 					  struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 	struct mac80211_hwsim_data *data2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 	struct ieee80211_rx_status rx_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	struct ieee80211_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 	const u8 *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	int frame_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 	void *frame_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 	struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 	struct ieee80211_channel *channel = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 	if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 	    !info->attrs[HWSIM_ATTR_FRAME] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	    !info->attrs[HWSIM_ATTR_RX_RATE] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	    !info->attrs[HWSIM_ATTR_SIGNAL])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	dst = (void *)nla_data(info->attrs[HWSIM_ATTR_ADDR_RECEIVER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 	frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 	frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 	/* Allocate new skb here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	skb = alloc_skb(frame_data_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 	if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 	if (frame_data_len > IEEE80211_MAX_DATA_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 	/* Copy the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 	skb_put_data(skb, frame_data, frame_data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 	data2 = get_hwsim_data_ref_from_addr(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 	if (!data2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 	if (data2->use_chanctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 		if (data2->tmp_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 			channel = data2->tmp_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 		else if (data2->chanctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 			channel = data2->chanctx->def.chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 		channel = data2->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 	if (!channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 	if (!hwsim_virtio_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 		if (hwsim_net_get_netgroup(genl_info_net(info)) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 		    data2->netgroup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 		if (info->snd_portid != data2->wmediumd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	/* check if radio is configured properly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 	if ((data2->idle && !data2->tmp_chan) || !data2->started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 	/* A frame is received from user space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 	memset(&rx_status, 0, sizeof(rx_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 	if (info->attrs[HWSIM_ATTR_FREQ]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 		/* throw away off-channel packets, but allow both the temporary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 		 * ("hw" scan/remain-on-channel) and regular channel, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 		 * internal datapath also allows this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 		mutex_lock(&data2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 		rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 		if (rx_status.freq != channel->center_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 			mutex_unlock(&data2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 		mutex_unlock(&data2->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 		rx_status.freq = channel->center_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 	rx_status.band = channel->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 	rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 	hdr = (void *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 	if (ieee80211_is_beacon(hdr->frame_control) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 	    ieee80211_is_probe_resp(hdr->frame_control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 		rx_status.boottime_ns = ktime_get_boottime_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 	data2->rx_pkts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 	data2->rx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 	ieee80211_rx_irqsafe(data2->hw, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 	pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 	dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 	return -EINVAL;
^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) static int hwsim_register_received_nl(struct sk_buff *skb_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 				      struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 	struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 	struct mac80211_hwsim_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 	int chans = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 	list_for_each_entry(data, &hwsim_radios, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 		chans = max(chans, data->channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 	/* In the future we should revise the userspace API and allow it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 	 * to set a flag that it does support multi-channel, then we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 	 * let this pass conditionally on the flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 	 * For current userspace, prohibit it since it won't work right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 	if (chans > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 	if (hwsim_net_get_wmediumd(net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 	hwsim_register_wmediumd(net, info->snd_portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 	pr_debug("mac80211_hwsim: received a REGISTER, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 	       "switching to wmediumd mode with pid %d\n", info->snd_portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) /* ensures ciphers only include ciphers listed in 'hwsim_ciphers' array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) static bool hwsim_known_ciphers(const u32 *ciphers, int n_ciphers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 	for (i = 0; i < n_ciphers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 		int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 		int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 		for (j = 0; j < ARRAY_SIZE(hwsim_ciphers); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 			if (ciphers[i] == hwsim_ciphers[j]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 				found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 		if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 	struct hwsim_new_radio_params param = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 	const char *hwname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 	param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 	param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 	param.channels = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 	param.destroy_on_close =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 		info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 	if (info->attrs[HWSIM_ATTR_CHANNELS])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 		param.channels = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	if (param.channels < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 		GENL_SET_ERR_MSG(info, "must have at least one channel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 	if (param.channels > CFG80211_MAX_NUM_DIFFERENT_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 		GENL_SET_ERR_MSG(info, "too many channels specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 	if (info->attrs[HWSIM_ATTR_NO_VIF])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 		param.no_vif = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 	if (info->attrs[HWSIM_ATTR_USE_CHANCTX])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 		param.use_chanctx = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 		param.use_chanctx = (param.channels > 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 	if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 		param.reg_alpha2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 			nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 	if (info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 		u32 idx = nla_get_u32(info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 		if (idx >= ARRAY_SIZE(hwsim_world_regdom_custom))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 		idx = array_index_nospec(idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 					 ARRAY_SIZE(hwsim_world_regdom_custom));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 		param.regd = hwsim_world_regdom_custom[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 	if (info->attrs[HWSIM_ATTR_PERM_ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 		if (!is_valid_ether_addr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 				nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 			GENL_SET_ERR_MSG(info,"MAC is no valid source addr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 			NL_SET_BAD_ATTR(info->extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 					info->attrs[HWSIM_ATTR_PERM_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 		param.perm_addr = nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 	if (info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 		param.iftypes =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 			nla_get_u32(info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 		if (param.iftypes & ~HWSIM_IFTYPE_SUPPORT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 			NL_SET_ERR_MSG_ATTR(info->extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 					    info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 					    "cannot support more iftypes than kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 		param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 	/* ensure both flag and iftype support is honored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 	if (param.p2p_device ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 	    param.iftypes & BIT(NL80211_IFTYPE_P2P_DEVICE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 		param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 		param.p2p_device = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 	if (info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 		u32 len = nla_len(info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 		param.ciphers =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 			nla_data(info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 		if (len % sizeof(u32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 			NL_SET_ERR_MSG_ATTR(info->extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 					    info->attrs[HWSIM_ATTR_CIPHER_SUPPORT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 					    "bad cipher list length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 		param.n_ciphers = len / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 		if (param.n_ciphers > ARRAY_SIZE(hwsim_ciphers)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 			NL_SET_ERR_MSG_ATTR(info->extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 					    info->attrs[HWSIM_ATTR_CIPHER_SUPPORT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 					    "too many ciphers specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 		if (!hwsim_known_ciphers(param.ciphers, param.n_ciphers)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 			NL_SET_ERR_MSG_ATTR(info->extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 					    info->attrs[HWSIM_ATTR_CIPHER_SUPPORT],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 					    "unsupported ciphers specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 	if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 		hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 				  nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 				  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 		if (!hwname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 		param.hwname = hwname;
^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) 	ret = mac80211_hwsim_new_radio(info, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 	kfree(hwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 	struct mac80211_hwsim_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 	s64 idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	const char *hwname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 	if (info->attrs[HWSIM_ATTR_RADIO_ID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 		idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 	} else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 		hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 				  nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 				  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 		if (!hwname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 	list_for_each_entry(data, &hwsim_radios, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 		if (idx >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 			if (data->idx != idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 			if (!hwname ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 			    strcmp(hwname, wiphy_name(data->hw->wiphy)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 		if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 		list_del(&data->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 		rhashtable_remove_fast(&hwsim_radios_rht, &data->rht,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 				       hwsim_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 		hwsim_radios_generation++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 		spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 		mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 					 info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 		kfree(hwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 	kfree(hwname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 	struct mac80211_hwsim_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 	int idx, res = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 	if (!info->attrs[HWSIM_ATTR_RADIO_ID])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 	idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 	list_for_each_entry(data, &hwsim_radios, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 		if (data->idx != idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 		if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 		skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 		if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 			res = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 			goto out_err;
^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) 		res = mac80211_hwsim_get_radio(skb, data, info->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 					       info->snd_seq, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 		if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 			nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 		res = genlmsg_reply(skb, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) static int hwsim_dump_radio_nl(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 			       struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	int last_idx = cb->args[0] - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 	struct mac80211_hwsim_data *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 	int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 	cb->seq = hwsim_radios_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 	if (last_idx >= hwsim_radio_idx-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 	list_for_each_entry(data, &hwsim_radios, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 		if (data->idx <= last_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 		if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 		res = mac80211_hwsim_get_radio(skb, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 					       NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 					       cb->nlh->nlmsg_seq, cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 					       NLM_F_MULTI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 		if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 		last_idx = data->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 	cb->args[0] = last_idx + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 	/* list changed, but no new element sent, set interrupted flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 	if (skb->len == 0 && cb->prev_seq && cb->seq != cb->prev_seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 		hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 				  cb->nlh->nlmsg_seq, &hwsim_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 				  NLM_F_MULTI, HWSIM_CMD_GET_RADIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 		if (hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 			genl_dump_check_consistent(cb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 			genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 			res = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 	return res ?: skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) /* Generic Netlink operations array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) static const struct genl_small_ops hwsim_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 		.cmd = HWSIM_CMD_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 		.doit = hwsim_register_received_nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 		.cmd = HWSIM_CMD_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 		.doit = hwsim_cloned_frame_received_nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 		.cmd = HWSIM_CMD_TX_INFO_FRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 		.doit = hwsim_tx_info_frame_received_nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 		.cmd = HWSIM_CMD_NEW_RADIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 		.doit = hwsim_new_radio_nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 		.cmd = HWSIM_CMD_DEL_RADIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 		.doit = hwsim_del_radio_nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 		.flags = GENL_UNS_ADMIN_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 		.cmd = HWSIM_CMD_GET_RADIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 		.doit = hwsim_get_radio_nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 		.dumpit = hwsim_dump_radio_nl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) static struct genl_family hwsim_genl_family __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 	.name = "MAC80211_HWSIM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 	.version = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 	.maxattr = HWSIM_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 	.policy = hwsim_genl_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 	.netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 	.module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 	.small_ops = hwsim_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	.n_small_ops = ARRAY_SIZE(hwsim_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 	.mcgrps = hwsim_mcgrps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 	.n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) static void remove_user_radios(u32 portid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 	struct mac80211_hwsim_data *entry, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 	LIST_HEAD(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 	list_for_each_entry_safe(entry, tmp, &hwsim_radios, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 		if (entry->destroy_on_close && entry->portid == portid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 			list_move(&entry->list, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 			rhashtable_remove_fast(&hwsim_radios_rht, &entry->rht,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 					       hwsim_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 			hwsim_radios_generation++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 	list_for_each_entry_safe(entry, tmp, &list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 		list_del(&entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 		mac80211_hwsim_del_radio(entry, wiphy_name(entry->hw->wiphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 					 NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) static int mac80211_hwsim_netlink_notify(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 					 unsigned long state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 					 void *_notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 	struct netlink_notify *notify = _notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 	if (state != NETLINK_URELEASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 		return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 	remove_user_radios(notify->portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 	if (notify->portid == hwsim_net_get_wmediumd(notify->net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 		printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 		       " socket, switching to perfect channel medium\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 		hwsim_register_wmediumd(notify->net, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 	return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) static struct notifier_block hwsim_netlink_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 	.notifier_call = mac80211_hwsim_netlink_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) static int __init hwsim_init_netlink(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 	printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 	rc = genl_register_family(&hwsim_genl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 		goto failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 	rc = netlink_register_notifier(&hwsim_netlink_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 		genl_unregister_family(&hwsim_genl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 		goto failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 	pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) static __net_init int hwsim_init_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 	return hwsim_net_set_netgroup(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) static void __net_exit hwsim_exit_net(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 	struct mac80211_hwsim_data *data, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 	LIST_HEAD(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 	spin_lock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 	list_for_each_entry_safe(data, tmp, &hwsim_radios, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) 		if (!net_eq(wiphy_net(data->hw->wiphy), net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 		/* Radios created in init_net are returned to init_net. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 		if (data->netgroup == hwsim_net_get_netgroup(&init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 		list_move(&data->list, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 		rhashtable_remove_fast(&hwsim_radios_rht, &data->rht,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 				       hwsim_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 		hwsim_radios_generation++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 	spin_unlock_bh(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 	list_for_each_entry_safe(data, tmp, &list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 		list_del(&data->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 		mac80211_hwsim_del_radio(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 					 wiphy_name(data->hw->wiphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 					 NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 	ida_simple_remove(&hwsim_netgroup_ida, hwsim_net_get_netgroup(net));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) static struct pernet_operations hwsim_net_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 	.init = hwsim_init_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 	.exit = hwsim_exit_net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 	.id   = &hwsim_net_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 	.size = sizeof(struct hwsim_net),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) static void hwsim_exit_netlink(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 	/* unregister the notifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 	netlink_unregister_notifier(&hwsim_netlink_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 	/* unregister the family */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 	genl_unregister_family(&hwsim_genl_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) #if IS_REACHABLE(CONFIG_VIRTIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) static void hwsim_virtio_tx_done(struct virtqueue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 	unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 	spin_lock_irqsave(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 	while ((skb = virtqueue_get_buf(vq, &len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 		nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 	spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) static int hwsim_virtio_handle_cmd(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 	struct nlmsghdr *nlh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 	struct genlmsghdr *gnlh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 	struct nlattr *tb[HWSIM_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 	struct genl_info info = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 	nlh = nlmsg_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 	gnlh = nlmsg_data(nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 	err = genlmsg_parse(nlh, &hwsim_genl_family, tb, HWSIM_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 			    hwsim_genl_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 		pr_err_ratelimited("hwsim: genlmsg_parse returned %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 	info.attrs = tb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 	switch (gnlh->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 	case HWSIM_CMD_FRAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 		hwsim_cloned_frame_received_nl(skb, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 	case HWSIM_CMD_TX_INFO_FRAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 		hwsim_tx_info_frame_received_nl(skb, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 		pr_err_ratelimited("hwsim: invalid cmd: %d\n", gnlh->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 		return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) static void hwsim_virtio_rx_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 	struct virtqueue *vq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 	unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 	struct scatterlist sg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 	spin_lock_irqsave(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 	if (!hwsim_virtio_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 	skb = virtqueue_get_buf(hwsim_vqs[HWSIM_VQ_RX], &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 	spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 	skb->data = skb->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	skb_set_tail_pointer(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 	hwsim_virtio_handle_cmd(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 	spin_lock_irqsave(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 	if (!hwsim_virtio_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 		nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 	vq = hwsim_vqs[HWSIM_VQ_RX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 	sg_init_one(sg, skb->head, skb_end_offset(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 	err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 	if (WARN(err, "virtqueue_add_inbuf returned %d\n", err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 		nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 		virtqueue_kick(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 	schedule_work(&hwsim_virtio_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) static void hwsim_virtio_rx_done(struct virtqueue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 	schedule_work(&hwsim_virtio_rx);
^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) static int init_vqs(struct virtio_device *vdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 	vq_callback_t *callbacks[HWSIM_NUM_VQS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 		[HWSIM_VQ_TX] = hwsim_virtio_tx_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 		[HWSIM_VQ_RX] = hwsim_virtio_rx_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 	const char *names[HWSIM_NUM_VQS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 		[HWSIM_VQ_TX] = "tx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 		[HWSIM_VQ_RX] = "rx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 	return virtio_find_vqs(vdev, HWSIM_NUM_VQS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 			       hwsim_vqs, callbacks, names, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) static int fill_vq(struct virtqueue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 	struct scatterlist sg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 	for (i = 0; i < virtqueue_get_vring_size(vq); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 		skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 		if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 		sg_init_one(sg, skb->head, skb_end_offset(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 		err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 			nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 	virtqueue_kick(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 	return 0;
^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) static void remove_vqs(struct virtio_device *vdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 	vdev->config->reset(vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 	for (i = 0; i < ARRAY_SIZE(hwsim_vqs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 		struct virtqueue *vq = hwsim_vqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 		struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 		while ((skb = virtqueue_detach_unused_buf(vq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 			nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 	vdev->config->del_vqs(vdev);
^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) static int hwsim_virtio_probe(struct virtio_device *vdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 	spin_lock_irqsave(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 	if (hwsim_virtio_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 		spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 		return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 	err = init_vqs(vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 	err = fill_vq(hwsim_vqs[HWSIM_VQ_RX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) 		goto out_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 	spin_lock_irqsave(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 	hwsim_virtio_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 	spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 	schedule_work(&hwsim_virtio_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) out_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 	remove_vqs(vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) static void hwsim_virtio_remove(struct virtio_device *vdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 	hwsim_virtio_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	cancel_work_sync(&hwsim_virtio_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 	remove_vqs(vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) /* MAC80211_HWSIM virtio device id table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) static const struct virtio_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 	{ VIRTIO_ID_MAC80211_HWSIM, VIRTIO_DEV_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 	{ 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) MODULE_DEVICE_TABLE(virtio, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) static struct virtio_driver virtio_hwsim = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 	.driver.name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 	.driver.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 	.id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 	.probe = hwsim_virtio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 	.remove = hwsim_virtio_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) static int hwsim_register_virtio_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 	spin_lock_init(&hwsim_virtio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 	return register_virtio_driver(&virtio_hwsim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) static void hwsim_unregister_virtio_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) 	unregister_virtio_driver(&virtio_hwsim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) static inline int hwsim_register_virtio_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 	return 0;
^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 inline void hwsim_unregister_virtio_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) static int __init init_mac80211_hwsim(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 	if (radios < 0 || radios > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 	if (channels < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 	spin_lock_init(&hwsim_radio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 	err = rhashtable_init(&hwsim_radios_rht, &hwsim_rht_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 	err = register_pernet_device(&hwsim_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) 		goto out_free_rht;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 	err = platform_driver_register(&mac80211_hwsim_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 		goto out_unregister_pernet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 	err = hwsim_init_netlink();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 		goto out_unregister_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 	err = hwsim_register_virtio_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 		goto out_exit_netlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 	hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 	if (IS_ERR(hwsim_class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 		err = PTR_ERR(hwsim_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 		goto out_exit_virtio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 	hwsim_init_s1g_channels(hwsim_channels_s1g);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 	for (i = 0; i < radios; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 		struct hwsim_new_radio_params param = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) 		param.channels = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 		switch (regtest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 		case HWSIM_REGTEST_DIFF_COUNTRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 			if (i < ARRAY_SIZE(hwsim_alpha2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 				param.reg_alpha2 = hwsim_alpha2s[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 		case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 			if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 				param.reg_alpha2 = hwsim_alpha2s[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 		case HWSIM_REGTEST_STRICT_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 			param.reg_strict = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 		case HWSIM_REGTEST_DRIVER_REG_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 			param.reg_alpha2 = hwsim_alpha2s[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 		case HWSIM_REGTEST_WORLD_ROAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 			if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 				param.regd = &hwsim_world_regdom_custom_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 		case HWSIM_REGTEST_CUSTOM_WORLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 			param.regd = &hwsim_world_regdom_custom_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 		case HWSIM_REGTEST_CUSTOM_WORLD_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 			if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 				param.regd = &hwsim_world_regdom_custom_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 			else if (i == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 				param.regd = &hwsim_world_regdom_custom_02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) 		case HWSIM_REGTEST_STRICT_FOLLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 			if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 				param.reg_strict = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 				param.reg_alpha2 = hwsim_alpha2s[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 		case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) 			if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 				param.reg_strict = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) 				param.reg_alpha2 = hwsim_alpha2s[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 			} else if (i == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 				param.reg_alpha2 = hwsim_alpha2s[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 		case HWSIM_REGTEST_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 			switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 			case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 				param.regd = &hwsim_world_regdom_custom_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) 			case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 				param.regd = &hwsim_world_regdom_custom_02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 			case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) 				param.reg_alpha2 = hwsim_alpha2s[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 			case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 				param.reg_alpha2 = hwsim_alpha2s[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 			case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 				param.reg_strict = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 				param.reg_alpha2 = hwsim_alpha2s[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 		param.p2p_device = support_p2p_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 		param.use_chanctx = channels > 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 		param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 		if (param.p2p_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 			param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 		err = mac80211_hwsim_new_radio(NULL, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 			goto out_free_radios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 	hwsim_mon = alloc_netdev(0, "hwsim%d", NET_NAME_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 				 hwsim_mon_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 	if (hwsim_mon == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 		goto out_free_radios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 	rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 	err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 		rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 		goto out_free_mon;
^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) 	err = register_netdevice(hwsim_mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 		rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 		goto out_free_mon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 	rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) out_free_mon:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 	free_netdev(hwsim_mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) out_free_radios:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 	mac80211_hwsim_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) out_exit_virtio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 	hwsim_unregister_virtio_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) out_exit_netlink:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 	hwsim_exit_netlink();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) out_unregister_driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 	platform_driver_unregister(&mac80211_hwsim_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) out_unregister_pernet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 	unregister_pernet_device(&hwsim_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) out_free_rht:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 	rhashtable_destroy(&hwsim_radios_rht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) module_init(init_mac80211_hwsim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) static void __exit exit_mac80211_hwsim(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) 	pr_debug("mac80211_hwsim: unregister radios\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 	hwsim_unregister_virtio_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 	hwsim_exit_netlink();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 	mac80211_hwsim_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 	rhashtable_destroy(&hwsim_radios_rht);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 	unregister_netdev(hwsim_mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 	platform_driver_unregister(&mac80211_hwsim_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 	unregister_pernet_device(&hwsim_net_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) module_exit(exit_mac80211_hwsim);