hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/net/mac80211/debugfs.c
....@@ -1,11 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * mac80211 debugfs for wireless PHYs
34 *
45 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
56 * Copyright 2013-2014 Intel Mobile Communications GmbH
6
- *
7
- * GPLv2
8
- *
7
+ * Copyright (C) 2018 - 2019 Intel Corporation
98 */
109
1110 #include <linux/debugfs.h>
....@@ -60,6 +59,8 @@
6059 debugfs_create_file(#name, mode, phyd, local, &name## _ops);
6160
6261
62
+DEBUGFS_READONLY_FILE(hw_conf, "%x",
63
+ local->hw.conf.flags);
6364 DEBUGFS_READONLY_FILE(user_power, "%d",
6465 local->user_power_level);
6566 DEBUGFS_READONLY_FILE(power, "%d",
....@@ -119,18 +120,17 @@
119120 {
120121 struct ieee80211_local *local = file->private_data;
121122 char buf[100];
122
- size_t len;
123123
124
- if (count > sizeof(buf))
124
+ if (count >= sizeof(buf))
125125 return -EINVAL;
126126
127127 if (copy_from_user(buf, user_buf, count))
128128 return -EFAULT;
129129
130
- buf[sizeof(buf) - 1] = '\0';
131
- len = strlen(buf);
132
- if (len > 0 && buf[len-1] == '\n')
133
- buf[len-1] = 0;
130
+ if (count && buf[count - 1] == '\n')
131
+ buf[count - 1] = '\0';
132
+ else
133
+ buf[count] = '\0';
134134
135135 if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1)
136136 return count;
....@@ -145,6 +145,189 @@
145145 static const struct file_operations aqm_ops = {
146146 .write = aqm_write,
147147 .read = aqm_read,
148
+ .open = simple_open,
149
+ .llseek = default_llseek,
150
+};
151
+
152
+static ssize_t airtime_flags_read(struct file *file,
153
+ char __user *user_buf,
154
+ size_t count, loff_t *ppos)
155
+{
156
+ struct ieee80211_local *local = file->private_data;
157
+ char buf[128] = {}, *pos, *end;
158
+
159
+ pos = buf;
160
+ end = pos + sizeof(buf) - 1;
161
+
162
+ if (local->airtime_flags & AIRTIME_USE_TX)
163
+ pos += scnprintf(pos, end - pos, "AIRTIME_TX\t(%lx)\n",
164
+ AIRTIME_USE_TX);
165
+ if (local->airtime_flags & AIRTIME_USE_RX)
166
+ pos += scnprintf(pos, end - pos, "AIRTIME_RX\t(%lx)\n",
167
+ AIRTIME_USE_RX);
168
+
169
+ return simple_read_from_buffer(user_buf, count, ppos, buf,
170
+ strlen(buf));
171
+}
172
+
173
+static ssize_t airtime_flags_write(struct file *file,
174
+ const char __user *user_buf,
175
+ size_t count, loff_t *ppos)
176
+{
177
+ struct ieee80211_local *local = file->private_data;
178
+ char buf[16];
179
+
180
+ if (count >= sizeof(buf))
181
+ return -EINVAL;
182
+
183
+ if (copy_from_user(buf, user_buf, count))
184
+ return -EFAULT;
185
+
186
+ if (count && buf[count - 1] == '\n')
187
+ buf[count - 1] = '\0';
188
+ else
189
+ buf[count] = '\0';
190
+
191
+ if (kstrtou16(buf, 0, &local->airtime_flags))
192
+ return -EINVAL;
193
+
194
+ return count;
195
+}
196
+
197
+static const struct file_operations airtime_flags_ops = {
198
+ .write = airtime_flags_write,
199
+ .read = airtime_flags_read,
200
+ .open = simple_open,
201
+ .llseek = default_llseek,
202
+};
203
+
204
+static ssize_t aql_txq_limit_read(struct file *file,
205
+ char __user *user_buf,
206
+ size_t count,
207
+ loff_t *ppos)
208
+{
209
+ struct ieee80211_local *local = file->private_data;
210
+ char buf[400];
211
+ int len = 0;
212
+
213
+ len = scnprintf(buf, sizeof(buf),
214
+ "AC AQL limit low AQL limit high\n"
215
+ "VO %u %u\n"
216
+ "VI %u %u\n"
217
+ "BE %u %u\n"
218
+ "BK %u %u\n",
219
+ local->aql_txq_limit_low[IEEE80211_AC_VO],
220
+ local->aql_txq_limit_high[IEEE80211_AC_VO],
221
+ local->aql_txq_limit_low[IEEE80211_AC_VI],
222
+ local->aql_txq_limit_high[IEEE80211_AC_VI],
223
+ local->aql_txq_limit_low[IEEE80211_AC_BE],
224
+ local->aql_txq_limit_high[IEEE80211_AC_BE],
225
+ local->aql_txq_limit_low[IEEE80211_AC_BK],
226
+ local->aql_txq_limit_high[IEEE80211_AC_BK]);
227
+ return simple_read_from_buffer(user_buf, count, ppos,
228
+ buf, len);
229
+}
230
+
231
+static ssize_t aql_txq_limit_write(struct file *file,
232
+ const char __user *user_buf,
233
+ size_t count,
234
+ loff_t *ppos)
235
+{
236
+ struct ieee80211_local *local = file->private_data;
237
+ char buf[100];
238
+ u32 ac, q_limit_low, q_limit_high, q_limit_low_old, q_limit_high_old;
239
+ struct sta_info *sta;
240
+
241
+ if (count >= sizeof(buf))
242
+ return -EINVAL;
243
+
244
+ if (copy_from_user(buf, user_buf, count))
245
+ return -EFAULT;
246
+
247
+ if (count && buf[count - 1] == '\n')
248
+ buf[count - 1] = '\0';
249
+ else
250
+ buf[count] = '\0';
251
+
252
+ if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
253
+ return -EINVAL;
254
+
255
+ if (ac >= IEEE80211_NUM_ACS)
256
+ return -EINVAL;
257
+
258
+ q_limit_low_old = local->aql_txq_limit_low[ac];
259
+ q_limit_high_old = local->aql_txq_limit_high[ac];
260
+
261
+ local->aql_txq_limit_low[ac] = q_limit_low;
262
+ local->aql_txq_limit_high[ac] = q_limit_high;
263
+
264
+ mutex_lock(&local->sta_mtx);
265
+ list_for_each_entry(sta, &local->sta_list, list) {
266
+ /* If a sta has customized queue limits, keep it */
267
+ if (sta->airtime[ac].aql_limit_low == q_limit_low_old &&
268
+ sta->airtime[ac].aql_limit_high == q_limit_high_old) {
269
+ sta->airtime[ac].aql_limit_low = q_limit_low;
270
+ sta->airtime[ac].aql_limit_high = q_limit_high;
271
+ }
272
+ }
273
+ mutex_unlock(&local->sta_mtx);
274
+ return count;
275
+}
276
+
277
+static const struct file_operations aql_txq_limit_ops = {
278
+ .write = aql_txq_limit_write,
279
+ .read = aql_txq_limit_read,
280
+ .open = simple_open,
281
+ .llseek = default_llseek,
282
+};
283
+
284
+static ssize_t force_tx_status_read(struct file *file,
285
+ char __user *user_buf,
286
+ size_t count,
287
+ loff_t *ppos)
288
+{
289
+ struct ieee80211_local *local = file->private_data;
290
+ char buf[3];
291
+ int len = 0;
292
+
293
+ len = scnprintf(buf, sizeof(buf), "%d\n", (int)local->force_tx_status);
294
+
295
+ return simple_read_from_buffer(user_buf, count, ppos,
296
+ buf, len);
297
+}
298
+
299
+static ssize_t force_tx_status_write(struct file *file,
300
+ const char __user *user_buf,
301
+ size_t count,
302
+ loff_t *ppos)
303
+{
304
+ struct ieee80211_local *local = file->private_data;
305
+ char buf[3];
306
+
307
+ if (count >= sizeof(buf))
308
+ return -EINVAL;
309
+
310
+ if (copy_from_user(buf, user_buf, count))
311
+ return -EFAULT;
312
+
313
+ if (count && buf[count - 1] == '\n')
314
+ buf[count - 1] = '\0';
315
+ else
316
+ buf[count] = '\0';
317
+
318
+ if (buf[0] == '0' && buf[1] == '\0')
319
+ local->force_tx_status = 0;
320
+ else if (buf[0] == '1' && buf[1] == '\0')
321
+ local->force_tx_status = 1;
322
+ else
323
+ return -EINVAL;
324
+
325
+ return count;
326
+}
327
+
328
+static const struct file_operations force_tx_status_ops = {
329
+ .write = force_tx_status_write,
330
+ .read = force_tx_status_read,
148331 .open = simple_open,
149332 .llseek = default_llseek,
150333 };
....@@ -214,6 +397,14 @@
214397 FLAG(SUPPORTS_TDLS_BUFFER_STA),
215398 FLAG(DEAUTH_NEED_MGD_TX_PREP),
216399 FLAG(DOESNT_SUPPORT_QOS_NDP),
400
+ FLAG(BUFF_MMPDU_TXQ),
401
+ FLAG(SUPPORTS_VHT_EXT_NSS_BW),
402
+ FLAG(STA_MMPDU_TXQ),
403
+ FLAG(TX_STATUS_NO_AMPDU_LEN),
404
+ FLAG(SUPPORTS_MULTI_BSSID),
405
+ FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
406
+ FLAG(AMPDU_KEYBORDER_SUPPORT),
407
+ FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
217408 #undef FLAG
218409 };
219410
....@@ -375,10 +566,18 @@
375566 DEBUGFS_ADD(hwflags);
376567 DEBUGFS_ADD(user_power);
377568 DEBUGFS_ADD(power);
569
+ DEBUGFS_ADD(hw_conf);
570
+ DEBUGFS_ADD_MODE(force_tx_status, 0600);
378571
379572 if (local->ops->wake_tx_queue)
380573 DEBUGFS_ADD_MODE(aqm, 0600);
381574
575
+ DEBUGFS_ADD_MODE(airtime_flags, 0600);
576
+
577
+ DEBUGFS_ADD(aql_txq_limit);
578
+ debugfs_create_u32("aql_threshold", 0600,
579
+ phyd, &local->aql_threshold);
580
+
382581 statsd = debugfs_create_dir("statistics", phyd);
383582
384583 /* if the dir failed, don't put all the other things into the root! */