Parse the DTIM count and period advertised in beacons and store them
in the node structure. This should be useful for iwm(4) in the future.
The TIM IE is documented in 802.11-2012 section "8.4.2.7 TIM element".

ok?

There used to be code in iwm(4) which read these values from the ic
(ic->ic_dtim_count and ic->ic_dtim_period) and did math based on them.
An obvious bug in hindsight. The device needs live values from the AP
and not some static values we set in our stack. The driver code that did
this has already been deleted because it didn't allow 8k devices to work.

Index: net80211/ieee80211_input.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.178
diff -u -p -r1.178 ieee80211_input.c
--- net80211/ieee80211_input.c  18 May 2016 08:15:28 -0000      1.178
+++ net80211/ieee80211_input.c  20 Sep 2016 12:02:11 -0000
@@ -1393,7 +1393,7 @@ ieee80211_recv_probe_resp(struct ieee802
        const u_int8_t *tstamp, *ssid, *rates, *xrates, *edcaie, *wmmie;
        const u_int8_t *rsnie, *wpaie, *htcaps, *htop;
        u_int16_t capinfo, bintval;
-       u_int8_t chan, bchan, erp;
+       u_int8_t chan, bchan, erp, dtim_count, dtim_period;
        int is_new;
 
        /*
@@ -1436,6 +1436,7 @@ ieee80211_recv_probe_resp(struct ieee802
        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++;
@@ -1477,6 +1478,12 @@ ieee80211_recv_probe_resp(struct ieee802
                case IEEE80211_ELEMID_HTOP:
                        htop = frm;
                        break;
+               case IEEE80211_ELEMID_TIM:
+                       if (frm[1] > 3) {
+                               dtim_count = frm[2];
+                               dtim_period = frm[3];
+                       }
+                       break;
                case IEEE80211_ELEMID_VENDOR:
                        if (frm[1] < 4) {
                                ic->ic_stats.is_rx_elem_toosmall++;
@@ -1567,6 +1574,9 @@ ieee80211_recv_probe_resp(struct ieee802
                ieee80211_setup_htcaps(ni, htcaps + 2, htcaps[1]);
        if (htop && !ieee80211_setup_htop(ni, htop + 2, htop[1]))
                htop = NULL; /* invalid HTOP */
+
+       ni->ni_dtimcount = dtim_count;
+       ni->ni_dtimperiod = dtim_period;
 
        /*
         * When operating in station mode, check for state updates
Index: net80211/ieee80211_node.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.h,v
retrieving revision 1.60
diff -u -p -r1.60 ieee80211_node.h
--- net80211/ieee80211_node.h   28 Apr 2016 08:18:10 -0000      1.60
+++ net80211/ieee80211_node.h   20 Sep 2016 12:01:37 -0000
@@ -188,9 +188,10 @@ struct ieee80211_node {
        struct ieee80211_channel *ni_chan;
        u_int8_t                ni_erp;         /* 11g only */
 
-#ifdef notyet
        /* DTIM and contention free period (CFP) */
+       u_int8_t                ni_dtimcount;
        u_int8_t                ni_dtimperiod;
+#ifdef notyet
        u_int8_t                ni_cfpperiod;   /* # of DTIMs between CFPs */
        u_int16_t               ni_cfpduremain; /* remaining cfp duration */
        u_int16_t               ni_cfpmaxduration;/* max CFP duration in TU */

Reply via email to