summaryrefslogtreecommitdiff
path: root/sys/net80211
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2022-01-21 15:51:04 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2022-01-21 15:51:04 +0000
commitf8547beb5ca95bae25874eb43400333a598c21ab (patch)
treeaa3c1cda44df9461f21146e27c99cadf8baf5e10 /sys/net80211
parentf41e79d10eba835c1d3cf295c2df1da31e868c10 (diff)
Fix and re-enable active scans on iwm(4) and iwx(4).
Ensure that we supply the access point's DTIM period to firmware after an active scan, as soon as the next beacon arrives. This prevents the problems which prompted us to keep active scans disabled in our drivers. Problem debugged and patch by zxystd from the OpenIntelWireless project. I made some tweaks regarding TIM parsing, which were reviewed by zxystd. Johannes Berg from Intel has confirmed to me via IRC that firmware will misbehave if running with a zero DTIM period. Tested: 8265: jca, stsp 9260: kettenis (possible fallout observed here; will keep an eye on it) 9650: stsp ax200: zxystd, kevlo, stsp ax201: stsp ok kevlo@ kettenis@
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_input.c30
-rw-r--r--sys/net80211/ieee80211_var.h3
2 files changed, 22 insertions, 11 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index d764aa0cc43..fcc847845b2 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_input.c,v 1.242 2022/01/12 08:29:27 stsp Exp $ */
+/* $OpenBSD: ieee80211_input.c,v 1.243 2022/01/21 15:51:03 stsp Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
@@ -1605,10 +1605,10 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m,
struct ieee80211_node *ni;
const struct ieee80211_frame *wh;
const u_int8_t *frm, *efrm;
- const u_int8_t *tstamp, *ssid, *rates, *xrates, *edcaie, *wmmie;
+ const u_int8_t *tstamp, *ssid, *rates, *xrates, *edcaie, *wmmie, *tim;
const u_int8_t *rsnie, *wpaie, *htcaps, *htop;
u_int16_t capinfo, bintval;
- u_int8_t chan, bchan, erp, dtim_count, dtim_period;
+ u_int8_t chan, bchan, erp;
int is_new;
/*
@@ -1646,12 +1646,11 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m,
bintval = LE_READ_2(frm); frm += 2;
capinfo = LE_READ_2(frm); frm += 2;
- ssid = rates = xrates = edcaie = wmmie = rsnie = wpaie = NULL;
+ ssid = rates = xrates = edcaie = wmmie = rsnie = wpaie = tim = NULL;
htcaps = htop = NULL;
bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
chan = bchan;
erp = 0;
- dtim_count = dtim_period = 0;
while (frm + 2 <= efrm) {
if (frm + 2 + frm[1] > efrm) {
ic->ic_stats.is_rx_elem_toosmall++;
@@ -1694,10 +1693,11 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m,
htop = frm;
break;
case IEEE80211_ELEMID_TIM:
- if (frm[1] > 3) {
- dtim_count = frm[2];
- dtim_period = frm[3];
+ if (frm[1] < 4) {
+ ic->ic_stats.is_rx_elem_toosmall++;
+ break;
}
+ tim = frm;
break;
case IEEE80211_ELEMID_VENDOR:
if (frm[1] < 4) {
@@ -1780,8 +1780,10 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m,
if (htop && !ieee80211_setup_htop(ni, htop + 2, htop[1], 1))
htop = NULL; /* invalid HTOP */
- ni->ni_dtimcount = dtim_count;
- ni->ni_dtimperiod = dtim_period;
+ if (tim) {
+ ni->ni_dtimcount = tim[2];
+ ni->ni_dtimperiod = tim[3];
+ }
/*
* When operating in station mode, check for state updates
@@ -1860,6 +1862,14 @@ ieee80211_recv_probe_resp(struct ieee80211com *ic, struct mbuf *m,
(capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
}
+ if (tim && ic->ic_bss->ni_dtimperiod != ni->ni_dtimperiod) {
+ ic->ic_bss->ni_dtimperiod = ni->ni_dtimperiod;
+ ic->ic_bss->ni_dtimcount = ni->ni_dtimcount;
+
+ if (ic->ic_updatedtim != NULL)
+ ic->ic_updatedtim(ic);
+ }
+
/*
* Reset management timer. If it is non-zero in RUN state, the
* driver sent a probe request after a missed beacon event.
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index d211947e3d0..161853a6298 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_var.h,v 1.109 2021/12/05 11:33:45 stsp Exp $ */
+/* $OpenBSD: ieee80211_var.h,v 1.110 2022/01/21 15:51:03 stsp Exp $ */
/* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */
/*-
@@ -249,6 +249,7 @@ struct ieee80211com {
struct ieee80211_node *, u_int8_t);
void (*ic_updateprot)(struct ieee80211com *);
void (*ic_updatechan)(struct ieee80211com *);
+ void (*ic_updatedtim)(struct ieee80211com *);
int (*ic_bgscan_start)(struct ieee80211com *);
void (*ic_bgscan_done)(struct ieee80211com *,
struct ieee80211_node_switch_bss_arg *,