Make our old BSSID available to iwm_newstate() when roaming.
authorstsp <stsp@openbsd.org>
Thu, 7 Oct 2021 08:15:04 +0000 (08:15 +0000)
committerstsp <stsp@openbsd.org>
Thu, 7 Oct 2021 08:15:04 +0000 (08:15 +0000)
ic_bss->ni_bssid has already been overwritten once we enter
iwm_newstate() to perform the state transitions necessary for
roaming to our new access point (RUN->AUTH->ASSOC->RUN).

We do however use the BSSID in commands sent to firmware.
Cache our BSSID in struct iwm_node such that firmware commands
keep using the old BSSID while we are still tearing things down.
Switch to the new BSSID only once we start back up in iwm_auth().
This should be consistent from the firmware's point of view.

ok mpi@

sys/dev/pci/if_iwm.c
sys/dev/pci/if_iwmvar.h

index 112de43..6a14572 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwm.c,v 1.373 2021/10/06 13:36:47 stsp Exp $       */
+/*     $OpenBSD: if_iwm.c,v 1.374 2021/10/07 08:15:04 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -5718,9 +5718,9 @@ iwm_rx_compressed_ba(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
 {
        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_rx_packet *pkt,
                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 *in, int update)
                            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
@@ -7899,7 +7896,7 @@ iwm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
                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);
@@ -8301,6 +8298,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) {
@@ -9750,7 +9748,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;
@@ -9763,7 +9761,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);
@@ -9932,6 +9930,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;
index bcda8e9..1d94b1a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwmvar.h,v 1.69 2021/07/08 17:14:08 stsp Exp $     */
+/*     $OpenBSD: if_iwmvar.h,v 1.70 2021/10/07 08:15:04 stsp Exp $     */
 
 /*
  * Copyright (c) 2014 genua mbh <info@genua.de>
@@ -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;