root/drivers/net/wireless/intel/iwlegacy/debug.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. il_clear_traffic_stats
  2. il_update_stats
  3. il_get_mgmt_string
  4. il_get_ctrl_string
  5. il_dbgfs_tx_stats_read
  6. il_dbgfs_clear_traffic_stats_write
  7. il_dbgfs_rx_stats_read
  8. il_dbgfs_sram_read
  9. il_dbgfs_sram_write
  10. il_dbgfs_stations_read
  11. il_dbgfs_nvm_read
  12. il_dbgfs_channels_read
  13. il_dbgfs_status_read
  14. il_dbgfs_interrupt_read
  15. il_dbgfs_interrupt_write
  16. il_dbgfs_qos_read
  17. il_dbgfs_disable_ht40_write
  18. il_dbgfs_disable_ht40_read
  19. il_dbgfs_tx_queue_read
  20. il_dbgfs_rx_queue_read
  21. il_dbgfs_ucode_rx_stats_read
  22. il_dbgfs_ucode_tx_stats_read
  23. il_dbgfs_ucode_general_stats_read
  24. il_dbgfs_sensitivity_read
  25. il_dbgfs_chain_noise_read
  26. il_dbgfs_power_save_status_read
  27. il_dbgfs_clear_ucode_stats_write
  28. il_dbgfs_rxon_flags_read
  29. il_dbgfs_rxon_filter_flags_read
  30. il_dbgfs_fh_reg_read
  31. il_dbgfs_missed_beacon_read
  32. il_dbgfs_missed_beacon_write
  33. il_dbgfs_force_reset_read
  34. il_dbgfs_force_reset_write
  35. il_dbgfs_wd_timeout_write
  36. il_dbgfs_register
  37. il_dbgfs_unregister

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
   5  *
   6  * Contact Information:
   7  *  Intel Linux Wireless <ilw@linux.intel.com>
   8  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
   9  *****************************************************************************/
  10 #include <linux/ieee80211.h>
  11 #include <linux/export.h>
  12 #include <net/mac80211.h>
  13 
  14 #include "common.h"
  15 
  16 static void
  17 il_clear_traffic_stats(struct il_priv *il)
  18 {
  19         memset(&il->tx_stats, 0, sizeof(struct traffic_stats));
  20         memset(&il->rx_stats, 0, sizeof(struct traffic_stats));
  21 }
  22 
  23 /*
  24  * il_update_stats function record all the MGMT, CTRL and DATA pkt for
  25  * both TX and Rx . Use debugfs to display the rx/rx_stats
  26  */
  27 void
  28 il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
  29 {
  30         struct traffic_stats *stats;
  31 
  32         if (is_tx)
  33                 stats = &il->tx_stats;
  34         else
  35                 stats = &il->rx_stats;
  36 
  37         if (ieee80211_is_mgmt(fc)) {
  38                 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
  39                 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
  40                         stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
  41                         break;
  42                 case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
  43                         stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
  44                         break;
  45                 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
  46                         stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
  47                         break;
  48                 case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
  49                         stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
  50                         break;
  51                 case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
  52                         stats->mgmt[MANAGEMENT_PROBE_REQ]++;
  53                         break;
  54                 case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
  55                         stats->mgmt[MANAGEMENT_PROBE_RESP]++;
  56                         break;
  57                 case cpu_to_le16(IEEE80211_STYPE_BEACON):
  58                         stats->mgmt[MANAGEMENT_BEACON]++;
  59                         break;
  60                 case cpu_to_le16(IEEE80211_STYPE_ATIM):
  61                         stats->mgmt[MANAGEMENT_ATIM]++;
  62                         break;
  63                 case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
  64                         stats->mgmt[MANAGEMENT_DISASSOC]++;
  65                         break;
  66                 case cpu_to_le16(IEEE80211_STYPE_AUTH):
  67                         stats->mgmt[MANAGEMENT_AUTH]++;
  68                         break;
  69                 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
  70                         stats->mgmt[MANAGEMENT_DEAUTH]++;
  71                         break;
  72                 case cpu_to_le16(IEEE80211_STYPE_ACTION):
  73                         stats->mgmt[MANAGEMENT_ACTION]++;
  74                         break;
  75                 }
  76         } else if (ieee80211_is_ctl(fc)) {
  77                 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
  78                 case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
  79                         stats->ctrl[CONTROL_BACK_REQ]++;
  80                         break;
  81                 case cpu_to_le16(IEEE80211_STYPE_BACK):
  82                         stats->ctrl[CONTROL_BACK]++;
  83                         break;
  84                 case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
  85                         stats->ctrl[CONTROL_PSPOLL]++;
  86                         break;
  87                 case cpu_to_le16(IEEE80211_STYPE_RTS):
  88                         stats->ctrl[CONTROL_RTS]++;
  89                         break;
  90                 case cpu_to_le16(IEEE80211_STYPE_CTS):
  91                         stats->ctrl[CONTROL_CTS]++;
  92                         break;
  93                 case cpu_to_le16(IEEE80211_STYPE_ACK):
  94                         stats->ctrl[CONTROL_ACK]++;
  95                         break;
  96                 case cpu_to_le16(IEEE80211_STYPE_CFEND):
  97                         stats->ctrl[CONTROL_CFEND]++;
  98                         break;
  99                 case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
 100                         stats->ctrl[CONTROL_CFENDACK]++;
 101                         break;
 102                 }
 103         } else {
 104                 /* data */
 105                 stats->data_cnt++;
 106                 stats->data_bytes += len;
 107         }
 108 }
 109 EXPORT_SYMBOL(il_update_stats);
 110 
 111 /* create and remove of files */
 112 #define DEBUGFS_ADD_FILE(name, parent, mode) do {                       \
 113         debugfs_create_file(#name, mode, parent, il,                    \
 114                             &il_dbgfs_##name##_ops);                    \
 115 } while (0)
 116 
 117 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do {                        \
 118         debugfs_create_bool(#name, 0600, parent, ptr);                  \
 119 } while (0)
 120 
 121 /* file operation */
 122 #define DEBUGFS_READ_FUNC(name)                                         \
 123 static ssize_t il_dbgfs_##name##_read(struct file *file,               \
 124                                         char __user *user_buf,          \
 125                                         size_t count, loff_t *ppos);
 126 
 127 #define DEBUGFS_WRITE_FUNC(name)                                        \
 128 static ssize_t il_dbgfs_##name##_write(struct file *file,              \
 129                                         const char __user *user_buf,    \
 130                                         size_t count, loff_t *ppos);
 131 
 132 
 133 #define DEBUGFS_READ_FILE_OPS(name)                             \
 134         DEBUGFS_READ_FUNC(name);                                \
 135 static const struct file_operations il_dbgfs_##name##_ops = {   \
 136         .read = il_dbgfs_##name##_read,                         \
 137         .open = simple_open,                                    \
 138         .llseek = generic_file_llseek,                          \
 139 };
 140 
 141 #define DEBUGFS_WRITE_FILE_OPS(name)                            \
 142         DEBUGFS_WRITE_FUNC(name);                               \
 143 static const struct file_operations il_dbgfs_##name##_ops = {   \
 144         .write = il_dbgfs_##name##_write,                       \
 145         .open = simple_open,                                    \
 146         .llseek = generic_file_llseek,                          \
 147 };
 148 
 149 #define DEBUGFS_READ_WRITE_FILE_OPS(name)                       \
 150         DEBUGFS_READ_FUNC(name);                                \
 151         DEBUGFS_WRITE_FUNC(name);                               \
 152 static const struct file_operations il_dbgfs_##name##_ops = {   \
 153         .write = il_dbgfs_##name##_write,                       \
 154         .read = il_dbgfs_##name##_read,                         \
 155         .open = simple_open,                                    \
 156         .llseek = generic_file_llseek,                          \
 157 };
 158 
 159 static const char *
 160 il_get_mgmt_string(int cmd)
 161 {
 162         switch (cmd) {
 163         IL_CMD(MANAGEMENT_ASSOC_REQ);
 164         IL_CMD(MANAGEMENT_ASSOC_RESP);
 165         IL_CMD(MANAGEMENT_REASSOC_REQ);
 166         IL_CMD(MANAGEMENT_REASSOC_RESP);
 167         IL_CMD(MANAGEMENT_PROBE_REQ);
 168         IL_CMD(MANAGEMENT_PROBE_RESP);
 169         IL_CMD(MANAGEMENT_BEACON);
 170         IL_CMD(MANAGEMENT_ATIM);
 171         IL_CMD(MANAGEMENT_DISASSOC);
 172         IL_CMD(MANAGEMENT_AUTH);
 173         IL_CMD(MANAGEMENT_DEAUTH);
 174         IL_CMD(MANAGEMENT_ACTION);
 175         default:
 176                 return "UNKNOWN";
 177 
 178         }
 179 }
 180 
 181 static const char *
 182 il_get_ctrl_string(int cmd)
 183 {
 184         switch (cmd) {
 185         IL_CMD(CONTROL_BACK_REQ);
 186         IL_CMD(CONTROL_BACK);
 187         IL_CMD(CONTROL_PSPOLL);
 188         IL_CMD(CONTROL_RTS);
 189         IL_CMD(CONTROL_CTS);
 190         IL_CMD(CONTROL_ACK);
 191         IL_CMD(CONTROL_CFEND);
 192         IL_CMD(CONTROL_CFENDACK);
 193         default:
 194                 return "UNKNOWN";
 195 
 196         }
 197 }
 198 
 199 static ssize_t
 200 il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count,
 201                        loff_t *ppos)
 202 {
 203 
 204         struct il_priv *il = file->private_data;
 205         char *buf;
 206         int pos = 0;
 207 
 208         int cnt;
 209         ssize_t ret;
 210         const size_t bufsz =
 211             100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
 212         buf = kzalloc(bufsz, GFP_KERNEL);
 213         if (!buf)
 214                 return -ENOMEM;
 215         pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
 216         for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
 217                 pos +=
 218                     scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
 219                               il_get_mgmt_string(cnt), il->tx_stats.mgmt[cnt]);
 220         }
 221         pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
 222         for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
 223                 pos +=
 224                     scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
 225                               il_get_ctrl_string(cnt), il->tx_stats.ctrl[cnt]);
 226         }
 227         pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
 228         pos +=
 229             scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
 230                       il->tx_stats.data_cnt);
 231         pos +=
 232             scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
 233                       il->tx_stats.data_bytes);
 234         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 235         kfree(buf);
 236         return ret;
 237 }
 238 
 239 static ssize_t
 240 il_dbgfs_clear_traffic_stats_write(struct file *file,
 241                                    const char __user *user_buf, size_t count,
 242                                    loff_t *ppos)
 243 {
 244         struct il_priv *il = file->private_data;
 245         u32 clear_flag;
 246         char buf[8];
 247         int buf_size;
 248 
 249         memset(buf, 0, sizeof(buf));
 250         buf_size = min(count, sizeof(buf) - 1);
 251         if (copy_from_user(buf, user_buf, buf_size))
 252                 return -EFAULT;
 253         if (sscanf(buf, "%x", &clear_flag) != 1)
 254                 return -EFAULT;
 255         il_clear_traffic_stats(il);
 256 
 257         return count;
 258 }
 259 
 260 static ssize_t
 261 il_dbgfs_rx_stats_read(struct file *file, char __user *user_buf, size_t count,
 262                        loff_t *ppos)
 263 {
 264 
 265         struct il_priv *il = file->private_data;
 266         char *buf;
 267         int pos = 0;
 268         int cnt;
 269         ssize_t ret;
 270         const size_t bufsz =
 271             100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
 272         buf = kzalloc(bufsz, GFP_KERNEL);
 273         if (!buf)
 274                 return -ENOMEM;
 275 
 276         pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
 277         for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
 278                 pos +=
 279                     scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
 280                               il_get_mgmt_string(cnt), il->rx_stats.mgmt[cnt]);
 281         }
 282         pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
 283         for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
 284                 pos +=
 285                     scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",
 286                               il_get_ctrl_string(cnt), il->rx_stats.ctrl[cnt]);
 287         }
 288         pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
 289         pos +=
 290             scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
 291                       il->rx_stats.data_cnt);
 292         pos +=
 293             scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
 294                       il->rx_stats.data_bytes);
 295 
 296         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 297         kfree(buf);
 298         return ret;
 299 }
 300 
 301 #define BYTE1_MASK 0x000000ff;
 302 #define BYTE2_MASK 0x0000ffff;
 303 #define BYTE3_MASK 0x00ffffff;
 304 static ssize_t
 305 il_dbgfs_sram_read(struct file *file, char __user *user_buf, size_t count,
 306                    loff_t *ppos)
 307 {
 308         u32 val;
 309         char *buf;
 310         ssize_t ret;
 311         int i;
 312         int pos = 0;
 313         struct il_priv *il = file->private_data;
 314         size_t bufsz;
 315 
 316         /* default is to dump the entire data segment */
 317         if (!il->dbgfs_sram_offset && !il->dbgfs_sram_len) {
 318                 il->dbgfs_sram_offset = 0x800000;
 319                 if (il->ucode_type == UCODE_INIT)
 320                         il->dbgfs_sram_len = il->ucode_init_data.len;
 321                 else
 322                         il->dbgfs_sram_len = il->ucode_data.len;
 323         }
 324         bufsz = 30 + il->dbgfs_sram_len * sizeof(char) * 10;
 325         buf = kmalloc(bufsz, GFP_KERNEL);
 326         if (!buf)
 327                 return -ENOMEM;
 328         pos +=
 329             scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",
 330                       il->dbgfs_sram_len);
 331         pos +=
 332             scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
 333                       il->dbgfs_sram_offset);
 334         for (i = il->dbgfs_sram_len; i > 0; i -= 4) {
 335                 val =
 336                     il_read_targ_mem(il,
 337                                      il->dbgfs_sram_offset +
 338                                      il->dbgfs_sram_len - i);
 339                 if (i < 4) {
 340                         switch (i) {
 341                         case 1:
 342                                 val &= BYTE1_MASK;
 343                                 break;
 344                         case 2:
 345                                 val &= BYTE2_MASK;
 346                                 break;
 347                         case 3:
 348                                 val &= BYTE3_MASK;
 349                                 break;
 350                         }
 351                 }
 352                 if (!(i % 16))
 353                         pos += scnprintf(buf + pos, bufsz - pos, "\n");
 354                 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
 355         }
 356         pos += scnprintf(buf + pos, bufsz - pos, "\n");
 357 
 358         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 359         kfree(buf);
 360         return ret;
 361 }
 362 
 363 static ssize_t
 364 il_dbgfs_sram_write(struct file *file, const char __user *user_buf,
 365                     size_t count, loff_t *ppos)
 366 {
 367         struct il_priv *il = file->private_data;
 368         char buf[64];
 369         int buf_size;
 370         u32 offset, len;
 371 
 372         memset(buf, 0, sizeof(buf));
 373         buf_size = min(count, sizeof(buf) - 1);
 374         if (copy_from_user(buf, user_buf, buf_size))
 375                 return -EFAULT;
 376 
 377         if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
 378                 il->dbgfs_sram_offset = offset;
 379                 il->dbgfs_sram_len = len;
 380         } else {
 381                 il->dbgfs_sram_offset = 0;
 382                 il->dbgfs_sram_len = 0;
 383         }
 384 
 385         return count;
 386 }
 387 
 388 static ssize_t
 389 il_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count,
 390                        loff_t *ppos)
 391 {
 392         struct il_priv *il = file->private_data;
 393         struct il_station_entry *station;
 394         int max_sta = il->hw_params.max_stations;
 395         char *buf;
 396         int i, j, pos = 0;
 397         ssize_t ret;
 398         /* Add 30 for initial string */
 399         const size_t bufsz = 30 + sizeof(char) * 500 * (il->num_stations);
 400 
 401         buf = kmalloc(bufsz, GFP_KERNEL);
 402         if (!buf)
 403                 return -ENOMEM;
 404 
 405         pos +=
 406             scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
 407                       il->num_stations);
 408 
 409         for (i = 0; i < max_sta; i++) {
 410                 station = &il->stations[i];
 411                 if (!station->used)
 412                         continue;
 413                 pos +=
 414                     scnprintf(buf + pos, bufsz - pos,
 415                               "station %d - addr: %pM, flags: %#x\n", i,
 416                               station->sta.sta.addr,
 417                               station->sta.station_flags_msk);
 418                 pos +=
 419                     scnprintf(buf + pos, bufsz - pos,
 420                               "TID\tseq_num\ttxq_id\tframes\ttfds\t");
 421                 pos +=
 422                     scnprintf(buf + pos, bufsz - pos,
 423                               "start_idx\tbitmap\t\t\trate_n_flags\n");
 424 
 425                 for (j = 0; j < MAX_TID_COUNT; j++) {
 426                         pos +=
 427                             scnprintf(buf + pos, bufsz - pos,
 428                                       "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
 429                                       j, station->tid[j].seq_number,
 430                                       station->tid[j].agg.txq_id,
 431                                       station->tid[j].agg.frame_count,
 432                                       station->tid[j].tfds_in_queue,
 433                                       station->tid[j].agg.start_idx,
 434                                       station->tid[j].agg.bitmap,
 435                                       station->tid[j].agg.rate_n_flags);
 436 
 437                         if (station->tid[j].agg.wait_for_ba)
 438                                 pos +=
 439                                     scnprintf(buf + pos, bufsz - pos,
 440                                               " - waitforba");
 441                         pos += scnprintf(buf + pos, bufsz - pos, "\n");
 442                 }
 443 
 444                 pos += scnprintf(buf + pos, bufsz - pos, "\n");
 445         }
 446 
 447         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 448         kfree(buf);
 449         return ret;
 450 }
 451 
 452 static ssize_t
 453 il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count,
 454                   loff_t *ppos)
 455 {
 456         ssize_t ret;
 457         struct il_priv *il = file->private_data;
 458         int pos = 0, ofs = 0, buf_size = 0;
 459         const u8 *ptr;
 460         char *buf;
 461         u16 eeprom_ver;
 462         size_t eeprom_len = il->cfg->eeprom_size;
 463         buf_size = 4 * eeprom_len + 256;
 464 
 465         if (eeprom_len % 16) {
 466                 IL_ERR("NVM size is not multiple of 16.\n");
 467                 return -ENODATA;
 468         }
 469 
 470         ptr = il->eeprom;
 471         if (!ptr) {
 472                 IL_ERR("Invalid EEPROM memory\n");
 473                 return -ENOMEM;
 474         }
 475 
 476         /* 4 characters for byte 0xYY */
 477         buf = kzalloc(buf_size, GFP_KERNEL);
 478         if (!buf) {
 479                 IL_ERR("Can not allocate Buffer\n");
 480                 return -ENOMEM;
 481         }
 482         eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
 483         pos +=
 484             scnprintf(buf + pos, buf_size - pos, "EEPROM " "version: 0x%x\n",
 485                       eeprom_ver);
 486         for (ofs = 0; ofs < eeprom_len; ofs += 16) {
 487                 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x %16ph\n",
 488                                  ofs, ptr + ofs);
 489         }
 490 
 491         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 492         kfree(buf);
 493         return ret;
 494 }
 495 
 496 static ssize_t
 497 il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
 498                        loff_t *ppos)
 499 {
 500         struct il_priv *il = file->private_data;
 501         struct ieee80211_channel *channels = NULL;
 502         const struct ieee80211_supported_band *supp_band = NULL;
 503         int pos = 0, i, bufsz = PAGE_SIZE;
 504         char *buf;
 505         ssize_t ret;
 506 
 507         if (!test_bit(S_GEO_CONFIGURED, &il->status))
 508                 return -EAGAIN;
 509 
 510         buf = kzalloc(bufsz, GFP_KERNEL);
 511         if (!buf) {
 512                 IL_ERR("Can not allocate Buffer\n");
 513                 return -ENOMEM;
 514         }
 515 
 516         supp_band = il_get_hw_mode(il, NL80211_BAND_2GHZ);
 517         if (supp_band) {
 518                 channels = supp_band->channels;
 519 
 520                 pos +=
 521                     scnprintf(buf + pos, bufsz - pos,
 522                               "Displaying %d channels in 2.4GHz band 802.11bg):\n",
 523                               supp_band->n_channels);
 524 
 525                 for (i = 0; i < supp_band->n_channels; i++)
 526                         pos +=
 527                             scnprintf(buf + pos, bufsz - pos,
 528                                       "%d: %ddBm: BSS%s%s, %s.\n",
 529                                       channels[i].hw_value,
 530                                       channels[i].max_power,
 531                                       channels[i].
 532                                       flags & IEEE80211_CHAN_RADAR ?
 533                                       " (IEEE 802.11h required)" : "",
 534                                       ((channels[i].
 535                                         flags & IEEE80211_CHAN_NO_IR) ||
 536                                        (channels[i].
 537                                         flags & IEEE80211_CHAN_RADAR)) ? "" :
 538                                       ", IBSS",
 539                                       channels[i].
 540                                       flags & IEEE80211_CHAN_NO_IR ?
 541                                       "passive only" : "active/passive");
 542         }
 543         supp_band = il_get_hw_mode(il, NL80211_BAND_5GHZ);
 544         if (supp_band) {
 545                 channels = supp_band->channels;
 546 
 547                 pos +=
 548                     scnprintf(buf + pos, bufsz - pos,
 549                               "Displaying %d channels in 5.2GHz band (802.11a)\n",
 550                               supp_band->n_channels);
 551 
 552                 for (i = 0; i < supp_band->n_channels; i++)
 553                         pos +=
 554                             scnprintf(buf + pos, bufsz - pos,
 555                                       "%d: %ddBm: BSS%s%s, %s.\n",
 556                                       channels[i].hw_value,
 557                                       channels[i].max_power,
 558                                       channels[i].
 559                                       flags & IEEE80211_CHAN_RADAR ?
 560                                       " (IEEE 802.11h required)" : "",
 561                                       ((channels[i].
 562                                         flags & IEEE80211_CHAN_NO_IR) ||
 563                                        (channels[i].
 564                                         flags & IEEE80211_CHAN_RADAR)) ? "" :
 565                                       ", IBSS",
 566                                       channels[i].
 567                                       flags & IEEE80211_CHAN_NO_IR ?
 568                                       "passive only" : "active/passive");
 569         }
 570         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 571         kfree(buf);
 572         return ret;
 573 }
 574 
 575 static ssize_t
 576 il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count,
 577                      loff_t *ppos)
 578 {
 579 
 580         struct il_priv *il = file->private_data;
 581         char buf[512];
 582         int pos = 0;
 583         const size_t bufsz = sizeof(buf);
 584 
 585         pos +=
 586             scnprintf(buf + pos, bufsz - pos, "S_HCMD_ACTIVE:\t %d\n",
 587                       test_bit(S_HCMD_ACTIVE, &il->status));
 588         pos +=
 589             scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
 590                       test_bit(S_INT_ENABLED, &il->status));
 591         pos +=
 592             scnprintf(buf + pos, bufsz - pos, "S_RFKILL:\t %d\n",
 593                       test_bit(S_RFKILL, &il->status));
 594         pos +=
 595             scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
 596                       test_bit(S_CT_KILL, &il->status));
 597         pos +=
 598             scnprintf(buf + pos, bufsz - pos, "S_INIT:\t\t %d\n",
 599                       test_bit(S_INIT, &il->status));
 600         pos +=
 601             scnprintf(buf + pos, bufsz - pos, "S_ALIVE:\t\t %d\n",
 602                       test_bit(S_ALIVE, &il->status));
 603         pos +=
 604             scnprintf(buf + pos, bufsz - pos, "S_READY:\t\t %d\n",
 605                       test_bit(S_READY, &il->status));
 606         pos +=
 607             scnprintf(buf + pos, bufsz - pos, "S_TEMPERATURE:\t %d\n",
 608                       test_bit(S_TEMPERATURE, &il->status));
 609         pos +=
 610             scnprintf(buf + pos, bufsz - pos, "S_GEO_CONFIGURED:\t %d\n",
 611                       test_bit(S_GEO_CONFIGURED, &il->status));
 612         pos +=
 613             scnprintf(buf + pos, bufsz - pos, "S_EXIT_PENDING:\t %d\n",
 614                       test_bit(S_EXIT_PENDING, &il->status));
 615         pos +=
 616             scnprintf(buf + pos, bufsz - pos, "S_STATS:\t %d\n",
 617                       test_bit(S_STATS, &il->status));
 618         pos +=
 619             scnprintf(buf + pos, bufsz - pos, "S_SCANNING:\t %d\n",
 620                       test_bit(S_SCANNING, &il->status));
 621         pos +=
 622             scnprintf(buf + pos, bufsz - pos, "S_SCAN_ABORTING:\t %d\n",
 623                       test_bit(S_SCAN_ABORTING, &il->status));
 624         pos +=
 625             scnprintf(buf + pos, bufsz - pos, "S_SCAN_HW:\t\t %d\n",
 626                       test_bit(S_SCAN_HW, &il->status));
 627         pos +=
 628             scnprintf(buf + pos, bufsz - pos, "S_POWER_PMI:\t %d\n",
 629                       test_bit(S_POWER_PMI, &il->status));
 630         pos +=
 631             scnprintf(buf + pos, bufsz - pos, "S_FW_ERROR:\t %d\n",
 632                       test_bit(S_FW_ERROR, &il->status));
 633         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 634 }
 635 
 636 static ssize_t
 637 il_dbgfs_interrupt_read(struct file *file, char __user *user_buf, size_t count,
 638                         loff_t *ppos)
 639 {
 640 
 641         struct il_priv *il = file->private_data;
 642         int pos = 0;
 643         int cnt = 0;
 644         char *buf;
 645         int bufsz = 24 * 64;    /* 24 items * 64 char per item */
 646         ssize_t ret;
 647 
 648         buf = kzalloc(bufsz, GFP_KERNEL);
 649         if (!buf) {
 650                 IL_ERR("Can not allocate Buffer\n");
 651                 return -ENOMEM;
 652         }
 653 
 654         pos +=
 655             scnprintf(buf + pos, bufsz - pos, "Interrupt Statistics Report:\n");
 656 
 657         pos +=
 658             scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
 659                       il->isr_stats.hw);
 660         pos +=
 661             scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
 662                       il->isr_stats.sw);
 663         if (il->isr_stats.sw || il->isr_stats.hw) {
 664                 pos +=
 665                     scnprintf(buf + pos, bufsz - pos,
 666                               "\tLast Restarting Code:  0x%X\n",
 667                               il->isr_stats.err_code);
 668         }
 669 #ifdef CONFIG_IWLEGACY_DEBUG
 670         pos +=
 671             scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
 672                       il->isr_stats.sch);
 673         pos +=
 674             scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
 675                       il->isr_stats.alive);
 676 #endif
 677         pos +=
 678             scnprintf(buf + pos, bufsz - pos,
 679                       "HW RF KILL switch toggled:\t %u\n",
 680                       il->isr_stats.rfkill);
 681 
 682         pos +=
 683             scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
 684                       il->isr_stats.ctkill);
 685 
 686         pos +=
 687             scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
 688                       il->isr_stats.wakeup);
 689 
 690         pos +=
 691             scnprintf(buf + pos, bufsz - pos, "Rx command responses:\t\t %u\n",
 692                       il->isr_stats.rx);
 693         for (cnt = 0; cnt < IL_CN_MAX; cnt++) {
 694                 if (il->isr_stats.handlers[cnt] > 0)
 695                         pos +=
 696                             scnprintf(buf + pos, bufsz - pos,
 697                                       "\tRx handler[%36s]:\t\t %u\n",
 698                                       il_get_cmd_string(cnt),
 699                                       il->isr_stats.handlers[cnt]);
 700         }
 701 
 702         pos +=
 703             scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
 704                       il->isr_stats.tx);
 705 
 706         pos +=
 707             scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
 708                       il->isr_stats.unhandled);
 709 
 710         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 711         kfree(buf);
 712         return ret;
 713 }
 714 
 715 static ssize_t
 716 il_dbgfs_interrupt_write(struct file *file, const char __user *user_buf,
 717                          size_t count, loff_t *ppos)
 718 {
 719         struct il_priv *il = file->private_data;
 720         char buf[8];
 721         int buf_size;
 722         u32 reset_flag;
 723 
 724         memset(buf, 0, sizeof(buf));
 725         buf_size = min(count, sizeof(buf) - 1);
 726         if (copy_from_user(buf, user_buf, buf_size))
 727                 return -EFAULT;
 728         if (sscanf(buf, "%x", &reset_flag) != 1)
 729                 return -EFAULT;
 730         if (reset_flag == 0)
 731                 il_clear_isr_stats(il);
 732 
 733         return count;
 734 }
 735 
 736 static ssize_t
 737 il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
 738                   loff_t *ppos)
 739 {
 740         struct il_priv *il = file->private_data;
 741         int pos = 0, i;
 742         char buf[256];
 743         const size_t bufsz = sizeof(buf);
 744 
 745         for (i = 0; i < AC_NUM; i++) {
 746                 pos +=
 747                     scnprintf(buf + pos, bufsz - pos,
 748                               "\tcw_min\tcw_max\taifsn\ttxop\n");
 749                 pos +=
 750                     scnprintf(buf + pos, bufsz - pos,
 751                               "AC[%d]\t%u\t%u\t%u\t%u\n", i,
 752                               il->qos_data.def_qos_parm.ac[i].cw_min,
 753                               il->qos_data.def_qos_parm.ac[i].cw_max,
 754                               il->qos_data.def_qos_parm.ac[i].aifsn,
 755                               il->qos_data.def_qos_parm.ac[i].edca_txop);
 756         }
 757 
 758         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 759 }
 760 
 761 static ssize_t
 762 il_dbgfs_disable_ht40_write(struct file *file, const char __user *user_buf,
 763                             size_t count, loff_t *ppos)
 764 {
 765         struct il_priv *il = file->private_data;
 766         char buf[8];
 767         int buf_size;
 768         int ht40;
 769 
 770         memset(buf, 0, sizeof(buf));
 771         buf_size = min(count, sizeof(buf) - 1);
 772         if (copy_from_user(buf, user_buf, buf_size))
 773                 return -EFAULT;
 774         if (sscanf(buf, "%d", &ht40) != 1)
 775                 return -EFAULT;
 776         if (!il_is_any_associated(il))
 777                 il->disable_ht40 = ht40 ? true : false;
 778         else {
 779                 IL_ERR("Sta associated with AP - "
 780                        "Change to 40MHz channel support is not allowed\n");
 781                 return -EINVAL;
 782         }
 783 
 784         return count;
 785 }
 786 
 787 static ssize_t
 788 il_dbgfs_disable_ht40_read(struct file *file, char __user *user_buf,
 789                            size_t count, loff_t *ppos)
 790 {
 791         struct il_priv *il = file->private_data;
 792         char buf[100];
 793         int pos = 0;
 794         const size_t bufsz = sizeof(buf);
 795 
 796         pos +=
 797             scnprintf(buf + pos, bufsz - pos, "11n 40MHz Mode: %s\n",
 798                       il->disable_ht40 ? "Disabled" : "Enabled");
 799         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 800 }
 801 
 802 DEBUGFS_READ_WRITE_FILE_OPS(sram);
 803 DEBUGFS_READ_FILE_OPS(nvm);
 804 DEBUGFS_READ_FILE_OPS(stations);
 805 DEBUGFS_READ_FILE_OPS(channels);
 806 DEBUGFS_READ_FILE_OPS(status);
 807 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 808 DEBUGFS_READ_FILE_OPS(qos);
 809 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
 810 
 811 static ssize_t
 812 il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
 813                        loff_t *ppos)
 814 {
 815 
 816         struct il_priv *il = file->private_data;
 817         struct il_tx_queue *txq;
 818         struct il_queue *q;
 819         char *buf;
 820         int pos = 0;
 821         int cnt;
 822         int ret;
 823         const size_t bufsz =
 824             sizeof(char) * 64 * il->cfg->num_of_queues;
 825 
 826         if (!il->txq) {
 827                 IL_ERR("txq not ready\n");
 828                 return -EAGAIN;
 829         }
 830         buf = kzalloc(bufsz, GFP_KERNEL);
 831         if (!buf)
 832                 return -ENOMEM;
 833 
 834         for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
 835                 txq = &il->txq[cnt];
 836                 q = &txq->q;
 837                 pos +=
 838                     scnprintf(buf + pos, bufsz - pos,
 839                               "hwq %.2d: read=%u write=%u stop=%d"
 840                               " swq_id=%#.2x (ac %d/hwq %d)\n", cnt,
 841                               q->read_ptr, q->write_ptr,
 842                               !!test_bit(cnt, il->queue_stopped),
 843                               txq->swq_id, txq->swq_id & 3,
 844                               (txq->swq_id >> 2) & 0x1f);
 845                 if (cnt >= 4)
 846                         continue;
 847                 /* for the ACs, display the stop count too */
 848                 pos +=
 849                     scnprintf(buf + pos, bufsz - pos,
 850                               "        stop-count: %d\n",
 851                               atomic_read(&il->queue_stop_count[cnt]));
 852         }
 853         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 854         kfree(buf);
 855         return ret;
 856 }
 857 
 858 static ssize_t
 859 il_dbgfs_rx_queue_read(struct file *file, char __user *user_buf, size_t count,
 860                        loff_t *ppos)
 861 {
 862 
 863         struct il_priv *il = file->private_data;
 864         struct il_rx_queue *rxq = &il->rxq;
 865         char buf[256];
 866         int pos = 0;
 867         const size_t bufsz = sizeof(buf);
 868 
 869         pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", rxq->read);
 870         pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", rxq->write);
 871         pos +=
 872             scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
 873                       rxq->free_count);
 874         if (rxq->rb_stts) {
 875                 pos +=
 876                     scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
 877                               le16_to_cpu(rxq->rb_stts->
 878                                           closed_rb_num) & 0x0FFF);
 879         } else {
 880                 pos +=
 881                     scnprintf(buf + pos, bufsz - pos,
 882                               "closed_rb_num: Not Allocated\n");
 883         }
 884         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 885 }
 886 
 887 static ssize_t
 888 il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,
 889                              size_t count, loff_t *ppos)
 890 {
 891         struct il_priv *il = file->private_data;
 892 
 893         return il->debugfs_ops->rx_stats_read(file, user_buf, count, ppos);
 894 }
 895 
 896 static ssize_t
 897 il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
 898                              size_t count, loff_t *ppos)
 899 {
 900         struct il_priv *il = file->private_data;
 901 
 902         return il->debugfs_ops->tx_stats_read(file, user_buf, count, ppos);
 903 }
 904 
 905 static ssize_t
 906 il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
 907                                   size_t count, loff_t *ppos)
 908 {
 909         struct il_priv *il = file->private_data;
 910 
 911         return il->debugfs_ops->general_stats_read(file, user_buf, count, ppos);
 912 }
 913 
 914 static ssize_t
 915 il_dbgfs_sensitivity_read(struct file *file, char __user *user_buf,
 916                           size_t count, loff_t *ppos)
 917 {
 918 
 919         struct il_priv *il = file->private_data;
 920         int pos = 0;
 921         int cnt = 0;
 922         char *buf;
 923         int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100;
 924         ssize_t ret;
 925         struct il_sensitivity_data *data;
 926 
 927         data = &il->sensitivity_data;
 928         buf = kzalloc(bufsz, GFP_KERNEL);
 929         if (!buf) {
 930                 IL_ERR("Can not allocate Buffer\n");
 931                 return -ENOMEM;
 932         }
 933 
 934         pos +=
 935             scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
 936                       data->auto_corr_ofdm);
 937         pos +=
 938             scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc:\t\t %u\n",
 939                       data->auto_corr_ofdm_mrc);
 940         pos +=
 941             scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
 942                       data->auto_corr_ofdm_x1);
 943         pos +=
 944             scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc_x1:\t\t %u\n",
 945                       data->auto_corr_ofdm_mrc_x1);
 946         pos +=
 947             scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
 948                       data->auto_corr_cck);
 949         pos +=
 950             scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
 951                       data->auto_corr_cck_mrc);
 952         pos +=
 953             scnprintf(buf + pos, bufsz - pos,
 954                       "last_bad_plcp_cnt_ofdm:\t\t %u\n",
 955                       data->last_bad_plcp_cnt_ofdm);
 956         pos +=
 957             scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
 958                       data->last_fa_cnt_ofdm);
 959         pos +=
 960             scnprintf(buf + pos, bufsz - pos, "last_bad_plcp_cnt_cck:\t\t %u\n",
 961                       data->last_bad_plcp_cnt_cck);
 962         pos +=
 963             scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
 964                       data->last_fa_cnt_cck);
 965         pos +=
 966             scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
 967                       data->nrg_curr_state);
 968         pos +=
 969             scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
 970                       data->nrg_prev_state);
 971         pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
 972         for (cnt = 0; cnt < 10; cnt++) {
 973                 pos +=
 974                     scnprintf(buf + pos, bufsz - pos, " %u",
 975                               data->nrg_value[cnt]);
 976         }
 977         pos += scnprintf(buf + pos, bufsz - pos, "\n");
 978         pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
 979         for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
 980                 pos +=
 981                     scnprintf(buf + pos, bufsz - pos, " %u",
 982                               data->nrg_silence_rssi[cnt]);
 983         }
 984         pos += scnprintf(buf + pos, bufsz - pos, "\n");
 985         pos +=
 986             scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
 987                       data->nrg_silence_ref);
 988         pos +=
 989             scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
 990                       data->nrg_energy_idx);
 991         pos +=
 992             scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
 993                       data->nrg_silence_idx);
 994         pos +=
 995             scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
 996                       data->nrg_th_cck);
 997         pos +=
 998             scnprintf(buf + pos, bufsz - pos,
 999                       "nrg_auto_corr_silence_diff:\t %u\n",
1000                       data->nrg_auto_corr_silence_diff);
1001         pos +=
1002             scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
1003                       data->num_in_cck_no_fa);
1004         pos +=
1005             scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
1006                       data->nrg_th_ofdm);
1007 
1008         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1009         kfree(buf);
1010         return ret;
1011 }
1012 
1013 static ssize_t
1014 il_dbgfs_chain_noise_read(struct file *file, char __user *user_buf,
1015                           size_t count, loff_t *ppos)
1016 {
1017 
1018         struct il_priv *il = file->private_data;
1019         int pos = 0;
1020         int cnt = 0;
1021         char *buf;
1022         int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100;
1023         ssize_t ret;
1024         struct il_chain_noise_data *data;
1025 
1026         data = &il->chain_noise_data;
1027         buf = kzalloc(bufsz, GFP_KERNEL);
1028         if (!buf) {
1029                 IL_ERR("Can not allocate Buffer\n");
1030                 return -ENOMEM;
1031         }
1032 
1033         pos +=
1034             scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
1035                       data->active_chains);
1036         pos +=
1037             scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
1038                       data->chain_noise_a);
1039         pos +=
1040             scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
1041                       data->chain_noise_b);
1042         pos +=
1043             scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
1044                       data->chain_noise_c);
1045         pos +=
1046             scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
1047                       data->chain_signal_a);
1048         pos +=
1049             scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
1050                       data->chain_signal_b);
1051         pos +=
1052             scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
1053                       data->chain_signal_c);
1054         pos +=
1055             scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
1056                       data->beacon_count);
1057 
1058         pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
1059         for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
1060                 pos +=
1061                     scnprintf(buf + pos, bufsz - pos, " %u",
1062                               data->disconn_array[cnt]);
1063         }
1064         pos += scnprintf(buf + pos, bufsz - pos, "\n");
1065         pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
1066         for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
1067                 pos +=
1068                     scnprintf(buf + pos, bufsz - pos, " %u",
1069                               data->delta_gain_code[cnt]);
1070         }
1071         pos += scnprintf(buf + pos, bufsz - pos, "\n");
1072         pos +=
1073             scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
1074                       data->radio_write);
1075         pos +=
1076             scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
1077                       data->state);
1078 
1079         ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1080         kfree(buf);
1081         return ret;
1082 }
1083 
1084 static ssize_t
1085 il_dbgfs_power_save_status_read(struct file *file, char __user *user_buf,
1086                                 size_t count, loff_t *ppos)
1087 {
1088         struct il_priv *il = file->private_data;
1089         char buf[60];
1090         int pos = 0;
1091         const size_t bufsz = sizeof(buf);
1092         u32 pwrsave_status;
1093 
1094         pwrsave_status =
1095             _il_rd(il, CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK;
1096 
1097         pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
1098         pos +=
1099             scnprintf(buf + pos, bufsz - pos, "%s\n",
1100                       (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :
1101                       (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :
1102                       (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :
1103                       "error");
1104 
1105         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1106 }
1107 
1108 static ssize_t
1109 il_dbgfs_clear_ucode_stats_write(struct file *file,
1110                                  const char __user *user_buf, size_t count,
1111                                  loff_t *ppos)
1112 {
1113         struct il_priv *il = file->private_data;
1114         char buf[8];
1115         int buf_size;
1116         int clear;
1117 
1118         memset(buf, 0, sizeof(buf));
1119         buf_size = min(count, sizeof(buf) - 1);
1120         if (copy_from_user(buf, user_buf, buf_size))
1121                 return -EFAULT;
1122         if (sscanf(buf, "%d", &clear) != 1)
1123                 return -EFAULT;
1124 
1125         /* make request to uCode to retrieve stats information */
1126         mutex_lock(&il->mutex);
1127         il_send_stats_request(il, CMD_SYNC, true);
1128         mutex_unlock(&il->mutex);
1129 
1130         return count;
1131 }
1132 
1133 static ssize_t
1134 il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf,
1135                          size_t count, loff_t *ppos)
1136 {
1137 
1138         struct il_priv *il = file->private_data;
1139         int len = 0;
1140         char buf[20];
1141 
1142         len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags));
1143         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1144 }
1145 
1146 static ssize_t
1147 il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf,
1148                                 size_t count, loff_t *ppos)
1149 {
1150 
1151         struct il_priv *il = file->private_data;
1152         int len = 0;
1153         char buf[20];
1154 
1155         len =
1156             sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
1157         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1158 }
1159 
1160 static ssize_t
1161 il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
1162                      loff_t *ppos)
1163 {
1164         struct il_priv *il = file->private_data;
1165         char *buf;
1166         int pos = 0;
1167         ssize_t ret = -EFAULT;
1168 
1169         if (il->ops->dump_fh) {
1170                 ret = pos = il->ops->dump_fh(il, &buf, true);
1171                 if (buf) {
1172                         ret =
1173                             simple_read_from_buffer(user_buf, count, ppos, buf,
1174                                                     pos);
1175                         kfree(buf);
1176                 }
1177         }
1178 
1179         return ret;
1180 }
1181 
1182 static ssize_t
1183 il_dbgfs_missed_beacon_read(struct file *file, char __user *user_buf,
1184                             size_t count, loff_t *ppos)
1185 {
1186 
1187         struct il_priv *il = file->private_data;
1188         int pos = 0;
1189         char buf[12];
1190         const size_t bufsz = sizeof(buf);
1191 
1192         pos +=
1193             scnprintf(buf + pos, bufsz - pos, "%d\n",
1194                       il->missed_beacon_threshold);
1195 
1196         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1197 }
1198 
1199 static ssize_t
1200 il_dbgfs_missed_beacon_write(struct file *file, const char __user *user_buf,
1201                              size_t count, loff_t *ppos)
1202 {
1203         struct il_priv *il = file->private_data;
1204         char buf[8];
1205         int buf_size;
1206         int missed;
1207 
1208         memset(buf, 0, sizeof(buf));
1209         buf_size = min(count, sizeof(buf) - 1);
1210         if (copy_from_user(buf, user_buf, buf_size))
1211                 return -EFAULT;
1212         if (sscanf(buf, "%d", &missed) != 1)
1213                 return -EINVAL;
1214 
1215         if (missed < IL_MISSED_BEACON_THRESHOLD_MIN ||
1216             missed > IL_MISSED_BEACON_THRESHOLD_MAX)
1217                 il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;
1218         else
1219                 il->missed_beacon_threshold = missed;
1220 
1221         return count;
1222 }
1223 
1224 static ssize_t
1225 il_dbgfs_force_reset_read(struct file *file, char __user *user_buf,
1226                           size_t count, loff_t *ppos)
1227 {
1228 
1229         struct il_priv *il = file->private_data;
1230         int pos = 0;
1231         char buf[300];
1232         const size_t bufsz = sizeof(buf);
1233         struct il_force_reset *force_reset;
1234 
1235         force_reset = &il->force_reset;
1236 
1237         pos +=
1238             scnprintf(buf + pos, bufsz - pos, "\tnumber of reset request: %d\n",
1239                       force_reset->reset_request_count);
1240         pos +=
1241             scnprintf(buf + pos, bufsz - pos,
1242                       "\tnumber of reset request success: %d\n",
1243                       force_reset->reset_success_count);
1244         pos +=
1245             scnprintf(buf + pos, bufsz - pos,
1246                       "\tnumber of reset request reject: %d\n",
1247                       force_reset->reset_reject_count);
1248         pos +=
1249             scnprintf(buf + pos, bufsz - pos, "\treset duration: %lu\n",
1250                       force_reset->reset_duration);
1251 
1252         return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1253 }
1254 
1255 static ssize_t
1256 il_dbgfs_force_reset_write(struct file *file, const char __user *user_buf,
1257                            size_t count, loff_t *ppos)
1258 {
1259 
1260         int ret;
1261         struct il_priv *il = file->private_data;
1262 
1263         ret = il_force_reset(il, true);
1264 
1265         return ret ? ret : count;
1266 }
1267 
1268 static ssize_t
1269 il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
1270                           size_t count, loff_t *ppos)
1271 {
1272 
1273         struct il_priv *il = file->private_data;
1274         char buf[8];
1275         int buf_size;
1276         int timeout;
1277 
1278         memset(buf, 0, sizeof(buf));
1279         buf_size = min(count, sizeof(buf) - 1);
1280         if (copy_from_user(buf, user_buf, buf_size))
1281                 return -EFAULT;
1282         if (sscanf(buf, "%d", &timeout) != 1)
1283                 return -EINVAL;
1284         if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
1285                 timeout = IL_DEF_WD_TIMEOUT;
1286 
1287         il->cfg->wd_timeout = timeout;
1288         il_setup_watchdog(il);
1289         return count;
1290 }
1291 
1292 DEBUGFS_READ_FILE_OPS(rx_stats);
1293 DEBUGFS_READ_FILE_OPS(tx_stats);
1294 DEBUGFS_READ_FILE_OPS(rx_queue);
1295 DEBUGFS_READ_FILE_OPS(tx_queue);
1296 DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
1297 DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
1298 DEBUGFS_READ_FILE_OPS(ucode_general_stats);
1299 DEBUGFS_READ_FILE_OPS(sensitivity);
1300 DEBUGFS_READ_FILE_OPS(chain_noise);
1301 DEBUGFS_READ_FILE_OPS(power_save_status);
1302 DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats);
1303 DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats);
1304 DEBUGFS_READ_FILE_OPS(fh_reg);
1305 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
1306 DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
1307 DEBUGFS_READ_FILE_OPS(rxon_flags);
1308 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
1309 DEBUGFS_WRITE_FILE_OPS(wd_timeout);
1310 
1311 /*
1312  * Create the debugfs files and directories
1313  *
1314  */
1315 void
1316 il_dbgfs_register(struct il_priv *il, const char *name)
1317 {
1318         struct dentry *phyd = il->hw->wiphy->debugfsdir;
1319         struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;
1320 
1321         dir_drv = debugfs_create_dir(name, phyd);
1322         il->debugfs_dir = dir_drv;
1323 
1324         dir_data = debugfs_create_dir("data", dir_drv);
1325         dir_rf = debugfs_create_dir("rf", dir_drv);
1326         dir_debug = debugfs_create_dir("debug", dir_drv);
1327 
1328         DEBUGFS_ADD_FILE(nvm, dir_data, 0400);
1329         DEBUGFS_ADD_FILE(sram, dir_data, 0600);
1330         DEBUGFS_ADD_FILE(stations, dir_data, 0400);
1331         DEBUGFS_ADD_FILE(channels, dir_data, 0400);
1332         DEBUGFS_ADD_FILE(status, dir_data, 0400);
1333         DEBUGFS_ADD_FILE(interrupt, dir_data, 0600);
1334         DEBUGFS_ADD_FILE(qos, dir_data, 0400);
1335         DEBUGFS_ADD_FILE(disable_ht40, dir_data, 0600);
1336         DEBUGFS_ADD_FILE(rx_stats, dir_debug, 0400);
1337         DEBUGFS_ADD_FILE(tx_stats, dir_debug, 0400);
1338         DEBUGFS_ADD_FILE(rx_queue, dir_debug, 0400);
1339         DEBUGFS_ADD_FILE(tx_queue, dir_debug, 0400);
1340         DEBUGFS_ADD_FILE(power_save_status, dir_debug, 0400);
1341         DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, 0200);
1342         DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, 0200);
1343         DEBUGFS_ADD_FILE(fh_reg, dir_debug, 0400);
1344         DEBUGFS_ADD_FILE(missed_beacon, dir_debug, 0200);
1345         DEBUGFS_ADD_FILE(force_reset, dir_debug, 0600);
1346         DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, 0400);
1347         DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, 0400);
1348         DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, 0400);
1349 
1350         if (il->cfg->sensitivity_calib_by_driver)
1351                 DEBUGFS_ADD_FILE(sensitivity, dir_debug, 0400);
1352         if (il->cfg->chain_noise_calib_by_driver)
1353                 DEBUGFS_ADD_FILE(chain_noise, dir_debug, 0400);
1354         DEBUGFS_ADD_FILE(rxon_flags, dir_debug, 0200);
1355         DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, 0200);
1356         DEBUGFS_ADD_FILE(wd_timeout, dir_debug, 0200);
1357         if (il->cfg->sensitivity_calib_by_driver)
1358                 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
1359                                  &il->disable_sens_cal);
1360         if (il->cfg->chain_noise_calib_by_driver)
1361                 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
1362                                  &il->disable_chain_noise_cal);
1363         DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal);
1364 }
1365 EXPORT_SYMBOL(il_dbgfs_register);
1366 
1367 /**
1368  * Remove the debugfs files and directories
1369  *
1370  */
1371 void
1372 il_dbgfs_unregister(struct il_priv *il)
1373 {
1374         if (!il->debugfs_dir)
1375                 return;
1376 
1377         debugfs_remove_recursive(il->debugfs_dir);
1378         il->debugfs_dir = NULL;
1379 }
1380 EXPORT_SYMBOL(il_dbgfs_unregister);

/* [<][>][^][v][top][bottom][index][help] */