[net80211] extend the ieee80211_rx_stats struct to include more information.

There are a variety of more interesting RX statistics that we should
keep track of but we don't.  This is a starting point for adding more
information.

Specifically:

* now the RX rate information and some of the packet status is
  passed up;
* The 32 bit or 64 bit TSF is passed up;
* the PHY mode is passed up;
* the "I'm decap'ed AMSDU!" state is passed up;
* number of RX chains is bumped to 4.

This is all mostly a placeholder for getting the data into the RX status
before we pass it up to net80211 - unfortunately we don't yet enforce
that drivers provide it, nor do we pass the provided info back up the
stack so anyone can use the data.

We're going to need to use some of this data moving forward.
Notably, now that some hardware can do AMSDU decap for us (the intel iwm
driver can do it when we flip it on; the ath10k port I'm doing does
it for us) then we need to pass it up through the stack so the duplicate
RX sequence numbers and crypto/IV details don't cause the packet to
be dropped and/or counted against a replay counter.

It's also the beginning of being able to do more interesting node
accounting in net80211.  Specifically, once drivers start populating
per-packet rate information, AMPDU information, timestamps, etc,
we can start providing histograms of rate-versus-RSSI, account
for receive time spent per node and other such interesting things.

(Note: I'm also hoping to include ranging and RTT information for
future chipset support; and it's likely going to include it in
this kind of fashion.)
This commit is contained in:
Adrian Chadd 2016-10-08 01:12:29 +00:00
parent 0bfc75bfbb
commit e97796e2b6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=306837
5 changed files with 79 additions and 30 deletions

View File

@ -2975,8 +2975,8 @@ iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc,
}
/* rssi is in 1/2db units */
rxs.rssi = rssi * 2;
rxs.nf = sc->sc_noise;
rxs.c_rssi = rssi * 2;
rxs.c_nf = sc->sc_noise;
if (ieee80211_radiotap_active_vap(vap)) {
struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;

View File

@ -1710,8 +1710,8 @@ otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq)
/* Add RSSI/NF to this mbuf */
bzero(&rxs, sizeof(rxs));
rxs.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
rxs.nf = sc->sc_nf[0]; /* XXX chain 0 != combined rssi/nf */
rxs.rssi = tail->rssi;
rxs.c_nf = sc->sc_nf[0]; /* XXX chain 0 != combined rssi/nf */
rxs.c_rssi = tail->rssi;
/* XXX TODO: add MIMO RSSI/NF as well */
ieee80211_add_rx_params(m, &rxs);

View File

@ -1534,8 +1534,8 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
rxs.c_ieee = le32toh(bss->config.dsconfig);
rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, IEEE80211_CHAN_2GHZ);
/* This is a number from 0..100; so let's just divide it down a bit */
rxs.rssi = le32toh(bss->rssi) / 2;
rxs.nf = -96;
rxs.c_rssi = le32toh(bss->rssi) / 2;
rxs.c_nf = -96;
/* XXX avoid a LOR */
RSU_UNLOCK(sc);

View File

