522-ath9k_per_chain_signal_strength.patch 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. --- a/include/net/mac80211.h
  2. +++ b/include/net/mac80211.h
  3. @@ -816,6 +816,9 @@ enum mac80211_rx_flags {
  4. * @signal: signal strength when receiving this frame, either in dBm, in dB or
  5. * unspecified depending on the hardware capabilities flags
  6. * @IEEE80211_HW_SIGNAL_*
  7. + * @chains: bitmask of receive chains for which separate signal strength
  8. + * values were filled.
  9. + * @chain_signal: per-chain signal strength, same format as @signal
  10. * @antenna: antenna used
  11. * @rate_idx: index of data rate into band's supported rates or MCS index if
  12. * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
  13. @@ -847,6 +850,8 @@ struct ieee80211_rx_status {
  14. u8 band;
  15. u8 antenna;
  16. s8 signal;
  17. + u8 chains;
  18. + s8 chain_signal[4];
  19. u8 ampdu_delimiter_crc;
  20. u8 vendor_radiotap_align;
  21. u8 vendor_radiotap_oui[3];
  22. --- a/net/mac80211/sta_info.h
  23. +++ b/net/mac80211/sta_info.h
  24. @@ -329,6 +329,11 @@ struct sta_info {
  25. int last_signal;
  26. struct ewma avg_signal;
  27. int last_ack_signal;
  28. +
  29. + u8 chains;
  30. + s8 chain_signal_last[4];
  31. + struct ewma chain_signal_avg[4];
  32. +
  33. /* Plus 1 for non-QoS frames */
  34. __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
  35. --- a/net/mac80211/rx.c
  36. +++ b/net/mac80211/rx.c
  37. @@ -1375,6 +1375,7 @@ ieee80211_rx_h_sta_process(struct ieee80
  38. struct sk_buff *skb = rx->skb;
  39. struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
  40. struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  41. + int i;
  42. if (!sta)
  43. return RX_CONTINUE;
  44. @@ -1425,6 +1426,19 @@ ieee80211_rx_h_sta_process(struct ieee80
  45. ewma_add(&sta->avg_signal, -status->signal);
  46. }
  47. + if (status->chains) {
  48. + sta->chains = status->chains;
  49. + for (i = 0; i < 4; i++) {
  50. + int signal = status->chain_signal[i];
  51. +
  52. + if (!(status->chains & BIT(i)))
  53. + continue;
  54. +
  55. + sta->chain_signal_last[i] = signal;
  56. + ewma_add(&sta->chain_signal_avg[i], -signal);
  57. + }
  58. + }
  59. +
  60. /*
  61. * Change STA power saving mode only at the end of a frame
  62. * exchange sequence.
  63. --- a/net/mac80211/sta_info.c
  64. +++ b/net/mac80211/sta_info.c
  65. @@ -324,6 +324,8 @@ struct sta_info *sta_info_alloc(struct i
  66. do_posix_clock_monotonic_gettime(&uptime);
  67. sta->last_connected = uptime.tv_sec;
  68. ewma_init(&sta->avg_signal, 1024, 8);
  69. + for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
  70. + ewma_init(&sta->chain_signal_avg[i], 1024, 8);
  71. if (sta_prepare_rate_control(local, sta, gfp)) {
  72. kfree(sta);
  73. --- a/include/net/cfg80211.h
  74. +++ b/include/net/cfg80211.h
  75. @@ -653,6 +653,8 @@ struct station_parameters {
  76. * @STATION_INFO_STA_FLAGS: @sta_flags filled
  77. * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled
  78. * @STATION_INFO_T_OFFSET: @t_offset filled
  79. + * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
  80. + * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
  81. */
  82. enum station_info_flags {
  83. STATION_INFO_INACTIVE_TIME = 1<<0,
  84. @@ -676,6 +678,8 @@ enum station_info_flags {
  85. STATION_INFO_STA_FLAGS = 1<<18,
  86. STATION_INFO_BEACON_LOSS_COUNT = 1<<19,
  87. STATION_INFO_T_OFFSET = 1<<20,
  88. + STATION_INFO_CHAIN_SIGNAL = 1<<21,
  89. + STATION_INFO_CHAIN_SIGNAL_AVG = 1<<22,
  90. };
  91. /**
  92. @@ -769,6 +773,9 @@ struct sta_bss_parameters {
  93. * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
  94. * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
  95. * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
  96. + * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
  97. + * @chain_signal: per-chain signal strength of last received packet in dBm
  98. + * @chain_signal_avg: per-chain signal strength average in dBm
  99. * @txrate: current unicast bitrate from this station
  100. * @rxrate: current unicast bitrate to this station
  101. * @rx_packets: packets received from this station
  102. @@ -801,6 +808,11 @@ struct station_info {
  103. u8 plink_state;
  104. s8 signal;
  105. s8 signal_avg;
  106. +
  107. + u8 chains;
  108. + s8 chain_signal[4];
  109. + s8 chain_signal_avg[4];
  110. +
  111. struct rate_info txrate;
  112. struct rate_info rxrate;
  113. u32 rx_packets;
  114. --- a/drivers/net/wireless/ath/ath9k/mac.h
  115. +++ b/drivers/net/wireless/ath/ath9k/mac.h
  116. @@ -133,12 +133,8 @@ struct ath_rx_status {
  117. u8 rs_rate;
  118. u8 rs_antenna;
  119. u8 rs_more;
  120. - int8_t rs_rssi_ctl0;
  121. - int8_t rs_rssi_ctl1;
  122. - int8_t rs_rssi_ctl2;
  123. - int8_t rs_rssi_ext0;
  124. - int8_t rs_rssi_ext1;
  125. - int8_t rs_rssi_ext2;
  126. + int8_t rs_rssi_ctl[3];
  127. + int8_t rs_rssi_ext[3];
  128. u8 rs_isaggr;
  129. u8 rs_moreaggr;
  130. u8 rs_num_delims;
  131. --- a/drivers/net/wireless/ath/ath9k/recv.c
  132. +++ b/drivers/net/wireless/ath/ath9k/recv.c
  133. @@ -955,6 +955,7 @@ static int ath9k_rx_skb_preprocess(struc
  134. bool *decrypt_error)
  135. {
  136. struct ath_hw *ah = common->ah;
  137. + int i, j;
  138. /*
  139. * everything but the rate is checked here, the rate check is done
  140. @@ -980,6 +981,20 @@ static int ath9k_rx_skb_preprocess(struc
  141. if (rx_stats->rs_moreaggr)
  142. rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
  143. + for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
  144. + s8 rssi;
  145. +
  146. + if (!(ah->rxchainmask & BIT(i)))
  147. + continue;
  148. +
  149. + rssi = rx_stats->rs_rssi_ctl[i];
  150. + if (rssi != ATH9K_RSSI_BAD) {
  151. + rx_status->chains |= BIT(j);
  152. + rx_status->chain_signal[j] = ah->noise + rssi;
  153. + }
  154. + j++;
  155. + }
  156. +
  157. return 0;
  158. }
  159. --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
  160. +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
  161. @@ -475,12 +475,12 @@ int ath9k_hw_process_rxdesc_edma(struct
  162. /* XXX: Keycache */
  163. rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
  164. - rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
  165. - rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
  166. - rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
  167. - rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
  168. - rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
  169. - rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
  170. + rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
  171. + rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
  172. + rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
  173. + rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
  174. + rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
  175. + rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
  176. if (rxsp->status11 & AR_RxKeyIdxValid)
  177. rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
  178. --- a/drivers/net/wireless/ath/ath9k/mac.c
  179. +++ b/drivers/net/wireless/ath/ath9k/mac.c
  180. @@ -553,25 +553,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
  181. if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
  182. rs->rs_rssi = ATH9K_RSSI_BAD;
  183. - rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
  184. - rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
  185. - rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
  186. - rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
  187. - rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
  188. - rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
  189. + rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
  190. + rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
  191. + rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
  192. + rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
  193. + rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
  194. + rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
  195. } else {
  196. rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
  197. - rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
  198. + rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
  199. AR_RxRSSIAnt00);
  200. - rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
  201. + rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
  202. AR_RxRSSIAnt01);
  203. - rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
  204. + rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
  205. AR_RxRSSIAnt02);
  206. - rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
  207. + rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
  208. AR_RxRSSIAnt10);
  209. - rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
  210. + rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
  211. AR_RxRSSIAnt11);
  212. - rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
  213. + rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
  214. AR_RxRSSIAnt12);
  215. }
  216. if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
  217. --- a/drivers/net/wireless/ath/ath9k/debug.c
  218. +++ b/drivers/net/wireless/ath/ath9k/debug.c
  219. @@ -939,12 +939,12 @@ void ath_debug_stat_rx(struct ath_softc
  220. #ifdef CONFIG_ATH9K_MAC_DEBUG
  221. spin_lock(&sc->debug.samp_lock);
  222. RX_SAMP_DBG(jiffies) = jiffies;
  223. - RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
  224. - RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
  225. - RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
  226. - RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
  227. - RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
  228. - RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
  229. + RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0];
  230. + RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1];
  231. + RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2];
  232. + RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0];
  233. + RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1];
  234. + RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2];
  235. RX_SAMP_DBG(antenna) = rs->rs_antenna;
  236. RX_SAMP_DBG(rssi) = rs->rs_rssi;
  237. RX_SAMP_DBG(rate) = rs->rs_rate;
  238. --- a/include/uapi/linux/nl80211.h
  239. +++ b/include/uapi/linux/nl80211.h
  240. @@ -1834,6 +1834,8 @@ enum nl80211_sta_bss_param {
  241. * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
  242. * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
  243. * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
  244. + * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
  245. + * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
  246. * @__NL80211_STA_INFO_AFTER_LAST: internal
  247. * @NL80211_STA_INFO_MAX: highest possible station info attribute
  248. */
  249. @@ -1858,6 +1860,8 @@ enum nl80211_sta_info {
  250. NL80211_STA_INFO_STA_FLAGS,
  251. NL80211_STA_INFO_BEACON_LOSS,
  252. NL80211_STA_INFO_T_OFFSET,
  253. + NL80211_STA_INFO_CHAIN_SIGNAL,
  254. + NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
  255. /* keep last */
  256. __NL80211_STA_INFO_AFTER_LAST,
  257. --- a/net/wireless/nl80211.c
  258. +++ b/net/wireless/nl80211.c
  259. @@ -2910,6 +2910,32 @@ static bool nl80211_put_sta_rate(struct
  260. return true;
  261. }
  262. +static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
  263. + int id)
  264. +{
  265. + void *attr;
  266. + int i = 0;
  267. +
  268. + if (!mask)
  269. + return true;
  270. +
  271. + attr = nla_nest_start(msg, id);
  272. + if (!attr)
  273. + return false;
  274. +
  275. + for (i = 0; i < 4; i++) {
  276. + if (!(mask & BIT(i)))
  277. + continue;
  278. +
  279. + if (nla_put_u8(msg, i, signal[i]))
  280. + return false;
  281. + }
  282. +
  283. + nla_nest_end(msg, attr);
  284. +
  285. + return true;
  286. +}
  287. +
  288. static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
  289. int flags,
  290. struct cfg80211_registered_device *rdev,
  291. @@ -2971,6 +2997,18 @@ static int nl80211_send_station(struct s
  292. default:
  293. break;
  294. }
  295. + if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
  296. + if (!nl80211_put_signal(msg, sinfo->chains,
  297. + sinfo->chain_signal,
  298. + NL80211_STA_INFO_CHAIN_SIGNAL))
  299. + goto nla_put_failure;
  300. + }
  301. + if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
  302. + if (!nl80211_put_signal(msg, sinfo->chains,
  303. + sinfo->chain_signal_avg,
  304. + NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
  305. + goto nla_put_failure;
  306. + }
  307. if (sinfo->filled & STATION_INFO_TX_BITRATE) {
  308. if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
  309. NL80211_STA_INFO_TX_BITRATE))
  310. --- a/net/mac80211/cfg.c
  311. +++ b/net/mac80211/cfg.c
  312. @@ -435,6 +435,7 @@ static void sta_set_sinfo(struct sta_inf
  313. struct ieee80211_sub_if_data *sdata = sta->sdata;
  314. struct ieee80211_local *local = sdata->local;
  315. struct timespec uptime;
  316. + int i;
  317. sinfo->generation = sdata->local->sta_generation;
  318. @@ -474,6 +475,17 @@ static void sta_set_sinfo(struct sta_inf
  319. sinfo->signal = (s8)sta->last_signal;
  320. sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
  321. }
  322. + if (sta->chains) {
  323. + sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
  324. + STATION_INFO_CHAIN_SIGNAL_AVG;
  325. +
  326. + sinfo->chains = sta->chains;
  327. + for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
  328. + sinfo->chain_signal[i] = sta->chain_signal_last[i];
  329. + sinfo->chain_signal_avg[i] =
  330. + (s8) -ewma_read(&sta->chain_signal_avg[i]);
  331. + }
  332. + }
  333. sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
  334. sta_set_rate_info_rx(sta, &sinfo->rxrate);
  335. --- a/drivers/net/wireless/ath/ath9k/dfs.c
  336. +++ b/drivers/net/wireless/ath/ath9k/dfs.c
  337. @@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath
  338. return;
  339. }
  340. - ard.rssi = rs->rs_rssi_ctl0;
  341. - ard.ext_rssi = rs->rs_rssi_ext0;
  342. + ard.rssi = rs->rs_rssi_ctl[0];
  343. + ard.ext_rssi = rs->rs_rssi_ext[0];
  344. /*
  345. * hardware stores this as 8 bit signed value.
  346. --- a/drivers/net/wireless/ath/ath9k/antenna.c
  347. +++ b/drivers/net/wireless/ath/ath9k/antenna.c
  348. @@ -546,14 +546,14 @@ void ath_ant_comb_scan(struct ath_softc
  349. struct ath_ant_comb *antcomb = &sc->ant_comb;
  350. int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
  351. int curr_main_set;
  352. - int main_rssi = rs->rs_rssi_ctl0;
  353. - int alt_rssi = rs->rs_rssi_ctl1;
  354. + int main_rssi = rs->rs_rssi_ctl[0];
  355. + int alt_rssi = rs->rs_rssi_ctl[1];
  356. int rx_ant_conf, main_ant_conf;
  357. bool short_scan = false;
  358. - rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
  359. + rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
  360. ATH_ANT_RX_MASK;
  361. - main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
  362. + main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
  363. ATH_ANT_RX_MASK;
  364. /* Record packet only when both main_rssi and alt_rssi is positive */