7 static int parse_vht_chunk(const char *arg
, __u8
*nss
, __u16
*mcs
)
10 unsigned int inss
, mcs_start
, mcs_end
, tab
[10];
14 if (strchr(arg
, '-')) {
15 /* Format: NSS:MCS_START-MCS_END */
16 count
= sscanf(arg
, "%u:%u-%u", &inss
, &mcs_start
, &mcs_end
);
21 if (inss
< 1 || inss
> NL80211_VHT_NSS_MAX
)
24 if (mcs_start
> mcs_end
)
27 if (mcs_start
> 9 || mcs_end
> 9)
31 for (i
= mcs_start
; i
<= mcs_end
; i
++)
35 /* Format: NSS:MCSx,MCSy,... */
36 count
= sscanf(arg
, "%u:%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", &inss
,
37 &tab
[0], &tab
[1], &tab
[2], &tab
[3], &tab
[4], &tab
[5],
38 &tab
[6], &tab
[7], &tab
[8], &tab
[9]);
43 if (inss
< 1 || inss
> NL80211_VHT_NSS_MAX
)
47 for (i
= 0; i
< count
- 1; i
++) {
57 static int setup_vht(struct nl80211_txrate_vht
*txrate_vht
,
58 int argc
, char **argv
)
64 memset(txrate_vht
, 0, sizeof(*txrate_vht
));
66 for (i
= 0; i
< argc
; i
++) {
67 if(!parse_vht_chunk(argv
[i
], &nss
, &mcs
))
71 txrate_vht
->mcs
[nss
] |= mcs
;
77 #define VHT_ARGC_MAX 100
79 static int handle_bitrates(struct nl80211_state
*state
,
82 int argc
, char **argv
,
85 struct nlattr
*nl_rates
, *nl_band
;
87 bool have_legacy_24
= false, have_legacy_5
= false;
88 uint8_t legacy_24
[32], legacy_5
[32];
89 int n_legacy_24
= 0, n_legacy_5
= 0;
90 uint8_t *legacy
= NULL
;
92 bool have_ht_mcs_24
= false, have_ht_mcs_5
= false;
93 bool have_vht_mcs_24
= false, have_vht_mcs_5
= false;
94 uint8_t ht_mcs_24
[77], ht_mcs_5
[77];
95 int n_ht_mcs_24
= 0, n_ht_mcs_5
= 0;
96 struct nl80211_txrate_vht txrate_vht_24
= {};
97 struct nl80211_txrate_vht txrate_vht_5
= {};
100 char *vht_argv_5
[VHT_ARGC_MAX
] = {}; char *vht_argv_24
[VHT_ARGC_MAX
] = {};
101 char **vht_argv
= NULL
;
102 int vht_argc_5
= 0; int vht_argc_24
= 0;
103 int *vht_argc
= NULL
;
110 } parser_state
= S_NONE
;
112 for (i
= 0; i
< argc
; i
++) {
117 if (strcmp(argv
[i
], "legacy-2.4") == 0) {
120 parser_state
= S_LEGACY
;
122 n_legacy
= &n_legacy_24
;
123 have_legacy_24
= true;
124 } else if (strcmp(argv
[i
], "legacy-5") == 0) {
127 parser_state
= S_LEGACY
;
129 n_legacy
= &n_legacy_5
;
130 have_legacy_5
= true;
132 else if (strcmp(argv
[i
], "ht-mcs-2.4") == 0) {
137 n_mcs
= &n_ht_mcs_24
;
138 have_ht_mcs_24
= true;
139 } else if (strcmp(argv
[i
], "ht-mcs-5") == 0) {
145 have_ht_mcs_5
= true;
146 } else if (strcmp(argv
[i
], "vht-mcs-2.4") == 0) {
149 parser_state
= S_VHT
;
150 vht_argv
= vht_argv_24
;
151 vht_argc
= &vht_argc_24
;
152 have_vht_mcs_24
= true;
153 } else if (strcmp(argv
[i
], "vht-mcs-5") == 0) {
156 parser_state
= S_VHT
;
157 vht_argv
= vht_argv_5
;
158 vht_argc
= &vht_argc_5
;
159 have_vht_mcs_5
= true;
161 else switch (parser_state
) {
163 tmpd
= strtod(argv
[i
], &end
);
166 if (tmpd
< 1 || tmpd
> 255 * 2)
168 legacy
[(*n_legacy
)++] = tmpd
* 2;
171 tmpl
= strtol(argv
[i
], &end
, 0);
174 if (tmpl
< 0 || tmpl
> 255)
176 mcs
[(*n_mcs
)++] = tmpl
;
179 if (*vht_argc
>= VHT_ARGC_MAX
)
181 vht_argv
[(*vht_argc
)++] = argv
[i
];
189 if(!setup_vht(&txrate_vht_24
, vht_argc_24
, vht_argv_24
))
193 if(!setup_vht(&txrate_vht_5
, vht_argc_5
, vht_argv_5
))
196 nl_rates
= nla_nest_start(msg
, NL80211_ATTR_TX_RATES
);
198 goto nla_put_failure
;
200 if (have_legacy_24
|| have_ht_mcs_24
|| have_vht_mcs_24
) {
201 nl_band
= nla_nest_start(msg
, NL80211_BAND_2GHZ
);
203 goto nla_put_failure
;
205 nla_put(msg
, NL80211_TXRATE_LEGACY
, n_legacy_24
, legacy_24
);
207 nla_put(msg
, NL80211_TXRATE_HT
, n_ht_mcs_24
, ht_mcs_24
);
209 nla_put(msg
, NL80211_TXRATE_VHT
, sizeof(txrate_vht_24
), &txrate_vht_24
);
210 nla_nest_end(msg
, nl_band
);
213 if (have_legacy_5
|| have_ht_mcs_5
|| have_vht_mcs_5
) {
214 nl_band
= nla_nest_start(msg
, NL80211_BAND_5GHZ
);
216 goto nla_put_failure
;
218 nla_put(msg
, NL80211_TXRATE_LEGACY
, n_legacy_5
, legacy_5
);
220 nla_put(msg
, NL80211_TXRATE_HT
, n_ht_mcs_5
, ht_mcs_5
);
222 nla_put(msg
, NL80211_TXRATE_VHT
, sizeof(txrate_vht_5
), &txrate_vht_5
);
223 nla_nest_end(msg
, nl_band
);
226 nla_nest_end(msg
, nl_rates
);
233 #define DESCR_LEGACY "[legacy-<2.4|5> <legacy rate in Mbps>*]"
234 #define DESCR DESCR_LEGACY " [ht-mcs-<2.4|5> <MCS index>*] [vht-mcs-<2.4|5> <NSS:MCSx,MCSy... | NSS:MCSx-MCSy>*]"
236 COMMAND(set
, bitrates
, "[legacy-<2.4|5> <legacy rate in Mbps>*] [ht-mcs-<2.4|5> <MCS index>*] [vht-mcs-<2.4|5> <NSS:MCSx,MCSy... | NSS:MCSx-MCSy>*]",
237 NL80211_CMD_SET_TX_BITRATE_MASK
, 0, CIB_NETDEV
, handle_bitrates
,
238 "Sets up the specified rate masks.\n"
239 "Not passing any arguments would clear the existing mask (if any).");