@ -622,33 +622,82 @@ int ieee80211_add_xmit_params(struct mbuf *m,
int ieee80211_get_xmit_params(struct mbuf *m,
struct ieee80211_bpf_params *);
#define IEEE80211_MAX_CHAINS 3
/*
* Note: this is fine for 3x3 (and 4x4) 11n HT40;
* but getting EVM information for VHT80, VHT160
* will involve more than 6 EVM pilots.
*/
#define IEEE80211_MAX_CHAINS 4
#define IEEE80211_MAX_EVM_PILOTS 6
#define IEEE80211_R_NF 0x0000001 /* global NF value valid */
#define IEEE80211_R_RSSI 0x0000002 /* global RSSI value valid */
#define IEEE80211_R_C_CHAIN 0x0000004 /* RX chain count valid */
#define IEEE80211_R_C_NF 0x0000008 /* per-chain NF value valid */
#define IEEE80211_R_C_RSSI 0x0000010 /* per-chain RSSI value valid */
#define IEEE80211_R_C_EVM 0x0000020 /* per-chain EVM valid */
#define IEEE80211_R_C_HT40 0x0000040 /* RX'ed packet is 40mhz, pilots 4,5 valid */
#define IEEE80211_R_FREQ 0x0000080 /* Freq value populated, MHz */
#define IEEE80211_R_IEEE 0x0000100 /* IEEE value populated */
#define IEEE80211_R_BAND 0x0000200 /* Frequency band populated */
#define IEEE80211_R_NF 0x00000001 /* global NF value valid */
#define IEEE80211_R_RSSI 0x00000002 /* global RSSI value valid */
#define IEEE80211_R_C_CHAIN 0x00000004 /* RX chain count valid */
#define IEEE80211_R_C_NF 0x00000008 /* per-chain NF value valid */
#define IEEE80211_R_C_RSSI 0x00000010 /* per-chain RSSI value valid */
#define IEEE80211_R_C_EVM 0x00000020 /* per-chain EVM valid */
#define IEEE80211_R_C_HT40 0x00000040 /* RX'ed packet is 40mhz, pilots 4,5 valid */
#define IEEE80211_R_FREQ 0x00000080 /* Freq value populated, MHz */
#define IEEE80211_R_IEEE 0x00000100 /* IEEE value populated */
#define IEEE80211_R_BAND 0x00000200 /* Frequency band populated */
#define IEEE80211_R_TSF32 0x00004000 /* 32 bit TSF */
#define IEEE80211_R_TSF64 0x00008000 /* 64 bit TSF */
#define IEEE80211_R_TSF_START 0x00010000 /* TSF is sampled at start of frame */
#define IEEE80211_R_TSF_END 0x00020000 /* TSF is sampled at end of frame */
/* RX packet flags - describe the kind of frame */
#define IEEE80211_RX_F_STBC 0x00000001
#define IEEE80211_RX_F_LDPC 0x00000002
#define IEEE80211_RX_F_AMSDU 0x00000004 /* This is the start of an decap AMSDU list */
#define IEEE80211_RX_F_AMSDU_MORE 0x00000008 /* This is another decap AMSDU frame in the batch */
#define IEEE80211_RX_F_AMPDU 0x00000010 /* This is the start of an decap AMPDU list */
#define IEEE80211_RX_F_AMPDU_MORE 0x00000020 /* This is another decap AMPDU frame in the batch */
/* Channel width */
#define IEEE80211_RX_FW_20MHZ 1
#define IEEE80211_RX_FW_40MHZ 2
#define IEEE80211_RX_FW_80MHZ 3
/* PHY type */
#define IEEE80211_RX_FP_11B 1
#define IEEE80211_RX_FP_11G 2
#define IEEE80211_RX_FP_11A 3
#define IEEE80211_RX_FP_11NA 4
#define IEEE80211_RX_FP_11NG 5
struct ieee80211_rx_stats {
uint32_t r_flags; /* IEEE80211_R_* flags */
uint32_t c_pktflags; /* IEEE80211_RX_F_* flags */
uint64_t c_rx_tsf; /* 32 or 64 bit TSF */
/* All DWORD aligned */
int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */
int16_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */
int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */
int16_t c_rssi_ext[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */
/* 32 bits */
uint8_t c_nf; /* global NF */
uint8_t c_rssi; /* global RSSI */
uint8_t c_chain; /* number of RX chains involved */
int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */
int16_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */
int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */
int16_t c_rssi_ext[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */
uint8_t nf; /* global NF */
uint8_t rssi; /* global RSSI */
uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
/* per-chain, per-pilot EVM values */
uint16_t c_freq;
uint8_t c_ieee;
uint8_t c_rate; /* legacy + 11n rate code */
/* 32 bits */
uint16_t c_freq; /* Frequency, MHz */
uint8_t c_ieee; /* Channel */
uint8_t c_width; /* channel width, FW flags above */
/* Force alignment to DWORD */
union {
uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
/* per-chain, per-pilot EVM values */
uint32_t __aln[8];
} evm;
/* 32 bits */
uint8_t c_phytype; /* PHY type, FW flags above */
uint8_t c_pad2[3];
};
struct ieee80211_rx_params {

View File

@ -100,7 +100,7 @@ ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m,
ieee80211_process_mimo(ni, &rxs);
//return ieee80211_input(ni, m, rx->rssi, rx->nf);
return ni->ni_vap->iv_input(ni, m, &rxs, rxs.rssi, rxs.nf);
return ni->ni_vap->iv_input(ni, m, &rxs, rxs.c_rssi, rxs.c_nf);
}
int
@ -109,8 +109,8 @@ ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf)
struct ieee80211_rx_stats rx;
rx.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
rx.nf = nf;
rx.rssi = rssi;
rx.c_nf = nf;
rx.c_rssi = rssi;
return ieee80211_input_mimo_all(ic, m, &rx);
}