diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-debugfs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debugfs.c | 103 |
1 files changed, 95 insertions, 8 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 9a30e1df311d..ed948dc59b3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
35 | 35 | ||
36 | 36 | ||
37 | #include "iwl-4965.h" | 37 | #include "iwl-dev.h" |
38 | #include "iwl-debug.h" | 38 | #include "iwl-debug.h" |
39 | #include "iwl-core.h" | 39 | #include "iwl-core.h" |
40 | #include "iwl-io.h" | 40 | #include "iwl-io.h" |
@@ -55,6 +55,13 @@ | |||
55 | goto err; \ | 55 | goto err; \ |
56 | } while (0) | 56 | } while (0) |
57 | 57 | ||
58 | #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ | ||
59 | dbgfs->dbgfs_##parent##_files.file_##name = \ | ||
60 | debugfs_create_bool(#name, 0644, dbgfs->dir_##parent, ptr); \ | ||
61 | if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)) \ | ||
62 | goto err; \ | ||
63 | } while (0) | ||
64 | |||
58 | #define DEBUGFS_REMOVE(name) do { \ | 65 | #define DEBUGFS_REMOVE(name) do { \ |
59 | debugfs_remove(name); \ | 66 | debugfs_remove(name); \ |
60 | name = NULL; \ | 67 | name = NULL; \ |
@@ -85,6 +92,14 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ | |||
85 | .open = iwl_dbgfs_open_file_generic, \ | 92 | .open = iwl_dbgfs_open_file_generic, \ |
86 | }; | 93 | }; |
87 | 94 | ||
95 | #define DEBUGFS_WRITE_FILE_OPS(name) \ | ||
96 | DEBUGFS_WRITE_FUNC(name); \ | ||
97 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ | ||
98 | .write = iwl_dbgfs_##name##_write, \ | ||
99 | .open = iwl_dbgfs_open_file_generic, \ | ||
100 | }; | ||
101 | |||
102 | |||
88 | #define DEBUGFS_READ_WRITE_FILE_OPS(name) \ | 103 | #define DEBUGFS_READ_WRITE_FILE_OPS(name) \ |
89 | DEBUGFS_READ_FUNC(name); \ | 104 | DEBUGFS_READ_FUNC(name); \ |
90 | DEBUGFS_WRITE_FUNC(name); \ | 105 | DEBUGFS_WRITE_FUNC(name); \ |
@@ -206,7 +221,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
206 | size_t count, loff_t *ppos) | 221 | size_t count, loff_t *ppos) |
207 | { | 222 | { |
208 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 223 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
209 | struct iwl4965_station_entry *station; | 224 | struct iwl_station_entry *station; |
210 | int max_sta = priv->hw_params.max_stations; | 225 | int max_sta = priv->hw_params.max_stations; |
211 | char *buf; | 226 | char *buf; |
212 | int i, j, pos = 0; | 227 | int i, j, pos = 0; |
@@ -240,21 +255,18 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
240 | pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); | 255 | pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); |
241 | pos += scnprintf(buf + pos, bufsz - pos, | 256 | pos += scnprintf(buf + pos, bufsz - pos, |
242 | "seq_num\t\ttxq_id"); | 257 | "seq_num\t\ttxq_id"); |
243 | #ifdef CONFIG_IWL4965_HT | ||
244 | pos += scnprintf(buf + pos, bufsz - pos, | 258 | pos += scnprintf(buf + pos, bufsz - pos, |
245 | "\tframe_count\twait_for_ba\t"); | 259 | "\tframe_count\twait_for_ba\t"); |
246 | pos += scnprintf(buf + pos, bufsz - pos, | 260 | pos += scnprintf(buf + pos, bufsz - pos, |
247 | "start_idx\tbitmap0\t"); | 261 | "start_idx\tbitmap0\t"); |
248 | pos += scnprintf(buf + pos, bufsz - pos, | 262 | pos += scnprintf(buf + pos, bufsz - pos, |
249 | "bitmap1\trate_n_flags"); | 263 | "bitmap1\trate_n_flags"); |
250 | #endif | ||
251 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | 264 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
252 | 265 | ||
253 | for (j = 0; j < MAX_TID_COUNT; j++) { | 266 | for (j = 0; j < MAX_TID_COUNT; j++) { |
254 | pos += scnprintf(buf + pos, bufsz - pos, | 267 | pos += scnprintf(buf + pos, bufsz - pos, |
255 | "[%d]:\t\t%u", j, | 268 | "[%d]:\t\t%u", j, |
256 | station->tid[j].seq_number); | 269 | station->tid[j].seq_number); |
257 | #ifdef CONFIG_IWL4965_HT | ||
258 | pos += scnprintf(buf + pos, bufsz - pos, | 270 | pos += scnprintf(buf + pos, bufsz - pos, |
259 | "\t%u\t\t%u\t\t%u\t\t", | 271 | "\t%u\t\t%u\t\t%u\t\t", |
260 | station->tid[j].agg.txq_id, | 272 | station->tid[j].agg.txq_id, |
@@ -265,7 +277,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
265 | station->tid[j].agg.start_idx, | 277 | station->tid[j].agg.start_idx, |
266 | (unsigned long long)station->tid[j].agg.bitmap, | 278 | (unsigned long long)station->tid[j].agg.bitmap, |
267 | station->tid[j].agg.rate_n_flags); | 279 | station->tid[j].agg.rate_n_flags); |
268 | #endif | ||
269 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | 280 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
270 | } | 281 | } |
271 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | 282 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
@@ -277,8 +288,70 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
277 | return ret; | 288 | return ret; |
278 | } | 289 | } |
279 | 290 | ||
291 | static ssize_t iwl_dbgfs_eeprom_read(struct file *file, | ||
292 | char __user *user_buf, | ||
293 | size_t count, | ||
294 | loff_t *ppos) | ||
295 | { | ||
296 | ssize_t ret; | ||
297 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
298 | int pos = 0, ofs = 0, buf_size = 0; | ||
299 | const u8 *ptr; | ||
300 | char *buf; | ||
301 | size_t eeprom_len = priv->cfg->eeprom_size; | ||
302 | buf_size = 4 * eeprom_len + 256; | ||
303 | |||
304 | if (eeprom_len % 16) { | ||
305 | IWL_ERROR("EEPROM size is not multiple of 16.\n"); | ||
306 | return -ENODATA; | ||
307 | } | ||
308 | |||
309 | /* 4 characters for byte 0xYY */ | ||
310 | buf = kzalloc(buf_size, GFP_KERNEL); | ||
311 | if (!buf) { | ||
312 | IWL_ERROR("Can not allocate Buffer\n"); | ||
313 | return -ENOMEM; | ||
314 | } | ||
315 | |||
316 | ptr = priv->eeprom; | ||
317 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { | ||
318 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); | ||
319 | hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, | ||
320 | buf_size - pos, 0); | ||
321 | pos += strlen(buf); | ||
322 | if (buf_size - pos > 0) | ||
323 | buf[pos++] = '\n'; | ||
324 | } | ||
325 | |||
326 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
327 | kfree(buf); | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | static ssize_t iwl_dbgfs_log_event_write(struct file *file, | ||
332 | const char __user *user_buf, | ||
333 | size_t count, loff_t *ppos) | ||
334 | { | ||
335 | struct iwl_priv *priv = file->private_data; | ||
336 | u32 event_log_flag; | ||
337 | char buf[8]; | ||
338 | int buf_size; | ||
339 | |||
340 | memset(buf, 0, sizeof(buf)); | ||
341 | buf_size = min(count, sizeof(buf) - 1); | ||
342 | if (copy_from_user(buf, user_buf, buf_size)) | ||
343 | return -EFAULT; | ||
344 | if (sscanf(buf, "%d", &event_log_flag) != 1) | ||
345 | return -EFAULT; | ||
346 | if (event_log_flag == 1) | ||
347 | iwl_dump_nic_event_log(priv); | ||
348 | |||
349 | return count; | ||
350 | } | ||
280 | 351 | ||
281 | DEBUGFS_READ_WRITE_FILE_OPS(sram); | 352 | DEBUGFS_READ_WRITE_FILE_OPS(sram); |
353 | DEBUGFS_WRITE_FILE_OPS(log_event); | ||
354 | DEBUGFS_READ_FILE_OPS(eeprom); | ||
282 | DEBUGFS_READ_FILE_OPS(stations); | 355 | DEBUGFS_READ_FILE_OPS(stations); |
283 | DEBUGFS_READ_FILE_OPS(rx_statistics); | 356 | DEBUGFS_READ_FILE_OPS(rx_statistics); |
284 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 357 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
@@ -290,6 +363,7 @@ DEBUGFS_READ_FILE_OPS(tx_statistics); | |||
290 | int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | 363 | int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) |
291 | { | 364 | { |
292 | struct iwl_debugfs *dbgfs; | 365 | struct iwl_debugfs *dbgfs; |
366 | struct dentry *phyd = priv->hw->wiphy->debugfsdir; | ||
293 | 367 | ||
294 | dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); | 368 | dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); |
295 | if (!dbgfs) { | 369 | if (!dbgfs) { |
@@ -298,17 +372,23 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
298 | 372 | ||
299 | priv->dbgfs = dbgfs; | 373 | priv->dbgfs = dbgfs; |
300 | dbgfs->name = name; | 374 | dbgfs->name = name; |
301 | dbgfs->dir_drv = debugfs_create_dir(name, NULL); | 375 | dbgfs->dir_drv = debugfs_create_dir(name, phyd); |
302 | if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)){ | 376 | if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)){ |
303 | goto err; | 377 | goto err; |
304 | } | 378 | } |
305 | 379 | ||
306 | DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); | 380 | DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); |
381 | DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); | ||
382 | DEBUGFS_ADD_FILE(eeprom, data); | ||
307 | DEBUGFS_ADD_FILE(sram, data); | 383 | DEBUGFS_ADD_FILE(sram, data); |
384 | DEBUGFS_ADD_FILE(log_event, data); | ||
308 | DEBUGFS_ADD_FILE(stations, data); | 385 | DEBUGFS_ADD_FILE(stations, data); |
309 | DEBUGFS_ADD_FILE(rx_statistics, data); | 386 | DEBUGFS_ADD_FILE(rx_statistics, data); |
310 | DEBUGFS_ADD_FILE(tx_statistics, data); | 387 | DEBUGFS_ADD_FILE(tx_statistics, data); |
311 | 388 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); | |
389 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, | ||
390 | &priv->disable_chain_noise_cal); | ||
391 | DEBUGFS_ADD_BOOL(disable_tx_power, rf, &priv->disable_tx_power_cal); | ||
312 | return 0; | 392 | return 0; |
313 | 393 | ||
314 | err: | 394 | err: |
@@ -327,11 +407,17 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
327 | if (!(priv->dbgfs)) | 407 | if (!(priv->dbgfs)) |
328 | return; | 408 | return; |
329 | 409 | ||
410 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom); | ||
330 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); | 411 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); |
331 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); | 412 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); |
332 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); | 413 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); |
414 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); | ||
333 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); | 415 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); |
334 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); | 416 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); |
417 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); | ||
418 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); | ||
419 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power); | ||
420 | DEBUGFS_REMOVE(priv->dbgfs->dir_rf); | ||
335 | DEBUGFS_REMOVE(priv->dbgfs->dir_drv); | 421 | DEBUGFS_REMOVE(priv->dbgfs->dir_drv); |
336 | kfree(priv->dbgfs); | 422 | kfree(priv->dbgfs); |
337 | priv->dbgfs = NULL; | 423 | priv->dbgfs = NULL; |
@@ -339,3 +425,4 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
339 | EXPORT_SYMBOL(iwl_dbgfs_unregister); | 425 | EXPORT_SYMBOL(iwl_dbgfs_unregister); |
340 | 426 | ||
341 | 427 | ||
428 | |||