forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/net/wireless/mac80211_hwsim.c
....@@ -1,12 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
34 * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
45 * Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
56 * Copyright (c) 2016 - 2017 Intel Deutschland GmbH
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
7
+ * Copyright (C) 2018 - 2020 Intel Corporation
108 */
119
1210 /*
....@@ -35,6 +33,9 @@
3533 #include <net/netns/generic.h>
3634 #include <linux/rhashtable.h>
3735 #include <linux/nospec.h>
36
+#include <linux/virtio.h>
37
+#include <linux/virtio_ids.h>
38
+#include <linux/virtio_config.h>
3839 #include "mac80211_hwsim.h"
3940
4041 #define WARN_QUEUE 100
....@@ -63,6 +64,10 @@
6364 static bool support_p2p_device = true;
6465 module_param(support_p2p_device, bool, 0444);
6566 MODULE_PARM_DESC(support_p2p_device, "Support P2P-Device interface type");
67
+
68
+static ushort mac_prefix;
69
+module_param(mac_prefix, ushort, 0444);
70
+MODULE_PARM_DESC(mac_prefix, "Second and third most significant octets in MAC");
6671
6772 /**
6873 * enum hwsim_regtest - the type of regulatory tests we offer
....@@ -98,7 +103,7 @@
98103 * domain requests. The first radio will adhere to the first custom world
99104 * regulatory domain, the second one to the second custom world regulatory
100105 * domain. All other devices will world roam.
101
- * @HWSIM_REGTEST_STRICT_FOLLOW_: Used for testing strict regulatory domain
106
+ * @HWSIM_REGTEST_STRICT_FOLLOW: Used for testing strict regulatory domain
102107 * settings, only the first radio will send a regulatory domain request
103108 * and use strict settings. The rest of the radios are expected to follow.
104109 * @HWSIM_REGTEST_STRICT_ALL: Used for testing strict regulatory domain
....@@ -150,23 +155,25 @@
150155 };
151156
152157 static const struct ieee80211_regdomain hwsim_world_regdom_custom_01 = {
153
- .n_reg_rules = 4,
158
+ .n_reg_rules = 5,
154159 .alpha2 = "99",
155160 .reg_rules = {
156161 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
157162 REG_RULE(2484-10, 2484+10, 40, 0, 20, 0),
158163 REG_RULE(5150-10, 5240+10, 40, 0, 30, 0),
159164 REG_RULE(5745-10, 5825+10, 40, 0, 30, 0),
165
+ REG_RULE(5855-10, 5925+10, 40, 0, 33, 0),
160166 }
161167 };
162168
163169 static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
164
- .n_reg_rules = 2,
170
+ .n_reg_rules = 3,
165171 .alpha2 = "99",
166172 .reg_rules = {
167173 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
168174 REG_RULE(5725-10, 5850+10, 40, 0, 30,
169175 NL80211_RRF_NO_IR),
176
+ REG_RULE(5855-10, 5925+10, 40, 0, 33, 0),
170177 }
171178 };
172179
....@@ -300,14 +307,12 @@
300307 .band = NL80211_BAND_2GHZ, \
301308 .center_freq = (_freq), \
302309 .hw_value = (_freq), \
303
- .max_power = 20, \
304310 }
305311
306312 #define CHAN5G(_freq) { \
307313 .band = NL80211_BAND_5GHZ, \
308314 .center_freq = (_freq), \
309315 .hw_value = (_freq), \
310
- .max_power = 20, \
311316 }
312317
313318 static const struct ieee80211_channel hwsim_channels_2ghz[] = {
....@@ -356,7 +361,68 @@
356361 CHAN5G(5805), /* Channel 161 */
357362 CHAN5G(5825), /* Channel 165 */
358363 CHAN5G(5845), /* Channel 169 */
364
+
365
+ CHAN5G(5855), /* Channel 171 */
366
+ CHAN5G(5860), /* Channel 172 */
367
+ CHAN5G(5865), /* Channel 173 */
368
+ CHAN5G(5870), /* Channel 174 */
369
+
370
+ CHAN5G(5875), /* Channel 175 */
371
+ CHAN5G(5880), /* Channel 176 */
372
+ CHAN5G(5885), /* Channel 177 */
373
+ CHAN5G(5890), /* Channel 178 */
374
+ CHAN5G(5895), /* Channel 179 */
375
+ CHAN5G(5900), /* Channel 180 */
376
+ CHAN5G(5905), /* Channel 181 */
377
+
378
+ CHAN5G(5910), /* Channel 182 */
379
+ CHAN5G(5915), /* Channel 183 */
380
+ CHAN5G(5920), /* Channel 184 */
381
+ CHAN5G(5925), /* Channel 185 */
359382 };
383
+
384
+#define NUM_S1G_CHANS_US 51
385
+static struct ieee80211_channel hwsim_channels_s1g[NUM_S1G_CHANS_US];
386
+
387
+static const struct ieee80211_sta_s1g_cap hwsim_s1g_cap = {
388
+ .s1g = true,
389
+ .cap = { S1G_CAP0_SGI_1MHZ | S1G_CAP0_SGI_2MHZ,
390
+ 0,
391
+ 0,
392
+ S1G_CAP3_MAX_MPDU_LEN,
393
+ 0,
394
+ S1G_CAP5_AMPDU,
395
+ 0,
396
+ S1G_CAP7_DUP_1MHZ,
397
+ S1G_CAP8_TWT_RESPOND | S1G_CAP8_TWT_REQUEST,
398
+ 0},
399
+ .nss_mcs = { 0xfc | 1, /* MCS 7 for 1 SS */
400
+ /* RX Highest Supported Long GI Data Rate 0:7 */
401
+ 0,
402
+ /* RX Highest Supported Long GI Data Rate 0:7 */
403
+ /* TX S1G MCS Map 0:6 */
404
+ 0xfa,
405
+ /* TX S1G MCS Map :7 */
406
+ /* TX Highest Supported Long GI Data Rate 0:6 */
407
+ 0x80,
408
+ /* TX Highest Supported Long GI Data Rate 7:8 */
409
+ /* Rx Single spatial stream and S1G-MCS Map for 1MHz */
410
+ /* Tx Single spatial stream and S1G-MCS Map for 1MHz */
411
+ 0 },
412
+};
413
+
414
+static void hwsim_init_s1g_channels(struct ieee80211_channel *channels)
415
+{
416
+ int ch, freq;
417
+
418
+ for (ch = 0; ch < NUM_S1G_CHANS_US; ch++) {
419
+ freq = 902000 + (ch + 1) * 500;
420
+ channels[ch].band = NL80211_BAND_S1GHZ;
421
+ channels[ch].center_freq = KHZ_TO_MHZ(freq);
422
+ channels[ch].freq_offset = freq % 1000;
423
+ channels[ch].hw_value = ch + 1;
424
+ }
425
+}
360426
361427 static const struct ieee80211_rate hwsim_rates[] = {
362428 { .bitrate = 10 },
....@@ -371,6 +437,20 @@
371437 { .bitrate = 360 },
372438 { .bitrate = 480 },
373439 { .bitrate = 540 }
440
+};
441
+
442
+static const u32 hwsim_ciphers[] = {
443
+ WLAN_CIPHER_SUITE_WEP40,
444
+ WLAN_CIPHER_SUITE_WEP104,
445
+ WLAN_CIPHER_SUITE_TKIP,
446
+ WLAN_CIPHER_SUITE_CCMP,
447
+ WLAN_CIPHER_SUITE_CCMP_256,
448
+ WLAN_CIPHER_SUITE_GCMP,
449
+ WLAN_CIPHER_SUITE_GCMP_256,
450
+ WLAN_CIPHER_SUITE_AES_CMAC,
451
+ WLAN_CIPHER_SUITE_BIP_CMAC_256,
452
+ WLAN_CIPHER_SUITE_BIP_GMAC_128,
453
+ WLAN_CIPHER_SUITE_BIP_GMAC_256,
374454 };
375455
376456 #define OUI_QCA 0x001374
....@@ -394,8 +474,8 @@
394474 int err;
395475 u32 val;
396476
397
- err = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
398
- hwsim_vendor_test_policy, NULL);
477
+ err = nla_parse_deprecated(tb, QCA_WLAN_VENDOR_ATTR_MAX, data,
478
+ data_len, hwsim_vendor_test_policy, NULL);
399479 if (err)
400480 return err;
401481 if (!tb[QCA_WLAN_VENDOR_ATTR_TEST])
....@@ -442,6 +522,8 @@
442522 .subcmd = QCA_NL80211_SUBCMD_TEST },
443523 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV,
444524 .doit = mac80211_hwsim_vendor_cmd_test,
525
+ .policy = hwsim_vendor_test_policy,
526
+ .maxattr = QCA_WLAN_VENDOR_ATTR_MAX,
445527 }
446528 };
447529
....@@ -450,51 +532,8 @@
450532 { .vendor_id = OUI_QCA, .subcmd = 1 },
451533 };
452534
453
-static const struct ieee80211_iface_limit hwsim_if_limits[] = {
454
- { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
455
- { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
456
- BIT(NL80211_IFTYPE_P2P_CLIENT) |
457
-#ifdef CONFIG_MAC80211_MESH
458
- BIT(NL80211_IFTYPE_MESH_POINT) |
459
-#endif
460
- BIT(NL80211_IFTYPE_AP) |
461
- BIT(NL80211_IFTYPE_P2P_GO) },
462
- /* must be last, see hwsim_if_comb */
463
- { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }
464
-};
465
-
466
-static const struct ieee80211_iface_combination hwsim_if_comb[] = {
467
- {
468
- .limits = hwsim_if_limits,
469
- /* remove the last entry which is P2P_DEVICE */
470
- .n_limits = ARRAY_SIZE(hwsim_if_limits) - 1,
471
- .max_interfaces = 2048,
472
- .num_different_channels = 1,
473
- .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
474
- BIT(NL80211_CHAN_WIDTH_20) |
475
- BIT(NL80211_CHAN_WIDTH_40) |
476
- BIT(NL80211_CHAN_WIDTH_80) |
477
- BIT(NL80211_CHAN_WIDTH_160),
478
- },
479
-};
480
-
481
-static const struct ieee80211_iface_combination hwsim_if_comb_p2p_dev[] = {
482
- {
483
- .limits = hwsim_if_limits,
484
- .n_limits = ARRAY_SIZE(hwsim_if_limits),
485
- .max_interfaces = 2048,
486
- .num_different_channels = 1,
487
- .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
488
- BIT(NL80211_CHAN_WIDTH_20) |
489
- BIT(NL80211_CHAN_WIDTH_40) |
490
- BIT(NL80211_CHAN_WIDTH_80) |
491
- BIT(NL80211_CHAN_WIDTH_160),
492
- },
493
-};
494
-
495535 static spinlock_t hwsim_radio_lock;
496536 static LIST_HEAD(hwsim_radios);
497
-static struct workqueue_struct *hwsim_wq;
498537 static struct rhashtable hwsim_radios_rht;
499538 static int hwsim_radio_idx;
500539 static int hwsim_radios_generation = 1;
....@@ -513,10 +552,16 @@
513552 struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
514553 struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
515554 struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
555
+ struct ieee80211_channel channels_s1g[ARRAY_SIZE(hwsim_channels_s1g)];
516556 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
517557 struct ieee80211_iface_combination if_combination;
558
+ struct ieee80211_iface_limit if_limits[3];
559
+ int n_if_limits;
560
+
561
+ u32 ciphers[ARRAY_SIZE(hwsim_ciphers)];
518562
519563 struct mac_address addresses[2];
564
+ struct ieee80211_chanctx_conf *chanctx;
520565 int channels, idx;
521566 bool use_chanctx;
522567 bool destroy_on_close;
....@@ -545,14 +590,14 @@
545590 unsigned int rx_filter;
546591 bool started, idle, scanning;
547592 struct mutex mutex;
548
- struct tasklet_hrtimer beacon_timer;
593
+ struct hrtimer beacon_timer;
549594 enum ps_mode {
550595 PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
551596 } ps;
552597 bool ps_poll_pending;
553598 struct dentry *debugfs;
554599
555
- uintptr_t pending_cookie;
600
+ atomic_t pending_cookie;
556601 struct sk_buff_head pending; /* packets pending */
557602 /*
558603 * Only radios in the same group can communicate together (the
....@@ -620,14 +665,14 @@
620665 /* MAC80211_HWSIM netlink policy */
621666
622667 static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
623
- [HWSIM_ATTR_ADDR_RECEIVER] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
624
- [HWSIM_ATTR_ADDR_TRANSMITTER] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
668
+ [HWSIM_ATTR_ADDR_RECEIVER] = NLA_POLICY_ETH_ADDR_COMPAT,
669
+ [HWSIM_ATTR_ADDR_TRANSMITTER] = NLA_POLICY_ETH_ADDR_COMPAT,
625670 [HWSIM_ATTR_FRAME] = { .type = NLA_BINARY,
626671 .len = IEEE80211_MAX_DATA_LEN },
627672 [HWSIM_ATTR_FLAGS] = { .type = NLA_U32 },
628673 [HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 },
629674 [HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 },
630
- [HWSIM_ATTR_TX_INFO] = { .type = NLA_UNSPEC,
675
+ [HWSIM_ATTR_TX_INFO] = { .type = NLA_BINARY,
631676 .len = IEEE80211_TX_MAX_RATES *
632677 sizeof(struct hwsim_tx_rate)},
633678 [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 },
....@@ -637,12 +682,60 @@
637682 [HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 },
638683 [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG },
639684 [HWSIM_ATTR_SUPPORT_P2P_DEVICE] = { .type = NLA_FLAG },
685
+ [HWSIM_ATTR_USE_CHANCTX] = { .type = NLA_FLAG },
640686 [HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE] = { .type = NLA_FLAG },
641687 [HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING },
642688 [HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG },
643689 [HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
644
- [HWSIM_ATTR_PERM_ADDR] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
690
+ [HWSIM_ATTR_TX_INFO_FLAGS] = { .type = NLA_BINARY },
691
+ [HWSIM_ATTR_PERM_ADDR] = NLA_POLICY_ETH_ADDR_COMPAT,
692
+ [HWSIM_ATTR_IFTYPE_SUPPORT] = { .type = NLA_U32 },
693
+ [HWSIM_ATTR_CIPHER_SUPPORT] = { .type = NLA_BINARY },
645694 };
695
+
696
+#if IS_REACHABLE(CONFIG_VIRTIO)
697
+
698
+/* MAC80211_HWSIM virtio queues */
699
+static struct virtqueue *hwsim_vqs[HWSIM_NUM_VQS];
700
+static bool hwsim_virtio_enabled;
701
+static spinlock_t hwsim_virtio_lock;
702
+
703
+static void hwsim_virtio_rx_work(struct work_struct *work);
704
+static DECLARE_WORK(hwsim_virtio_rx, hwsim_virtio_rx_work);
705
+
706
+static int hwsim_tx_virtio(struct mac80211_hwsim_data *data,
707
+ struct sk_buff *skb)
708
+{
709
+ struct scatterlist sg[1];
710
+ unsigned long flags;
711
+ int err;
712
+
713
+ spin_lock_irqsave(&hwsim_virtio_lock, flags);
714
+ if (!hwsim_virtio_enabled) {
715
+ err = -ENODEV;
716
+ goto out_free;
717
+ }
718
+
719
+ sg_init_one(sg, skb->head, skb_end_offset(skb));
720
+ err = virtqueue_add_outbuf(hwsim_vqs[HWSIM_VQ_TX], sg, 1, skb,
721
+ GFP_ATOMIC);
722
+ if (err)
723
+ goto out_free;
724
+ virtqueue_kick(hwsim_vqs[HWSIM_VQ_TX]);
725
+ spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
726
+ return 0;
727
+
728
+out_free:
729
+ spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
730
+ nlmsg_free(skb);
731
+ return err;
732
+}
733
+#else
734
+/* cause a linker error if this ends up being needed */
735
+extern int hwsim_tx_virtio(struct mac80211_hwsim_data *data,
736
+ struct sk_buff *skb);
737
+#define hwsim_virtio_enabled false
738
+#endif
646739
647740 static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
648741 struct sk_buff *skb,
....@@ -686,6 +779,7 @@
686779 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
687780 struct sk_buff *skb;
688781 struct ieee80211_hdr *hdr;
782
+ struct ieee80211_tx_info *cb;
689783
690784 if (!vp->assoc)
691785 return;
....@@ -706,6 +800,10 @@
706800 memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
707801 memcpy(hdr->addr2, mac, ETH_ALEN);
708802 memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
803
+
804
+ cb = IEEE80211_SKB_CB(skb);
805
+ cb->control.rates[0].count = 1;
806
+ cb->control.rates[1].idx = -1;
709807
710808 rcu_read_lock();
711809 mac80211_hwsim_tx_frame(data->hw, skb,
....@@ -772,8 +870,8 @@
772870 return 0;
773871 }
774872
775
-DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
776
- "%llu\n");
873
+DEFINE_DEBUGFS_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
874
+ "%llu\n");
777875
778876 static int hwsim_write_simulate_radar(void *dat, u64 val)
779877 {
....@@ -784,8 +882,8 @@
784882 return 0;
785883 }
786884
787
-DEFINE_SIMPLE_ATTRIBUTE(hwsim_simulate_radar, NULL,
788
- hwsim_write_simulate_radar, "%llu\n");
885
+DEFINE_DEBUGFS_ATTRIBUTE(hwsim_simulate_radar, NULL,
886
+ hwsim_write_simulate_radar, "%llu\n");
789887
790888 static int hwsim_fops_group_read(void *dat, u64 *val)
791889 {
....@@ -801,9 +899,9 @@
801899 return 0;
802900 }
803901
804
-DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group,
805
- hwsim_fops_group_read, hwsim_fops_group_write,
806
- "%llx\n");
902
+DEFINE_DEBUGFS_ATTRIBUTE(hwsim_fops_group,
903
+ hwsim_fops_group_read, hwsim_fops_group_write,
904
+ "%llx\n");
807905
808906 static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
809907 struct net_device *dev)
....@@ -856,12 +954,14 @@
856954 struct mac80211_hwsim_data *data = hw->priv;
857955 struct sk_buff *skb;
858956 struct hwsim_radiotap_hdr *hdr;
859
- u16 flags;
957
+ u16 flags, bitrate;
860958 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb);
861959 struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
862960
863
- if (WARN_ON(!txrate))
864
- return;
961
+ if (!txrate)
962
+ bitrate = 0;
963
+ else
964
+ bitrate = txrate->bitrate;
865965
866966 if (!netif_running(hwsim_mon))
867967 return;
....@@ -880,10 +980,10 @@
880980 (1 << IEEE80211_RADIOTAP_CHANNEL));
881981 hdr->rt_tsft = __mac80211_hwsim_get_tsf(data);
882982 hdr->rt_flags = 0;
883
- hdr->rt_rate = txrate->bitrate / 5;
983
+ hdr->rt_rate = bitrate / 5;
884984 hdr->rt_channel = cpu_to_le16(chan->center_freq);
885985 flags = IEEE80211_CHAN_2GHZ;
886
- if (txrate->flags & IEEE80211_RATE_ERP_G)
986
+ if (txrate && txrate->flags & IEEE80211_RATE_ERP_G)
887987 flags |= IEEE80211_CHAN_OFDM;
888988 else
889989 flags |= IEEE80211_CHAN_CCK;
....@@ -1024,6 +1124,47 @@
10241124 return res;
10251125 }
10261126
1127
+static void mac80211_hwsim_config_mac_nl(struct ieee80211_hw *hw,
1128
+ const u8 *addr, bool add)
1129
+{
1130
+ struct mac80211_hwsim_data *data = hw->priv;
1131
+ u32 _portid = READ_ONCE(data->wmediumd);
1132
+ struct sk_buff *skb;
1133
+ void *msg_head;
1134
+
1135
+ if (!_portid && !hwsim_virtio_enabled)
1136
+ return;
1137
+
1138
+ skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
1139
+ if (!skb)
1140
+ return;
1141
+
1142
+ msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
1143
+ add ? HWSIM_CMD_ADD_MAC_ADDR :
1144
+ HWSIM_CMD_DEL_MAC_ADDR);
1145
+ if (!msg_head) {
1146
+ pr_debug("mac80211_hwsim: problem with msg_head\n");
1147
+ goto nla_put_failure;
1148
+ }
1149
+
1150
+ if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
1151
+ ETH_ALEN, data->addresses[1].addr))
1152
+ goto nla_put_failure;
1153
+
1154
+ if (nla_put(skb, HWSIM_ATTR_ADDR_RECEIVER, ETH_ALEN, addr))
1155
+ goto nla_put_failure;
1156
+
1157
+ genlmsg_end(skb, msg_head);
1158
+
1159
+ if (hwsim_virtio_enabled)
1160
+ hwsim_tx_virtio(data, skb);
1161
+ else
1162
+ hwsim_unicast_netgroup(data, skb, _portid);
1163
+ return;
1164
+nla_put_failure:
1165
+ nlmsg_free(skb);
1166
+}
1167
+
10271168 static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate)
10281169 {
10291170 u16 result = 0;
....@@ -1056,7 +1197,8 @@
10561197
10571198 static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
10581199 struct sk_buff *my_skb,
1059
- int dst_portid)
1200
+ int dst_portid,
1201
+ struct ieee80211_channel *channel)
10601202 {
10611203 struct sk_buff *skb;
10621204 struct mac80211_hwsim_data *data = hw->priv;
....@@ -1111,7 +1253,7 @@
11111253 if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags))
11121254 goto nla_put_failure;
11131255
1114
- if (nla_put_u32(skb, HWSIM_ATTR_FREQ, data->channel->center_freq))
1256
+ if (nla_put_u32(skb, HWSIM_ATTR_FREQ, channel->center_freq))
11151257 goto nla_put_failure;
11161258
11171259 /* We get the tx control (rate and retries) info*/
....@@ -1136,15 +1278,20 @@
11361278 goto nla_put_failure;
11371279
11381280 /* We create a cookie to identify this skb */
1139
- data->pending_cookie++;
1140
- cookie = data->pending_cookie;
1281
+ cookie = atomic_inc_return(&data->pending_cookie);
11411282 info->rate_driver_data[0] = (void *)cookie;
11421283 if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD))
11431284 goto nla_put_failure;
11441285
11451286 genlmsg_end(skb, msg_head);
1146
- if (hwsim_unicast_netgroup(data, skb, dst_portid))
1147
- goto err_free_txskb;
1287
+
1288
+ if (hwsim_virtio_enabled) {
1289
+ if (hwsim_tx_virtio(data, skb))
1290
+ goto err_free_txskb;
1291
+ } else {
1292
+ if (hwsim_unicast_netgroup(data, skb, dst_portid))
1293
+ goto err_free_txskb;
1294
+ }
11481295
11491296 /* Enqueue the packet */
11501297 skb_queue_tail(&data->pending, my_skb);
....@@ -1250,6 +1397,7 @@
12501397 memset(&rx_status, 0, sizeof(rx_status));
12511398 rx_status.flag |= RX_FLAG_MACTIME_START;
12521399 rx_status.freq = chan->center_freq;
1400
+ rx_status.freq_offset = chan->freq_offset ? 1 : 0;
12531401 rx_status.band = chan->band;
12541402 if (info->control.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) {
12551403 rx_status.rate_idx =
....@@ -1284,8 +1432,8 @@
12841432 skb_orphan(skb);
12851433 skb_dst_drop(skb);
12861434 skb->mark = 0;
1287
- secpath_reset(skb);
1288
- nf_reset(skb);
1435
+ skb_ext_reset(skb);
1436
+ nf_reset_ct(skb);
12891437
12901438 /*
12911439 * Get absolute mactime here so all HWs RX at the "same time", and
....@@ -1295,10 +1443,12 @@
12951443 * probably doesn't really matter.
12961444 */
12971445 if (ieee80211_is_beacon(hdr->frame_control) ||
1298
- ieee80211_is_probe_resp(hdr->frame_control))
1446
+ ieee80211_is_probe_resp(hdr->frame_control)) {
1447
+ rx_status.boottime_ns = ktime_get_boottime_ns();
12991448 now = data->abs_bcn_ts;
1300
- else
1449
+ } else {
13011450 now = mac80211_hwsim_get_tsf_raw();
1451
+ }
13021452
13031453 /* Copy skb to all enabled radios that are on the current frequency */
13041454 spin_lock(&hwsim_radio_lock);
....@@ -1429,14 +1579,18 @@
14291579 /* fake header transmission time */
14301580 struct ieee80211_mgmt *mgmt;
14311581 struct ieee80211_rate *txrate;
1582
+ /* TODO: get MCS */
1583
+ int bitrate = 100;
14321584 u64 ts;
14331585
14341586 mgmt = (struct ieee80211_mgmt *)skb->data;
14351587 txrate = ieee80211_get_tx_rate(hw, txi);
1588
+ if (txrate)
1589
+ bitrate = txrate->bitrate;
14361590 ts = mac80211_hwsim_get_tsf_raw();
14371591 mgmt->u.probe_resp.timestamp =
14381592 cpu_to_le64(ts + data->tsf_offset +
1439
- 24 * 8 * 10 / txrate->bitrate);
1593
+ 24 * 8 * 10 / bitrate);
14401594 }
14411595
14421596 mac80211_hwsim_monitor_rx(hw, skb, channel);
....@@ -1444,8 +1598,8 @@
14441598 /* wmediumd mode check */
14451599 _portid = READ_ONCE(data->wmediumd);
14461600
1447
- if (_portid)
1448
- return mac80211_hwsim_tx_frame_nl(hw, skb, _portid);
1601
+ if (_portid || hwsim_virtio_enabled)
1602
+ return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, channel);
14491603
14501604 /* NO wmediumd detected, perfect medium simulation */
14511605 data->tx_pkts++;
....@@ -1479,8 +1633,13 @@
14791633 static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
14801634 {
14811635 struct mac80211_hwsim_data *data = hw->priv;
1636
+
14821637 data->started = false;
1483
- tasklet_hrtimer_cancel(&data->beacon_timer);
1638
+ hrtimer_cancel(&data->beacon_timer);
1639
+
1640
+ while (!skb_queue_empty(&data->pending))
1641
+ ieee80211_free_txskb(hw, skb_dequeue(&data->pending));
1642
+
14841643 wiphy_dbg(hw->wiphy, "%s\n", __func__);
14851644 }
14861645
....@@ -1492,6 +1651,9 @@
14921651 __func__, ieee80211_vif_type_p2p(vif),
14931652 vif->addr);
14941653 hwsim_set_magic(vif);
1654
+
1655
+ if (vif->type != NL80211_IFTYPE_MONITOR)
1656
+ mac80211_hwsim_config_mac_nl(hw, vif->addr, true);
14951657
14961658 vif->cab_queue = 0;
14971659 vif->hw_queue[IEEE80211_AC_VO] = 0;
....@@ -1532,6 +1694,8 @@
15321694 vif->addr);
15331695 hwsim_check_magic(vif);
15341696 hwsim_clear_magic(vif);
1697
+ if (vif->type != NL80211_IFTYPE_MONITOR)
1698
+ mac80211_hwsim_config_mac_nl(hw, vif->addr, false);
15351699 }
15361700
15371701 static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
....@@ -1550,8 +1714,8 @@
15501714
15511715 mac80211_hwsim_monitor_rx(hw, skb, chan);
15521716
1553
- if (_pid)
1554
- return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
1717
+ if (_pid || hwsim_virtio_enabled)
1718
+ return mac80211_hwsim_tx_frame_nl(hw, skb, _pid, chan);
15551719
15561720 mac80211_hwsim_tx_frame_no_nl(hw, skb, chan);
15571721 dev_kfree_skb(skb);
....@@ -1566,12 +1730,15 @@
15661730 struct ieee80211_rate *txrate;
15671731 struct ieee80211_mgmt *mgmt;
15681732 struct sk_buff *skb;
1733
+ /* TODO: get MCS */
1734
+ int bitrate = 100;
15691735
15701736 hwsim_check_magic(vif);
15711737
15721738 if (vif->type != NL80211_IFTYPE_AP &&
15731739 vif->type != NL80211_IFTYPE_MESH_POINT &&
1574
- vif->type != NL80211_IFTYPE_ADHOC)
1740
+ vif->type != NL80211_IFTYPE_ADHOC &&
1741
+ vif->type != NL80211_IFTYPE_OCB)
15751742 return;
15761743
15771744 skb = ieee80211_beacon_get(hw, vif);
....@@ -1584,18 +1751,35 @@
15841751 ARRAY_SIZE(info->control.rates));
15851752
15861753 txrate = ieee80211_get_tx_rate(hw, info);
1754
+ if (txrate)
1755
+ bitrate = txrate->bitrate;
15871756
15881757 mgmt = (struct ieee80211_mgmt *) skb->data;
15891758 /* fake header transmission time */
15901759 data->abs_bcn_ts = mac80211_hwsim_get_tsf_raw();
1591
- mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts +
1592
- data->tsf_offset +
1593
- 24 * 8 * 10 / txrate->bitrate);
1760
+ if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
1761
+ struct ieee80211_ext *ext = (void *) mgmt;
1762
+
1763
+ ext->u.s1g_beacon.timestamp = cpu_to_le32(data->abs_bcn_ts +
1764
+ data->tsf_offset +
1765
+ 10 * 8 * 10 /
1766
+ bitrate);
1767
+ } else {
1768
+ mgmt->u.beacon.timestamp = cpu_to_le64(data->abs_bcn_ts +
1769
+ data->tsf_offset +
1770
+ 24 * 8 * 10 /
1771
+ bitrate);
1772
+ }
15941773
15951774 mac80211_hwsim_tx_frame(hw, skb,
15961775 rcu_dereference(vif->chanctx_conf)->def.chan);
15971776
1598
- if (vif->csa_active && ieee80211_csa_is_complete(vif))
1777
+ while ((skb = ieee80211_get_buffered_bc(hw, vif)) != NULL) {
1778
+ mac80211_hwsim_tx_frame(hw, skb,
1779
+ rcu_dereference(vif->chanctx_conf)->def.chan);
1780
+ }
1781
+
1782
+ if (vif->csa_active && ieee80211_beacon_cntdwn_is_complete(vif))
15991783 ieee80211_csa_finish(vif);
16001784 }
16011785
....@@ -1603,14 +1787,12 @@
16031787 mac80211_hwsim_beacon(struct hrtimer *timer)
16041788 {
16051789 struct mac80211_hwsim_data *data =
1606
- container_of(timer, struct mac80211_hwsim_data,
1607
- beacon_timer.timer);
1790
+ container_of(timer, struct mac80211_hwsim_data, beacon_timer);
16081791 struct ieee80211_hw *hw = data->hw;
16091792 u64 bcn_int = data->beacon_int;
1610
- ktime_t next_bcn;
16111793
16121794 if (!data->started)
1613
- goto out;
1795
+ return HRTIMER_NORESTART;
16141796
16151797 ieee80211_iterate_active_interfaces_atomic(
16161798 hw, IEEE80211_IFACE_ITER_NORMAL,
....@@ -1621,21 +1803,25 @@
16211803 bcn_int -= data->bcn_delta;
16221804 data->bcn_delta = 0;
16231805 }
1624
-
1625
- next_bcn = ktime_add(hrtimer_get_expires(timer),
1626
- ns_to_ktime(bcn_int * 1000));
1627
- tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS);
1628
-out:
1629
- return HRTIMER_NORESTART;
1806
+ hrtimer_forward_now(&data->beacon_timer,
1807
+ ns_to_ktime(bcn_int * NSEC_PER_USEC));
1808
+ return HRTIMER_RESTART;
16301809 }
16311810
16321811 static const char * const hwsim_chanwidths[] = {
1812
+ [NL80211_CHAN_WIDTH_5] = "ht5",
1813
+ [NL80211_CHAN_WIDTH_10] = "ht10",
16331814 [NL80211_CHAN_WIDTH_20_NOHT] = "noht",
16341815 [NL80211_CHAN_WIDTH_20] = "ht20",
16351816 [NL80211_CHAN_WIDTH_40] = "ht40",
16361817 [NL80211_CHAN_WIDTH_80] = "vht80",
16371818 [NL80211_CHAN_WIDTH_80P80] = "vht80p80",
16381819 [NL80211_CHAN_WIDTH_160] = "vht160",
1820
+ [NL80211_CHAN_WIDTH_1] = "1MHz",
1821
+ [NL80211_CHAN_WIDTH_2] = "2MHz",
1822
+ [NL80211_CHAN_WIDTH_4] = "4MHz",
1823
+ [NL80211_CHAN_WIDTH_8] = "8MHz",
1824
+ [NL80211_CHAN_WIDTH_16] = "16MHz",
16391825 };
16401826
16411827 static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
....@@ -1700,15 +1886,15 @@
17001886 mutex_unlock(&data->mutex);
17011887
17021888 if (!data->started || !data->beacon_int)
1703
- tasklet_hrtimer_cancel(&data->beacon_timer);
1704
- else if (!hrtimer_is_queued(&data->beacon_timer.timer)) {
1889
+ hrtimer_cancel(&data->beacon_timer);
1890
+ else if (!hrtimer_is_queued(&data->beacon_timer)) {
17051891 u64 tsf = mac80211_hwsim_get_tsf(hw, NULL);
17061892 u32 bcn_int = data->beacon_int;
17071893 u64 until_tbtt = bcn_int - do_div(tsf, bcn_int);
17081894
1709
- tasklet_hrtimer_start(&data->beacon_timer,
1710
- ns_to_ktime(until_tbtt * 1000),
1711
- HRTIMER_MODE_REL);
1895
+ hrtimer_start(&data->beacon_timer,
1896
+ ns_to_ktime(until_tbtt * NSEC_PER_USEC),
1897
+ HRTIMER_MODE_REL_SOFT);
17121898 }
17131899
17141900 return 0;
....@@ -1726,6 +1912,8 @@
17261912 data->rx_filter = 0;
17271913 if (*total_flags & FIF_ALLMULTI)
17281914 data->rx_filter |= FIF_ALLMULTI;
1915
+ if (*total_flags & FIF_MCAST_ACTION)
1916
+ data->rx_filter |= FIF_MCAST_ACTION;
17291917
17301918 *total_flags = data->rx_filter;
17311919 }
....@@ -1771,7 +1959,7 @@
17711959 info->enable_beacon, info->beacon_int);
17721960 vp->bcn_en = info->enable_beacon;
17731961 if (data->started &&
1774
- !hrtimer_is_queued(&data->beacon_timer.timer) &&
1962
+ !hrtimer_is_queued(&data->beacon_timer) &&
17751963 info->enable_beacon) {
17761964 u64 tsf, until_tbtt;
17771965 u32 bcn_int;
....@@ -1779,9 +1967,10 @@
17791967 tsf = mac80211_hwsim_get_tsf(hw, vif);
17801968 bcn_int = data->beacon_int;
17811969 until_tbtt = bcn_int - do_div(tsf, bcn_int);
1782
- tasklet_hrtimer_start(&data->beacon_timer,
1783
- ns_to_ktime(until_tbtt * 1000),
1784
- HRTIMER_MODE_REL);
1970
+
1971
+ hrtimer_start(&data->beacon_timer,
1972
+ ns_to_ktime(until_tbtt * NSEC_PER_USEC),
1973
+ HRTIMER_MODE_REL_SOFT);
17851974 } else if (!info->enable_beacon) {
17861975 unsigned int count = 0;
17871976 ieee80211_iterate_active_interfaces_atomic(
....@@ -1790,7 +1979,7 @@
17901979 wiphy_dbg(hw->wiphy, " beaconing vifs remaining: %u",
17911980 count);
17921981 if (count == 0) {
1793
- tasklet_hrtimer_cancel(&data->beacon_timer);
1982
+ hrtimer_cancel(&data->beacon_timer);
17941983 data->beacon_int = 0;
17951984 }
17961985 }
....@@ -1956,8 +2145,8 @@
19562145 struct sk_buff *skb;
19572146 int err, ps;
19582147
1959
- err = nla_parse(tb, HWSIM_TM_ATTR_MAX, data, len,
1960
- hwsim_testmode_policy, NULL);
2148
+ err = nla_parse_deprecated(tb, HWSIM_TM_ATTR_MAX, data, len,
2149
+ hwsim_testmode_policy, NULL);
19612150 if (err)
19622151 return err;
19632152
....@@ -2004,8 +2193,7 @@
20042193
20052194 switch (action) {
20062195 case IEEE80211_AMPDU_TX_START:
2007
- ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
2008
- break;
2196
+ return IEEE80211_AMPDU_TX_START_IMMEDIATE;
20092197 case IEEE80211_AMPDU_TX_STOP_CONT:
20102198 case IEEE80211_AMPDU_TX_STOP_FLUSH:
20112199 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
....@@ -2049,6 +2237,8 @@
20492237 hwsim->hw_scan_vif = NULL;
20502238 hwsim->tmp_chan = NULL;
20512239 mutex_unlock(&hwsim->mutex);
2240
+ mac80211_hwsim_config_mac_nl(hwsim->hw, hwsim->scan_addr,
2241
+ false);
20522242 return;
20532243 }
20542244
....@@ -2082,9 +2272,21 @@
20822272 if (req->ie_len)
20832273 skb_put_data(probe, req->ie, req->ie_len);
20842274
2275
+ rcu_read_lock();
2276
+ if (!ieee80211_tx_prepare_skb(hwsim->hw,
2277
+ hwsim->hw_scan_vif,
2278
+ probe,
2279
+ hwsim->tmp_chan->band,
2280
+ NULL)) {
2281
+ rcu_read_unlock();
2282
+ kfree_skb(probe);
2283
+ continue;
2284
+ }
2285
+
20852286 local_bh_disable();
20862287 mac80211_hwsim_tx_frame(hwsim->hw, probe,
20872288 hwsim->tmp_chan);
2289
+ rcu_read_unlock();
20882290 local_bh_enable();
20892291 }
20902292 }
....@@ -2122,6 +2324,7 @@
21222324 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
21232325 mutex_unlock(&hwsim->mutex);
21242326
2327
+ mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true);
21252328 wiphy_dbg(hw->wiphy, "hwsim hw_scan request\n");
21262329
21272330 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
....@@ -2165,6 +2368,7 @@
21652368 pr_debug("hwsim sw_scan request, prepping stuff\n");
21662369
21672370 memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
2371
+ mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, true);
21682372 hwsim->scanning = true;
21692373 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
21702374
....@@ -2181,6 +2385,7 @@
21812385
21822386 pr_debug("hwsim sw_scan_complete\n");
21832387 hwsim->scanning = false;
2388
+ mac80211_hwsim_config_mac_nl(hw, hwsim->scan_addr, false);
21842389 eth_zero_addr(hwsim->scan_addr);
21852390
21862391 mutex_unlock(&hwsim->mutex);
....@@ -2241,7 +2446,8 @@
22412446 return 0;
22422447 }
22432448
2244
-static int mac80211_hwsim_croc(struct ieee80211_hw *hw)
2449
+static int mac80211_hwsim_croc(struct ieee80211_hw *hw,
2450
+ struct ieee80211_vif *vif)
22452451 {
22462452 struct mac80211_hwsim_data *hwsim = hw->priv;
22472453
....@@ -2260,6 +2466,11 @@
22602466 static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw,
22612467 struct ieee80211_chanctx_conf *ctx)
22622468 {
2469
+ struct mac80211_hwsim_data *hwsim = hw->priv;
2470
+
2471
+ mutex_lock(&hwsim->mutex);
2472
+ hwsim->chanctx = ctx;
2473
+ mutex_unlock(&hwsim->mutex);
22632474 hwsim_set_chanctx_magic(ctx);
22642475 wiphy_dbg(hw->wiphy,
22652476 "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
....@@ -2271,6 +2482,11 @@
22712482 static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
22722483 struct ieee80211_chanctx_conf *ctx)
22732484 {
2485
+ struct mac80211_hwsim_data *hwsim = hw->priv;
2486
+
2487
+ mutex_lock(&hwsim->mutex);
2488
+ hwsim->chanctx = NULL;
2489
+ mutex_unlock(&hwsim->mutex);
22742490 wiphy_dbg(hw->wiphy,
22752491 "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
22762492 ctx->def.chan->center_freq, ctx->def.width,
....@@ -2283,6 +2499,11 @@
22832499 struct ieee80211_chanctx_conf *ctx,
22842500 u32 changed)
22852501 {
2502
+ struct mac80211_hwsim_data *hwsim = hw->priv;
2503
+
2504
+ mutex_lock(&hwsim->mutex);
2505
+ hwsim->chanctx = ctx;
2506
+ mutex_unlock(&hwsim->mutex);
22862507 hwsim_check_chanctx_magic(ctx);
22872508 wiphy_dbg(hw->wiphy,
22882509 "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
....@@ -2357,6 +2578,11 @@
23572578 WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN);
23582579 }
23592580
2581
+static int mac80211_hwsim_tx_last_beacon(struct ieee80211_hw *hw)
2582
+{
2583
+ return 1;
2584
+}
2585
+
23602586 #define HWSIM_COMMON_OPS \
23612587 .tx = mac80211_hwsim_tx, \
23622588 .start = mac80211_hwsim_start, \
....@@ -2367,6 +2593,7 @@
23672593 .config = mac80211_hwsim_config, \
23682594 .configure_filter = mac80211_hwsim_configure_filter, \
23692595 .bss_info_changed = mac80211_hwsim_bss_info_changed, \
2596
+ .tx_last_beacon = mac80211_hwsim_tx_last_beacon, \
23702597 .sta_add = mac80211_hwsim_sta_add, \
23712598 .sta_remove = mac80211_hwsim_sta_remove, \
23722599 .sta_notify = mac80211_hwsim_sta_notify, \
....@@ -2414,6 +2641,9 @@
24142641 const char *hwname;
24152642 bool no_vif;
24162643 const u8 *perm_addr;
2644
+ u32 iftypes;
2645
+ u32 *ciphers;
2646
+ u8 n_ciphers;
24172647 };
24182648
24192649 static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
....@@ -2518,122 +2748,234 @@
25182748 nlmsg_free(mcast_skb);
25192749 }
25202750
2521
-static const struct ieee80211_sband_iftype_data he_capa_2ghz = {
2522
- /* TODO: should we support other types, e.g., P2P?*/
2523
- .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP),
2524
- .he_cap = {
2525
- .has_he = true,
2526
- .he_cap_elem = {
2527
- .mac_cap_info[0] =
2528
- IEEE80211_HE_MAC_CAP0_HTC_HE,
2529
- .mac_cap_info[1] =
2530
- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
2531
- IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_8,
2532
- .mac_cap_info[2] =
2533
- IEEE80211_HE_MAC_CAP2_BSR |
2534
- IEEE80211_HE_MAC_CAP2_MU_CASCADING |
2535
- IEEE80211_HE_MAC_CAP2_ACK_EN,
2536
- .mac_cap_info[3] =
2537
- IEEE80211_HE_MAC_CAP3_GRP_ADDR_MULTI_STA_BA_DL_MU |
2538
- IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
2539
- IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_2,
2540
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
2541
- .phy_cap_info[0] =
2542
- IEEE80211_HE_PHY_CAP0_DUAL_BAND,
2543
- .phy_cap_info[1] =
2544
- IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
2545
- IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
2546
- IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
2547
- IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS,
2548
- .phy_cap_info[2] =
2549
- IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
2550
- IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
2551
- IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
2552
- IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
2553
- IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
2751
+static const struct ieee80211_sband_iftype_data he_capa_2ghz[] = {
2752
+ {
2753
+ /* TODO: should we support other types, e.g., P2P?*/
2754
+ .types_mask = BIT(NL80211_IFTYPE_STATION) |
2755
+ BIT(NL80211_IFTYPE_AP),
2756
+ .he_cap = {
2757
+ .has_he = true,
2758
+ .he_cap_elem = {
2759
+ .mac_cap_info[0] =
2760
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
2761
+ .mac_cap_info[1] =
2762
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
2763
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
2764
+ .mac_cap_info[2] =
2765
+ IEEE80211_HE_MAC_CAP2_BSR |
2766
+ IEEE80211_HE_MAC_CAP2_MU_CASCADING |
2767
+ IEEE80211_HE_MAC_CAP2_ACK_EN,
2768
+ .mac_cap_info[3] =
2769
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
2770
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
2771
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
2772
+ .phy_cap_info[1] =
2773
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
2774
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
2775
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
2776
+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
2777
+ .phy_cap_info[2] =
2778
+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
2779
+ IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
2780
+ IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
2781
+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
2782
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
25542783
2555
- /* Leave all the other PHY capability bytes unset, as
2556
- * DCM, beam forming, RU and PPE threshold information
2557
- * are not supported
2558
- */
2559
- },
2560
- .he_mcs_nss_supp = {
2561
- .rx_mcs_80 = cpu_to_le16(0xfffa),
2562
- .tx_mcs_80 = cpu_to_le16(0xfffa),
2563
- .rx_mcs_160 = cpu_to_le16(0xffff),
2564
- .tx_mcs_160 = cpu_to_le16(0xffff),
2565
- .rx_mcs_80p80 = cpu_to_le16(0xffff),
2566
- .tx_mcs_80p80 = cpu_to_le16(0xffff),
2784
+ /* Leave all the other PHY capability bytes
2785
+ * unset, as DCM, beam forming, RU and PPE
2786
+ * threshold information are not supported
2787
+ */
2788
+ },
2789
+ .he_mcs_nss_supp = {
2790
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
2791
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
2792
+ .rx_mcs_160 = cpu_to_le16(0xffff),
2793
+ .tx_mcs_160 = cpu_to_le16(0xffff),
2794
+ .rx_mcs_80p80 = cpu_to_le16(0xffff),
2795
+ .tx_mcs_80p80 = cpu_to_le16(0xffff),
2796
+ },
25672797 },
25682798 },
2569
-};
2799
+#ifdef CONFIG_MAC80211_MESH
2800
+ {
2801
+ /* TODO: should we support other types, e.g., IBSS?*/
2802
+ .types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
2803
+ .he_cap = {
2804
+ .has_he = true,
2805
+ .he_cap_elem = {
2806
+ .mac_cap_info[0] =
2807
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
2808
+ .mac_cap_info[1] =
2809
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
2810
+ .mac_cap_info[2] =
2811
+ IEEE80211_HE_MAC_CAP2_ACK_EN,
2812
+ .mac_cap_info[3] =
2813
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
2814
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
2815
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
2816
+ .phy_cap_info[1] =
2817
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
2818
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
2819
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
2820
+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
2821
+ .phy_cap_info[2] = 0,
25702822
2571
-static const struct ieee80211_sband_iftype_data he_capa_5ghz = {
2572
- /* TODO: should we support other types, e.g., P2P?*/
2573
- .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP),
2574
- .he_cap = {
2575
- .has_he = true,
2576
- .he_cap_elem = {
2577
- .mac_cap_info[0] =
2578
- IEEE80211_HE_MAC_CAP0_HTC_HE,
2579
- .mac_cap_info[1] =
2580
- IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
2581
- IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_8,
2582
- .mac_cap_info[2] =
2583
- IEEE80211_HE_MAC_CAP2_BSR |
2584
- IEEE80211_HE_MAC_CAP2_MU_CASCADING |
2585
- IEEE80211_HE_MAC_CAP2_ACK_EN,
2586
- .mac_cap_info[3] =
2587
- IEEE80211_HE_MAC_CAP3_GRP_ADDR_MULTI_STA_BA_DL_MU |
2588
- IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
2589
- IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_2,
2590
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
2591
- .phy_cap_info[0] =
2592
- IEEE80211_HE_PHY_CAP0_DUAL_BAND |
2593
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
2594
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
2595
- IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
2596
- .phy_cap_info[1] =
2597
- IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
2598
- IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
2599
- IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
2600
- IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS,
2601
- .phy_cap_info[2] =
2602
- IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
2603
- IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
2604
- IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
2605
- IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
2606
- IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
2607
-
2608
- /* Leave all the other PHY capability bytes unset, as
2609
- * DCM, beam forming, RU and PPE threshold information
2610
- * are not supported
2611
- */
2612
- },
2613
- .he_mcs_nss_supp = {
2614
- .rx_mcs_80 = cpu_to_le16(0xfffa),
2615
- .tx_mcs_80 = cpu_to_le16(0xfffa),
2616
- .rx_mcs_160 = cpu_to_le16(0xfffa),
2617
- .tx_mcs_160 = cpu_to_le16(0xfffa),
2618
- .rx_mcs_80p80 = cpu_to_le16(0xfffa),
2619
- .tx_mcs_80p80 = cpu_to_le16(0xfffa),
2823
+ /* Leave all the other PHY capability bytes
2824
+ * unset, as DCM, beam forming, RU and PPE
2825
+ * threshold information are not supported
2826
+ */
2827
+ },
2828
+ .he_mcs_nss_supp = {
2829
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
2830
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
2831
+ .rx_mcs_160 = cpu_to_le16(0xffff),
2832
+ .tx_mcs_160 = cpu_to_le16(0xffff),
2833
+ .rx_mcs_80p80 = cpu_to_le16(0xffff),
2834
+ .tx_mcs_80p80 = cpu_to_le16(0xffff),
2835
+ },
26202836 },
26212837 },
2838
+#endif
26222839 };
26232840
2624
-static void mac80211_hswim_he_capab(struct ieee80211_supported_band *sband)
2841
+static const struct ieee80211_sband_iftype_data he_capa_5ghz[] = {
2842
+ {
2843
+ /* TODO: should we support other types, e.g., P2P?*/
2844
+ .types_mask = BIT(NL80211_IFTYPE_STATION) |
2845
+ BIT(NL80211_IFTYPE_AP),
2846
+ .he_cap = {
2847
+ .has_he = true,
2848
+ .he_cap_elem = {
2849
+ .mac_cap_info[0] =
2850
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
2851
+ .mac_cap_info[1] =
2852
+ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
2853
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
2854
+ .mac_cap_info[2] =
2855
+ IEEE80211_HE_MAC_CAP2_BSR |
2856
+ IEEE80211_HE_MAC_CAP2_MU_CASCADING |
2857
+ IEEE80211_HE_MAC_CAP2_ACK_EN,
2858
+ .mac_cap_info[3] =
2859
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
2860
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
2861
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
2862
+ .phy_cap_info[0] =
2863
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
2864
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
2865
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
2866
+ .phy_cap_info[1] =
2867
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
2868
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
2869
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
2870
+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
2871
+ .phy_cap_info[2] =
2872
+ IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
2873
+ IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
2874
+ IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
2875
+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
2876
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,
2877
+
2878
+ /* Leave all the other PHY capability bytes
2879
+ * unset, as DCM, beam forming, RU and PPE
2880
+ * threshold information are not supported
2881
+ */
2882
+ },
2883
+ .he_mcs_nss_supp = {
2884
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
2885
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
2886
+ .rx_mcs_160 = cpu_to_le16(0xfffa),
2887
+ .tx_mcs_160 = cpu_to_le16(0xfffa),
2888
+ .rx_mcs_80p80 = cpu_to_le16(0xfffa),
2889
+ .tx_mcs_80p80 = cpu_to_le16(0xfffa),
2890
+ },
2891
+ },
2892
+ },
2893
+#ifdef CONFIG_MAC80211_MESH
2894
+ {
2895
+ /* TODO: should we support other types, e.g., IBSS?*/
2896
+ .types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
2897
+ .he_cap = {
2898
+ .has_he = true,
2899
+ .he_cap_elem = {
2900
+ .mac_cap_info[0] =
2901
+ IEEE80211_HE_MAC_CAP0_HTC_HE,
2902
+ .mac_cap_info[1] =
2903
+ IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
2904
+ .mac_cap_info[2] =
2905
+ IEEE80211_HE_MAC_CAP2_ACK_EN,
2906
+ .mac_cap_info[3] =
2907
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
2908
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
2909
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
2910
+ .phy_cap_info[0] =
2911
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
2912
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
2913
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
2914
+ .phy_cap_info[1] =
2915
+ IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
2916
+ IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
2917
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
2918
+ IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
2919
+ .phy_cap_info[2] = 0,
2920
+
2921
+ /* Leave all the other PHY capability bytes
2922
+ * unset, as DCM, beam forming, RU and PPE
2923
+ * threshold information are not supported
2924
+ */
2925
+ },
2926
+ .he_mcs_nss_supp = {
2927
+ .rx_mcs_80 = cpu_to_le16(0xfffa),
2928
+ .tx_mcs_80 = cpu_to_le16(0xfffa),
2929
+ .rx_mcs_160 = cpu_to_le16(0xfffa),
2930
+ .tx_mcs_160 = cpu_to_le16(0xfffa),
2931
+ .rx_mcs_80p80 = cpu_to_le16(0xfffa),
2932
+ .tx_mcs_80p80 = cpu_to_le16(0xfffa),
2933
+ },
2934
+ },
2935
+ },
2936
+#endif
2937
+};
2938
+
2939
+static void mac80211_hwsim_he_capab(struct ieee80211_supported_band *sband)
26252940 {
2626
- if (sband->band == NL80211_BAND_2GHZ)
2627
- sband->iftype_data =
2628
- (struct ieee80211_sband_iftype_data *)&he_capa_2ghz;
2629
- else if (sband->band == NL80211_BAND_5GHZ)
2630
- sband->iftype_data =
2631
- (struct ieee80211_sband_iftype_data *)&he_capa_5ghz;
2632
- else
2633
- return;
2941
+ u16 n_iftype_data;
26342942
2635
- sband->n_iftype_data = 1;
2943
+ if (sband->band == NL80211_BAND_2GHZ) {
2944
+ n_iftype_data = ARRAY_SIZE(he_capa_2ghz);
2945
+ sband->iftype_data =
2946
+ (struct ieee80211_sband_iftype_data *)he_capa_2ghz;
2947
+ } else if (sband->band == NL80211_BAND_5GHZ) {
2948
+ n_iftype_data = ARRAY_SIZE(he_capa_5ghz);
2949
+ sband->iftype_data =
2950
+ (struct ieee80211_sband_iftype_data *)he_capa_5ghz;
2951
+ } else {
2952
+ return;
2953
+ }
2954
+
2955
+ sband->n_iftype_data = n_iftype_data;
26362956 }
2957
+
2958
+#ifdef CONFIG_MAC80211_MESH
2959
+#define HWSIM_MESH_BIT BIT(NL80211_IFTYPE_MESH_POINT)
2960
+#else
2961
+#define HWSIM_MESH_BIT 0
2962
+#endif
2963
+
2964
+#define HWSIM_DEFAULT_IF_LIMIT \
2965
+ (BIT(NL80211_IFTYPE_STATION) | \
2966
+ BIT(NL80211_IFTYPE_P2P_CLIENT) | \
2967
+ BIT(NL80211_IFTYPE_AP) | \
2968
+ BIT(NL80211_IFTYPE_P2P_GO) | \
2969
+ HWSIM_MESH_BIT)
2970
+
2971
+#define HWSIM_IFTYPE_SUPPORT_MASK \
2972
+ (BIT(NL80211_IFTYPE_STATION) | \
2973
+ BIT(NL80211_IFTYPE_AP) | \
2974
+ BIT(NL80211_IFTYPE_P2P_CLIENT) | \
2975
+ BIT(NL80211_IFTYPE_P2P_GO) | \
2976
+ BIT(NL80211_IFTYPE_ADHOC) | \
2977
+ BIT(NL80211_IFTYPE_MESH_POINT) | \
2978
+ BIT(NL80211_IFTYPE_OCB))
26372979
26382980 static int mac80211_hwsim_new_radio(struct genl_info *info,
26392981 struct hwsim_new_radio_params *param)
....@@ -2645,7 +2987,8 @@
26452987 enum nl80211_band band;
26462988 const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
26472989 struct net *net;
2648
- int idx;
2990
+ int idx, i;
2991
+ int n_limits = 0;
26492992
26502993 if (WARN_ON(param->channels > 1 && !param->use_chanctx))
26512994 return -EINVAL;
....@@ -2697,6 +3040,8 @@
26973040 if (!param->perm_addr) {
26983041 eth_zero_addr(addr);
26993042 addr[0] = 0x02;
3043
+ addr[1] = (mac_prefix >> 8) & 0xFF;
3044
+ addr[2] = mac_prefix & 0xFF;
27003045 addr[3] = idx >> 8;
27013046 addr[4] = idx;
27023047 memcpy(data->addresses[0].addr, addr, ETH_ALEN);
....@@ -2721,26 +3066,79 @@
27213066 if (info)
27223067 data->portid = info->snd_portid;
27233068
3069
+ /* setup interface limits, only on interface types we support */
3070
+ if (param->iftypes & BIT(NL80211_IFTYPE_ADHOC)) {
3071
+ data->if_limits[n_limits].max = 1;
3072
+ data->if_limits[n_limits].types = BIT(NL80211_IFTYPE_ADHOC);
3073
+ n_limits++;
3074
+ }
3075
+
3076
+ if (param->iftypes & HWSIM_DEFAULT_IF_LIMIT) {
3077
+ data->if_limits[n_limits].max = 2048;
3078
+ /*
3079
+ * For this case, we may only support a subset of
3080
+ * HWSIM_DEFAULT_IF_LIMIT, therefore we only want to add the
3081
+ * bits that both param->iftype & HWSIM_DEFAULT_IF_LIMIT have.
3082
+ */
3083
+ data->if_limits[n_limits].types =
3084
+ HWSIM_DEFAULT_IF_LIMIT & param->iftypes;
3085
+ n_limits++;
3086
+ }
3087
+
3088
+ if (param->iftypes & BIT(NL80211_IFTYPE_P2P_DEVICE)) {
3089
+ data->if_limits[n_limits].max = 1;
3090
+ data->if_limits[n_limits].types =
3091
+ BIT(NL80211_IFTYPE_P2P_DEVICE);
3092
+ n_limits++;
3093
+ }
3094
+
27243095 if (data->use_chanctx) {
27253096 hw->wiphy->max_scan_ssids = 255;
27263097 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
27273098 hw->wiphy->max_remain_on_channel_duration = 1000;
2728
- hw->wiphy->iface_combinations = &data->if_combination;
2729
- if (param->p2p_device)
2730
- data->if_combination = hwsim_if_comb_p2p_dev[0];
2731
- else
2732
- data->if_combination = hwsim_if_comb[0];
2733
- hw->wiphy->n_iface_combinations = 1;
2734
- /* For channels > 1 DFS is not allowed */
27353099 data->if_combination.radar_detect_widths = 0;
27363100 data->if_combination.num_different_channels = data->channels;
2737
- } else if (param->p2p_device) {
2738
- hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev;
2739
- hw->wiphy->n_iface_combinations =
2740
- ARRAY_SIZE(hwsim_if_comb_p2p_dev);
3101
+ data->chanctx = NULL;
27413102 } else {
2742
- hw->wiphy->iface_combinations = hwsim_if_comb;
2743
- hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
3103
+ data->if_combination.num_different_channels = 1;
3104
+ data->if_combination.radar_detect_widths =
3105
+ BIT(NL80211_CHAN_WIDTH_5) |
3106
+ BIT(NL80211_CHAN_WIDTH_10) |
3107
+ BIT(NL80211_CHAN_WIDTH_20_NOHT) |
3108
+ BIT(NL80211_CHAN_WIDTH_20) |
3109
+ BIT(NL80211_CHAN_WIDTH_40) |
3110
+ BIT(NL80211_CHAN_WIDTH_80) |
3111
+ BIT(NL80211_CHAN_WIDTH_160);
3112
+ }
3113
+
3114
+ if (!n_limits) {
3115
+ err = -EINVAL;
3116
+ goto failed_hw;
3117
+ }
3118
+
3119
+ data->if_combination.max_interfaces = 0;
3120
+ for (i = 0; i < n_limits; i++)
3121
+ data->if_combination.max_interfaces +=
3122
+ data->if_limits[i].max;
3123
+
3124
+ data->if_combination.n_limits = n_limits;
3125
+ data->if_combination.limits = data->if_limits;
3126
+
3127
+ /*
3128
+ * If we actually were asked to support combinations,
3129
+ * advertise them - if there's only a single thing like
3130
+ * only IBSS then don't advertise it as combinations.
3131
+ */
3132
+ if (data->if_combination.max_interfaces > 1) {
3133
+ hw->wiphy->iface_combinations = &data->if_combination;
3134
+ hw->wiphy->n_iface_combinations = 1;
3135
+ }
3136
+
3137
+ if (param->ciphers) {
3138
+ memcpy(data->ciphers, param->ciphers,
3139
+ param->n_ciphers * sizeof(u32));
3140
+ hw->wiphy->cipher_suites = data->ciphers;
3141
+ hw->wiphy->n_cipher_suites = param->n_ciphers;
27443142 }
27453143
27463144 INIT_DELAYED_WORK(&data->roc_start, hw_roc_start);
....@@ -2749,15 +3147,6 @@
27493147
27503148 hw->queues = 5;
27513149 hw->offchannel_tx_hw_queue = 4;
2752
- hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2753
- BIT(NL80211_IFTYPE_AP) |
2754
- BIT(NL80211_IFTYPE_P2P_CLIENT) |
2755
- BIT(NL80211_IFTYPE_P2P_GO) |
2756
- BIT(NL80211_IFTYPE_ADHOC) |
2757
- BIT(NL80211_IFTYPE_MESH_POINT);
2758
-
2759
- if (param->p2p_device)
2760
- hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
27613150
27623151 ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
27633152 ieee80211_hw_set(hw, CHANCTX_STA_CSA);
....@@ -2768,13 +3157,19 @@
27683157 ieee80211_hw_set(hw, MFP_CAPABLE);
27693158 ieee80211_hw_set(hw, SIGNAL_DBM);
27703159 ieee80211_hw_set(hw, SUPPORTS_PS);
3160
+ ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
3161
+ ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
3162
+ ieee80211_hw_set(hw, PS_NULLFUNC_STACK);
27713163 ieee80211_hw_set(hw, TDLS_WIDER_BW);
27723164 if (rctbl)
27733165 ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
3166
+ ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
27743167
3168
+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
27753169 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
27763170 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
27773171 WIPHY_FLAG_AP_UAPSD |
3172
+ WIPHY_FLAG_SUPPORTS_5_10_MHZ |
27783173 WIPHY_FLAG_HAS_CHANNEL_SWITCH;
27793174 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR |
27803175 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
....@@ -2782,6 +3177,13 @@
27823177 NL80211_FEATURE_DYNAMIC_SMPS |
27833178 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
27843179 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
3180
+ wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION);
3181
+ wiphy_ext_feature_set(hw->wiphy,
3182
+ NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS);
3183
+ wiphy_ext_feature_set(hw->wiphy,
3184
+ NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
3185
+
3186
+ hw->wiphy->interface_modes = param->iftypes;
27853187
27863188 /* ask mac80211 to reserve space for magic */
27873189 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
....@@ -2792,6 +3194,8 @@
27923194 sizeof(hwsim_channels_2ghz));
27933195 memcpy(data->channels_5ghz, hwsim_channels_5ghz,
27943196 sizeof(hwsim_channels_5ghz));
3197
+ memcpy(data->channels_s1g, hwsim_channels_s1g,
3198
+ sizeof(hwsim_channels_s1g));
27953199 memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
27963200
27973201 for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
....@@ -2834,6 +3238,12 @@
28343238 sband->vht_cap.vht_mcs.tx_mcs_map =
28353239 sband->vht_cap.vht_mcs.rx_mcs_map;
28363240 break;
3241
+ case NL80211_BAND_S1GHZ:
3242
+ memcpy(&sband->s1g_cap, &hwsim_s1g_cap,
3243
+ sizeof(sband->s1g_cap));
3244
+ sband->channels = data->channels_s1g;
3245
+ sband->n_channels = ARRAY_SIZE(hwsim_channels_s1g);
3246
+ break;
28373247 default:
28383248 continue;
28393249 }
....@@ -2852,7 +3262,7 @@
28523262 sband->ht_cap.mcs.rx_mask[1] = 0xff;
28533263 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
28543264
2855
- mac80211_hswim_he_capab(sband);
3265
+ mac80211_hwsim_he_capab(sband);
28563266
28573267 hw->wiphy->bands[band] = sband;
28583268 }
....@@ -2889,9 +3299,9 @@
28893299
28903300 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
28913301
2892
- tasklet_hrtimer_init(&data->beacon_timer,
2893
- mac80211_hwsim_beacon,
2894
- CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
3302
+ hrtimer_init(&data->beacon_timer, CLOCK_MONOTONIC,
3303
+ HRTIMER_MODE_ABS_SOFT);
3304
+ data->beacon_timer.function = mac80211_hwsim_beacon;
28953305
28963306 err = ieee80211_register_hw(hw);
28973307 if (err < 0) {
....@@ -3108,6 +3518,7 @@
31083518 const u8 *src;
31093519 unsigned int hwsim_flags;
31103520 int i;
3521
+ unsigned long flags;
31113522 bool found = false;
31123523
31133524 if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
....@@ -3125,25 +3536,30 @@
31253536 if (!data2)
31263537 goto out;
31273538
3128
- if (hwsim_net_get_netgroup(genl_info_net(info)) != data2->netgroup)
3129
- goto out;
3539
+ if (!hwsim_virtio_enabled) {
3540
+ if (hwsim_net_get_netgroup(genl_info_net(info)) !=
3541
+ data2->netgroup)
3542
+ goto out;
31303543
3131
- if (info->snd_portid != data2->wmediumd)
3132
- goto out;
3544
+ if (info->snd_portid != data2->wmediumd)
3545
+ goto out;
3546
+ }
31333547
31343548 /* look for the skb matching the cookie passed back from user */
3549
+ spin_lock_irqsave(&data2->pending.lock, flags);
31353550 skb_queue_walk_safe(&data2->pending, skb, tmp) {
3136
- u64 skb_cookie;
3551
+ uintptr_t skb_cookie;
31373552
31383553 txi = IEEE80211_SKB_CB(skb);
3139
- skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0];
3554
+ skb_cookie = (uintptr_t)txi->rate_driver_data[0];
31403555
31413556 if (skb_cookie == ret_skb_cookie) {
3142
- skb_unlink(skb, &data2->pending);
3557
+ __skb_unlink(skb, &data2->pending);
31433558 found = true;
31443559 break;
31453560 }
31463561 }
3562
+ spin_unlock_irqrestore(&data2->pending.lock, flags);
31473563
31483564 /* not found */
31493565 if (!found)
....@@ -3176,6 +3592,10 @@
31763592 }
31773593 txi->flags |= IEEE80211_TX_STAT_ACK;
31783594 }
3595
+
3596
+ if (hwsim_flags & HWSIM_TX_CTL_NO_ACK)
3597
+ txi->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
3598
+
31793599 ieee80211_tx_status_irqsafe(data2->hw, skb);
31803600 return 0;
31813601 out:
....@@ -3188,10 +3608,12 @@
31883608 {
31893609 struct mac80211_hwsim_data *data2;
31903610 struct ieee80211_rx_status rx_status;
3611
+ struct ieee80211_hdr *hdr;
31913612 const u8 *dst;
31923613 int frame_data_len;
31933614 void *frame_data;
31943615 struct sk_buff *skb = NULL;
3616
+ struct ieee80211_channel *channel = NULL;
31953617
31963618 if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] ||
31973619 !info->attrs[HWSIM_ATTR_FRAME] ||
....@@ -3203,12 +3625,13 @@
32033625 frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]);
32043626 frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
32053627
3628
+ if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) ||
3629
+ frame_data_len > IEEE80211_MAX_DATA_LEN)
3630
+ goto err;
3631
+
32063632 /* Allocate new skb here */
32073633 skb = alloc_skb(frame_data_len, GFP_KERNEL);
32083634 if (skb == NULL)
3209
- goto err;
3210
-
3211
- if (frame_data_len > IEEE80211_MAX_DATA_LEN)
32123635 goto err;
32133636
32143637 /* Copy the data */
....@@ -3218,15 +3641,29 @@
32183641 if (!data2)
32193642 goto out;
32203643
3221
- if (hwsim_net_get_netgroup(genl_info_net(info)) != data2->netgroup)
3644
+ if (data2->use_chanctx) {
3645
+ if (data2->tmp_chan)
3646
+ channel = data2->tmp_chan;
3647
+ else if (data2->chanctx)
3648
+ channel = data2->chanctx->def.chan;
3649
+ } else {
3650
+ channel = data2->channel;
3651
+ }
3652
+ if (!channel)
32223653 goto out;
32233654
3224
- if (info->snd_portid != data2->wmediumd)
3225
- goto out;
3655
+ if (!hwsim_virtio_enabled) {
3656
+ if (hwsim_net_get_netgroup(genl_info_net(info)) !=
3657
+ data2->netgroup)
3658
+ goto out;
3659
+
3660
+ if (info->snd_portid != data2->wmediumd)
3661
+ goto out;
3662
+ }
32263663
32273664 /* check if radio is configured properly */
32283665
3229
- if (data2->idle || !data2->started)
3666
+ if ((data2->idle && !data2->tmp_chan) || !data2->started)
32303667 goto out;
32313668
32323669 /* A frame is received from user space */
....@@ -3239,20 +3676,26 @@
32393676 mutex_lock(&data2->mutex);
32403677 rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
32413678
3242
- if (rx_status.freq != data2->channel->center_freq &&
3243
- (!data2->tmp_chan ||
3244
- rx_status.freq != data2->tmp_chan->center_freq)) {
3679
+ if (rx_status.freq != channel->center_freq) {
32453680 mutex_unlock(&data2->mutex);
32463681 goto out;
32473682 }
32483683 mutex_unlock(&data2->mutex);
32493684 } else {
3250
- rx_status.freq = data2->channel->center_freq;
3685
+ rx_status.freq = channel->center_freq;
32513686 }
32523687
3253
- rx_status.band = data2->channel->band;
3688
+ rx_status.band = channel->band;
32543689 rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
3690
+ if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
3691
+ goto out;
32553692 rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
3693
+
3694
+ hdr = (void *)skb->data;
3695
+
3696
+ if (ieee80211_is_beacon(hdr->frame_control) ||
3697
+ ieee80211_is_probe_resp(hdr->frame_control))
3698
+ rx_status.boottime_ns = ktime_get_boottime_ns();
32563699
32573700 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
32583701 data2->rx_pkts++;
....@@ -3298,6 +3741,29 @@
32983741 return 0;
32993742 }
33003743
3744
+/* ensures ciphers only include ciphers listed in 'hwsim_ciphers' array */
3745
+static bool hwsim_known_ciphers(const u32 *ciphers, int n_ciphers)
3746
+{
3747
+ int i;
3748
+
3749
+ for (i = 0; i < n_ciphers; i++) {
3750
+ int j;
3751
+ int found = 0;
3752
+
3753
+ for (j = 0; j < ARRAY_SIZE(hwsim_ciphers); j++) {
3754
+ if (ciphers[i] == hwsim_ciphers[j]) {
3755
+ found = 1;
3756
+ break;
3757
+ }
3758
+ }
3759
+
3760
+ if (!found)
3761
+ return false;
3762
+ }
3763
+
3764
+ return true;
3765
+}
3766
+
33013767 static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
33023768 {
33033769 struct hwsim_new_radio_params param = { 0 };
....@@ -3326,15 +3792,6 @@
33263792 if (info->attrs[HWSIM_ATTR_NO_VIF])
33273793 param.no_vif = true;
33283794
3329
- if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
3330
- hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]),
3331
- nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
3332
- GFP_KERNEL);
3333
- if (!hwname)
3334
- return -ENOMEM;
3335
- param.hwname = hwname;
3336
- }
3337
-
33383795 if (info->attrs[HWSIM_ATTR_USE_CHANCTX])
33393796 param.use_chanctx = true;
33403797 else
....@@ -3347,10 +3804,8 @@
33473804 if (info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]) {
33483805 u32 idx = nla_get_u32(info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]);
33493806
3350
- if (idx >= ARRAY_SIZE(hwsim_world_regdom_custom)) {
3351
- kfree(hwname);
3807
+ if (idx >= ARRAY_SIZE(hwsim_world_regdom_custom))
33523808 return -EINVAL;
3353
- }
33543809
33553810 idx = array_index_nospec(idx,
33563811 ARRAY_SIZE(hwsim_world_regdom_custom));
....@@ -3363,12 +3818,70 @@
33633818 GENL_SET_ERR_MSG(info,"MAC is no valid source addr");
33643819 NL_SET_BAD_ATTR(info->extack,
33653820 info->attrs[HWSIM_ATTR_PERM_ADDR]);
3366
- kfree(hwname);
33673821 return -EINVAL;
33683822 }
33693823
3370
-
33713824 param.perm_addr = nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]);
3825
+ }
3826
+
3827
+ if (info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT]) {
3828
+ param.iftypes =
3829
+ nla_get_u32(info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT]);
3830
+
3831
+ if (param.iftypes & ~HWSIM_IFTYPE_SUPPORT_MASK) {
3832
+ NL_SET_ERR_MSG_ATTR(info->extack,
3833
+ info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT],
3834
+ "cannot support more iftypes than kernel");
3835
+ return -EINVAL;
3836
+ }
3837
+ } else {
3838
+ param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
3839
+ }
3840
+
3841
+ /* ensure both flag and iftype support is honored */
3842
+ if (param.p2p_device ||
3843
+ param.iftypes & BIT(NL80211_IFTYPE_P2P_DEVICE)) {
3844
+ param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
3845
+ param.p2p_device = true;
3846
+ }
3847
+
3848
+ if (info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]) {
3849
+ u32 len = nla_len(info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]);
3850
+
3851
+ param.ciphers =
3852
+ nla_data(info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]);
3853
+
3854
+ if (len % sizeof(u32)) {
3855
+ NL_SET_ERR_MSG_ATTR(info->extack,
3856
+ info->attrs[HWSIM_ATTR_CIPHER_SUPPORT],
3857
+ "bad cipher list length");
3858
+ return -EINVAL;
3859
+ }
3860
+
3861
+ param.n_ciphers = len / sizeof(u32);
3862
+
3863
+ if (param.n_ciphers > ARRAY_SIZE(hwsim_ciphers)) {
3864
+ NL_SET_ERR_MSG_ATTR(info->extack,
3865
+ info->attrs[HWSIM_ATTR_CIPHER_SUPPORT],
3866
+ "too many ciphers specified");
3867
+ return -EINVAL;
3868
+ }
3869
+
3870
+ if (!hwsim_known_ciphers(param.ciphers, param.n_ciphers)) {
3871
+ NL_SET_ERR_MSG_ATTR(info->extack,
3872
+ info->attrs[HWSIM_ATTR_CIPHER_SUPPORT],
3873
+ "unsupported ciphers specified");
3874
+ return -EINVAL;
3875
+ }
3876
+ }
3877
+
3878
+ if (info->attrs[HWSIM_ATTR_RADIO_NAME]) {
3879
+ hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]),
3880
+ nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]),
3881
+ GFP_KERNEL);
3882
+ if (!hwname)
3883
+ return -ENOMEM;
3884
+ param.hwname = hwname;
33723885 }
33733886
33743887 ret = mac80211_hwsim_new_radio(info, &param);
....@@ -3516,38 +4029,38 @@
35164029 }
35174030
35184031 /* Generic Netlink operations array */
3519
-static const struct genl_ops hwsim_ops[] = {
4032
+static const struct genl_small_ops hwsim_ops[] = {
35204033 {
35214034 .cmd = HWSIM_CMD_REGISTER,
3522
- .policy = hwsim_genl_policy,
4035
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
35234036 .doit = hwsim_register_received_nl,
35244037 .flags = GENL_UNS_ADMIN_PERM,
35254038 },
35264039 {
35274040 .cmd = HWSIM_CMD_FRAME,
3528
- .policy = hwsim_genl_policy,
4041
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
35294042 .doit = hwsim_cloned_frame_received_nl,
35304043 },
35314044 {
35324045 .cmd = HWSIM_CMD_TX_INFO_FRAME,
3533
- .policy = hwsim_genl_policy,
4046
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
35344047 .doit = hwsim_tx_info_frame_received_nl,
35354048 },
35364049 {
35374050 .cmd = HWSIM_CMD_NEW_RADIO,
3538
- .policy = hwsim_genl_policy,
4051
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
35394052 .doit = hwsim_new_radio_nl,
35404053 .flags = GENL_UNS_ADMIN_PERM,
35414054 },
35424055 {
35434056 .cmd = HWSIM_CMD_DEL_RADIO,
3544
- .policy = hwsim_genl_policy,
4057
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
35454058 .doit = hwsim_del_radio_nl,
35464059 .flags = GENL_UNS_ADMIN_PERM,
35474060 },
35484061 {
35494062 .cmd = HWSIM_CMD_GET_RADIO,
3550
- .policy = hwsim_genl_policy,
4063
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
35514064 .doit = hwsim_get_radio_nl,
35524065 .dumpit = hwsim_dump_radio_nl,
35534066 },
....@@ -3557,10 +4070,11 @@
35574070 .name = "MAC80211_HWSIM",
35584071 .version = 1,
35594072 .maxattr = HWSIM_ATTR_MAX,
4073
+ .policy = hwsim_genl_policy,
35604074 .netnsok = true,
35614075 .module = THIS_MODULE,
3562
- .ops = hwsim_ops,
3563
- .n_ops = ARRAY_SIZE(hwsim_ops),
4076
+ .small_ops = hwsim_ops,
4077
+ .n_small_ops = ARRAY_SIZE(hwsim_ops),
35644078 .mcgrps = hwsim_mcgrps,
35654079 .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
35664080 };
....@@ -3686,6 +4200,234 @@
36864200 genl_unregister_family(&hwsim_genl_family);
36874201 }
36884202
4203
+#if IS_REACHABLE(CONFIG_VIRTIO)
4204
+static void hwsim_virtio_tx_done(struct virtqueue *vq)
4205
+{
4206
+ unsigned int len;
4207
+ struct sk_buff *skb;
4208
+ unsigned long flags;
4209
+
4210
+ spin_lock_irqsave(&hwsim_virtio_lock, flags);
4211
+ while ((skb = virtqueue_get_buf(vq, &len)))
4212
+ nlmsg_free(skb);
4213
+ spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
4214
+}
4215
+
4216
+static int hwsim_virtio_handle_cmd(struct sk_buff *skb)
4217
+{
4218
+ struct nlmsghdr *nlh;
4219
+ struct genlmsghdr *gnlh;
4220
+ struct nlattr *tb[HWSIM_ATTR_MAX + 1];
4221
+ struct genl_info info = {};
4222
+ int err;
4223
+
4224
+ nlh = nlmsg_hdr(skb);
4225
+ gnlh = nlmsg_data(nlh);
4226
+
4227
+ if (skb->len < nlh->nlmsg_len)
4228
+ return -EINVAL;
4229
+
4230
+ err = genlmsg_parse(nlh, &hwsim_genl_family, tb, HWSIM_ATTR_MAX,
4231
+ hwsim_genl_policy, NULL);
4232
+ if (err) {
4233
+ pr_err_ratelimited("hwsim: genlmsg_parse returned %d\n", err);
4234
+ return err;
4235
+ }
4236
+
4237
+ info.attrs = tb;
4238
+
4239
+ switch (gnlh->cmd) {
4240
+ case HWSIM_CMD_FRAME:
4241
+ hwsim_cloned_frame_received_nl(skb, &info);
4242
+ break;
4243
+ case HWSIM_CMD_TX_INFO_FRAME:
4244
+ hwsim_tx_info_frame_received_nl(skb, &info);
4245
+ break;
4246
+ default:
4247
+ pr_err_ratelimited("hwsim: invalid cmd: %d\n", gnlh->cmd);
4248
+ return -EPROTO;
4249
+ }
4250
+ return 0;
4251
+}
4252
+
4253
+static void hwsim_virtio_rx_work(struct work_struct *work)
4254
+{
4255
+ struct virtqueue *vq;
4256
+ unsigned int len;
4257
+ struct sk_buff *skb;
4258
+ struct scatterlist sg[1];
4259
+ int err;
4260
+ unsigned long flags;
4261
+
4262
+ spin_lock_irqsave(&hwsim_virtio_lock, flags);
4263
+ if (!hwsim_virtio_enabled)
4264
+ goto out_unlock;
4265
+
4266
+ skb = virtqueue_get_buf(hwsim_vqs[HWSIM_VQ_RX], &len);
4267
+ if (!skb)
4268
+ goto out_unlock;
4269
+ spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
4270
+
4271
+ skb->data = skb->head;
4272
+ skb_reset_tail_pointer(skb);
4273
+ skb_put(skb, len);
4274
+ hwsim_virtio_handle_cmd(skb);
4275
+
4276
+ spin_lock_irqsave(&hwsim_virtio_lock, flags);
4277
+ if (!hwsim_virtio_enabled) {
4278
+ nlmsg_free(skb);
4279
+ goto out_unlock;
4280
+ }
4281
+ vq = hwsim_vqs[HWSIM_VQ_RX];
4282
+ sg_init_one(sg, skb->head, skb_end_offset(skb));
4283
+ err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_ATOMIC);
4284
+ if (WARN(err, "virtqueue_add_inbuf returned %d\n", err))
4285
+ nlmsg_free(skb);
4286
+ else
4287
+ virtqueue_kick(vq);
4288
+ schedule_work(&hwsim_virtio_rx);
4289
+
4290
+out_unlock:
4291
+ spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
4292
+}
4293
+
4294
+static void hwsim_virtio_rx_done(struct virtqueue *vq)
4295
+{
4296
+ schedule_work(&hwsim_virtio_rx);
4297
+}
4298
+
4299
+static int init_vqs(struct virtio_device *vdev)
4300
+{
4301
+ vq_callback_t *callbacks[HWSIM_NUM_VQS] = {
4302
+ [HWSIM_VQ_TX] = hwsim_virtio_tx_done,
4303
+ [HWSIM_VQ_RX] = hwsim_virtio_rx_done,
4304
+ };
4305
+ const char *names[HWSIM_NUM_VQS] = {
4306
+ [HWSIM_VQ_TX] = "tx",
4307
+ [HWSIM_VQ_RX] = "rx",
4308
+ };
4309
+
4310
+ return virtio_find_vqs(vdev, HWSIM_NUM_VQS,
4311
+ hwsim_vqs, callbacks, names, NULL);
4312
+}
4313
+
4314
+static int fill_vq(struct virtqueue *vq)
4315
+{
4316
+ int i, err;
4317
+ struct sk_buff *skb;
4318
+ struct scatterlist sg[1];
4319
+
4320
+ for (i = 0; i < virtqueue_get_vring_size(vq); i++) {
4321
+ skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4322
+ if (!skb)
4323
+ return -ENOMEM;
4324
+
4325
+ sg_init_one(sg, skb->head, skb_end_offset(skb));
4326
+ err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_KERNEL);
4327
+ if (err) {
4328
+ nlmsg_free(skb);
4329
+ return err;
4330
+ }
4331
+ }
4332
+ virtqueue_kick(vq);
4333
+ return 0;
4334
+}
4335
+
4336
+static void remove_vqs(struct virtio_device *vdev)
4337
+{
4338
+ int i;
4339
+
4340
+ vdev->config->reset(vdev);
4341
+
4342
+ for (i = 0; i < ARRAY_SIZE(hwsim_vqs); i++) {
4343
+ struct virtqueue *vq = hwsim_vqs[i];
4344
+ struct sk_buff *skb;
4345
+
4346
+ while ((skb = virtqueue_detach_unused_buf(vq)))
4347
+ nlmsg_free(skb);
4348
+ }
4349
+
4350
+ vdev->config->del_vqs(vdev);
4351
+}
4352
+
4353
+static int hwsim_virtio_probe(struct virtio_device *vdev)
4354
+{
4355
+ int err;
4356
+ unsigned long flags;
4357
+
4358
+ spin_lock_irqsave(&hwsim_virtio_lock, flags);
4359
+ if (hwsim_virtio_enabled) {
4360
+ spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
4361
+ return -EEXIST;
4362
+ }
4363
+ spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
4364
+
4365
+ err = init_vqs(vdev);
4366
+ if (err)
4367
+ return err;
4368
+
4369
+ err = fill_vq(hwsim_vqs[HWSIM_VQ_RX]);
4370
+ if (err)
4371
+ goto out_remove;
4372
+
4373
+ spin_lock_irqsave(&hwsim_virtio_lock, flags);
4374
+ hwsim_virtio_enabled = true;
4375
+ spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
4376
+
4377
+ schedule_work(&hwsim_virtio_rx);
4378
+ return 0;
4379
+
4380
+out_remove:
4381
+ remove_vqs(vdev);
4382
+ return err;
4383
+}
4384
+
4385
+static void hwsim_virtio_remove(struct virtio_device *vdev)
4386
+{
4387
+ hwsim_virtio_enabled = false;
4388
+
4389
+ cancel_work_sync(&hwsim_virtio_rx);
4390
+
4391
+ remove_vqs(vdev);
4392
+}
4393
+
4394
+/* MAC80211_HWSIM virtio device id table */
4395
+static const struct virtio_device_id id_table[] = {
4396
+ { VIRTIO_ID_MAC80211_HWSIM, VIRTIO_DEV_ANY_ID },
4397
+ { 0 }
4398
+};
4399
+MODULE_DEVICE_TABLE(virtio, id_table);
4400
+
4401
+static struct virtio_driver virtio_hwsim = {
4402
+ .driver.name = KBUILD_MODNAME,
4403
+ .driver.owner = THIS_MODULE,
4404
+ .id_table = id_table,
4405
+ .probe = hwsim_virtio_probe,
4406
+ .remove = hwsim_virtio_remove,
4407
+};
4408
+
4409
+static int hwsim_register_virtio_driver(void)
4410
+{
4411
+ spin_lock_init(&hwsim_virtio_lock);
4412
+
4413
+ return register_virtio_driver(&virtio_hwsim);
4414
+}
4415
+
4416
+static void hwsim_unregister_virtio_driver(void)
4417
+{
4418
+ unregister_virtio_driver(&virtio_hwsim);
4419
+}
4420
+#else
4421
+static inline int hwsim_register_virtio_driver(void)
4422
+{
4423
+ return 0;
4424
+}
4425
+
4426
+static inline void hwsim_unregister_virtio_driver(void)
4427
+{
4428
+}
4429
+#endif
4430
+
36894431 static int __init init_mac80211_hwsim(void)
36904432 {
36914433 int i, err;
....@@ -3698,13 +4440,9 @@
36984440
36994441 spin_lock_init(&hwsim_radio_lock);
37004442
3701
- hwsim_wq = alloc_workqueue("hwsim_wq", 0, 0);
3702
- if (!hwsim_wq)
3703
- return -ENOMEM;
3704
-
37054443 err = rhashtable_init(&hwsim_radios_rht, &hwsim_rht_params);
37064444 if (err)
3707
- goto out_free_wq;
4445
+ return err;
37084446
37094447 err = register_pernet_device(&hwsim_net_ops);
37104448 if (err)
....@@ -3718,11 +4456,17 @@
37184456 if (err)
37194457 goto out_unregister_driver;
37204458
4459
+ err = hwsim_register_virtio_driver();
4460
+ if (err)
4461
+ goto out_exit_netlink;
4462
+
37214463 hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
37224464 if (IS_ERR(hwsim_class)) {
37234465 err = PTR_ERR(hwsim_class);
3724
- goto out_exit_netlink;
4466
+ goto out_exit_virtio;
37254467 }
4468
+
4469
+ hwsim_init_s1g_channels(hwsim_channels_s1g);
37264470
37274471 for (i = 0; i < radios; i++) {
37284472 struct hwsim_new_radio_params param = { 0 };
....@@ -3740,6 +4484,7 @@
37404484 break;
37414485 case HWSIM_REGTEST_STRICT_ALL:
37424486 param.reg_strict = true;
4487
+ fallthrough;
37434488 case HWSIM_REGTEST_DRIVER_REG_ALL:
37444489 param.reg_alpha2 = hwsim_alpha2s[0];
37454490 break;
....@@ -3796,6 +4541,9 @@
37964541
37974542 param.p2p_device = support_p2p_device;
37984543 param.use_chanctx = channels > 1;
4544
+ param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
4545
+ if (param.p2p_device)
4546
+ param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
37994547
38004548 err = mac80211_hwsim_new_radio(NULL, &param);
38014549 if (err < 0)
....@@ -3813,7 +4561,7 @@
38134561 err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
38144562 if (err < 0) {
38154563 rtnl_unlock();
3816
- goto out_free_radios;
4564
+ goto out_free_mon;
38174565 }
38184566
38194567 err = register_netdevice(hwsim_mon);
....@@ -3829,6 +4577,8 @@
38294577 free_netdev(hwsim_mon);
38304578 out_free_radios:
38314579 mac80211_hwsim_free();
4580
+out_exit_virtio:
4581
+ hwsim_unregister_virtio_driver();
38324582 out_exit_netlink:
38334583 hwsim_exit_netlink();
38344584 out_unregister_driver:
....@@ -3837,8 +4587,6 @@
38374587 unregister_pernet_device(&hwsim_net_ops);
38384588 out_free_rht:
38394589 rhashtable_destroy(&hwsim_radios_rht);
3840
-out_free_wq:
3841
- destroy_workqueue(hwsim_wq);
38424590 return err;
38434591 }
38444592 module_init(init_mac80211_hwsim);
....@@ -3847,15 +4595,14 @@
38474595 {
38484596 pr_debug("mac80211_hwsim: unregister radios\n");
38494597
4598
+ hwsim_unregister_virtio_driver();
38504599 hwsim_exit_netlink();
38514600
38524601 mac80211_hwsim_free();
3853
- flush_workqueue(hwsim_wq);
38544602
38554603 rhashtable_destroy(&hwsim_radios_rht);
38564604 unregister_netdev(hwsim_mon);
38574605 platform_driver_unregister(&mac80211_hwsim_driver);
38584606 unregister_pernet_device(&hwsim_net_ops);
3859
- destroy_workqueue(hwsim_wq);
38604607 }
38614608 module_exit(exit_mac80211_hwsim);