blob: 45a50a1cd21b8a310ac94b588561adb4f8dacf89 [file] [log] [blame]
/* Copyright (C) 2021 Mediatek Inc. */
#define _GNU_SOURCE
#include "mtk_vendor_nl80211.h"
#include "mt76-vendor.h"
#include "mwctl.h"
static int mt76_ap_rfeatures_set_attr(struct nl_msg *msg, int argc, char **argv)
{
char *val, *s1, *s2, *cur;
void *data;
int idx = MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_EN;
val = strchr(argv[0], '=');
if (!val)
return -EINVAL;
*(val++) = 0;
if (!strncmp(argv[0], "he_gi", 5)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "he_ltf", 6)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_LTF, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "trig_type", 9)) {
data = nla_nest_start(msg,
MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TYPE_CFG | NLA_F_NESTED);
if (!data)
return -ENOMEM;
s1 = s2 = strdup(val);
while ((cur = strsep(&s1, ",")) != NULL)
nla_put_u8(msg, idx++, strtoul(cur, NULL, 0));
nla_nest_end(msg, data);
free(s2);
} else if (!strncmp(argv[0], "ack_policy", 10)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_RFEATURE_CTRL_ACK_PLCY, strtoul(val, NULL, 0));
}
return 0;
}
int mt76_ap_rfeatures_set(struct nl_msg *msg, int argc,
char **argv, void *ctx)
{
void *data;
int ret = 0;
if (argc < 1)
return 1;
data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
if (!data)
return -ENOMEM;
mt76_ap_rfeatures_set_attr(msg, argc, argv);
nla_nest_end(msg, data);
return ret;
}
static int mt76_ap_wireless_set_attr(struct nl_msg *msg, int argc, char **argv)
{
char *val;
val = strchr(argv[0], '=');
if (!val)
return -EINVAL;
*(val++) = 0;
if (!strncmp(argv[0], "fixed_mcs", 9)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_MCS, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "ofdma", 5)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_FIXED_OFDMA, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "ppdu_type", 9)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_PPDU_TX_TYPE, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "nusers_ofdma", 12)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "add_ba_req_bufsize", 18)) {
nla_put_u16(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE,
strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "mimo", 4)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "ampdu", 5)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMPDU, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "amsdu", 5)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU, strtoul(val, NULL, 0));
} else if (!strncmp(argv[0], "cert", 4)) {
nla_put_u8(msg, MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT, strtoul(val, NULL, 0));
}
return 0;
}
int mt76_ap_wireless_set(struct nl_msg *msg, int argc,
char **argv, void *ctx)
{
void *data;
int ret = 0;
if (argc < 1)
return 1;
data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA | NLA_F_NESTED);
if (!data)
return -ENOMEM;
mt76_ap_wireless_set_attr(msg, argc, argv);
nla_nest_end(msg, data);
return ret;
}
DECLARE_SECTION(set);
COMMAND(set, ap_rfeatures, "he_gi=<val>",
MTK_NL80211_VENDOR_SUBCMD_RFEATURE_CTRL, 0, CIB_NETDEV, mt76_ap_rfeatures_set,
"set ap_rfeatures he_gi=<val>"
"set ap_rfeatures he_ltf=<val>"
"set ap_rfeatures trig_type=<enable>,<val> (val: 0-7)"
"set ap_rfeatures ack_policy=<val> (val: 0-4)");
DECLARE_SECTION(set);
COMMAND(set, ap_wireless, "he_gi=<val>",
MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL, 0, CIB_NETDEV, mt76_ap_wireless_set,
"set ap_wireless fixed_mcs=<val>"
"set ap_wireless ofdma=<val> (0: disable, 1: DL, 2: UL)"
"set ap_wireless nusers_ofdma=<val>"
"set ap_wireless ppdu_type=<val> (0: SU, 1: MU, 4: LEGACY)"
"set ap_wireless add_ba_req_bufsize=<val>"
"set ap_wireless mimo=<val> (0: DL, 1: UL)"
"set ap_wireless ampdu=<enable>"
"set ap_wireless amsdu=<enable>"
"set ap_wireless cert=<enable>");