hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
....@@ -5,10 +5,9 @@
55 *
66 * GPL LICENSE SUMMARY
77 *
8
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
98 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
109 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11
- * Copyright(c) 2018 Intel Corporation
10
+ * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
1211 *
1312 * This program is free software; you can redistribute it and/or modify
1413 * it under the terms of version 2 of the GNU General Public License as
....@@ -19,11 +18,6 @@
1918 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2019 * General Public License for more details.
2120 *
22
- * You should have received a copy of the GNU General Public License
23
- * along with this program; if not, write to the Free Software
24
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
25
- * USA
26
- *
2721 * The full GNU General Public License is included in this distribution
2822 * in the file called COPYING.
2923 *
....@@ -33,10 +27,9 @@
3327 *
3428 * BSD LICENSE
3529 *
36
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
3730 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
3831 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
39
- * Copyright(c) 2018 Intel Corporation
32
+ * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
4033 * All rights reserved.
4134 *
4235 * Redistribution and use in source and binary forms, with or without
....@@ -74,6 +67,7 @@
7467 #include "sta.h"
7568 #include "iwl-io.h"
7669 #include "debugfs.h"
70
+#include "iwl-modparams.h"
7771 #include "fw/error-dump.h"
7872
7973 static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file,
....@@ -152,7 +146,8 @@
152146 "FLUSHING all tids queues on sta_id = %d\n",
153147 flush_arg);
154148 mutex_lock(&mvm->mutex);
155
- ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFF, 0) ? : count;
149
+ ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFFFF, 0)
150
+ ? : count;
156151 mutex_unlock(&mvm->mutex);
157152 return ret;
158153 }
....@@ -179,7 +174,7 @@
179174
180175 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
181176 return -EINVAL;
182
- if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT)
177
+ if (sta_id < 0 || sta_id >= mvm->fw->ucode_capa.num_stations)
183178 return -EINVAL;
184179 if (drain < 0 || drain > 1)
185180 return -EINVAL;
....@@ -381,7 +376,7 @@
381376 pos = scnprintf(buf, bufsz,
382377 "SAR geographic profile disabled\n");
383378 } else {
384
- value = &mvm->geo_profiles[tbl_idx - 1].values[0];
379
+ value = &mvm->fwrt.geo_profiles[tbl_idx - 1].values[0];
385380
386381 pos += scnprintf(buf + pos, bufsz - pos,
387382 "Use geographic profile %d\n", tbl_idx);
....@@ -408,7 +403,7 @@
408403
409404 mutex_lock(&mvm->mutex);
410405
411
- for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
406
+ for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
412407 pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i);
413408 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
414409 lockdep_is_held(&mvm->mutex));
....@@ -464,11 +459,58 @@
464459
465460 desc += rs_pretty_print_rate(buff + desc, bufsz - desc,
466461 lq_sta->last_rate_n_flags);
462
+ if (desc < bufsz - 1)
463
+ buff[desc++] = '\n';
467464 mutex_unlock(&mvm->mutex);
468465
469466 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
470467 kfree(buff);
471468 return ret;
469
+}
470
+
471
+static ssize_t iwl_dbgfs_amsdu_len_write(struct ieee80211_sta *sta,
472
+ char *buf, size_t count,
473
+ loff_t *ppos)
474
+{
475
+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
476
+ int i;
477
+ u16 amsdu_len;
478
+
479
+ if (kstrtou16(buf, 0, &amsdu_len))
480
+ return -EINVAL;
481
+
482
+ /* only change from debug set <-> debug unset */
483
+ if ((amsdu_len && mvmsta->orig_amsdu_len) ||
484
+ (!!amsdu_len && mvmsta->orig_amsdu_len))
485
+ return -EBUSY;
486
+
487
+ if (amsdu_len) {
488
+ mvmsta->orig_amsdu_len = sta->max_amsdu_len;
489
+ sta->max_amsdu_len = amsdu_len;
490
+ for (i = 0; i < ARRAY_SIZE(sta->max_tid_amsdu_len); i++)
491
+ sta->max_tid_amsdu_len[i] = amsdu_len;
492
+ } else {
493
+ sta->max_amsdu_len = mvmsta->orig_amsdu_len;
494
+ mvmsta->orig_amsdu_len = 0;
495
+ }
496
+ return count;
497
+}
498
+
499
+static ssize_t iwl_dbgfs_amsdu_len_read(struct file *file,
500
+ char __user *user_buf,
501
+ size_t count, loff_t *ppos)
502
+{
503
+ struct ieee80211_sta *sta = file->private_data;
504
+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
505
+
506
+ char buf[32];
507
+ int pos;
508
+
509
+ pos = scnprintf(buf, sizeof(buf), "current %d ", sta->max_amsdu_len);
510
+ pos += scnprintf(buf + pos, sizeof(buf) - pos, "stored %d\n",
511
+ mvmsta->orig_amsdu_len);
512
+
513
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
472514 }
473515
474516 static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
....@@ -671,16 +713,11 @@
671713 };
672714 int ret, bt_force_ant_mode;
673715
674
- for (bt_force_ant_mode = 0;
675
- bt_force_ant_mode < ARRAY_SIZE(modes_str);
676
- bt_force_ant_mode++) {
677
- if (!strcmp(buf, modes_str[bt_force_ant_mode]))
678
- break;
679
- }
716
+ ret = match_string(modes_str, ARRAY_SIZE(modes_str), buf);
717
+ if (ret < 0)
718
+ return ret;
680719
681
- if (bt_force_ant_mode >= ARRAY_SIZE(modes_str))
682
- return -EINVAL;
683
-
720
+ bt_force_ant_mode = ret;
684721 ret = 0;
685722 mutex_lock(&mvm->mutex);
686723 if (mvm->bt_force_ant_mode == bt_force_ant_mode)
....@@ -720,7 +757,7 @@
720757 pos += scnprintf(pos, endpos - pos, "FW: %s\n",
721758 mvm->fwrt.fw->human_readable);
722759 pos += scnprintf(pos, endpos - pos, "Device: %s\n",
723
- mvm->fwrt.trans->cfg->name);
760
+ mvm->fwrt.trans->name);
724761 pos += scnprintf(pos, endpos - pos, "Bus: %s\n",
725762 mvm->fwrt.dev->bus->name);
726763
....@@ -981,6 +1018,8 @@
9811018 (int)(ARRAY_SIZE(stats->last_rates) - i));
9821019 pos += rs_pretty_print_rate(pos, endpos - pos,
9831020 stats->last_rates[idx]);
1021
+ if (pos < endpos - 1)
1022
+ *pos++ = '\n';
9841023 }
9851024 spin_unlock_bh(&mvm->drv_stats_lock);
9861025
....@@ -1025,18 +1064,10 @@
10251064 static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
10261065 size_t count, loff_t *ppos)
10271066 {
1028
- int ret;
1029
-
10301067 if (!iwl_mvm_firmware_running(mvm))
10311068 return -EIO;
10321069
1033
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_NMI);
1034
- if (ret)
1035
- return ret;
1036
-
10371070 iwl_force_nmi(mvm->trans);
1038
-
1039
- iwl_mvm_unref(mvm, IWL_MVM_REF_NMI);
10401071
10411072 return count;
10421073 }
....@@ -1150,8 +1181,8 @@
11501181 struct iwl_rx_mpdu_desc *desc;
11511182 int bin_len = count / 2;
11521183 int ret = -EINVAL;
1153
- size_t mpdu_cmd_hdr_size =
1154
- (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ?
1184
+ size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >=
1185
+ IWL_DEVICE_FAMILY_AX210) ?
11551186 sizeof(struct iwl_rx_mpdu_desc) :
11561187 IWL_RX_DESC_SIZE_V1;
11571188
....@@ -1159,7 +1190,7 @@
11591190 return -EIO;
11601191
11611192 /* supporting only 9000 descriptor */
1162
- if (!mvm->trans->cfg->mq_rx_supported)
1193
+ if (!mvm->trans->trans_cfg->mq_rx_supported)
11631194 return -ENOTSUPP;
11641195
11651196 rxb._page = alloc_pages(GFP_ATOMIC, 0);
....@@ -1197,6 +1228,111 @@
11971228 return ret ?: count;
11981229 }
11991230
1231
+static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
1232
+{
1233
+ struct ieee80211_vif *vif;
1234
+ struct iwl_mvm_vif *mvmvif;
1235
+ struct sk_buff *beacon;
1236
+ struct ieee80211_tx_info *info;
1237
+ struct iwl_mac_beacon_cmd beacon_cmd = {};
1238
+ u8 rate;
1239
+ u16 flags;
1240
+ int i;
1241
+
1242
+ len /= 2;
1243
+
1244
+ /* Element len should be represented by u8 */
1245
+ if (len >= U8_MAX)
1246
+ return -EINVAL;
1247
+
1248
+ if (!iwl_mvm_firmware_running(mvm))
1249
+ return -EIO;
1250
+
1251
+ if (!iwl_mvm_has_new_tx_api(mvm) &&
1252
+ !fw_has_api(&mvm->fw->ucode_capa,
1253
+ IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE))
1254
+ return -EINVAL;
1255
+
1256
+ rcu_read_lock();
1257
+
1258
+ for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
1259
+ vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, true);
1260
+ if (!vif)
1261
+ continue;
1262
+
1263
+ if (vif->type == NL80211_IFTYPE_AP)
1264
+ break;
1265
+ }
1266
+
1267
+ if (i == NUM_MAC_INDEX_DRIVER || !vif)
1268
+ goto out_err;
1269
+
1270
+ mvm->hw->extra_beacon_tailroom = len;
1271
+
1272
+ beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
1273
+ if (!beacon)
1274
+ goto out_err;
1275
+
1276
+ if (len && hex2bin(skb_put_zero(beacon, len), bin, len)) {
1277
+ dev_kfree_skb(beacon);
1278
+ goto out_err;
1279
+ }
1280
+
1281
+ mvm->beacon_inject_active = true;
1282
+
1283
+ mvmvif = iwl_mvm_vif_from_mac80211(vif);
1284
+ info = IEEE80211_SKB_CB(beacon);
1285
+ rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
1286
+ flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
1287
+
1288
+ if (rate == IWL_FIRST_CCK_RATE)
1289
+ flags |= IWL_MAC_BEACON_CCK;
1290
+
1291
+ beacon_cmd.flags = cpu_to_le16(flags);
1292
+ beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
1293
+ beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
1294
+
1295
+ iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx,
1296
+ &beacon_cmd.tim_size,
1297
+ beacon->data, beacon->len);
1298
+
1299
+ mutex_lock(&mvm->mutex);
1300
+ iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd,
1301
+ sizeof(beacon_cmd));
1302
+ mutex_unlock(&mvm->mutex);
1303
+
1304
+ dev_kfree_skb(beacon);
1305
+
1306
+ rcu_read_unlock();
1307
+ return 0;
1308
+
1309
+out_err:
1310
+ rcu_read_unlock();
1311
+ return -EINVAL;
1312
+}
1313
+
1314
+static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm,
1315
+ char *buf, size_t count,
1316
+ loff_t *ppos)
1317
+{
1318
+ int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count);
1319
+
1320
+ mvm->hw->extra_beacon_tailroom = 0;
1321
+ return ret ?: count;
1322
+}
1323
+
1324
+static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm,
1325
+ char *buf,
1326
+ size_t count,
1327
+ loff_t *ppos)
1328
+{
1329
+ int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0);
1330
+
1331
+ mvm->hw->extra_beacon_tailroom = 0;
1332
+ mvm->beacon_inject_active = false;
1333
+ return ret ?: count;
1334
+}
1335
+
12001336 static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
12011337 char __user *user_buf,
12021338 size_t count, loff_t *ppos)
....@@ -1214,47 +1350,6 @@
12141350 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf);
12151351
12161352 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1217
-}
1218
-
1219
-/*
1220
- * Enable / Disable continuous recording.
1221
- * Cause the FW to start continuous recording, by sending the relevant hcmd.
1222
- * Enable: input of every integer larger than 0, ENABLE_CONT_RECORDING.
1223
- * Disable: for 0 as input, DISABLE_CONT_RECORDING.
1224
- */
1225
-static ssize_t iwl_dbgfs_cont_recording_write(struct iwl_mvm *mvm,
1226
- char *buf, size_t count,
1227
- loff_t *ppos)
1228
-{
1229
- struct iwl_trans *trans = mvm->trans;
1230
- const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg_dest_tlv;
1231
- struct iwl_continuous_record_cmd cont_rec = {};
1232
- int ret, rec_mode;
1233
-
1234
- if (!iwl_mvm_firmware_running(mvm))
1235
- return -EIO;
1236
-
1237
- if (!dest)
1238
- return -EOPNOTSUPP;
1239
-
1240
- if (dest->monitor_mode != SMEM_MODE ||
1241
- trans->cfg->device_family < IWL_DEVICE_FAMILY_8000)
1242
- return -EOPNOTSUPP;
1243
-
1244
- ret = kstrtoint(buf, 0, &rec_mode);
1245
- if (ret)
1246
- return ret;
1247
-
1248
- cont_rec.record_mode.enable_recording = rec_mode ?
1249
- cpu_to_le16(ENABLE_CONT_RECORDING) :
1250
- cpu_to_le16(DISABLE_CONT_RECORDING);
1251
-
1252
- mutex_lock(&mvm->mutex);
1253
- ret = iwl_mvm_send_cmd_pdu(mvm, LDBG_CONFIG_CMD, 0,
1254
- sizeof(cont_rec), &cont_rec);
1255
- mutex_unlock(&mvm->mutex);
1256
-
1257
- return ret ?: count;
12581353 }
12591354
12601355 static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
....@@ -1285,36 +1380,14 @@
12851380 char *buf, size_t count,
12861381 loff_t *ppos)
12871382 {
1288
- int ret;
1289
-
1290
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
1291
- if (ret)
1292
- return ret;
12931383 if (count == 0)
12941384 return 0;
12951385
1386
+ iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER,
1387
+ NULL);
1388
+
12961389 iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
12971390 (count - 1), NULL);
1298
-
1299
- iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
1300
-
1301
- return count;
1302
-}
1303
-
1304
-static ssize_t iwl_dbgfs_max_amsdu_len_write(struct iwl_mvm *mvm,
1305
- char *buf, size_t count,
1306
- loff_t *ppos)
1307
-{
1308
- unsigned int max_amsdu_len;
1309
- int ret;
1310
-
1311
- ret = kstrtouint(buf, 0, &max_amsdu_len);
1312
- if (ret)
1313
- return ret;
1314
-
1315
- if (max_amsdu_len > IEEE80211_MAX_MPDU_LEN_VHT_11454)
1316
- return -EINVAL;
1317
- mvm->max_amsdu_len = max_amsdu_len;
13181391
13191392 return count;
13201393 }
....@@ -1502,148 +1575,13 @@
15021575 }
15031576 #endif
15041577
1505
-#ifdef CONFIG_PM_SLEEP
1506
-static ssize_t iwl_dbgfs_d3_sram_write(struct iwl_mvm *mvm, char *buf,
1507
- size_t count, loff_t *ppos)
1508
-{
1509
- int store;
1510
-
1511
- if (sscanf(buf, "%d", &store) != 1)
1512
- return -EINVAL;
1513
-
1514
- mvm->store_d3_resume_sram = store;
1515
-
1516
- return count;
1517
-}
1518
-
1519
-static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
1520
- size_t count, loff_t *ppos)
1521
-{
1522
- struct iwl_mvm *mvm = file->private_data;
1523
- const struct fw_img *img;
1524
- int ofs, len, pos = 0;
1525
- size_t bufsz, ret;
1526
- char *buf;
1527
- u8 *ptr = mvm->d3_resume_sram;
1528
-
1529
- img = &mvm->fw->img[IWL_UCODE_WOWLAN];
1530
- len = img->sec[IWL_UCODE_SECTION_DATA].len;
1531
-
1532
- bufsz = len * 4 + 256;
1533
- buf = kzalloc(bufsz, GFP_KERNEL);
1534
- if (!buf)
1535
- return -ENOMEM;
1536
-
1537
- pos += scnprintf(buf, bufsz, "D3 SRAM capture: %sabled\n",
1538
- mvm->store_d3_resume_sram ? "en" : "dis");
1539
-
1540
- if (ptr) {
1541
- for (ofs = 0; ofs < len; ofs += 16) {
1542
- pos += scnprintf(buf + pos, bufsz - pos,
1543
- "0x%.4x %16ph\n", ofs, ptr + ofs);
1544
- }
1545
- } else {
1546
- pos += scnprintf(buf + pos, bufsz - pos,
1547
- "(no data captured)\n");
1548
- }
1549
-
1550
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1551
-
1552
- kfree(buf);
1553
-
1554
- return ret;
1555
-}
1556
-#endif
1557
-
1558
-#define PRINT_MVM_REF(ref) do { \
1559
- if (mvm->refs[ref]) \
1560
- pos += scnprintf(buf + pos, bufsz - pos, \
1561
- "\t(0x%lx): %d %s\n", \
1562
- BIT(ref), mvm->refs[ref], #ref); \
1563
-} while (0)
1564
-
1565
-static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
1566
- char __user *user_buf,
1567
- size_t count, loff_t *ppos)
1568
-{
1569
- struct iwl_mvm *mvm = file->private_data;
1570
- int i, pos = 0;
1571
- char buf[256];
1572
- const size_t bufsz = sizeof(buf);
1573
- u32 refs = 0;
1574
-
1575
- for (i = 0; i < IWL_MVM_REF_COUNT; i++)
1576
- if (mvm->refs[i])
1577
- refs |= BIT(i);
1578
-
1579
- pos += scnprintf(buf + pos, bufsz - pos, "taken mvm refs: 0x%x\n",
1580
- refs);
1581
-
1582
- PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN);
1583
- PRINT_MVM_REF(IWL_MVM_REF_SCAN);
1584
- PRINT_MVM_REF(IWL_MVM_REF_ROC);
1585
- PRINT_MVM_REF(IWL_MVM_REF_ROC_AUX);
1586
- PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT);
1587
- PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS);
1588
- PRINT_MVM_REF(IWL_MVM_REF_USER);
1589
- PRINT_MVM_REF(IWL_MVM_REF_TX);
1590
- PRINT_MVM_REF(IWL_MVM_REF_TX_AGG);
1591
- PRINT_MVM_REF(IWL_MVM_REF_ADD_IF);
1592
- PRINT_MVM_REF(IWL_MVM_REF_START_AP);
1593
- PRINT_MVM_REF(IWL_MVM_REF_BSS_CHANGED);
1594
- PRINT_MVM_REF(IWL_MVM_REF_PREPARE_TX);
1595
- PRINT_MVM_REF(IWL_MVM_REF_PROTECT_TDLS);
1596
- PRINT_MVM_REF(IWL_MVM_REF_CHECK_CTKILL);
1597
- PRINT_MVM_REF(IWL_MVM_REF_PRPH_READ);
1598
- PRINT_MVM_REF(IWL_MVM_REF_PRPH_WRITE);
1599
- PRINT_MVM_REF(IWL_MVM_REF_NMI);
1600
- PRINT_MVM_REF(IWL_MVM_REF_TM_CMD);
1601
- PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
1602
- PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA);
1603
- PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT);
1604
- PRINT_MVM_REF(IWL_MVM_REF_INIT_UCODE);
1605
- PRINT_MVM_REF(IWL_MVM_REF_SENDING_CMD);
1606
- PRINT_MVM_REF(IWL_MVM_REF_RX);
1607
-
1608
- return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1609
-}
1610
-
1611
-static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf,
1612
- size_t count, loff_t *ppos)
1613
-{
1614
- unsigned long value;
1615
- int ret;
1616
- bool taken;
1617
-
1618
- ret = kstrtoul(buf, 10, &value);
1619
- if (ret < 0)
1620
- return ret;
1621
-
1622
- mutex_lock(&mvm->mutex);
1623
-
1624
- taken = mvm->refs[IWL_MVM_REF_USER];
1625
- if (value == 1 && !taken)
1626
- iwl_mvm_ref(mvm, IWL_MVM_REF_USER);
1627
- else if (value == 0 && taken)
1628
- iwl_mvm_unref(mvm, IWL_MVM_REF_USER);
1629
- else
1630
- ret = -EINVAL;
1631
-
1632
- mutex_unlock(&mvm->mutex);
1633
-
1634
- if (ret < 0)
1635
- return ret;
1636
- return count;
1637
-}
1638
-
16391578 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
16401579 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
16411580 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
16421581 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
16431582 #define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \
1644
- if (!debugfs_create_file(alias, mode, parent, mvm, \
1645
- &iwl_dbgfs_##name##_ops)) \
1646
- goto err; \
1583
+ debugfs_create_file(alias, mode, parent, mvm, \
1584
+ &iwl_dbgfs_##name##_ops); \
16471585 } while (0)
16481586 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
16491587 MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
....@@ -1654,9 +1592,8 @@
16541592 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta)
16551593
16561594 #define MVM_DEBUGFS_ADD_STA_FILE_ALIAS(alias, name, parent, mode) do { \
1657
- if (!debugfs_create_file(alias, mode, parent, sta, \
1658
- &iwl_dbgfs_##name##_ops)) \
1659
- goto err; \
1595
+ debugfs_create_file(alias, mode, parent, sta, \
1596
+ &iwl_dbgfs_##name##_ops); \
16601597 } while (0)
16611598 #define MVM_DEBUGFS_ADD_STA_FILE(name, parent, mode) \
16621599 MVM_DEBUGFS_ADD_STA_FILE_ALIAS(#name, name, parent, mode)
....@@ -1670,20 +1607,13 @@
16701607 int pos = 0;
16711608 char buf[32];
16721609 const size_t bufsz = sizeof(buf);
1673
- int ret;
16741610
16751611 if (!mvm->dbgfs_prph_reg_addr)
16761612 return -EINVAL;
16771613
1678
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_READ);
1679
- if (ret)
1680
- return ret;
1681
-
16821614 pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
16831615 mvm->dbgfs_prph_reg_addr,
16841616 iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
1685
-
1686
- iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_READ);
16871617
16881618 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
16891619 }
....@@ -1694,7 +1624,6 @@
16941624 {
16951625 u8 args;
16961626 u32 value;
1697
- int ret;
16981627
16991628 args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
17001629 /* if we only want to set the reg address - nothing more to do */
....@@ -1705,13 +1634,8 @@
17051634 if (args != 2)
17061635 return -EINVAL;
17071636
1708
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
1709
- if (ret)
1710
- return ret;
1711
-
17121637 iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
17131638
1714
- iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
17151639 out:
17161640 return count;
17171641 }
....@@ -1730,6 +1654,98 @@
17301654 mutex_unlock(&mvm->mutex);
17311655
17321656 return ret ?: count;
1657
+}
1658
+
1659
+struct iwl_mvm_sniffer_apply {
1660
+ struct iwl_mvm *mvm;
1661
+ u8 *bssid;
1662
+ u16 aid;
1663
+};
1664
+
1665
+static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data,
1666
+ struct iwl_rx_packet *pkt, void *data)
1667
+{
1668
+ struct iwl_mvm_sniffer_apply *apply = data;
1669
+
1670
+ apply->mvm->cur_aid = cpu_to_le16(apply->aid);
1671
+ memcpy(apply->mvm->cur_bssid, apply->bssid,
1672
+ sizeof(apply->mvm->cur_bssid));
1673
+
1674
+ return true;
1675
+}
1676
+
1677
+static ssize_t
1678
+iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
1679
+ size_t count, loff_t *ppos)
1680
+{
1681
+ struct iwl_notification_wait wait;
1682
+ struct iwl_he_monitor_cmd he_mon_cmd = {};
1683
+ struct iwl_mvm_sniffer_apply apply = {
1684
+ .mvm = mvm,
1685
+ };
1686
+ u16 wait_cmds[] = {
1687
+ iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD, DATA_PATH_GROUP, 0),
1688
+ };
1689
+ u32 aid;
1690
+ int ret;
1691
+
1692
+ if (!iwl_mvm_firmware_running(mvm))
1693
+ return -EIO;
1694
+
1695
+ ret = sscanf(buf, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid,
1696
+ &he_mon_cmd.bssid[0], &he_mon_cmd.bssid[1],
1697
+ &he_mon_cmd.bssid[2], &he_mon_cmd.bssid[3],
1698
+ &he_mon_cmd.bssid[4], &he_mon_cmd.bssid[5]);
1699
+ if (ret != 7)
1700
+ return -EINVAL;
1701
+
1702
+ he_mon_cmd.aid = cpu_to_le16(aid);
1703
+
1704
+ apply.aid = aid;
1705
+ apply.bssid = (void *)he_mon_cmd.bssid;
1706
+
1707
+ mutex_lock(&mvm->mutex);
1708
+
1709
+ /*
1710
+ * Use the notification waiter to get our function triggered
1711
+ * in sequence with other RX. This ensures that frames we get
1712
+ * on the RX queue _before_ the new configuration is applied
1713
+ * still have mvm->cur_aid pointing to the old AID, and that
1714
+ * frames on the RX queue _after_ the firmware processed the
1715
+ * new configuration (and sent the response, synchronously)
1716
+ * get mvm->cur_aid correctly set to the new AID.
1717
+ */
1718
+ iwl_init_notification_wait(&mvm->notif_wait, &wait,
1719
+ wait_cmds, ARRAY_SIZE(wait_cmds),
1720
+ iwl_mvm_sniffer_apply, &apply);
1721
+
1722
+ ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD,
1723
+ DATA_PATH_GROUP, 0), 0,
1724
+ sizeof(he_mon_cmd), &he_mon_cmd);
1725
+
1726
+ /* no need to really wait, we already did anyway */
1727
+ iwl_remove_notification(&mvm->notif_wait, &wait);
1728
+
1729
+ mutex_unlock(&mvm->mutex);
1730
+
1731
+ return ret ?: count;
1732
+}
1733
+
1734
+static ssize_t
1735
+iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf,
1736
+ size_t count, loff_t *ppos)
1737
+{
1738
+ struct iwl_mvm *mvm = file->private_data;
1739
+ u8 buf[32];
1740
+ int len;
1741
+
1742
+ len = scnprintf(buf, sizeof(buf),
1743
+ "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
1744
+ le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0],
1745
+ mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3],
1746
+ mvm->cur_bssid[4], mvm->cur_bssid[5]);
1747
+
1748
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
17331749 }
17341750
17351751 static ssize_t
....@@ -1751,6 +1767,38 @@
17511767 mutex_unlock(&mvm->mutex);
17521768
17531769 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1770
+}
1771
+
1772
+static ssize_t
1773
+iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm,
1774
+ char *buf, size_t count, loff_t *ppos)
1775
+{
1776
+ int ret;
1777
+ struct iwl_ltr_config_cmd ltr_config = {0};
1778
+
1779
+ if (!iwl_mvm_firmware_running(mvm))
1780
+ return -EIO;
1781
+
1782
+ if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x",
1783
+ &ltr_config.flags,
1784
+ &ltr_config.static_long,
1785
+ &ltr_config.static_short,
1786
+ &ltr_config.ltr_cfg_values[0],
1787
+ &ltr_config.ltr_cfg_values[1],
1788
+ &ltr_config.ltr_cfg_values[2],
1789
+ &ltr_config.ltr_cfg_values[3]) != 7) {
1790
+ return -EINVAL;
1791
+ }
1792
+
1793
+ mutex_lock(&mvm->mutex);
1794
+ ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config),
1795
+ &ltr_config);
1796
+ mutex_unlock(&mvm->mutex);
1797
+
1798
+ if (ret)
1799
+ IWL_ERR(mvm, "failed to send ltr configuration cmd\n");
1800
+
1801
+ return ret ?: count;
17541802 }
17551803
17561804 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
....@@ -1778,14 +1826,13 @@
17781826 MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
17791827 MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
17801828 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1781
-MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
17821829 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
17831830 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
1784
-MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8);
1785
-MVM_DEBUGFS_WRITE_FILE_OPS(max_amsdu_len, 8);
17861831 MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
17871832 (IWL_RSS_INDIRECTION_TABLE_SIZE * 2));
17881833 MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512);
1834
+MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512);
1835
+MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512);
17891836
17901837 MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids);
17911838
....@@ -1794,12 +1841,15 @@
17941841 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
17951842 #endif
17961843
1797
-#ifdef CONFIG_PM_SLEEP
1798
-MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
1799
-#endif
18001844 #ifdef CONFIG_ACPI
18011845 MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
18021846 #endif
1847
+
1848
+MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16);
1849
+
1850
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
1851
+
1852
+MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512);
18031853
18041854 static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
18051855 size_t count, loff_t *ppos)
....@@ -1940,15 +1990,13 @@
19401990 {
19411991 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
19421992
1943
- if (iwl_mvm_has_tlc_offload(mvm))
1993
+ if (iwl_mvm_has_tlc_offload(mvm)) {
19441994 MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, 0400);
1945
-
1946
- return;
1947
-err:
1948
- IWL_ERR(mvm, "Can't create the mvm station debugfs entry\n");
1995
+ }
1996
+ MVM_DEBUGFS_ADD_STA_FILE(amsdu_len, dir, 0600);
19491997 }
19501998
1951
-int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1999
+void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
19522000 {
19532001 struct dentry *bcast_dir __maybe_unused;
19542002 char buf[100];
....@@ -1978,26 +2026,25 @@
19782026 MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200);
19792027 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600);
19802028 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600);
1981
- MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, 0600);
19822029 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600);
19832030 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200);
1984
- MVM_DEBUGFS_ADD_FILE(max_amsdu_len, mvm->debugfs_dir, 0200);
19852031 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
1986
- MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, 0200);
19872032 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200);
19882033 MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200);
2034
+ MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200);
2035
+ MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200);
19892036 #ifdef CONFIG_ACPI
19902037 MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400);
19912038 #endif
2039
+ MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
19922040
1993
- if (!debugfs_create_bool("enable_scan_iteration_notif",
1994
- 0600,
1995
- mvm->debugfs_dir,
1996
- &mvm->scan_iter_notif_enabled))
1997
- goto err;
1998
- if (!debugfs_create_bool("drop_bcn_ap_mode", 0600,
1999
- mvm->debugfs_dir, &mvm->drop_bcn_ap_mode))
2000
- goto err;
2041
+ if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
2042
+ MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200);
2043
+
2044
+ debugfs_create_bool("enable_scan_iteration_notif", 0600,
2045
+ mvm->debugfs_dir, &mvm->scan_iter_notif_enabled);
2046
+ debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir,
2047
+ &mvm->drop_bcn_ap_mode);
20012048
20022049 MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR);
20032050
....@@ -2005,13 +2052,9 @@
20052052 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
20062053 bcast_dir = debugfs_create_dir("bcast_filtering",
20072054 mvm->debugfs_dir);
2008
- if (!bcast_dir)
2009
- goto err;
20102055
2011
- if (!debugfs_create_bool("override", 0600,
2012
- bcast_dir,
2013
- &mvm->dbgfs_bcast_filtering.override))
2014
- goto err;
2056
+ debugfs_create_bool("override", 0600, bcast_dir,
2057
+ &mvm->dbgfs_bcast_filtering.override);
20152058
20162059 MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters,
20172060 bcast_dir, 0600);
....@@ -2021,34 +2064,27 @@
20212064 #endif
20222065
20232066 #ifdef CONFIG_PM_SLEEP
2024
- MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, 0600);
20252067 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
2026
- if (!debugfs_create_bool("d3_wake_sysassert", 0600,
2027
- mvm->debugfs_dir, &mvm->d3_wake_sysassert))
2028
- goto err;
2029
- if (!debugfs_create_u32("last_netdetect_scans", 0400,
2030
- mvm->debugfs_dir, &mvm->last_netdetect_scans))
2031
- goto err;
2068
+ debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
2069
+ &mvm->d3_wake_sysassert);
2070
+ debugfs_create_u32("last_netdetect_scans", 0400, mvm->debugfs_dir,
2071
+ &mvm->last_netdetect_scans);
20322072 #endif
20332073
2034
- if (!debugfs_create_u8("ps_disabled", 0400,
2035
- mvm->debugfs_dir, &mvm->ps_disabled))
2036
- goto err;
2037
- if (!debugfs_create_blob("nvm_hw", 0400,
2038
- mvm->debugfs_dir, &mvm->nvm_hw_blob))
2039
- goto err;
2040
- if (!debugfs_create_blob("nvm_sw", 0400,
2041
- mvm->debugfs_dir, &mvm->nvm_sw_blob))
2042
- goto err;
2043
- if (!debugfs_create_blob("nvm_calib", 0400,
2044
- mvm->debugfs_dir, &mvm->nvm_calib_blob))
2045
- goto err;
2046
- if (!debugfs_create_blob("nvm_prod", 0400,
2047
- mvm->debugfs_dir, &mvm->nvm_prod_blob))
2048
- goto err;
2049
- if (!debugfs_create_blob("nvm_phy_sku", 0400,
2050
- mvm->debugfs_dir, &mvm->nvm_phy_sku_blob))
2051
- goto err;
2074
+ debugfs_create_u8("ps_disabled", 0400, mvm->debugfs_dir,
2075
+ &mvm->ps_disabled);
2076
+ debugfs_create_blob("nvm_hw", 0400, mvm->debugfs_dir,
2077
+ &mvm->nvm_hw_blob);
2078
+ debugfs_create_blob("nvm_sw", 0400, mvm->debugfs_dir,
2079
+ &mvm->nvm_sw_blob);
2080
+ debugfs_create_blob("nvm_calib", 0400, mvm->debugfs_dir,
2081
+ &mvm->nvm_calib_blob);
2082
+ debugfs_create_blob("nvm_prod", 0400, mvm->debugfs_dir,
2083
+ &mvm->nvm_prod_blob);
2084
+ debugfs_create_blob("nvm_phy_sku", 0400, mvm->debugfs_dir,
2085
+ &mvm->nvm_phy_sku_blob);
2086
+ debugfs_create_blob("nvm_reg", S_IRUSR,
2087
+ mvm->debugfs_dir, &mvm->nvm_reg_blob);
20522088
20532089 debugfs_create_file("mem", 0600, dbgfs_dir, mvm, &iwl_dbgfs_mem_ops);
20542090
....@@ -2057,11 +2093,5 @@
20572093 * exists (before the opmode exists which removes the target.)
20582094 */
20592095 snprintf(buf, 100, "../../%pd2", dbgfs_dir->d_parent);
2060
- if (!debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf))
2061
- goto err;
2062
-
2063
- return 0;
2064
-err:
2065
- IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
2066
- return -ENOMEM;
2096
+ debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf);
20672097 }