git: bdfe17f129db - main - LinuxKPI: 802.11: dtim_period/beacon count
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 25 Aug 2025 09:54:10 UTC
The branch main has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=bdfe17f129db0e81b0826ffc3ce66d41b9cb93ae
commit bdfe17f129db0e81b0826ffc3ce66d41b9cb93ae
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-07-10 10:24:13 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-08-25 09:54:03 +0000
LinuxKPI: 802.11: dtim_period/beacon count
Hook into net80211's (*iv_recv_mgmt)() callback so we can track
beacons. This is mostly for us to know if we have seen any after
assoc or for further debugging when we run into beacon/connection loss
based on a firmware/driver event.
Also set/reset dtim_period depending on state and beacon/probe response
so that the value available to the driver reflects reality.
Sponsonred by: The FreeBSD Foundation
MFC after: 3 days
---
sys/compat/linuxkpi/common/src/linux_80211.c | 68 ++++++++++++++++++++++++++--
sys/compat/linuxkpi/common/src/linux_80211.h | 6 +++
2 files changed, 70 insertions(+), 4 deletions(-)
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 903061117fc3..76138dcc869b 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -1926,6 +1926,7 @@ lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
struct lkpi_hw *lhw)
{
enum ieee80211_bss_changed changed;
+ struct lkpi_vif *lvif;
changed = 0;
sta->aid = 0;
@@ -1949,6 +1950,9 @@ lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
* bss_info_changed() update.
* See lkpi_sta_run_to_init() for more detailed comment.
*/
+
+ lvif = VIF_TO_LVIF(vif);
+ lvif->beacons = 0;
}
return (changed);
@@ -2219,6 +2223,7 @@ lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int
/* vif->bss_conf.basic_rates ? Where exactly? */
+ lvif->beacons = 0;
/* Should almost assert it is this. */
vif->cfg.assoc = false;
vif->cfg.aid = 0;
@@ -2408,6 +2413,7 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int
struct lkpi_sta *lsta;
struct ieee80211_sta *sta;
struct ieee80211_prep_tx_info prep_tx_info;
+ enum ieee80211_bss_changed bss_changed;
int error;
lhw = vap->iv_ic->ic_softc;
@@ -2479,6 +2485,11 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int
lsta->added_to_drv = false; /* mo manages. */
#endif
+ bss_changed = 0;
+ vif->bss_conf.dtim_period = 0; /* go back to 0. */
+ bss_changed |= BSS_CHANGED_BEACON_INFO;
+ lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
+
lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
LKPI_80211_LVIF_LOCK(lvif);
@@ -2807,6 +2818,8 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i
vif->cfg.ssid_len = 0;
memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid));
bss_changed |= BSS_CHANGED_BSSID;
+ vif->bss_conf.dtim_period = 0; /* go back to 0. */
+ bss_changed |= BSS_CHANGED_BEACON_INFO;
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
LKPI_80211_LVIF_LOCK(lvif);
@@ -2939,6 +2952,7 @@ lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int
bss_changed |= lkpi_wme_update(lhw, vap, true);
#endif
if (!vif->cfg.assoc || vif->cfg.aid != IEEE80211_NODE_AID(ni)) {
+ lvif->beacons = 0;
vif->cfg.assoc = true;
vif->cfg.aid = IEEE80211_NODE_AID(ni);
bss_changed |= BSS_CHANGED_ASSOC;
@@ -3408,6 +3422,8 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int
vif->bss_conf.use_short_preamble = false;
vif->bss_conf.qos = false;
/* XXX BSS_CHANGED_???? */
+ vif->bss_conf.dtim_period = 0; /* go back to 0. */
+ bss_changed |= BSS_CHANGED_BEACON_INFO;
lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
LKPI_80211_LVIF_LOCK(lvif);
@@ -3710,6 +3726,42 @@ lkpi_ic_wme_update(struct ieee80211com *ic)
return (0); /* unused */
}
+static void
+lkpi_iv_sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
+{
+ struct lkpi_hw *lhw;
+ struct ieee80211_hw *hw;
+ struct lkpi_vif *lvif;
+ struct ieee80211_vif *vif;
+ enum ieee80211_bss_changed bss_changed;
+
+ lvif = VAP_TO_LVIF(ni->ni_vap);
+
+ lvif->iv_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
+
+ switch (subtype) {
+ case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
+ break;
+ case IEEE80211_FC0_SUBTYPE_BEACON:
+ lvif->beacons++;
+ break;
+ default:
+ return;
+ }
+
+ vif = LVIF_TO_VIF(lvif);
+ lhw = ni->ni_ic->ic_softc;
+ hw = LHW_TO_HW(lhw);
+
+ /*
+ * If this direct call to mo_bss_info_changed will not work due to
+ * locking, see if queue_work() is fast enough.
+ */
+ bss_changed = lkpi_update_dtim_tsf(vif, ni, ni->ni_vap, __func__, __LINE__);
+ lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
+}
+
/*
* Change link-layer address on the vif (if the vap is not started/"UP").
* This can happen if a user changes 'ether' using ifconfig.
@@ -3905,6 +3957,8 @@ lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
vap->iv_newstate = lkpi_iv_newstate;
lvif->iv_update_bss = vap->iv_update_bss;
vap->iv_update_bss = lkpi_iv_update_bss;
+ lvif->iv_recv_mgmt = vap->iv_recv_mgmt;
+ vap->iv_recv_mgmt = lkpi_iv_sta_recv_mgmt;
#ifdef LKPI_80211_HW_CRYPTO
/* Key management. */
@@ -7865,8 +7919,11 @@ linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *vif)
nstate = IEEE80211_S_INIT;
arg = 0; /* Not a valid reason. */
- ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__,
- vif, vap, ieee80211_state_name[vap->iv_state]);
+ ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s (synched %d, assoc %d "
+ "beacons %d dtim_period %d)\n", __func__, vif, vap,
+ ieee80211_state_name[vap->iv_state],
+ lvif->lvif_bss_synched, vif->cfg.assoc, lvif->beacons,
+ vif->bss_conf.dtim_period);
ieee80211_new_state(vap, nstate, arg);
}
@@ -7879,8 +7936,11 @@ linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *vif)
lvif = VIF_TO_LVIF(vif);
vap = LVIF_TO_VAP(lvif);
- ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__,
- vif, vap, ieee80211_state_name[vap->iv_state]);
+ ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s (synched %d, assoc %d "
+ "beacons %d dtim_period %d)\n", __func__, vif, vap,
+ ieee80211_state_name[vap->iv_state],
+ lvif->lvif_bss_synched, vif->cfg.assoc, lvif->beacons,
+ vif->bss_conf.dtim_period);
ieee80211_beacon_miss(vap->iv_ic);
}
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h
index 89afec1235bd..d21d58d7343c 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.h
+++ b/sys/compat/linuxkpi/common/src/linux_80211.h
@@ -187,6 +187,11 @@ struct lkpi_vif {
enum ieee80211_state, int);
struct ieee80211_node * (*iv_update_bss)(struct ieee80211vap *,
struct ieee80211_node *);
+ void (*iv_recv_mgmt)(struct ieee80211_node *,
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *,
+ int, int);
+
struct list_head lsta_list;
struct lkpi_sta *lvif_bss;
@@ -194,6 +199,7 @@ struct lkpi_vif {
struct ieee80211_node *key_update_iv_bss;
int ic_unlocked; /* Count of ic unlocks pending (*mo_set_key) */
int nt_unlocked; /* Count of nt unlocks pending (*mo_set_key) */
+ int beacons; /* # of beacons since assoc */
bool lvif_bss_synched;
bool added_to_drv; /* Driver knows; i.e. we called add_interface(). */