#include <kunit/test.h>
#include <linux/ieee80211.h>
#include "../ieee80211_i.h"
MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
static const struct ieee80211_ttlm_elem *
build_neg_ttlm_elem(u8 *buf, size_t elem_size,
u8 presence, u8 bm_size, const u16 *maps)
{
struct ieee80211_ttlm_elem *t = (void *)buf;
u8 control;
u8 *pos;
int i, tid;
memset(buf, 0, elem_size);
control = IEEE80211_TTLM_DIRECTION_BOTH;
if (bm_size == 1)
control |= IEEE80211_TTLM_CONTROL_LINK_MAP_SIZE;
t->control = control;
pos = (u8 *)t->optional;
*pos++ = presence;
i = 0;
for (tid = 0; tid < IEEE80211_TTLM_NUM_TIDS; tid++) {
if (!(presence & BIT(tid)))
continue;
if (bm_size == 1)
*pos = (u8)maps[i];
else
put_unaligned_le16(maps[i], pos);
pos += bm_size;
i++;
}
return t;
}
static void sparse_presence_no_oob_read(struct kunit *test)
{
const u8 presence = BIT(0) | BIT(7);
const u8 bm_size = 2;
const int npresent = 2;
const size_t elem_size = sizeof(struct ieee80211_ttlm_elem)
+ 1 + npresent * bm_size;
u8 *buf = kunit_kzalloc(test, elem_size, GFP_KERNEL);
const struct ieee80211_ttlm_elem *ttlm;
struct ieee80211_neg_ttlm neg_ttlm = {};
const u16 maps[2] = { 0x0001, 0x0001 };
u8 direction = 0;
int ret;
KUNIT_ASSERT_NOT_NULL(test, buf);
ttlm = build_neg_ttlm_elem(buf, elem_size, presence, bm_size, maps);
ret = ieee80211_parse_neg_ttlm(NULL, ttlm, &neg_ttlm, &direction);
KUNIT_EXPECT_EQ(test, ret, 0);
KUNIT_EXPECT_EQ(test, (int)direction, IEEE80211_TTLM_DIRECTION_BOTH);
KUNIT_EXPECT_EQ(test, (int)neg_ttlm.downlink[0], 0x0001);
KUNIT_EXPECT_EQ(test, (int)neg_ttlm.uplink[0], 0x0001);
KUNIT_EXPECT_EQ(test, (int)neg_ttlm.downlink[3], 0);
KUNIT_EXPECT_EQ(test, (int)neg_ttlm.uplink[3], 0);
KUNIT_EXPECT_EQ(test, (int)neg_ttlm.downlink[7], 0x0001);
KUNIT_EXPECT_EQ(test, (int)neg_ttlm.uplink[7], 0x0001);
}
static void dense_presence_baseline(struct kunit *test)
{
const u8 presence = 0xff;
const u8 bm_size = 2;
const int npresent = 8;
const size_t elem_size = sizeof(struct ieee80211_ttlm_elem)
+ 1 + npresent * bm_size;
u8 *buf = kunit_kzalloc(test, elem_size, GFP_KERNEL);
const struct ieee80211_ttlm_elem *ttlm;
struct ieee80211_neg_ttlm neg_ttlm = {};
const u16 maps[8] = {
0x0003, 0x0003, 0x0003, 0x0003,
0x0003, 0x0003, 0x0003, 0x0003,
};
u8 direction = 0;
int ret;
KUNIT_ASSERT_NOT_NULL(test, buf);
ttlm = build_neg_ttlm_elem(buf, elem_size, presence, bm_size, maps);
ret = ieee80211_parse_neg_ttlm(NULL, ttlm, &neg_ttlm, &direction);
KUNIT_EXPECT_EQ(test, ret, 0);
KUNIT_EXPECT_EQ(test, (int)direction, IEEE80211_TTLM_DIRECTION_BOTH);
for (int tid = 0; tid < IEEE80211_TTLM_NUM_TIDS; tid++) {
KUNIT_EXPECT_EQ(test, (int)neg_ttlm.downlink[tid], 0x0003);
KUNIT_EXPECT_EQ(test, (int)neg_ttlm.uplink[tid], 0x0003);
}
}
static struct kunit_case mac80211_ttlm_test_cases[] = {
KUNIT_CASE(sparse_presence_no_oob_read),
KUNIT_CASE(dense_presence_baseline),
{}
};
static struct kunit_suite mac80211_ttlm = {
.name = "mac80211-ttlm",
.test_cases = mac80211_ttlm_test_cases,
};
kunit_test_suite(mac80211_ttlm);