-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
wifi: mac80211: tests: add utility to create sdata skeleton
Some functions that should be tested may expect an sdata object that is configured to a basic degree. Add setup code to create such an object for use by tests. Signed-off-by: Benjamin Berg <benjamin.berg@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20250101070249.12eeefd3c98b.I6e8c2b8374d4305f16675524ca30621e089b6fb0@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- Loading branch information
Benjamin Berg
authored and
Johannes Berg
committed
Jan 13, 2025
1 parent
708d06b
commit 11cc69a
Showing
3 changed files
with
350 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
mac80211-tests-y += module.o elems.o mfp.o tpe.o | ||
mac80211-tests-y += module.o util.o elems.o mfp.o tpe.o | ||
|
||
obj-$(CONFIG_MAC80211_KUNIT_TEST) += mac80211-tests.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,313 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Utilities for mac80211 unit testing | ||
* | ||
* Copyright (C) 2024 Intel Corporation | ||
*/ | ||
#include <linux/ieee80211.h> | ||
#include <net/mac80211.h> | ||
#include <kunit/test.h> | ||
#include <kunit/test-bug.h> | ||
#include "util.h" | ||
|
||
#define CHAN2G(_freq) { \ | ||
.band = NL80211_BAND_2GHZ, \ | ||
.center_freq = (_freq), \ | ||
.hw_value = (_freq), \ | ||
} | ||
|
||
static const struct ieee80211_channel channels_2ghz[] = { | ||
CHAN2G(2412), /* Channel 1 */ | ||
CHAN2G(2417), /* Channel 2 */ | ||
CHAN2G(2422), /* Channel 3 */ | ||
CHAN2G(2427), /* Channel 4 */ | ||
CHAN2G(2432), /* Channel 5 */ | ||
CHAN2G(2437), /* Channel 6 */ | ||
CHAN2G(2442), /* Channel 7 */ | ||
CHAN2G(2447), /* Channel 8 */ | ||
CHAN2G(2452), /* Channel 9 */ | ||
CHAN2G(2457), /* Channel 10 */ | ||
CHAN2G(2462), /* Channel 11 */ | ||
CHAN2G(2467), /* Channel 12 */ | ||
CHAN2G(2472), /* Channel 13 */ | ||
CHAN2G(2484), /* Channel 14 */ | ||
}; | ||
|
||
#define CHAN5G(_freq) { \ | ||
.band = NL80211_BAND_5GHZ, \ | ||
.center_freq = (_freq), \ | ||
.hw_value = (_freq), \ | ||
} | ||
|
||
static const struct ieee80211_channel channels_5ghz[] = { | ||
CHAN5G(5180), /* Channel 36 */ | ||
CHAN5G(5200), /* Channel 40 */ | ||
CHAN5G(5220), /* Channel 44 */ | ||
CHAN5G(5240), /* Channel 48 */ | ||
}; | ||
|
||
static const struct ieee80211_rate bitrates[] = { | ||
{ .bitrate = 10 }, | ||
{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
{ .bitrate = 60 }, | ||
{ .bitrate = 90 }, | ||
{ .bitrate = 120 }, | ||
{ .bitrate = 180 }, | ||
{ .bitrate = 240 }, | ||
{ .bitrate = 360 }, | ||
{ .bitrate = 480 }, | ||
{ .bitrate = 540 } | ||
}; | ||
|
||
/* Copied from hwsim except that it only supports 4 EHT streams and STA/P2P mode */ | ||
static const struct ieee80211_sband_iftype_data sband_capa_5ghz[] = { | ||
{ | ||
.types_mask = BIT(NL80211_IFTYPE_STATION) | | ||
BIT(NL80211_IFTYPE_P2P_CLIENT), | ||
.he_cap = { | ||
.has_he = true, | ||
.he_cap_elem = { | ||
.mac_cap_info[0] = | ||
IEEE80211_HE_MAC_CAP0_HTC_HE, | ||
.mac_cap_info[1] = | ||
IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US | | ||
IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8, | ||
.mac_cap_info[2] = | ||
IEEE80211_HE_MAC_CAP2_BSR | | ||
IEEE80211_HE_MAC_CAP2_MU_CASCADING | | ||
IEEE80211_HE_MAC_CAP2_ACK_EN, | ||
.mac_cap_info[3] = | ||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL | | ||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3, | ||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU, | ||
.phy_cap_info[0] = | ||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | | ||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G | | ||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G, | ||
.phy_cap_info[1] = | ||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK | | ||
IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | | ||
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD | | ||
IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS, | ||
.phy_cap_info[2] = | ||
IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | | ||
IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ | | ||
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ | | ||
IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO | | ||
IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO, | ||
|
||
/* Leave all the other PHY capability bytes | ||
* unset, as DCM, beam forming, RU and PPE | ||
* threshold information are not supported | ||
*/ | ||
}, | ||
.he_mcs_nss_supp = { | ||
.rx_mcs_80 = cpu_to_le16(0xfffa), | ||
.tx_mcs_80 = cpu_to_le16(0xfffa), | ||
.rx_mcs_160 = cpu_to_le16(0xfffa), | ||
.tx_mcs_160 = cpu_to_le16(0xfffa), | ||
.rx_mcs_80p80 = cpu_to_le16(0xfffa), | ||
.tx_mcs_80p80 = cpu_to_le16(0xfffa), | ||
}, | ||
}, | ||
.eht_cap = { | ||
.has_eht = true, | ||
.eht_cap_elem = { | ||
.mac_cap_info[0] = | ||
IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS | | ||
IEEE80211_EHT_MAC_CAP0_OM_CONTROL | | ||
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1, | ||
.phy_cap_info[0] = | ||
IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ | | ||
IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI | | ||
IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO | | ||
IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER | | ||
IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE | | ||
IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK, | ||
.phy_cap_info[1] = | ||
IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK | | ||
IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK, | ||
.phy_cap_info[2] = | ||
IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK | | ||
IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK, | ||
.phy_cap_info[3] = | ||
IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK | | ||
IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK | | ||
IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK | | ||
IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK | | ||
IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK | | ||
IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK | | ||
IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK, | ||
.phy_cap_info[4] = | ||
IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO | | ||
IEEE80211_EHT_PHY_CAP4_PSR_SR_SUPP | | ||
IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP | | ||
IEEE80211_EHT_PHY_CAP4_EHT_MU_PPDU_4_EHT_LTF_08_GI | | ||
IEEE80211_EHT_PHY_CAP4_MAX_NC_MASK, | ||
.phy_cap_info[5] = | ||
IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK | | ||
IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP | | ||
IEEE80211_EHT_PHY_CAP5_RX_LESS_242_TONE_RU_SUPP | | ||
IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT | | ||
IEEE80211_EHT_PHY_CAP5_COMMON_NOMINAL_PKT_PAD_MASK | | ||
IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK, | ||
.phy_cap_info[6] = | ||
IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK | | ||
IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK, | ||
.phy_cap_info[7] = | ||
IEEE80211_EHT_PHY_CAP7_20MHZ_STA_RX_NDP_WIDER_BW | | ||
IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_80MHZ | | ||
IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_160MHZ | | ||
IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ | | ||
IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ, | ||
}, | ||
|
||
/* For all MCS and bandwidth, set 4 NSS for both Tx and | ||
* Rx | ||
*/ | ||
.eht_mcs_nss_supp = { | ||
/* | ||
* As B1 and B2 are set in the supported | ||
* channel width set field in the HE PHY | ||
* capabilities information field include all | ||
* the following MCS/NSS. | ||
*/ | ||
.bw._80 = { | ||
.rx_tx_mcs9_max_nss = 0x44, | ||
.rx_tx_mcs11_max_nss = 0x44, | ||
.rx_tx_mcs13_max_nss = 0x44, | ||
}, | ||
.bw._160 = { | ||
.rx_tx_mcs9_max_nss = 0x44, | ||
.rx_tx_mcs11_max_nss = 0x44, | ||
.rx_tx_mcs13_max_nss = 0x44, | ||
}, | ||
}, | ||
/* PPE threshold information is not supported */ | ||
}, | ||
}, | ||
}; | ||
|
||
int t_sdata_init(struct kunit_resource *resource, void *ctx) | ||
{ | ||
struct kunit *test = kunit_get_current_test(); | ||
struct t_sdata *t_sdata; | ||
|
||
t_sdata = kzalloc(sizeof(*t_sdata), GFP_KERNEL); | ||
KUNIT_ASSERT_NOT_NULL(test, t_sdata); | ||
|
||
resource->data = t_sdata; | ||
resource->name = "sdata"; | ||
|
||
t_sdata->sdata = kzalloc(sizeof(*t_sdata->sdata), GFP_KERNEL); | ||
KUNIT_ASSERT_NOT_NULL(test, t_sdata->sdata); | ||
|
||
t_sdata->wiphy = kzalloc(sizeof(*t_sdata->wiphy), GFP_KERNEL); | ||
KUNIT_ASSERT_NOT_NULL(test, t_sdata->wiphy); | ||
|
||
strscpy(t_sdata->sdata->name, "kunit"); | ||
|
||
t_sdata->sdata->local = &t_sdata->local; | ||
t_sdata->sdata->local->hw.wiphy = t_sdata->wiphy; | ||
t_sdata->sdata->wdev.wiphy = t_sdata->wiphy; | ||
t_sdata->sdata->vif.type = NL80211_IFTYPE_STATION; | ||
|
||
t_sdata->sdata->deflink.sdata = t_sdata->sdata; | ||
t_sdata->sdata->deflink.link_id = 0; | ||
|
||
t_sdata->wiphy->bands[NL80211_BAND_2GHZ] = &t_sdata->band_2ghz; | ||
t_sdata->wiphy->bands[NL80211_BAND_5GHZ] = &t_sdata->band_5ghz; | ||
|
||
for (int band = NL80211_BAND_2GHZ; band <= NL80211_BAND_5GHZ; band++) { | ||
struct ieee80211_supported_band *sband; | ||
|
||
sband = t_sdata->wiphy->bands[band]; | ||
sband->band = band; | ||
|
||
sband->bitrates = | ||
kmemdup(bitrates, sizeof(bitrates), GFP_KERNEL); | ||
sband->n_bitrates = ARRAY_SIZE(bitrates); | ||
|
||
/* Initialize channels, feel free to add more channels/bands */ | ||
switch (band) { | ||
case NL80211_BAND_2GHZ: | ||
sband->channels = kmemdup(channels_2ghz, | ||
sizeof(channels_2ghz), | ||
GFP_KERNEL); | ||
sband->n_channels = ARRAY_SIZE(channels_2ghz); | ||
sband->bitrates = kmemdup(bitrates, | ||
sizeof(bitrates), | ||
GFP_KERNEL); | ||
sband->n_bitrates = ARRAY_SIZE(bitrates); | ||
break; | ||
case NL80211_BAND_5GHZ: | ||
sband->channels = kmemdup(channels_5ghz, | ||
sizeof(channels_5ghz), | ||
GFP_KERNEL); | ||
sband->n_channels = ARRAY_SIZE(channels_5ghz); | ||
sband->bitrates = kmemdup(bitrates, | ||
sizeof(bitrates), | ||
GFP_KERNEL); | ||
sband->n_bitrates = ARRAY_SIZE(bitrates); | ||
|
||
sband->vht_cap.vht_supported = true; | ||
sband->vht_cap.cap = | ||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | | ||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | | ||
IEEE80211_VHT_CAP_RXLDPC | | ||
IEEE80211_VHT_CAP_SHORT_GI_80 | | ||
IEEE80211_VHT_CAP_SHORT_GI_160 | | ||
IEEE80211_VHT_CAP_TXSTBC | | ||
IEEE80211_VHT_CAP_RXSTBC_4 | | ||
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; | ||
sband->vht_cap.vht_mcs.rx_mcs_map = | ||
cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | | ||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | | ||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | | ||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | | ||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | | ||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | | ||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | | ||
IEEE80211_VHT_MCS_SUPPORT_0_9 << 14); | ||
sband->vht_cap.vht_mcs.tx_mcs_map = | ||
sband->vht_cap.vht_mcs.rx_mcs_map; | ||
break; | ||
default: | ||
continue; | ||
} | ||
|
||
sband->ht_cap.ht_supported = band != NL80211_BAND_6GHZ; | ||
sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
IEEE80211_HT_CAP_GRN_FLD | | ||
IEEE80211_HT_CAP_SGI_20 | | ||
IEEE80211_HT_CAP_SGI_40 | | ||
IEEE80211_HT_CAP_DSSSCCK40; | ||
sband->ht_cap.ampdu_factor = 0x3; | ||
sband->ht_cap.ampdu_density = 0x6; | ||
memset(&sband->ht_cap.mcs, 0, sizeof(sband->ht_cap.mcs)); | ||
sband->ht_cap.mcs.rx_mask[0] = 0xff; | ||
sband->ht_cap.mcs.rx_mask[1] = 0xff; | ||
sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | ||
} | ||
|
||
ieee80211_set_sband_iftype_data(&t_sdata->band_5ghz, sband_capa_5ghz); | ||
|
||
return 0; | ||
} | ||
|
||
void t_sdata_exit(struct kunit_resource *resource) | ||
{ | ||
struct t_sdata *t_sdata = resource->data; | ||
|
||
kfree(t_sdata->band_2ghz.channels); | ||
kfree(t_sdata->band_2ghz.bitrates); | ||
kfree(t_sdata->band_5ghz.channels); | ||
kfree(t_sdata->band_5ghz.bitrates); | ||
|
||
kfree(t_sdata->sdata); | ||
kfree(t_sdata->wiphy); | ||
|
||
kfree(t_sdata); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* | ||
* Utilities for mac80211 unit testing | ||
* | ||
* Copyright (C) 2024 Intel Corporation | ||
*/ | ||
#ifndef __MAC80211_UTILS_H | ||
#define __MAC80211_UTILS_H | ||
|
||
#include "../ieee80211_i.h" | ||
|
||
struct t_sdata { | ||
struct ieee80211_sub_if_data *sdata; | ||
struct wiphy *wiphy; | ||
struct ieee80211_local local; | ||
|
||
void *ctx; | ||
|
||
struct ieee80211_supported_band band_2ghz; | ||
struct ieee80211_supported_band band_5ghz; | ||
}; | ||
|
||
#define T_SDATA(test) ({ \ | ||
struct t_sdata *__t_sdata = \ | ||
kunit_alloc_resource(test, t_sdata_init, \ | ||
t_sdata_exit, \ | ||
GFP_KERNEL, NULL); \ | ||
\ | ||
KUNIT_ASSERT_NOT_NULL(test, __t_sdata); \ | ||
__t_sdata; \ | ||
}) | ||
|
||
int t_sdata_init(struct kunit_resource *resource, void *data); | ||
void t_sdata_exit(struct kunit_resource *resource); | ||
|
||
#endif /* __MAC80211_UTILS_H */ |