^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, ¶m);
^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, ¶m);
^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, ¶m);
^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);