On Mon, Jun 20, 2016 at 12:34:17PM +0200, Stefan Sperling wrote:
> I found that my 8260 iwm(4) device has trouble associating to my 5 GHz AP,
> which runs OpenBSD with athn(4) in hostap mode. Most of the time it won't
> even get a DHCP lease. Some frames it believes it has sent are not even
> visible on the air.
> 
> The iwm driver still has a copy of code from Linux that sends DTIM TSF
> information to the firmware. I believe this depends on Linux mac80211
> behaviour details and is bogus with our stack, and we should just let
> firmware handle TSF synchronization details by itself (and just look
> at those glories comments...)
> 
> Also, clear in_assoc when going down, as it effects early behaviour
> when coming up, before association (found by Imre).
> 
> I'm now getting much better results when switching between networks
> with the 8260. Doesn't cause problems on 7260 and 7265.
> 
> ok?

Sorry, the previous diff was missing a chunk and won't build.

Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.88
diff -u -p -r1.88 if_iwm.c
--- if_iwm.c    19 Jun 2016 12:05:25 -0000      1.88
+++ if_iwm.c    20 Jun 2016 10:36:47 -0000
@@ -5723,58 +5723,14 @@ iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm
        struct iwm_mac_data_sta *ctxt_sta, int force_assoc_off)
 {
        struct ieee80211_node *ni = &in->in_ni;
-       unsigned dtim_period, dtim_count;
        struct ieee80211com *ic = &sc->sc_ic;
 
-       /* will this work? */
-       dtim_period = ic->ic_dtim_period;
-       dtim_count = ic->ic_dtim_count;
-       DPRINTF(("dtim %d %d\n", dtim_period, dtim_count));
-
-       /* We need the dtim_period to set the MAC as associated */
-       if (in->in_assoc && dtim_period && !force_assoc_off) {
-               uint64_t tsf;
-               uint32_t dtim_offs;
-
-               /*
-                * The DTIM count counts down, so when it is N that means N
-                * more beacon intervals happen until the DTIM TBTT. Therefore
-                * add this to the current time. If that ends up being in the
-                * future, the firmware will handle it.
-                *
-                * Also note that the system_timestamp (which we get here as
-                * "sync_device_ts") and TSF timestamp aren't at exactly the
-                * same offset in the frame -- the TSF is at the first symbol
-                * of the TSF, the system timestamp is at signal acquisition
-                * time. This means there's an offset between them of at most
-                * a few hundred microseconds (24 * 8 bits + PLCP time gives
-                * 384us in the longest case), this is currently not relevant
-                * as the firmware wakes up around 2ms before the TBTT.
-                */
-               dtim_offs = dtim_count * ni->ni_intval;
-               /* convert TU to usecs */
-               dtim_offs *= 1024;
-
-               /* XXX: byte order? */
-               memcpy(&tsf, ni->ni_tstamp, sizeof(tsf));
-
-               ctxt_sta->dtim_tsf = htole64(tsf + dtim_offs);
-               ctxt_sta->dtim_time = htole64(ni->ni_rstamp + dtim_offs);
-
-               DPRINTF(("DTIM TBTT is 0x%llx/0x%x, offset %d\n",
-                   (long long)le64toh(ctxt_sta->dtim_tsf),
-                   le32toh(ctxt_sta->dtim_time), dtim_offs));
-
-               ctxt_sta->is_assoc = htole32(1);
-       } else {
-               ctxt_sta->is_assoc = htole32(0);
-       }
-
+       ctxt_sta->is_assoc = htole32(0);
        ctxt_sta->bi = htole32(ni->ni_intval);
        ctxt_sta->bi_reciprocal = htole32(iwm_mvm_reciprocal(ni->ni_intval));
-       ctxt_sta->dtim_interval = htole32(ni->ni_intval * dtim_period);
+       ctxt_sta->dtim_interval = htole32(ni->ni_intval * ic->ic_dtim_period);
        ctxt_sta->dtim_reciprocal =
-           htole32(iwm_mvm_reciprocal(ni->ni_intval * dtim_period));
+           htole32(iwm_mvm_reciprocal(ni->ni_intval * ic->ic_dtim_period));
 
        /* 10 = CONN_MAX_LISTEN_INTERVAL */
        ctxt_sta->listen_interval = htole32(10);
@@ -6877,6 +6833,7 @@ iwm_stop(struct ifnet *ifp, int disable)
 {
        struct iwm_softc *sc = ifp->if_softc;
        struct ieee80211com *ic = &sc->sc_ic;
+       struct iwm_node *in = (void *)ic->ic_bss;
 
        sc->sc_flags &= ~IWM_FLAG_HW_INITED;
        sc->sc_flags |= IWM_FLAG_STOPPED;
@@ -6884,6 +6841,9 @@ iwm_stop(struct ifnet *ifp, int disable)
        ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
        ifp->if_flags &= ~IFF_RUNNING;
        ifq_clr_oactive(&ifp->if_snd);
+
+       in->in_phyctxt = NULL;
+       in->in_assoc = 0;
 
        task_del(systq, &sc->init_task);
        task_del(sc->sc_nswq, &sc->newstate_task);

Reply via email to