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

Commit c8dcfd8a authored by Felix Fietkau's avatar Felix Fietkau Committed by John W. Linville
Browse files

cfg80211: add a field for the bitrate of the last rx data packet from a station



Also fix a typo in the STATION_INFO_TX_BITRATE description

Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e7a2a4f5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1243,6 +1243,8 @@ enum nl80211_rate_info {
 * @NL80211_STA_INFO_LLID: the station's mesh LLID
 * @NL80211_STA_INFO_PLID: the station's mesh PLID
 * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station
 * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested
 *	attribute, like NL80211_STA_INFO_TX_BITRATE.
 * @__NL80211_STA_INFO_AFTER_LAST: internal
 * @NL80211_STA_INFO_MAX: highest possible station info attribute
 */
@@ -1261,6 +1263,7 @@ enum nl80211_sta_info {
	NL80211_STA_INFO_TX_RETRIES,
	NL80211_STA_INFO_TX_FAILED,
	NL80211_STA_INFO_SIGNAL_AVG,
	NL80211_STA_INFO_RX_BITRATE,

	/* keep last */
	__NL80211_STA_INFO_AFTER_LAST,
+4 −1
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ struct station_parameters {
 * @STATION_INFO_PLID: @plid filled
 * @STATION_INFO_PLINK_STATE: @plink_state filled
 * @STATION_INFO_SIGNAL: @signal filled
 * @STATION_INFO_TX_BITRATE: @tx_bitrate fields are filled
 * @STATION_INFO_TX_BITRATE: @txrate fields are filled
 *  (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs)
 * @STATION_INFO_RX_PACKETS: @rx_packets filled
 * @STATION_INFO_TX_PACKETS: @tx_packets filled
@@ -421,6 +421,7 @@ struct station_parameters {
 * @STATION_INFO_TX_FAILED: @tx_failed filled
 * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled
 * @STATION_INFO_SIGNAL_AVG: @signal_avg filled
 * @STATION_INFO_RX_BITRATE: @rxrate fields are filled
 */
enum station_info_flags {
	STATION_INFO_INACTIVE_TIME	= 1<<0,
@@ -437,6 +438,7 @@ enum station_info_flags {
	STATION_INFO_TX_FAILED		= 1<<11,
	STATION_INFO_RX_DROP_MISC	= 1<<12,
	STATION_INFO_SIGNAL_AVG		= 1<<13,
	STATION_INFO_RX_BITRATE		= 1<<14,
};

/**
@@ -506,6 +508,7 @@ struct station_info {
	s8 signal;
	s8 signal_avg;
	struct rate_info txrate;
	struct rate_info rxrate;
	u32 rx_packets;
	u32 tx_packets;
	u32 tx_retries;
+37 −19
Original line number Diff line number Diff line
@@ -1968,13 +1968,41 @@ static int parse_station_flags(struct genl_info *info,
	return 0;
}

static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
				 int attr)
{
	struct nlattr *rate;
	u16 bitrate;

	rate = nla_nest_start(msg, attr);
	if (!rate)
		goto nla_put_failure;

	/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
	bitrate = cfg80211_calculate_bitrate(info);
	if (bitrate > 0)
		NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);

	if (info->flags & RATE_INFO_FLAGS_MCS)
		NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS, info->mcs);
	if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
		NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
	if (info->flags & RATE_INFO_FLAGS_SHORT_GI)
		NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);

	nla_nest_end(msg, rate);
	return true;

nla_put_failure:
	return false;
}

static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
				int flags, struct net_device *dev,
				const u8 *mac_addr, struct station_info *sinfo)
{
	void *hdr;
	struct nlattr *sinfoattr, *txrate;
	u16 bitrate;
	struct nlattr *sinfoattr;

	hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
	if (!hdr)
@@ -2013,24 +2041,14 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
		NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
			   sinfo->signal_avg);
	if (sinfo->filled & STATION_INFO_TX_BITRATE) {
		txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
		if (!txrate)
		if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
					  NL80211_STA_INFO_TX_BITRATE))
			goto nla_put_failure;
	}
	if (sinfo->filled & STATION_INFO_RX_BITRATE) {
		if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
					  NL80211_STA_INFO_RX_BITRATE))
			goto nla_put_failure;

		/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
		bitrate = cfg80211_calculate_bitrate(&sinfo->txrate);
		if (bitrate > 0)
			NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);

		if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
			NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
				    sinfo->txrate.mcs);
		if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
			NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
		if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
			NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);

		nla_nest_end(msg, txrate);
	}
	if (sinfo->filled & STATION_INFO_RX_PACKETS)
		NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS,