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

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

cfg80211: add support for per-chain signal strength reporting

parent f722406f
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -753,6 +753,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
 * @STATION_INFO_LOCAL_PM: @local_pm filled
 * @STATION_INFO_PEER_PM: @peer_pm filled
 * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled
 * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
 * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
 */
enum station_info_flags {
	STATION_INFO_INACTIVE_TIME	= 1<<0,
@@ -781,6 +783,8 @@ enum station_info_flags {
	STATION_INFO_NONPEER_PM		= 1<<23,
	STATION_INFO_RX_BYTES64		= 1<<24,
	STATION_INFO_TX_BYTES64		= 1<<25,
	STATION_INFO_CHAIN_SIGNAL	= 1<<26,
	STATION_INFO_CHAIN_SIGNAL_AVG	= 1<<27,
};

/**
@@ -857,6 +861,8 @@ struct sta_bss_parameters {
	u16 beacon_interval;
};

#define IEEE80211_MAX_CHAINS	4

/**
 * struct station_info - station information
 *
@@ -874,6 +880,9 @@ struct sta_bss_parameters {
 *	For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
 * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
 *	For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
 * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
 * @chain_signal: per-chain signal strength of last received packet in dBm
 * @chain_signal_avg: per-chain signal strength average in dBm
 * @txrate: current unicast bitrate from this station
 * @rxrate: current unicast bitrate to this station
 * @rx_packets: packets received from this station
@@ -909,6 +918,11 @@ struct station_info {
	u8 plink_state;
	s8 signal;
	s8 signal_avg;

	u8 chains;
	s8 chain_signal[IEEE80211_MAX_CHAINS];
	s8 chain_signal_avg[IEEE80211_MAX_CHAINS];

	struct rate_info txrate;
	struct rate_info rxrate;
	u32 rx_packets;
+6 −0
Original line number Diff line number Diff line
@@ -1991,6 +1991,10 @@ enum nl80211_sta_bss_param {
 * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
 * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
 *	non-peer STA
 * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
 *	Contains a nested array of signal strength attributes (u8, dBm)
 * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
 *	Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
 * @__NL80211_STA_INFO_AFTER_LAST: internal
 * @NL80211_STA_INFO_MAX: highest possible station info attribute
 */
@@ -2020,6 +2024,8 @@ enum nl80211_sta_info {
	NL80211_STA_INFO_NONPEER_PM,
	NL80211_STA_INFO_RX_BYTES64,
	NL80211_STA_INFO_TX_BYTES64,
	NL80211_STA_INFO_CHAIN_SIGNAL,
	NL80211_STA_INFO_CHAIN_SIGNAL_AVG,

	/* keep last */
	__NL80211_STA_INFO_AFTER_LAST,
+38 −0
Original line number Diff line number Diff line
@@ -3376,6 +3376,32 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
	return true;
}

static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
			       int id)
{
	void *attr;
	int i = 0;

	if (!mask)
		return true;

	attr = nla_nest_start(msg, id);
	if (!attr)
		return false;

	for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
		if (!(mask & BIT(i)))
			continue;

		if (nla_put_u8(msg, i, signal[i]))
			return false;
	}

	nla_nest_end(msg, attr);

	return true;
}

static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
				int flags,
				struct cfg80211_registered_device *rdev,
@@ -3447,6 +3473,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
	default:
		break;
	}
	if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
		if (!nl80211_put_signal(msg, sinfo->chains,
					sinfo->chain_signal,
					NL80211_STA_INFO_CHAIN_SIGNAL))
			goto nla_put_failure;
	}
	if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
		if (!nl80211_put_signal(msg, sinfo->chains,
					sinfo->chain_signal_avg,
					NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
			goto nla_put_failure;
	}
	if (sinfo->filled & STATION_INFO_TX_BITRATE) {
		if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
					  NL80211_STA_INFO_TX_BITRATE))