998-survey.patch 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  2. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  3. @@ -2893,6 +2893,63 @@ done:
  4. }
  5. static int
  6. +brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
  7. + int idx, struct survey_info *survey)
  8. +{
  9. + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
  10. + struct brcmf_if *ifp = netdev_priv(ndev);
  11. + struct brcmu_chan ch;
  12. + enum nl80211_band band = 0;
  13. + s32 err = 0;
  14. + int noise;
  15. + u32 freq;
  16. + u32 chanspec;
  17. +
  18. + memset(survey, 0, sizeof(struct survey_info));
  19. + if (idx != 0) {
  20. + if (idx >= cfg->pub->num_chan_stats || cfg->pub->chan_stats == NULL)
  21. + return -ENOENT;
  22. + if (cfg->pub->chan_stats[idx].freq == 0)
  23. + return -ENOENT;
  24. + survey->filled = SURVEY_INFO_NOISE_DBM;
  25. + survey->channel = ieee80211_get_channel(wiphy, cfg->pub->chan_stats[idx].freq);
  26. + survey->noise = cfg->pub->chan_stats[idx].noise;
  27. + return 0;
  28. + }
  29. +
  30. + err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec);
  31. + if (err) {
  32. + brcmf_err("chanspec failed (%d)\n", err);
  33. + return err;
  34. + }
  35. +
  36. + ch.chspec = chanspec;
  37. + cfg->d11inf.decchspec(&ch);
  38. +
  39. + switch (ch.band) {
  40. + case BRCMU_CHAN_BAND_2G:
  41. + band = NL80211_BAND_2GHZ;
  42. + break;
  43. + case BRCMU_CHAN_BAND_5G:
  44. + band = NL80211_BAND_5GHZ;
  45. + break;
  46. + }
  47. +
  48. + freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
  49. + survey->channel = ieee80211_get_channel(wiphy, freq);
  50. +
  51. + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PHY_NOISE, &noise);
  52. + if (err) {
  53. + brcmf_err("Could not get noise (%d)\n", err);
  54. + return err;
  55. + }
  56. +
  57. + survey->filled = SURVEY_INFO_NOISE_DBM | SURVEY_INFO_IN_USE;
  58. + survey->noise = le32_to_cpu(noise);
  59. + return 0;
  60. +}
  61. +
  62. +static int
  63. brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
  64. int idx, u8 *mac, struct station_info *sinfo)
  65. {
  66. @@ -2982,6 +3039,7 @@ static s32 brcmf_inform_single_bss(struc
  67. struct brcmu_chan ch;
  68. u16 channel;
  69. u32 freq;
  70. + int i;
  71. u16 notify_capability;
  72. u16 notify_interval;
  73. u8 *notify_ie;
  74. @@ -3006,6 +3064,17 @@ static s32 brcmf_inform_single_bss(struc
  75. band = NL80211_BAND_5GHZ;
  76. freq = ieee80211_channel_to_frequency(channel, band);
  77. + for (i = 0;i < cfg->pub->num_chan_stats;i++) {
  78. + if (freq == cfg->pub->chan_stats[i].freq)
  79. + break;
  80. + if (cfg->pub->chan_stats[i].freq == 0)
  81. + break;
  82. + }
  83. + if (i < cfg->pub->num_chan_stats) {
  84. + cfg->pub->chan_stats[i].freq = freq;
  85. + cfg->pub->chan_stats[i].noise = bi->phy_noise;
  86. + }
  87. +
  88. bss_data.chan = ieee80211_get_channel(wiphy, freq);
  89. bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
  90. bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
  91. @@ -5423,6 +5492,7 @@ static struct cfg80211_ops brcmf_cfg8021
  92. .leave_ibss = brcmf_cfg80211_leave_ibss,
  93. .get_station = brcmf_cfg80211_get_station,
  94. .dump_station = brcmf_cfg80211_dump_station,
  95. + .dump_survey = brcmf_cfg80211_dump_survey,
  96. .set_tx_power = brcmf_cfg80211_set_tx_power,
  97. .get_tx_power = brcmf_cfg80211_get_tx_power,
  98. .add_key = brcmf_cfg80211_add_key,
  99. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
  100. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
  101. @@ -1352,6 +1352,8 @@ int brcmf_attach(struct device *dev)
  102. /* Link to bus module */
  103. drvr->hdrlen = 0;
  104. + drvr->chan_stats = vzalloc(256 * sizeof(struct brcmf_chan_stats));
  105. + drvr->num_chan_stats = 256;
  106. /* Attach and link in the protocol */
  107. ret = brcmf_proto_attach(drvr);
  108. @@ -1434,6 +1436,12 @@ void brcmf_detach(struct device *dev)
  109. if (drvr == NULL)
  110. return;
  111. + drvr->num_chan_stats = 0;
  112. + if (drvr->chan_stats) {
  113. + vfree(drvr->chan_stats);
  114. + drvr->chan_stats = NULL;
  115. + }
  116. +
  117. #ifdef CONFIG_INET
  118. unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
  119. #endif
  120. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
  121. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
  122. @@ -91,6 +91,11 @@ struct brcmf_rev_info {
  123. u32 nvramrev;
  124. };
  125. +struct brcmf_chan_stats {
  126. + u32 freq;
  127. + int noise;
  128. +};
  129. +
  130. /* Common structure for module and instance linkage */
  131. struct brcmf_pub {
  132. /* Linkage ponters */
  133. @@ -100,6 +105,9 @@ struct brcmf_pub {
  134. struct cfg80211_ops *ops;
  135. struct brcmf_cfg80211_info *config;
  136. + int num_chan_stats;
  137. + struct brcmf_chan_stats *chan_stats;
  138. +
  139. /* Internal brcmf items */
  140. uint hdrlen; /* Total BRCMF header length (proto + bus) */