Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef0621e8 authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg
Browse files

mac80211: add support for per-chain signal strength reporting



Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
[fix unit documentation]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 119363c7
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -850,6 +850,10 @@ enum mac80211_rx_flags {
 * @signal: signal strength when receiving this frame, either in dBm, in dB or
 *	unspecified depending on the hardware capabilities flags
 *	@IEEE80211_HW_SIGNAL_*
 * @chains: bitmask of receive chains for which separate signal strength
 *	values were filled.
 * @chain_signal: per-chain signal strength, in dBm (unlike @signal, doesn't
 *	support dB or unspecified units)
 * @antenna: antenna used
 * @rate_idx: index of data rate into band's supported rates or MCS index if
 *	HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
@@ -881,6 +885,8 @@ struct ieee80211_rx_status {
	u8 band;
	u8 antenna;
	s8 signal;
	u8 chains;
	s8 chain_signal[IEEE80211_MAX_CHAINS];
	u8 ampdu_delimiter_crc;
	u8 vendor_radiotap_align;
	u8 vendor_radiotap_oui[3];
+12 −1
Original line number Diff line number Diff line
@@ -444,7 +444,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
	struct ieee80211_local *local = sdata->local;
	struct timespec uptime;
	u64 packets = 0;
	int ac;
	int i, ac;

	sinfo->generation = sdata->local->sta_generation;

@@ -488,6 +488,17 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
			sinfo->signal = (s8)sta->last_signal;
		sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
	}
	if (sta->chains) {
		sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
				 STATION_INFO_CHAIN_SIGNAL_AVG;

		sinfo->chains = sta->chains;
		for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
			sinfo->chain_signal[i] = sta->chain_signal_last[i];
			sinfo->chain_signal_avg[i] =
				(s8) -ewma_read(&sta->chain_signal_avg[i]);
		}
	}

	sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
	sta_set_rate_info_rx(sta, &sinfo->rxrate);
+14 −0
Original line number Diff line number Diff line
@@ -1372,6 +1372,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
	struct sk_buff *skb = rx->skb;
	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
	int i;

	if (!sta)
		return RX_CONTINUE;
@@ -1422,6 +1423,19 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
		ewma_add(&sta->avg_signal, -status->signal);
	}

	if (status->chains) {
		sta->chains = status->chains;
		for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
			int signal = status->chain_signal[i];

			if (!(status->chains & BIT(i)))
				continue;

			sta->chain_signal_last[i] = signal;
			ewma_add(&sta->chain_signal_avg[i], -signal);
		}
	}

	/*
	 * Change STA power saving mode only at the end of a frame
	 * exchange sequence.
+2 −0
Original line number Diff line number Diff line
@@ -358,6 +358,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
	do_posix_clock_monotonic_gettime(&uptime);
	sta->last_connected = uptime.tv_sec;
	ewma_init(&sta->avg_signal, 1024, 8);
	for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
		ewma_init(&sta->chain_signal_avg[i], 1024, 8);

	if (sta_prepare_rate_control(local, sta, gfp)) {
		kfree(sta);
+5 −0
Original line number Diff line number Diff line
@@ -344,6 +344,11 @@ struct sta_info {
	int last_signal;
	struct ewma avg_signal;
	int last_ack_signal;

	u8 chains;
	s8 chain_signal_last[IEEE80211_MAX_CHAINS];
	struct ewma chain_signal_avg[IEEE80211_MAX_CHAINS];

	/* Plus 1 for non-QoS frames */
	__le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];