When roaming between APs, all data in struct net80211_node is replaced as soon as we have decided to switch to a different AP.
This means that the BSSID of our old AP is no longer stored in ic_bss once we enter iwm_newstate(). We do however use this address in firmware commands while tearing things down, in order to prepare firmware for the switch. With this patch, firmware commands keep using the old BSSID while tearing things down. We switch to the new address once we start back up in iwm_auth(). This should keep things consistent from the firmware's point of view. (ic_bss->ni_chan is also affected. This will be fixed in a later patch by using the channel stored in the phy context instead of ni_chan.) Tested by florian, bket, and myself as part of a larger diff. ok? diff 10fe65f52d60daceea3a3690e6cc566759c1ab54 fbffc95c6dfab20098670aa21c2318a2eb3c9be7 blob - 64163c3776e9d3483e1e96c09efd40535626c10f blob + 3c088a34148b5b8a7a41fd88d133005b9b98bc89 --- sys/dev/pci/if_iwm.c +++ sys/dev/pci/if_iwm.c @@ -5718,9 +5718,9 @@ iwm_rx_compressed_ba(struct iwm_softc *sc, struct iwm_ { struct iwm_ba_notif *ban = (void *)pkt->data; struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni; + struct ieee80211_node *ni = ic->ic_bss; + struct iwm_node *in = (void *)ni; struct ieee80211_tx_ba *ba; - struct iwm_node *in; struct iwm_tx_ring *ring; uint16_t seq, ssn; int qid; @@ -5732,12 +5732,9 @@ iwm_rx_compressed_ba(struct iwm_softc *sc, struct iwm_ return; if (ban->sta_id != IWM_STATION_ID || - !IEEE80211_ADDR_EQ(ic->ic_bss->ni_macaddr, ban->sta_addr)) + !IEEE80211_ADDR_EQ(in->in_macaddr, ban->sta_addr)) return; - ni = ic->ic_bss; - in = (void *)ni; - qid = le16toh(ban->scd_flow); if (qid < IWM_FIRST_AGG_TX_QUEUE || qid > IWM_LAST_AGG_TX_QUEUE) return; @@ -6919,7 +6916,7 @@ iwm_add_sta_cmd(struct iwm_softc *sc, struct iwm_node etherbroadcastaddr); else IEEE80211_ADDR_COPY(&add_sta_cmd.addr, - in->in_ni.ni_bssid); + in->in_macaddr); } add_sta_cmd.add_modify = update ? 1 : 0; add_sta_cmd.station_flags_msk @@ -7900,7 +7897,7 @@ iwm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct i return; } - IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid); + IEEE80211_ADDR_COPY(cmd->bssid_addr, in->in_macaddr); iwm_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates); cmd->cck_rates = htole32(cck_ack_rates); cmd->ofdm_rates = htole32(ofdm_ack_rates); @@ -8302,6 +8299,7 @@ iwm_auth(struct iwm_softc *sc) return err; } in->in_phyctxt = &sc->sc_phyctxt[0]; + IEEE80211_ADDR_COPY(in->in_macaddr, in->in_ni.ni_macaddr); err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD, 0); if (err) { @@ -9749,7 +9747,7 @@ int iwm_allow_mcast(struct iwm_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; + struct iwm_node *in = (void *)ic->ic_bss; struct iwm_mcast_filter_cmd *cmd; size_t size; int err; @@ -9762,7 +9760,7 @@ iwm_allow_mcast(struct iwm_softc *sc) cmd->port_id = 0; cmd->count = 0; cmd->pass_all = 1; - IEEE80211_ADDR_COPY(cmd->bssid, ni->ni_bssid); + IEEE80211_ADDR_COPY(cmd->bssid, in->in_macaddr); err = iwm_send_cmd_pdu(sc, IWM_MCAST_FILTER_CMD, 0, size, cmd); @@ -9931,6 +9929,7 @@ iwm_stop(struct ifnet *ifp) in->in_phyctxt = NULL; in->tid_disable_ampdu = 0xffff; in->tfd_queue_msk = 0; + IEEE80211_ADDR_COPY(in->in_macaddr, etheranyaddr); sc->sc_flags &= ~(IWM_FLAG_SCANNING | IWM_FLAG_BGSCAN); sc->sc_flags &= ~IWM_FLAG_MAC_ACTIVE; blob - bcda8e9014625199c027cda244c649d0122f7560 blob + b43453c29a46742cad00be9e54c8a45f3ad6acb2 --- sys/dev/pci/if_iwmvar.h +++ sys/dev/pci/if_iwmvar.h @@ -654,6 +654,7 @@ struct iwm_softc { struct iwm_node { struct ieee80211_node in_ni; struct iwm_phy_ctxt *in_phyctxt; + uint8_t in_macaddr[ETHER_ADDR_LEN]; uint16_t in_id; uint16_t in_color;