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);