@@ -99,7 +99,7 @@ MODULE_PARM_DESC(support_p2p_device, "Support P2P-Device interface type");
9999 * domain requests. The first radio will adhere to the first custom world
100100 * regulatory domain, the second one to the second custom world regulatory
101101 * domain. All other devices will world roam.
102- * @HWSIM_REGTEST_STRICT_FOLLOW_ : Used for testing strict regulatory domain
102+ * @HWSIM_REGTEST_STRICT_FOLLOW : Used for testing strict regulatory domain
103103 * settings, only the first radio will send a regulatory domain request
104104 * and use strict settings. The rest of the radios are expected to follow.
105105 * @HWSIM_REGTEST_STRICT_ALL: Used for testing strict regulatory domain
@@ -377,6 +377,49 @@ static const struct ieee80211_channel hwsim_channels_5ghz[] = {
377377 CHAN5G (5925 ), /* Channel 185 */
378378};
379379
380+ #define NUM_S1G_CHANS_US 51
381+ static struct ieee80211_channel hwsim_channels_s1g [NUM_S1G_CHANS_US ];
382+
383+ static const struct ieee80211_sta_s1g_cap hwsim_s1g_cap = {
384+ .s1g = true,
385+ .cap = { S1G_CAP0_SGI_1MHZ | S1G_CAP0_SGI_2MHZ ,
386+ 0 ,
387+ 0 ,
388+ S1G_CAP3_MAX_MPDU_LEN ,
389+ 0 ,
390+ S1G_CAP5_AMPDU ,
391+ 0 ,
392+ S1G_CAP7_DUP_1MHZ ,
393+ S1G_CAP8_TWT_RESPOND | S1G_CAP8_TWT_REQUEST ,
394+ 0 },
395+ .nss_mcs = { 0xfc | 1 , /* MCS 7 for 1 SS */
396+ /* RX Highest Supported Long GI Data Rate 0:7 */
397+ 0 ,
398+ /* RX Highest Supported Long GI Data Rate 0:7 */
399+ /* TX S1G MCS Map 0:6 */
400+ 0xfa ,
401+ /* TX S1G MCS Map :7 */
402+ /* TX Highest Supported Long GI Data Rate 0:6 */
403+ 0x80 ,
404+ /* TX Highest Supported Long GI Data Rate 7:8 */
405+ /* Rx Single spatial stream and S1G-MCS Map for 1MHz */
406+ /* Tx Single spatial stream and S1G-MCS Map for 1MHz */
407+ 0 },
408+ };
409+
410+ static void hwsim_init_s1g_channels (struct ieee80211_channel * channels )
411+ {
412+ int ch , freq ;
413+
414+ for (ch = 0 ; ch < NUM_S1G_CHANS_US ; ch ++ ) {
415+ freq = 902000 + (ch + 1 ) * 500 ;
416+ channels [ch ].band = NL80211_BAND_S1GHZ ;
417+ channels [ch ].center_freq = KHZ_TO_MHZ (freq );
418+ channels [ch ].freq_offset = freq % 1000 ;
419+ channels [ch ].hw_value = ch + 1 ;
420+ }
421+ }
422+
380423static const struct ieee80211_rate hwsim_rates [] = {
381424 { .bitrate = 10 },
382425 { .bitrate = 20 , .flags = IEEE80211_RATE_SHORT_PREAMBLE },
@@ -505,6 +548,7 @@ struct mac80211_hwsim_data {
505548 struct ieee80211_supported_band bands [NUM_NL80211_BANDS ];
506549 struct ieee80211_channel channels_2ghz [ARRAY_SIZE (hwsim_channels_2ghz )];
507550 struct ieee80211_channel channels_5ghz [ARRAY_SIZE (hwsim_channels_5ghz )];
551+ struct ieee80211_channel channels_s1g [ARRAY_SIZE (hwsim_channels_s1g )];
508552 struct ieee80211_rate rates [ARRAY_SIZE (hwsim_rates )];
509553 struct ieee80211_iface_combination if_combination ;
510554 struct ieee80211_iface_limit if_limits [3 ];
@@ -900,12 +944,14 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
900944 struct mac80211_hwsim_data * data = hw -> priv ;
901945 struct sk_buff * skb ;
902946 struct hwsim_radiotap_hdr * hdr ;
903- u16 flags ;
947+ u16 flags , bitrate ;
904948 struct ieee80211_tx_info * info = IEEE80211_SKB_CB (tx_skb );
905949 struct ieee80211_rate * txrate = ieee80211_get_tx_rate (hw , info );
906950
907- if (WARN_ON (!txrate ))
908- return ;
951+ if (!txrate )
952+ bitrate = 0 ;
953+ else
954+ bitrate = txrate -> bitrate ;
909955
910956 if (!netif_running (hwsim_mon ))
911957 return ;
@@ -924,10 +970,10 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
924970 (1 << IEEE80211_RADIOTAP_CHANNEL ));
925971 hdr -> rt_tsft = __mac80211_hwsim_get_tsf (data );
926972 hdr -> rt_flags = 0 ;
927- hdr -> rt_rate = txrate -> bitrate / 5 ;
973+ hdr -> rt_rate = bitrate / 5 ;
928974 hdr -> rt_channel = cpu_to_le16 (chan -> center_freq );
929975 flags = IEEE80211_CHAN_2GHZ ;
930- if (txrate -> flags & IEEE80211_RATE_ERP_G )
976+ if (txrate && txrate -> flags & IEEE80211_RATE_ERP_G )
931977 flags |= IEEE80211_CHAN_OFDM ;
932978 else
933979 flags |= IEEE80211_CHAN_CCK ;
@@ -1341,6 +1387,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
13411387 memset (& rx_status , 0 , sizeof (rx_status ));
13421388 rx_status .flag |= RX_FLAG_MACTIME_START ;
13431389 rx_status .freq = chan -> center_freq ;
1390+ rx_status .freq_offset = chan -> freq_offset ? 1 : 0 ;
13441391 rx_status .band = chan -> band ;
13451392 if (info -> control .rates [0 ].flags & IEEE80211_TX_RC_VHT_MCS ) {
13461393 rx_status .rate_idx =
@@ -1522,14 +1569,18 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
15221569 /* fake header transmission time */
15231570 struct ieee80211_mgmt * mgmt ;
15241571 struct ieee80211_rate * txrate ;
1572+ /* TODO: get MCS */
1573+ int bitrate = 100 ;
15251574 u64 ts ;
15261575
15271576 mgmt = (struct ieee80211_mgmt * )skb -> data ;
15281577 txrate = ieee80211_get_tx_rate (hw , txi );
1578+ if (txrate )
1579+ bitrate = txrate -> bitrate ;
15291580 ts = mac80211_hwsim_get_tsf_raw ();
15301581 mgmt -> u .probe_resp .timestamp =
15311582 cpu_to_le64 (ts + data -> tsf_offset +
1532- 24 * 8 * 10 / txrate -> bitrate );
1583+ 24 * 8 * 10 / bitrate );
15331584 }
15341585
15351586 mac80211_hwsim_monitor_rx (hw , skb , channel );
@@ -1664,6 +1715,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
16641715 struct ieee80211_rate * txrate ;
16651716 struct ieee80211_mgmt * mgmt ;
16661717 struct sk_buff * skb ;
1718+ /* TODO: get MCS */
1719+ int bitrate = 100 ;
16671720
16681721 hwsim_check_magic (vif );
16691722
@@ -1683,13 +1736,25 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
16831736 ARRAY_SIZE (info -> control .rates ));
16841737
16851738 txrate = ieee80211_get_tx_rate (hw , info );
1739+ if (txrate )
1740+ bitrate = txrate -> bitrate ;
16861741
16871742 mgmt = (struct ieee80211_mgmt * ) skb -> data ;
16881743 /* fake header transmission time */
16891744 data -> abs_bcn_ts = mac80211_hwsim_get_tsf_raw ();
1690- mgmt -> u .beacon .timestamp = cpu_to_le64 (data -> abs_bcn_ts +
1691- data -> tsf_offset +
1692- 24 * 8 * 10 / txrate -> bitrate );
1745+ if (ieee80211_is_s1g_beacon (mgmt -> frame_control )) {
1746+ struct ieee80211_ext * ext = (void * ) mgmt ;
1747+
1748+ ext -> u .s1g_beacon .timestamp = cpu_to_le32 (data -> abs_bcn_ts +
1749+ data -> tsf_offset +
1750+ 10 * 8 * 10 /
1751+ bitrate );
1752+ } else {
1753+ mgmt -> u .beacon .timestamp = cpu_to_le64 (data -> abs_bcn_ts +
1754+ data -> tsf_offset +
1755+ 24 * 8 * 10 /
1756+ bitrate );
1757+ }
16931758
16941759 mac80211_hwsim_tx_frame (hw , skb ,
16951760 rcu_dereference (vif -> chanctx_conf )-> def .chan );
@@ -1737,6 +1802,11 @@ static const char * const hwsim_chanwidths[] = {
17371802 [NL80211_CHAN_WIDTH_80 ] = "vht80" ,
17381803 [NL80211_CHAN_WIDTH_80P80 ] = "vht80p80" ,
17391804 [NL80211_CHAN_WIDTH_160 ] = "vht160" ,
1805+ [NL80211_CHAN_WIDTH_1 ] = "1MHz" ,
1806+ [NL80211_CHAN_WIDTH_2 ] = "2MHz" ,
1807+ [NL80211_CHAN_WIDTH_4 ] = "4MHz" ,
1808+ [NL80211_CHAN_WIDTH_8 ] = "8MHz" ,
1809+ [NL80211_CHAN_WIDTH_16 ] = "16MHz" ,
17401810};
17411811
17421812static int mac80211_hwsim_config (struct ieee80211_hw * hw , u32 changed )
@@ -3079,6 +3149,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
30793149 sizeof (hwsim_channels_2ghz ));
30803150 memcpy (data -> channels_5ghz , hwsim_channels_5ghz ,
30813151 sizeof (hwsim_channels_5ghz ));
3152+ memcpy (data -> channels_s1g , hwsim_channels_s1g ,
3153+ sizeof (hwsim_channels_s1g ));
30823154 memcpy (data -> rates , hwsim_rates , sizeof (hwsim_rates ));
30833155
30843156 for (band = NL80211_BAND_2GHZ ; band < NUM_NL80211_BANDS ; band ++ ) {
@@ -3121,6 +3193,12 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
31213193 sband -> vht_cap .vht_mcs .tx_mcs_map =
31223194 sband -> vht_cap .vht_mcs .rx_mcs_map ;
31233195 break ;
3196+ case NL80211_BAND_S1GHZ :
3197+ memcpy (& sband -> s1g_cap , & hwsim_s1g_cap ,
3198+ sizeof (sband -> s1g_cap ));
3199+ sband -> channels = data -> channels_s1g ;
3200+ sband -> n_channels = ARRAY_SIZE (hwsim_channels_s1g );
3201+ break ;
31243202 default :
31253203 continue ;
31263204 }
@@ -4318,6 +4396,8 @@ static int __init init_mac80211_hwsim(void)
43184396 goto out_exit_virtio ;
43194397 }
43204398
4399+ hwsim_init_s1g_channels (hwsim_channels_s1g );
4400+
43214401 for (i = 0 ; i < radios ; i ++ ) {
43224402 struct hwsim_new_radio_params param = { 0 };
43234403
0 commit comments