net80211: define a type for rssi values

Due to net80211 keeping values in 0.5dBm relative to the noise floor
an int8_t is not good enough to prevent a double wrap around, which
means the reported rssi values can be wrong (see D50928 or likely
a commit in the future for more information).

In order to address the problem and not break the userspace API,
start by defining a type within the kernel and use that.  In a
next step we will then update the int8_t to int16_t to avoid the
problem up to the ioctl code.  This will then allow us to work
on the the user space API indepedently (see PR 293016 for possible
impact outside the base system).

No functional changes intended.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
Reviewed by:	adrian
Differential Revision: https://reviews.freebsd.org/D57021
This commit is contained in:
Bjoern A. Zeeb
2025-06-19 00:05:27 +00:00
parent d201e4e849
commit 96eaa6857f
15 changed files with 47 additions and 39 deletions
+2 -2
View File
@@ -179,7 +179,7 @@ static struct ieee80211_node *ath_node_alloc(struct ieee80211vap *,
static void ath_node_cleanup(struct ieee80211_node *);
static void ath_node_free(struct ieee80211_node *);
static void ath_node_getsignal(const struct ieee80211_node *,
int8_t *, int8_t *);
net80211_rssi_t *, int8_t *);
static void ath_txq_init(struct ath_softc *sc, struct ath_txq *, int);
static struct ath_txq *ath_txq_setup(struct ath_softc*, int qtype, int subtype);
static int ath_tx_setup(struct ath_softc *, int, int);
@@ -3957,7 +3957,7 @@ ath_node_free(struct ieee80211_node *ni)
}
static void
ath_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise)
ath_node_getsignal(const struct ieee80211_node *ni, net80211_rssi_t *rssi, int8_t *noise)
{
struct ieee80211com *ic = ni->ni_ic;
struct ath_softc *sc = ic->ic_softc;
+2 -2
View File
@@ -129,7 +129,7 @@ static struct ieee80211_node *mwl_node_alloc(struct ieee80211vap *,
static void mwl_node_cleanup(struct ieee80211_node *);
static void mwl_node_drain(struct ieee80211_node *);
static void mwl_node_getsignal(const struct ieee80211_node *,
int8_t *, int8_t *);
net80211_rssi_t *, int8_t *);
static void mwl_node_getmimoinfo(const struct ieee80211_node *,
struct ieee80211_mimo_info *);
static int mwl_rxbuf_init(struct mwl_softc *, struct mwl_rxbuf *);
@@ -2390,7 +2390,7 @@ mwl_node_drain(struct ieee80211_node *ni)
}
static void
mwl_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise)
mwl_node_getsignal(const struct ieee80211_node *ni, net80211_rssi_t *rssi, int8_t *noise)
{
*rssi = ni->ni_ic->ic_node_getrssi(ni);
#ifdef MWL_ANT_INFO_SUPPORT
+10 -5
View File
@@ -374,6 +374,11 @@ struct ieee80211_channel {
#define IEEE80211_AID_DEF 128
#define IEEE80211_AID_MIN 16
/*
* Definitions for (internal, basic) types.
*/
typedef int8_t net80211_rssi_t;
/*
* 802.11 rate set.
*/
@@ -618,14 +623,14 @@ struct ieee80211_rx_stats {
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 */
net80211_rssi_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */
net80211_rssi_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */
net80211_rssi_t c_rssi_ctl[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */
net80211_rssi_t c_rssi_ext[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */
/* 32 bits */
int8_t c_nf; /* global NF */
int8_t c_rssi; /* global RSSI */
net80211_rssi_t c_rssi; /* global RSSI */
uint8_t c_chain; /* number of RX chains involved */
uint8_t c_rate; /* legacy; 11n rate code; VHT MCS */
+2 -2
View File
@@ -68,7 +68,7 @@
static void adhoc_vattach(struct ieee80211vap *);
static int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int adhoc_input(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_rx_stats *, int, int);
const struct ieee80211_rx_stats *, net80211_rssi_t, int);
static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *,
int subtype, const struct ieee80211_rx_stats *, int, int);
static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *,
@@ -301,7 +301,7 @@ doprint(struct ieee80211vap *vap, int subtype)
*/
static int
adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *rxs, int rssi, int nf)
const struct ieee80211_rx_stats *rxs, net80211_rssi_t rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
+2 -2
View File
@@ -66,7 +66,7 @@ static void hostap_vattach(struct ieee80211vap *);
static int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int hostap_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *,
int rssi, int nf);
net80211_rssi_t rssi, int nf);
static void hostap_deliver_data(struct ieee80211vap *,
struct ieee80211_node *, struct mbuf *);
static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *,
@@ -466,7 +466,7 @@ doprint(struct ieee80211vap *vap, int subtype)
*/
static int
hostap_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *rxs, int rssi, int nf)
const struct ieee80211_rx_stats *rxs, net80211_rssi_t rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
+3 -1
View File
@@ -379,6 +379,7 @@ get_sta_info(void *arg, struct ieee80211_node *ni)
struct ieee80211_node_txrate tr;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211req_sta_info *si;
net80211_rssi_t rssi;
size_t ielen, len;
uint8_t *cp;
@@ -398,7 +399,8 @@ get_sta_info(void *arg, struct ieee80211_node *ni)
si->isi_flags = ni->ni_chan->ic_flags;
si->isi_state = ni->ni_flags;
si->isi_authmode = ni->ni_authmode;
vap->iv_ic->ic_node_getsignal(ni, &si->isi_rssi, &si->isi_noise);
vap->iv_ic->ic_node_getsignal(ni, &rssi, &si->isi_noise);
si->isi_rssi = rssi;
vap->iv_ic->ic_node_getmimoinfo(ni, &si->isi_mimo);
si->isi_capinfo = ni->ni_capinfo;
si->isi_erp = ni->ni_erp;
+2 -2
View File
@@ -83,7 +83,7 @@ static void mesh_transmit_to_gate(struct ieee80211vap *, struct mbuf *,
static void mesh_forward(struct ieee80211vap *, struct mbuf *,
const struct ieee80211_meshcntl *);
static int mesh_input(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_rx_stats *rxs, int, int);
const struct ieee80211_rx_stats *rxs, net80211_rssi_t, int);
static void mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
const struct ieee80211_rx_stats *rxs, int, int);
static void mesh_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
@@ -1525,7 +1525,7 @@ mesh_recv_group_data(struct ieee80211vap *vap, struct mbuf *m,
static int
mesh_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *rxs, int rssi, int nf)
const struct ieee80211_rx_stats *rxs, net80211_rssi_t rssi, int nf)
{
#define HAS_SEQ(type) ((type & 0x4) == 0)
#define MC01(mc) ((const struct ieee80211_meshcntl_ae01 *)mc)
+2 -2
View File
@@ -58,7 +58,7 @@
static void monitor_vattach(struct ieee80211vap *);
static int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int monitor_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *rxs, int rssi, int nf);
const struct ieee80211_rx_stats *rxs, net80211_rssi_t rssi, int nf);
void
ieee80211_monitor_attach(struct ieee80211com *ic)
@@ -123,7 +123,7 @@ monitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
*/
static int
monitor_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *rxs, int rssi, int nf)
const struct ieee80211_rx_stats *rxs, net80211_rssi_t rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ifnet *ifp = vap->iv_ifp;
+9 -9
View File
@@ -91,8 +91,8 @@ static int node_init(struct ieee80211_node *);
static void node_cleanup(struct ieee80211_node *);
static void node_free(struct ieee80211_node *);
static void node_age(struct ieee80211_node *);
static int8_t node_getrssi(const struct ieee80211_node *);
static void node_getsignal(const struct ieee80211_node *, int8_t *, int8_t *);
static net80211_rssi_t node_getrssi(const struct ieee80211_node *);
static void node_getsignal(const struct ieee80211_node *, net80211_rssi_t *, int8_t *);
static void node_getmimoinfo(const struct ieee80211_node *,
struct ieee80211_mimo_info *);
@@ -1341,7 +1341,7 @@ node_age(struct ieee80211_node *ni)
ieee80211_ht_node_age(ni);
}
static int8_t
static net80211_rssi_t
node_getrssi(const struct ieee80211_node *ni)
{
uint32_t avgrssi = ni->ni_avgrssi;
@@ -1354,7 +1354,7 @@ node_getrssi(const struct ieee80211_node *ni)
}
static void
node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise)
node_getsignal(const struct ieee80211_node *ni, net80211_rssi_t *rssi, int8_t *noise)
{
*rssi = node_getrssi(ni);
*noise = ni->ni_noise;
@@ -3039,7 +3039,7 @@ get_hostap_rssi(void *arg, struct ieee80211_node *ni)
{
struct rssiinfo *info = arg;
struct ieee80211vap *vap = ni->ni_vap;
int8_t rssi;
net80211_rssi_t rssi;
/* only associated stations */
if (ni->ni_associd == 0)
@@ -3056,7 +3056,7 @@ get_adhoc_rssi(void *arg, struct ieee80211_node *ni)
{
struct rssiinfo *info = arg;
struct ieee80211vap *vap = ni->ni_vap;
int8_t rssi;
net80211_rssi_t rssi;
/* only neighbors */
/* XXX check bssid */
@@ -3075,7 +3075,7 @@ get_mesh_rssi(void *arg, struct ieee80211_node *ni)
{
struct rssiinfo *info = arg;
struct ieee80211vap *vap = ni->ni_vap;
int8_t rssi;
net80211_rssi_t rssi;
/* only neighbors that peered successfully */
if (ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
@@ -3088,7 +3088,7 @@ get_mesh_rssi(void *arg, struct ieee80211_node *ni)
}
#endif /* IEEE80211_SUPPORT_MESH */
int8_t
net80211_rssi_t
ieee80211_getrssi(struct ieee80211vap *vap)
{
#define NZ(x) ((x) == 0 ? 1 : (x))
@@ -3126,7 +3126,7 @@ ieee80211_getrssi(struct ieee80211vap *vap)
}
void
ieee80211_getsignal(struct ieee80211vap *vap, int8_t *rssi, int8_t *noise)
ieee80211_getsignal(struct ieee80211vap *vap, net80211_rssi_t *rssi, int8_t *noise)
{
if (vap->iv_bss == NULL) /* NB: shouldn't happen */
+2 -2
View File
@@ -528,8 +528,8 @@ struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211vap *,
const struct ieee80211_scanparams *);
void ieee80211_node_join(struct ieee80211_node *,int);
void ieee80211_node_leave(struct ieee80211_node *);
int8_t ieee80211_getrssi(struct ieee80211vap *);
void ieee80211_getsignal(struct ieee80211vap *, int8_t *, int8_t *);
net80211_rssi_t ieee80211_getrssi(struct ieee80211vap *);
void ieee80211_getsignal(struct ieee80211vap *, net80211_rssi_t *, int8_t *);
/* TX sequence space related routines */
ieee80211_seq ieee80211_tx_seqno_fetch_incr(struct ieee80211_node *,
+1 -1
View File
@@ -63,7 +63,7 @@ struct ieee80211_ratectl_tx_status {
int final_rate; /* transmission rate */
uint_fast8_t short_retries; /* RTS/CTS retries */
uint_fast8_t long_retries; /* ACK retries */
int8_t rssi; /* ACK RSSI */
net80211_rssi_t rssi; /* ACK RSSI */
uint8_t spare[15]; /* for future use */
};
+1 -1
View File
@@ -282,7 +282,7 @@ struct ieee80211_scan_entry {
uint8_t se_fhindex; /* FH only */
uint8_t se_dtimperiod; /* DTIM period */
uint16_t se_erp; /* ERP from beacon/probe resp */
int8_t se_rssi; /* avg'd recv ssi */
net80211_rssi_t se_rssi; /* avg'd recv ssi */
int8_t se_noise; /* noise floor */
uint8_t se_cc[2]; /* captured country code */
uint8_t se_meshid[2+IEEE80211_MESHID_LEN];
+2 -2
View File
@@ -67,7 +67,7 @@ static void sta_vattach(struct ieee80211vap *);
static void sta_beacon_miss(struct ieee80211vap *);
static int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int sta_input(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_rx_stats *, int, int);
const struct ieee80211_rx_stats *, net80211_rssi_t, int);
static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *,
int subtype, const struct ieee80211_rx_stats *, int rssi, int nf);
static void sta_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
@@ -530,7 +530,7 @@ doprint(struct ieee80211vap *vap, int subtype)
*/
static int
sta_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *rxs, int rssi, int nf)
const struct ieee80211_rx_stats *rxs, net80211_rssi_t rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
+3 -3
View File
@@ -325,9 +325,9 @@ struct ieee80211com {
void (*ic_node_age)(struct ieee80211_node *);
void (*ic_node_drain)(struct ieee80211_node *);
int8_t (*ic_node_getrssi)(const struct ieee80211_node*);
net80211_rssi_t (*ic_node_getrssi)(const struct ieee80211_node*);
void (*ic_node_getsignal)(const struct ieee80211_node*,
int8_t *, int8_t *);
net80211_rssi_t *, int8_t *);
void (*ic_node_getmimoinfo)(
const struct ieee80211_node*,
struct ieee80211_mimo_info *);
@@ -543,7 +543,7 @@ struct ieee80211vap {
int (*iv_input)(struct ieee80211_node *,
struct mbuf *,
const struct ieee80211_rx_stats *,
int, int);
net80211_rssi_t, int);
void (*iv_recv_mgmt)(struct ieee80211_node *,
struct mbuf *, int,
const struct ieee80211_rx_stats *,
+4 -3
View File
@@ -62,7 +62,7 @@
static void wds_vattach(struct ieee80211vap *);
static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int wds_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *rxs, int, int);
const struct ieee80211_rx_stats *rxs, net80211_rssi_t, int);
static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *, int subtype,
const struct ieee80211_rx_stats *, int, int);
@@ -101,7 +101,8 @@ wds_flush(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
struct mbuf *m, *next;
int8_t rssi, nf;
net80211_rssi_t rssi;
int8_t nf;
m = ieee80211_ageq_remove(&ic->ic_stageq,
(void *)(uintptr_t) ieee80211_mac_hash(ic, ni->ni_macaddr));
@@ -404,7 +405,7 @@ wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
*/
static int
wds_input(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_rx_stats *rxs, int rssi, int nf)
const struct ieee80211_rx_stats *rxs, net80211_rssi_t rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;