aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/debug.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c564
1 files changed, 342 insertions, 222 deletions
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index c088744a6bfb..83a2c59f680b 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -104,37 +104,37 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
104 return -ENOMEM; 104 return -ENOMEM;
105 105
106 if (common->disable_ani) { 106 if (common->disable_ani) {
107 len += snprintf(buf + len, size - len, "%s: %s\n", 107 len += scnprintf(buf + len, size - len, "%s: %s\n",
108 "ANI", "DISABLED"); 108 "ANI", "DISABLED");
109 goto exit; 109 goto exit;
110 } 110 }
111 111
112 len += snprintf(buf + len, size - len, "%15s: %s\n", 112 len += scnprintf(buf + len, size - len, "%15s: %s\n",
113 "ANI", "ENABLED"); 113 "ANI", "ENABLED");
114 len += snprintf(buf + len, size - len, "%15s: %u\n", 114 len += scnprintf(buf + len, size - len, "%15s: %u\n",
115 "ANI RESET", ah->stats.ast_ani_reset); 115 "ANI RESET", ah->stats.ast_ani_reset);
116 len += snprintf(buf + len, size - len, "%15s: %u\n", 116 len += scnprintf(buf + len, size - len, "%15s: %u\n",
117 "SPUR UP", ah->stats.ast_ani_spurup); 117 "SPUR UP", ah->stats.ast_ani_spurup);
118 len += snprintf(buf + len, size - len, "%15s: %u\n", 118 len += scnprintf(buf + len, size - len, "%15s: %u\n",
119 "SPUR DOWN", ah->stats.ast_ani_spurup); 119 "SPUR DOWN", ah->stats.ast_ani_spurup);
120 len += snprintf(buf + len, size - len, "%15s: %u\n", 120 len += scnprintf(buf + len, size - len, "%15s: %u\n",
121 "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon); 121 "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
122 len += snprintf(buf + len, size - len, "%15s: %u\n", 122 len += scnprintf(buf + len, size - len, "%15s: %u\n",
123 "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff); 123 "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
124 len += snprintf(buf + len, size - len, "%15s: %u\n", 124 len += scnprintf(buf + len, size - len, "%15s: %u\n",
125 "MRC-CCK ON", ah->stats.ast_ani_ccklow); 125 "MRC-CCK ON", ah->stats.ast_ani_ccklow);
126 len += snprintf(buf + len, size - len, "%15s: %u\n", 126 len += scnprintf(buf + len, size - len, "%15s: %u\n",
127 "MRC-CCK OFF", ah->stats.ast_ani_cckhigh); 127 "MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
128 len += snprintf(buf + len, size - len, "%15s: %u\n", 128 len += scnprintf(buf + len, size - len, "%15s: %u\n",
129 "FIR-STEP UP", ah->stats.ast_ani_stepup); 129 "FIR-STEP UP", ah->stats.ast_ani_stepup);
130 len += snprintf(buf + len, size - len, "%15s: %u\n", 130 len += scnprintf(buf + len, size - len, "%15s: %u\n",
131 "FIR-STEP DOWN", ah->stats.ast_ani_stepdown); 131 "FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
132 len += snprintf(buf + len, size - len, "%15s: %u\n", 132 len += scnprintf(buf + len, size - len, "%15s: %u\n",
133 "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero); 133 "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
134 len += snprintf(buf + len, size - len, "%15s: %u\n", 134 len += scnprintf(buf + len, size - len, "%15s: %u\n",
135 "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs); 135 "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
136 len += snprintf(buf + len, size - len, "%15s: %u\n", 136 len += scnprintf(buf + len, size - len, "%15s: %u\n",
137 "CCK ERRORS", ah->stats.ast_ani_cckerrs); 137 "CCK ERRORS", ah->stats.ast_ani_cckerrs);
138exit: 138exit:
139 if (len > size) 139 if (len > size)
140 len = size; 140 len = size;
@@ -280,70 +280,70 @@ static ssize_t read_file_antenna_diversity(struct file *file,
280 return -ENOMEM; 280 return -ENOMEM;
281 281
282 if (!(pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)) { 282 if (!(pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)) {
283 len += snprintf(buf + len, size - len, "%s\n", 283 len += scnprintf(buf + len, size - len, "%s\n",
284 "Antenna Diversity Combining is disabled"); 284 "Antenna Diversity Combining is disabled");
285 goto exit; 285 goto exit;
286 } 286 }
287 287
288 ath9k_ps_wakeup(sc); 288 ath9k_ps_wakeup(sc);
289 ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); 289 ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf);
290 len += snprintf(buf + len, size - len, "Current MAIN config : %s\n", 290 len += scnprintf(buf + len, size - len, "Current MAIN config : %s\n",
291 lna_conf_str[div_ant_conf.main_lna_conf]); 291 lna_conf_str[div_ant_conf.main_lna_conf]);
292 len += snprintf(buf + len, size - len, "Current ALT config : %s\n", 292 len += scnprintf(buf + len, size - len, "Current ALT config : %s\n",
293 lna_conf_str[div_ant_conf.alt_lna_conf]); 293 lna_conf_str[div_ant_conf.alt_lna_conf]);
294 len += snprintf(buf + len, size - len, "Average MAIN RSSI : %d\n", 294 len += scnprintf(buf + len, size - len, "Average MAIN RSSI : %d\n",
295 as_main->rssi_avg); 295 as_main->rssi_avg);
296 len += snprintf(buf + len, size - len, "Average ALT RSSI : %d\n\n", 296 len += scnprintf(buf + len, size - len, "Average ALT RSSI : %d\n\n",
297 as_alt->rssi_avg); 297 as_alt->rssi_avg);
298 ath9k_ps_restore(sc); 298 ath9k_ps_restore(sc);
299 299
300 len += snprintf(buf + len, size - len, "Packet Receive Cnt:\n"); 300 len += scnprintf(buf + len, size - len, "Packet Receive Cnt:\n");
301 len += snprintf(buf + len, size - len, "-------------------\n"); 301 len += scnprintf(buf + len, size - len, "-------------------\n");
302 302
303 len += snprintf(buf + len, size - len, "%30s%15s\n", 303 len += scnprintf(buf + len, size - len, "%30s%15s\n",
304 "MAIN", "ALT"); 304 "MAIN", "ALT");
305 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 305 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
306 "TOTAL COUNT", 306 "TOTAL COUNT",
307 as_main->recv_cnt, 307 as_main->recv_cnt,
308 as_alt->recv_cnt); 308 as_alt->recv_cnt);
309 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 309 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
310 "LNA1", 310 "LNA1",
311 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1], 311 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1],
312 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]); 312 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]);
313 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 313 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
314 "LNA2", 314 "LNA2",
315 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2], 315 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2],
316 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]); 316 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]);
317 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 317 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
318 "LNA1 + LNA2", 318 "LNA1 + LNA2",
319 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2], 319 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
320 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]); 320 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
321 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 321 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
322 "LNA1 - LNA2", 322 "LNA1 - LNA2",
323 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2], 323 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
324 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]); 324 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
325 325
326 len += snprintf(buf + len, size - len, "\nLNA Config Attempts:\n"); 326 len += scnprintf(buf + len, size - len, "\nLNA Config Attempts:\n");
327 len += snprintf(buf + len, size - len, "--------------------\n"); 327 len += scnprintf(buf + len, size - len, "--------------------\n");
328 328
329 len += snprintf(buf + len, size - len, "%30s%15s\n", 329 len += scnprintf(buf + len, size - len, "%30s%15s\n",
330 "MAIN", "ALT"); 330 "MAIN", "ALT");
331 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 331 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
332 "LNA1", 332 "LNA1",
333 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1], 333 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1],
334 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]); 334 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]);
335 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 335 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
336 "LNA2", 336 "LNA2",
337 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2], 337 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2],
338 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]); 338 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]);
339 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 339 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
340 "LNA1 + LNA2", 340 "LNA1 + LNA2",
341 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2], 341 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
342 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]); 342 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
343 len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", 343 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
344 "LNA1 - LNA2", 344 "LNA1 - LNA2",
345 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2], 345 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
346 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]); 346 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
347 347
348exit: 348exit:
349 if (len > size) 349 if (len > size)
@@ -385,21 +385,21 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
385 (AR_MACMISC_MISC_OBS_BUS_1 << 385 (AR_MACMISC_MISC_OBS_BUS_1 <<
386 AR_MACMISC_MISC_OBS_BUS_MSB_S))); 386 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
387 387
388 len += snprintf(buf + len, DMA_BUF_LEN - len, 388 len += scnprintf(buf + len, DMA_BUF_LEN - len,
389 "Raw DMA Debug values:\n"); 389 "Raw DMA Debug values:\n");
390 390
391 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { 391 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
392 if (i % 4 == 0) 392 if (i % 4 == 0)
393 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n"); 393 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n");
394 394
395 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32))); 395 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32)));
396 len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ", 396 len += scnprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ",
397 i, val[i]); 397 i, val[i]);
398 } 398 }
399 399
400 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n"); 400 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n\n");
401 len += snprintf(buf + len, DMA_BUF_LEN - len, 401 len += scnprintf(buf + len, DMA_BUF_LEN - len,
402 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); 402 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
403 403
404 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { 404 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
405 if (i == 8) { 405 if (i == 8) {
@@ -412,39 +412,39 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
412 dcuBase++; 412 dcuBase++;
413 } 413 }
414 414
415 len += snprintf(buf + len, DMA_BUF_LEN - len, 415 len += scnprintf(buf + len, DMA_BUF_LEN - len,
416 "%2d %2x %1x %2x %2x\n", 416 "%2d %2x %1x %2x %2x\n",
417 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, 417 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
418 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), 418 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
419 val[2] & (0x7 << (i * 3)) >> (i * 3), 419 val[2] & (0x7 << (i * 3)) >> (i * 3),
420 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); 420 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
421 } 421 }
422 422
423 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n"); 423 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n");
424 424
425 len += snprintf(buf + len, DMA_BUF_LEN - len, 425 len += scnprintf(buf + len, DMA_BUF_LEN - len,
426 "qcu_stitch state: %2x qcu_fetch state: %2x\n", 426 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
427 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); 427 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
428 len += snprintf(buf + len, DMA_BUF_LEN - len, 428 len += scnprintf(buf + len, DMA_BUF_LEN - len,
429 "qcu_complete state: %2x dcu_complete state: %2x\n", 429 "qcu_complete state: %2x dcu_complete state: %2x\n",
430 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); 430 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
431 len += snprintf(buf + len, DMA_BUF_LEN - len, 431 len += scnprintf(buf + len, DMA_BUF_LEN - len,
432 "dcu_arb state: %2x dcu_fp state: %2x\n", 432 "dcu_arb state: %2x dcu_fp state: %2x\n",
433 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); 433 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
434 len += snprintf(buf + len, DMA_BUF_LEN - len, 434 len += scnprintf(buf + len, DMA_BUF_LEN - len,
435 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", 435 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
436 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); 436 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
437 len += snprintf(buf + len, DMA_BUF_LEN - len, 437 len += scnprintf(buf + len, DMA_BUF_LEN - len,
438 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", 438 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
439 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); 439 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
440 len += snprintf(buf + len, DMA_BUF_LEN - len, 440 len += scnprintf(buf + len, DMA_BUF_LEN - len,
441 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", 441 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
442 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); 442 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
443 443
444 len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n", 444 len += scnprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n",
445 REG_READ_D(ah, AR_OBS_BUS_1)); 445 REG_READ_D(ah, AR_OBS_BUS_1));
446 len += snprintf(buf + len, DMA_BUF_LEN - len, 446 len += scnprintf(buf + len, DMA_BUF_LEN - len,
447 "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR)); 447 "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR));
448 448
449 ath9k_ps_restore(sc); 449 ath9k_ps_restore(sc);
450 450
@@ -530,9 +530,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
530 530
531#define PR_IS(a, s) \ 531#define PR_IS(a, s) \
532 do { \ 532 do { \
533 len += snprintf(buf + len, mxlen - len, \ 533 len += scnprintf(buf + len, mxlen - len, \
534 "%21s: %10u\n", a, \ 534 "%21s: %10u\n", a, \
535 sc->debug.stats.istats.s); \ 535 sc->debug.stats.istats.s); \
536 } while (0) 536 } while (0)
537 537
538 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 538 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
@@ -563,8 +563,8 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
563 PR_IS("GENTIMER", gen_timer); 563 PR_IS("GENTIMER", gen_timer);
564 PR_IS("TOTAL", total); 564 PR_IS("TOTAL", total);
565 565
566 len += snprintf(buf + len, mxlen - len, 566 len += scnprintf(buf + len, mxlen - len,
567 "SYNC_CAUSE stats:\n"); 567 "SYNC_CAUSE stats:\n");
568 568
569 PR_IS("Sync-All", sync_cause_all); 569 PR_IS("Sync-All", sync_cause_all);
570 PR_IS("RTC-IRQ", sync_rtc_irq); 570 PR_IS("RTC-IRQ", sync_rtc_irq);
@@ -655,16 +655,16 @@ static ssize_t print_queue(struct ath_softc *sc, struct ath_txq *txq,
655 655
656 ath_txq_lock(sc, txq); 656 ath_txq_lock(sc, txq);
657 657
658 len += snprintf(buf + len, size - len, "%s: %d ", 658 len += scnprintf(buf + len, size - len, "%s: %d ",
659 "qnum", txq->axq_qnum); 659 "qnum", txq->axq_qnum);
660 len += snprintf(buf + len, size - len, "%s: %2d ", 660 len += scnprintf(buf + len, size - len, "%s: %2d ",
661 "qdepth", txq->axq_depth); 661 "qdepth", txq->axq_depth);
662 len += snprintf(buf + len, size - len, "%s: %2d ", 662 len += scnprintf(buf + len, size - len, "%s: %2d ",
663 "ampdu-depth", txq->axq_ampdu_depth); 663 "ampdu-depth", txq->axq_ampdu_depth);
664 len += snprintf(buf + len, size - len, "%s: %3d ", 664 len += scnprintf(buf + len, size - len, "%s: %3d ",
665 "pending", txq->pending_frames); 665 "pending", txq->pending_frames);
666 len += snprintf(buf + len, size - len, "%s: %d\n", 666 len += scnprintf(buf + len, size - len, "%s: %d\n",
667 "stopped", txq->stopped); 667 "stopped", txq->stopped);
668 668
669 ath_txq_unlock(sc, txq); 669 ath_txq_unlock(sc, txq);
670 return len; 670 return len;
@@ -687,11 +687,11 @@ static ssize_t read_file_queues(struct file *file, char __user *user_buf,
687 687
688 for (i = 0; i < IEEE80211_NUM_ACS; i++) { 688 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
689 txq = sc->tx.txq_map[i]; 689 txq = sc->tx.txq_map[i];
690 len += snprintf(buf + len, size - len, "(%s): ", qname[i]); 690 len += scnprintf(buf + len, size - len, "(%s): ", qname[i]);
691 len += print_queue(sc, txq, buf + len, size - len); 691 len += print_queue(sc, txq, buf + len, size - len);
692 } 692 }
693 693
694 len += snprintf(buf + len, size - len, "(CAB): "); 694 len += scnprintf(buf + len, size - len, "(CAB): ");
695 len += print_queue(sc, sc->beacon.cabq, buf + len, size - len); 695 len += print_queue(sc, sc->beacon.cabq, buf + len, size - len);
696 696
697 if (len > size) 697 if (len > size)
@@ -716,80 +716,82 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
716 unsigned int reg; 716 unsigned int reg;
717 u32 rxfilter; 717 u32 rxfilter;
718 718
719 len += snprintf(buf + len, sizeof(buf) - len, 719 len += scnprintf(buf + len, sizeof(buf) - len,
720 "BSSID: %pM\n", common->curbssid); 720 "BSSID: %pM\n", common->curbssid);
721 len += snprintf(buf + len, sizeof(buf) - len, 721 len += scnprintf(buf + len, sizeof(buf) - len,
722 "BSSID-MASK: %pM\n", common->bssidmask); 722 "BSSID-MASK: %pM\n", common->bssidmask);
723 len += snprintf(buf + len, sizeof(buf) - len, 723 len += scnprintf(buf + len, sizeof(buf) - len,
724 "OPMODE: %s\n", ath_opmode_to_string(sc->sc_ah->opmode)); 724 "OPMODE: %s\n",
725 ath_opmode_to_string(sc->sc_ah->opmode));
725 726
726 ath9k_ps_wakeup(sc); 727 ath9k_ps_wakeup(sc);
727 rxfilter = ath9k_hw_getrxfilter(sc->sc_ah); 728 rxfilter = ath9k_hw_getrxfilter(sc->sc_ah);
728 ath9k_ps_restore(sc); 729 ath9k_ps_restore(sc);
729 730
730 len += snprintf(buf + len, sizeof(buf) - len, 731 len += scnprintf(buf + len, sizeof(buf) - len,
731 "RXFILTER: 0x%x", rxfilter); 732 "RXFILTER: 0x%x", rxfilter);
732 733
733 if (rxfilter & ATH9K_RX_FILTER_UCAST) 734 if (rxfilter & ATH9K_RX_FILTER_UCAST)
734 len += snprintf(buf + len, sizeof(buf) - len, " UCAST"); 735 len += scnprintf(buf + len, sizeof(buf) - len, " UCAST");
735 if (rxfilter & ATH9K_RX_FILTER_MCAST) 736 if (rxfilter & ATH9K_RX_FILTER_MCAST)
736 len += snprintf(buf + len, sizeof(buf) - len, " MCAST"); 737 len += scnprintf(buf + len, sizeof(buf) - len, " MCAST");
737 if (rxfilter & ATH9K_RX_FILTER_BCAST) 738 if (rxfilter & ATH9K_RX_FILTER_BCAST)
738 len += snprintf(buf + len, sizeof(buf) - len, " BCAST"); 739 len += scnprintf(buf + len, sizeof(buf) - len, " BCAST");
739 if (rxfilter & ATH9K_RX_FILTER_CONTROL) 740 if (rxfilter & ATH9K_RX_FILTER_CONTROL)
740 len += snprintf(buf + len, sizeof(buf) - len, " CONTROL"); 741 len += scnprintf(buf + len, sizeof(buf) - len, " CONTROL");
741 if (rxfilter & ATH9K_RX_FILTER_BEACON) 742 if (rxfilter & ATH9K_RX_FILTER_BEACON)
742 len += snprintf(buf + len, sizeof(buf) - len, " BEACON"); 743 len += scnprintf(buf + len, sizeof(buf) - len, " BEACON");
743 if (rxfilter & ATH9K_RX_FILTER_PROM) 744 if (rxfilter & ATH9K_RX_FILTER_PROM)
744 len += snprintf(buf + len, sizeof(buf) - len, " PROM"); 745 len += scnprintf(buf + len, sizeof(buf) - len, " PROM");
745 if (rxfilter & ATH9K_RX_FILTER_PROBEREQ) 746 if (rxfilter & ATH9K_RX_FILTER_PROBEREQ)
746 len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); 747 len += scnprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
747 if (rxfilter & ATH9K_RX_FILTER_PHYERR) 748 if (rxfilter & ATH9K_RX_FILTER_PHYERR)
748 len += snprintf(buf + len, sizeof(buf) - len, " PHYERR"); 749 len += scnprintf(buf + len, sizeof(buf) - len, " PHYERR");
749 if (rxfilter & ATH9K_RX_FILTER_MYBEACON) 750 if (rxfilter & ATH9K_RX_FILTER_MYBEACON)
750 len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON"); 751 len += scnprintf(buf + len, sizeof(buf) - len, " MYBEACON");
751 if (rxfilter & ATH9K_RX_FILTER_COMP_BAR) 752 if (rxfilter & ATH9K_RX_FILTER_COMP_BAR)
752 len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR"); 753 len += scnprintf(buf + len, sizeof(buf) - len, " COMP_BAR");
753 if (rxfilter & ATH9K_RX_FILTER_PSPOLL) 754 if (rxfilter & ATH9K_RX_FILTER_PSPOLL)
754 len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL"); 755 len += scnprintf(buf + len, sizeof(buf) - len, " PSPOLL");
755 if (rxfilter & ATH9K_RX_FILTER_PHYRADAR) 756 if (rxfilter & ATH9K_RX_FILTER_PHYRADAR)
756 len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); 757 len += scnprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
757 if (rxfilter & ATH9K_RX_FILTER_MCAST_BCAST_ALL) 758 if (rxfilter & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
758 len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL"); 759 len += scnprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
759 if (rxfilter & ATH9K_RX_FILTER_CONTROL_WRAPPER) 760 if (rxfilter & ATH9K_RX_FILTER_CONTROL_WRAPPER)
760 len += snprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER"); 761 len += scnprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER");
761 762
762 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 763 len += scnprintf(buf + len, sizeof(buf) - len, "\n");
763 764
764 reg = sc->sc_ah->imask; 765 reg = sc->sc_ah->imask;
765 766
766 len += snprintf(buf + len, sizeof(buf) - len, "INTERRUPT-MASK: 0x%x", reg); 767 len += scnprintf(buf + len, sizeof(buf) - len,
768 "INTERRUPT-MASK: 0x%x", reg);
767 769
768 if (reg & ATH9K_INT_SWBA) 770 if (reg & ATH9K_INT_SWBA)
769 len += snprintf(buf + len, sizeof(buf) - len, " SWBA"); 771 len += scnprintf(buf + len, sizeof(buf) - len, " SWBA");
770 if (reg & ATH9K_INT_BMISS) 772 if (reg & ATH9K_INT_BMISS)
771 len += snprintf(buf + len, sizeof(buf) - len, " BMISS"); 773 len += scnprintf(buf + len, sizeof(buf) - len, " BMISS");
772 if (reg & ATH9K_INT_CST) 774 if (reg & ATH9K_INT_CST)
773 len += snprintf(buf + len, sizeof(buf) - len, " CST"); 775 len += scnprintf(buf + len, sizeof(buf) - len, " CST");
774 if (reg & ATH9K_INT_RX) 776 if (reg & ATH9K_INT_RX)
775 len += snprintf(buf + len, sizeof(buf) - len, " RX"); 777 len += scnprintf(buf + len, sizeof(buf) - len, " RX");
776 if (reg & ATH9K_INT_RXHP) 778 if (reg & ATH9K_INT_RXHP)
777 len += snprintf(buf + len, sizeof(buf) - len, " RXHP"); 779 len += scnprintf(buf + len, sizeof(buf) - len, " RXHP");
778 if (reg & ATH9K_INT_RXLP) 780 if (reg & ATH9K_INT_RXLP)
779 len += snprintf(buf + len, sizeof(buf) - len, " RXLP"); 781 len += scnprintf(buf + len, sizeof(buf) - len, " RXLP");
780 if (reg & ATH9K_INT_BB_WATCHDOG) 782 if (reg & ATH9K_INT_BB_WATCHDOG)
781 len += snprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG"); 783 len += scnprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG");
782 784
783 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 785 len += scnprintf(buf + len, sizeof(buf) - len, "\n");
784 786
785 ath9k_calculate_iter_data(hw, NULL, &iter_data); 787 ath9k_calculate_iter_data(hw, NULL, &iter_data);
786 788
787 len += snprintf(buf + len, sizeof(buf) - len, 789 len += scnprintf(buf + len, sizeof(buf) - len,
788 "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" 790 "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i"
789 " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", 791 " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
790 iter_data.naps, iter_data.nstations, iter_data.nmeshes, 792 iter_data.naps, iter_data.nstations, iter_data.nmeshes,
791 iter_data.nwds, iter_data.nadhocs, 793 iter_data.nwds, iter_data.nadhocs,
792 sc->nvifs, sc->nbcnvifs); 794 sc->nvifs, sc->nbcnvifs);
793 795
794 if (len > sizeof(buf)) 796 if (len > sizeof(buf))
795 len = sizeof(buf); 797 len = sizeof(buf);
@@ -805,27 +807,27 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf,
805 char buf[512]; 807 char buf[512];
806 unsigned int len = 0; 808 unsigned int len = 0;
807 809
808 len += snprintf(buf + len, sizeof(buf) - len, 810 len += scnprintf(buf + len, sizeof(buf) - len,
809 "%17s: %2d\n", "Baseband Hang", 811 "%17s: %2d\n", "Baseband Hang",
810 sc->debug.stats.reset[RESET_TYPE_BB_HANG]); 812 sc->debug.stats.reset[RESET_TYPE_BB_HANG]);
811 len += snprintf(buf + len, sizeof(buf) - len, 813 len += scnprintf(buf + len, sizeof(buf) - len,
812 "%17s: %2d\n", "Baseband Watchdog", 814 "%17s: %2d\n", "Baseband Watchdog",
813 sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]); 815 sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]);
814 len += snprintf(buf + len, sizeof(buf) - len, 816 len += scnprintf(buf + len, sizeof(buf) - len,
815 "%17s: %2d\n", "Fatal HW Error", 817 "%17s: %2d\n", "Fatal HW Error",
816 sc->debug.stats.reset[RESET_TYPE_FATAL_INT]); 818 sc->debug.stats.reset[RESET_TYPE_FATAL_INT]);
817 len += snprintf(buf + len, sizeof(buf) - len, 819 len += scnprintf(buf + len, sizeof(buf) - len,
818 "%17s: %2d\n", "TX HW error", 820 "%17s: %2d\n", "TX HW error",
819 sc->debug.stats.reset[RESET_TYPE_TX_ERROR]); 821 sc->debug.stats.reset[RESET_TYPE_TX_ERROR]);
820 len += snprintf(buf + len, sizeof(buf) - len, 822 len += scnprintf(buf + len, sizeof(buf) - len,
821 "%17s: %2d\n", "TX Path Hang", 823 "%17s: %2d\n", "TX Path Hang",
822 sc->debug.stats.reset[RESET_TYPE_TX_HANG]); 824 sc->debug.stats.reset[RESET_TYPE_TX_HANG]);
823 len += snprintf(buf + len, sizeof(buf) - len, 825 len += scnprintf(buf + len, sizeof(buf) - len,
824 "%17s: %2d\n", "PLL RX Hang", 826 "%17s: %2d\n", "PLL RX Hang",
825 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); 827 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
826 len += snprintf(buf + len, sizeof(buf) - len, 828 len += scnprintf(buf + len, sizeof(buf) - len,
827 "%17s: %2d\n", "MCI Reset", 829 "%17s: %2d\n", "MCI Reset",
828 sc->debug.stats.reset[RESET_TYPE_MCI]); 830 sc->debug.stats.reset[RESET_TYPE_MCI]);
829 831
830 if (len > sizeof(buf)) 832 if (len > sizeof(buf))
831 len = sizeof(buf); 833 len = sizeof(buf);
@@ -902,14 +904,14 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
902 size_t count, loff_t *ppos) 904 size_t count, loff_t *ppos)
903{ 905{
904#define PHY_ERR(s, p) \ 906#define PHY_ERR(s, p) \
905 len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \ 907 len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
906 sc->debug.stats.rxstats.phy_err_stats[p]); 908 sc->debug.stats.rxstats.phy_err_stats[p]);
907 909
908#define RXS_ERR(s, e) \ 910#define RXS_ERR(s, e) \
909 do { \ 911 do { \
910 len += snprintf(buf + len, size - len, \ 912 len += scnprintf(buf + len, size - len, \
911 "%22s : %10u\n", s, \ 913 "%22s : %10u\n", s, \
912 sc->debug.stats.rxstats.e); \ 914 sc->debug.stats.rxstats.e);\
913 } while (0) 915 } while (0)
914 916
915 struct ath_softc *sc = file->private_data; 917 struct ath_softc *sc = file->private_data;
@@ -1048,6 +1050,9 @@ static ssize_t write_file_spec_scan_ctl(struct file *file,
1048 char buf[32]; 1050 char buf[32];
1049 ssize_t len; 1051 ssize_t len;
1050 1052
1053 if (config_enabled(CONFIG_ATH9K_TX99))
1054 return -EOPNOTSUPP;
1055
1051 len = min(count, sizeof(buf) - 1); 1056 len = min(count, sizeof(buf) - 1);
1052 if (copy_from_user(buf, user_buf, len)) 1057 if (copy_from_user(buf, user_buf, len))
1053 return -EFAULT; 1058 return -EFAULT;
@@ -1439,22 +1444,22 @@ static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf,
1439 if (!buf) 1444 if (!buf)
1440 return -ENOMEM; 1445 return -ENOMEM;
1441 1446
1442 len += snprintf(buf + len, size - len, 1447 len += scnprintf(buf + len, size - len,
1443 "Channel Noise Floor : %d\n", ah->noise); 1448 "Channel Noise Floor : %d\n", ah->noise);
1444 len += snprintf(buf + len, size - len, 1449 len += scnprintf(buf + len, size - len,
1445 "Chain | privNF | # Readings | NF Readings\n"); 1450 "Chain | privNF | # Readings | NF Readings\n");
1446 for (i = 0; i < NUM_NF_READINGS; i++) { 1451 for (i = 0; i < NUM_NF_READINGS; i++) {
1447 if (!(chainmask & (1 << i)) || 1452 if (!(chainmask & (1 << i)) ||
1448 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) 1453 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
1449 continue; 1454 continue;
1450 1455
1451 nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - h[i].invalidNFcount; 1456 nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - h[i].invalidNFcount;
1452 len += snprintf(buf + len, size - len, " %d\t %d\t %d\t\t", 1457 len += scnprintf(buf + len, size - len, " %d\t %d\t %d\t\t",
1453 i, h[i].privNF, nread); 1458 i, h[i].privNF, nread);
1454 for (j = 0; j < nread; j++) 1459 for (j = 0; j < nread; j++)
1455 len += snprintf(buf + len, size - len, 1460 len += scnprintf(buf + len, size - len,
1456 " %d", h[i].nfCalBuffer[j]); 1461 " %d", h[i].nfCalBuffer[j]);
1457 len += snprintf(buf + len, size - len, "\n"); 1462 len += scnprintf(buf + len, size - len, "\n");
1458 } 1463 }
1459 1464
1460 if (len > size) 1465 if (len > size)
@@ -1543,8 +1548,8 @@ static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
1543 return -ENOMEM; 1548 return -ENOMEM;
1544 1549
1545 if (!sc->sc_ah->common.btcoex_enabled) { 1550 if (!sc->sc_ah->common.btcoex_enabled) {
1546 len = snprintf(buf, size, "%s\n", 1551 len = scnprintf(buf, size, "%s\n",
1547 "BTCOEX is disabled"); 1552 "BTCOEX is disabled");
1548 goto exit; 1553 goto exit;
1549 } 1554 }
1550 1555
@@ -1582,43 +1587,43 @@ static ssize_t read_file_node_stat(struct file *file, char __user *user_buf,
1582 return -ENOMEM; 1587 return -ENOMEM;
1583 1588
1584 if (!an->sta->ht_cap.ht_supported) { 1589 if (!an->sta->ht_cap.ht_supported) {
1585 len = snprintf(buf, size, "%s\n", 1590 len = scnprintf(buf, size, "%s\n",
1586 "HT not supported"); 1591 "HT not supported");
1587 goto exit; 1592 goto exit;
1588 } 1593 }
1589 1594
1590 len = snprintf(buf, size, "Max-AMPDU: %d\n", 1595 len = scnprintf(buf, size, "Max-AMPDU: %d\n",
1591 an->maxampdu); 1596 an->maxampdu);
1592 len += snprintf(buf + len, size - len, "MPDU Density: %d\n\n", 1597 len += scnprintf(buf + len, size - len, "MPDU Density: %d\n\n",
1593 an->mpdudensity); 1598 an->mpdudensity);
1594 1599
1595 len += snprintf(buf + len, size - len, 1600 len += scnprintf(buf + len, size - len,
1596 "%2s%7s\n", "AC", "SCHED"); 1601 "%2s%7s\n", "AC", "SCHED");
1597 1602
1598 for (acno = 0, ac = &an->ac[acno]; 1603 for (acno = 0, ac = &an->ac[acno];
1599 acno < IEEE80211_NUM_ACS; acno++, ac++) { 1604 acno < IEEE80211_NUM_ACS; acno++, ac++) {
1600 txq = ac->txq; 1605 txq = ac->txq;
1601 ath_txq_lock(sc, txq); 1606 ath_txq_lock(sc, txq);
1602 len += snprintf(buf + len, size - len, 1607 len += scnprintf(buf + len, size - len,
1603 "%2d%7d\n", 1608 "%2d%7d\n",
1604 acno, ac->sched); 1609 acno, ac->sched);
1605 ath_txq_unlock(sc, txq); 1610 ath_txq_unlock(sc, txq);
1606 } 1611 }
1607 1612
1608 len += snprintf(buf + len, size - len, 1613 len += scnprintf(buf + len, size - len,
1609 "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n", 1614 "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n",
1610 "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", 1615 "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
1611 "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); 1616 "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
1612 1617
1613 for (tidno = 0, tid = &an->tid[tidno]; 1618 for (tidno = 0, tid = &an->tid[tidno];
1614 tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { 1619 tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
1615 txq = tid->ac->txq; 1620 txq = tid->ac->txq;
1616 ath_txq_lock(sc, txq); 1621 ath_txq_lock(sc, txq);
1617 len += snprintf(buf + len, size - len, 1622 len += scnprintf(buf + len, size - len,
1618 "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n", 1623 "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n",
1619 tid->tidno, tid->seq_start, tid->seq_next, 1624 tid->tidno, tid->seq_start, tid->seq_next,
1620 tid->baw_size, tid->baw_head, tid->baw_tail, 1625 tid->baw_size, tid->baw_head, tid->baw_tail,
1621 tid->bar_index, tid->sched, tid->paused); 1626 tid->bar_index, tid->sched, tid->paused);
1622 ath_txq_unlock(sc, txq); 1627 ath_txq_unlock(sc, txq);
1623 } 1628 }
1624exit: 1629exit:
@@ -1773,6 +1778,111 @@ void ath9k_deinit_debug(struct ath_softc *sc)
1773 } 1778 }
1774} 1779}
1775 1780
1781static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
1782 size_t count, loff_t *ppos)
1783{
1784 struct ath_softc *sc = file->private_data;
1785 char buf[3];
1786 unsigned int len;
1787
1788 len = sprintf(buf, "%d\n", sc->tx99_state);
1789 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1790}
1791
1792static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
1793 size_t count, loff_t *ppos)
1794{
1795 struct ath_softc *sc = file->private_data;
1796 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1797 char buf[32];
1798 bool start;
1799 ssize_t len;
1800 int r;
1801
1802 if (sc->nvifs > 1)
1803 return -EOPNOTSUPP;
1804
1805 len = min(count, sizeof(buf) - 1);
1806 if (copy_from_user(buf, user_buf, len))
1807 return -EFAULT;
1808
1809 if (strtobool(buf, &start))
1810 return -EINVAL;
1811
1812 if (start == sc->tx99_state) {
1813 if (!start)
1814 return count;
1815 ath_dbg(common, XMIT, "Resetting TX99\n");
1816 ath9k_tx99_deinit(sc);
1817 }
1818
1819 if (!start) {
1820 ath9k_tx99_deinit(sc);
1821 return count;
1822 }
1823
1824 r = ath9k_tx99_init(sc);
1825 if (r)
1826 return r;
1827
1828 return count;
1829}
1830
1831static const struct file_operations fops_tx99 = {
1832 .read = read_file_tx99,
1833 .write = write_file_tx99,
1834 .open = simple_open,
1835 .owner = THIS_MODULE,
1836 .llseek = default_llseek,
1837};
1838
1839static ssize_t read_file_tx99_power(struct file *file,
1840 char __user *user_buf,
1841 size_t count, loff_t *ppos)
1842{
1843 struct ath_softc *sc = file->private_data;
1844 char buf[32];
1845 unsigned int len;
1846
1847 len = sprintf(buf, "%d (%d dBm)\n",
1848 sc->tx99_power,
1849 sc->tx99_power / 2);
1850
1851 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1852}
1853
1854static ssize_t write_file_tx99_power(struct file *file,
1855 const char __user *user_buf,
1856 size_t count, loff_t *ppos)
1857{
1858 struct ath_softc *sc = file->private_data;
1859 int r;
1860 u8 tx_power;
1861
1862 r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
1863 if (r)
1864 return r;
1865
1866 if (tx_power > MAX_RATE_POWER)
1867 return -EINVAL;
1868
1869 sc->tx99_power = tx_power;
1870
1871 ath9k_ps_wakeup(sc);
1872 ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
1873 ath9k_ps_restore(sc);
1874
1875 return count;
1876}
1877
1878static const struct file_operations fops_tx99_power = {
1879 .read = read_file_tx99_power,
1880 .write = write_file_tx99_power,
1881 .open = simple_open,
1882 .owner = THIS_MODULE,
1883 .llseek = default_llseek,
1884};
1885
1776int ath9k_init_debug(struct ath_hw *ah) 1886int ath9k_init_debug(struct ath_hw *ah)
1777{ 1887{
1778 struct ath_common *common = ath9k_hw_common(ah); 1888 struct ath_common *common = ath9k_hw_common(ah);
@@ -1864,5 +1974,15 @@ int ath9k_init_debug(struct ath_hw *ah)
1864 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, 1974 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc,
1865 &fops_btcoex); 1975 &fops_btcoex);
1866#endif 1976#endif
1977 if (config_enabled(CONFIG_ATH9K_TX99) &&
1978 AR_SREV_9300_20_OR_LATER(ah)) {
1979 debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
1980 sc->debug.debugfs_phy, sc,
1981 &fops_tx99);
1982 debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
1983 sc->debug.debugfs_phy, sc,
1984 &fops_tx99_power);
1985 }
1986
1867 return 0; 1987 return 0;
1868} 1988}