513-ath9k_channelbw_debugfs.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. --- a/drivers/net/wireless/ath/ath9k/ath9k.h
  2. +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
  3. @@ -624,6 +624,7 @@ struct ath_softc {
  4. struct ieee80211_hw *hw;
  5. struct device *dev;
  6. + u32 chan_bw;
  7. int chan_idx;
  8. int chan_is_ht;
  9. struct survey_info *cur_survey;
  10. @@ -691,6 +692,7 @@ struct ath_softc {
  11. u8 ant_tx, ant_rx;
  12. };
  13. +int ath9k_config(struct ieee80211_hw *hw, u32 changed);
  14. void ath9k_tasklet(unsigned long data);
  15. int ath_cabq_update(struct ath_softc *);
  16. --- a/drivers/net/wireless/ath/ath9k/debug.c
  17. +++ b/drivers/net/wireless/ath/ath9k/debug.c
  18. @@ -1576,6 +1576,50 @@ static const struct file_operations fops
  19. .owner = THIS_MODULE
  20. };
  21. +
  22. +static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf,
  23. + size_t count, loff_t *ppos)
  24. +{
  25. + struct ath_softc *sc = file->private_data;
  26. + char buf[32];
  27. + unsigned int len;
  28. +
  29. + len = sprintf(buf, "0x%08x\n", sc->chan_bw);
  30. + return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  31. +}
  32. +
  33. +static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf,
  34. + size_t count, loff_t *ppos)
  35. +{
  36. + struct ath_softc *sc = file->private_data;
  37. + unsigned long chan_bw;
  38. + char buf[32];
  39. + ssize_t len;
  40. +
  41. + len = min(count, sizeof(buf) - 1);
  42. + if (copy_from_user(buf, user_buf, len))
  43. + return -EFAULT;
  44. +
  45. + buf[len] = '\0';
  46. + if (strict_strtoul(buf, 0, &chan_bw))
  47. + return -EINVAL;
  48. +
  49. + sc->chan_bw = chan_bw;
  50. + if (!(sc->sc_flags & SC_OP_INVALID))
  51. + ath9k_config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL);
  52. +
  53. + return count;
  54. +}
  55. +
  56. +static const struct file_operations fops_chanbw = {
  57. + .read = read_file_chan_bw,
  58. + .write = write_file_chan_bw,
  59. + .open = ath9k_debugfs_open,
  60. + .owner = THIS_MODULE,
  61. + .llseek = default_llseek,
  62. +};
  63. +
  64. +
  65. int ath9k_init_debug(struct ath_hw *ah)
  66. {
  67. struct ath_common *common = ath9k_hw_common(ah);
  68. @@ -1642,5 +1686,8 @@ int ath9k_init_debug(struct ath_hw *ah)
  69. debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
  70. &fops_eeprom);
  71. + debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
  72. + sc, &fops_chanbw);
  73. +
  74. return 0;
  75. }
  76. --- a/drivers/net/wireless/ath/ath9k/main.c
  77. +++ b/drivers/net/wireless/ath/ath9k/main.c
  78. @@ -1537,7 +1537,7 @@ static void ath9k_disable_ps(struct ath_
  79. }
  80. -static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
  81. +int ath9k_config(struct ieee80211_hw *hw, u32 changed)
  82. {
  83. struct ath_softc *sc = hw->priv;
  84. struct ath_hw *ah = sc->sc_ah;
  85. @@ -1588,9 +1588,11 @@ static int ath9k_config(struct ieee80211
  86. if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
  87. struct ieee80211_channel *curchan = hw->conf.channel;
  88. + struct ath9k_channel *hchan;
  89. int pos = curchan->hw_value;
  90. int old_pos = -1;
  91. unsigned long flags;
  92. + u32 oldflags;
  93. if (ah->curchan)
  94. old_pos = ah->curchan - &ah->channels[0];
  95. @@ -1638,7 +1640,23 @@ static int ath9k_config(struct ieee80211
  96. memset(&sc->survey[pos], 0, sizeof(struct survey_info));
  97. }
  98. - if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
  99. + hchan = &sc->sc_ah->channels[pos];
  100. + oldflags = hchan->channelFlags;
  101. + switch (sc->chan_bw) {
  102. + case 5:
  103. + hchan->channelFlags &= ~CHANNEL_HALF;
  104. + hchan->channelFlags |= CHANNEL_QUARTER;
  105. + break;
  106. + case 10:
  107. + hchan->channelFlags &= ~CHANNEL_QUARTER;
  108. + hchan->channelFlags |= CHANNEL_HALF;
  109. + break;
  110. + default:
  111. + hchan->channelFlags &= ~(CHANNEL_HALF | CHANNEL_QUARTER);
  112. + break;
  113. + }
  114. +
  115. + if (ath_set_channel(sc, hw, hchan) < 0) {
  116. ath_err(common, "Unable to set channel\n");
  117. mutex_unlock(&sc->mutex);
  118. return -EINVAL;
  119. --- a/drivers/net/wireless/ath/ath9k/hw.c
  120. +++ b/drivers/net/wireless/ath/ath9k/hw.c
  121. @@ -1576,6 +1576,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
  122. caldata->rtt_hist.num_readings)
  123. allow_fbs = true;
  124. + if (!ah->curchan || ((ah->curchan->channelFlags ^ chan->channelFlags) &
  125. + (CHANNEL_HALF | CHANNEL_QUARTER)))
  126. + bChannelChange = false;
  127. +
  128. if (bChannelChange &&
  129. (ah->chip_fullsleep != true) &&
  130. (ah->curchan != NULL) &&