440-ath5k_channel_bw_debugfs.patch 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. This adds a bwmode debugfs file which can be used to set alternate
  2. channel operating bandwidths. Only tested with AR5413 and only at
  3. 5 and 20 mhz channels.
  4. Signed-off-by: Pat Erley <pat-lkml at erley.org>
  5. ---
  6. Other devices will need to be added to the switch in write_file_bwmode
  7. drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
  8. 1 files changed, 86 insertions(+), 0 deletions(-)
  9. Index: backports-v4.18-rc7/drivers/net/wireless/ath/ath5k/debug.c
  10. ===================================================================
  11. --- backports-v4.18-rc7.orig/drivers/net/wireless/ath/ath5k/debug.c
  12. +++ backports-v4.18-rc7/drivers/net/wireless/ath/ath5k/debug.c
  13. @@ -822,6 +822,97 @@ static const struct file_operations fops
  14. .llseek = default_llseek,
  15. };
  16. +/* debugfs: bwmode */
  17. +
  18. +static ssize_t read_file_bwmode(struct file *file, char __user *user_buf,
  19. + size_t count, loff_t *ppos)
  20. +{
  21. + struct ath5k_hw *ah = file->private_data;
  22. + char buf[15];
  23. + unsigned int len = 0;
  24. +
  25. + int cur_ah_bwmode = ah->ah_bwmode_debug;
  26. +
  27. +#define print_selected(MODE, LABEL) \
  28. + if (cur_ah_bwmode == MODE) \
  29. + len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \
  30. + else \
  31. + len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \
  32. + len += snprintf(buf+len, sizeof(buf)-len, " ");
  33. +
  34. + print_selected(AR5K_BWMODE_5MHZ, "5");
  35. + print_selected(AR5K_BWMODE_10MHZ, "10");
  36. + print_selected(AR5K_BWMODE_DEFAULT, "20");
  37. + print_selected(AR5K_BWMODE_40MHZ, "40");
  38. +#undef print_selected
  39. +
  40. + len += snprintf(buf+len, sizeof(buf)-len, "\n");
  41. +
  42. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  43. +}
  44. +
  45. +static ssize_t write_file_bwmode(struct file *file,
  46. + const char __user *userbuf,
  47. + size_t count, loff_t *ppos)
  48. +{
  49. + struct ath5k_hw *ah = file->private_data;
  50. + char buf[3];
  51. + int bw = 20;
  52. + int tobwmode = AR5K_BWMODE_DEFAULT;
  53. +
  54. + if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
  55. + return -EFAULT;
  56. +
  57. + /* TODO: Add check for active interface */
  58. +
  59. + if(strncmp(buf, "5", 1) == 0 ) {
  60. + tobwmode = AR5K_BWMODE_5MHZ;
  61. + bw = 5;
  62. + } else if ( strncmp(buf, "10", 2) == 0 ) {
  63. + tobwmode = AR5K_BWMODE_10MHZ;
  64. + bw = 10;
  65. + } else if ( strncmp(buf, "20", 2) == 0 ) {
  66. + tobwmode = AR5K_BWMODE_DEFAULT;
  67. + bw = 20;
  68. + } else if ( strncmp(buf, "40", 2) == 0 ) {
  69. + tobwmode = AR5K_BWMODE_40MHZ;
  70. + bw = 40;
  71. + } else
  72. + return -EINVAL;
  73. +
  74. + ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n",
  75. + bw, tobwmode);
  76. +
  77. + switch (ah->ah_radio) {
  78. + /* TODO: only define radios that actually support 5/10mhz channels */
  79. + case AR5K_RF5413:
  80. + case AR5K_RF5110:
  81. + case AR5K_RF5111:
  82. + case AR5K_RF5112:
  83. + case AR5K_RF2413:
  84. + case AR5K_RF2316:
  85. + case AR5K_RF2317:
  86. + case AR5K_RF2425:
  87. + if(ah->ah_bwmode_debug != tobwmode) {
  88. + mutex_lock(&ah->lock);
  89. + ah->ah_bwmode = tobwmode;
  90. + ah->ah_bwmode_debug = tobwmode;
  91. + mutex_unlock(&ah->lock);
  92. + }
  93. + break;
  94. + default:
  95. + return -EOPNOTSUPP;
  96. + }
  97. + return count;
  98. +}
  99. +
  100. +static const struct file_operations fops_bwmode = {
  101. + .read = read_file_bwmode,
  102. + .write = write_file_bwmode,
  103. + .open = simple_open,
  104. + .owner = THIS_MODULE,
  105. + .llseek = default_llseek,
  106. +};
  107. /* debugfs: queues etc */
  108. @@ -1016,6 +1107,8 @@ ath5k_debug_init_device(struct ath5k_hw
  109. debugfs_create_file("queue", 0600, phydir, ah, &fops_queue);
  110. debugfs_create_bool("32khz_clock", 0600, phydir,
  111. &ah->ah_use_32khz_clock);
  112. + debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah,
  113. + &fops_bwmode);
  114. }
  115. /* functions used in other places */
  116. Index: backports-v4.18-rc7/drivers/net/wireless/ath/ath5k/ath5k.h
  117. ===================================================================
  118. --- backports-v4.18-rc7.orig/drivers/net/wireless/ath/ath5k/ath5k.h
  119. +++ backports-v4.18-rc7/drivers/net/wireless/ath/ath5k/ath5k.h
  120. @@ -1372,6 +1372,7 @@ struct ath5k_hw {
  121. u8 ah_coverage_class;
  122. bool ah_ack_bitrate_high;
  123. u8 ah_bwmode;
  124. + u8 ah_bwmode_debug;
  125. bool ah_short_slot;
  126. /* Antenna Control */
  127. Index: backports-v4.18-rc7/drivers/net/wireless/ath/ath5k/base.c
  128. ===================================================================
  129. --- backports-v4.18-rc7.orig/drivers/net/wireless/ath/ath5k/base.c
  130. +++ backports-v4.18-rc7/drivers/net/wireless/ath/ath5k/base.c
  131. @@ -466,6 +466,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru
  132. return -EINVAL;
  133. }
  134. + if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT)
  135. + ah->ah_bwmode = ah->ah_bwmode_debug;
  136. +
  137. /*
  138. * To switch channels clear any pending DMA operations;
  139. * wait long enough for the RX fifo to drain, reset the