On Sat, Sep 26, 2015 at 03:37:22PM +0200, Stefan Sperling wrote:
> This diff fixes the issue for me.

Same diff, + my uncommitted mac context diff from
http://marc.info/?l=openbsd-tech&m=144294310002198&w=2

Also adds a tweak to the ioctl handler which finally fixes
  ifconfig iwm0 lladdr random
This depends on the etheranyaddr changes of the bsd.rd fix diff.

ok?

Index: dev/pci/if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.49
diff -u -p -r1.49 if_iwm.c
--- dev/pci/if_iwm.c    26 Sep 2015 10:52:09 -0000      1.49
+++ dev/pci/if_iwm.c    26 Sep 2015 15:06:42 -0000
@@ -2803,8 +2803,10 @@ iwm_run_init_mvm_ucode(struct iwm_softc 
                        printf("%s: failed to read nvm\n", DEVNAME(sc));
                        return error;
                }
-               memcpy(&sc->sc_ic.ic_myaddr,
-                   &sc->sc_nvm.hw_addr, ETHER_ADDR_LEN);
+
+               if (IEEE80211_ADDR_EQ(etheranyaddr, sc->sc_ic.ic_myaddr))
+                       IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
+                           sc->sc_nvm.hw_addr);
 
                sc->sc_scan_cmd_len = sizeof(struct iwm_scan_cmd)
                    + sc->sc_capa_max_probe_len
@@ -4634,7 +4636,8 @@ iwm_mvm_ack_rates(struct iwm_softc *sc, 
        uint8_t ofdm = 0;
        int i;
 
-       if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
+       if (ni->ni_chan == IEEE80211_CHAN_ANYC ||
+           IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
                for (i = 0; i <= IWM_LAST_CCK_RATE; i++) {
                        cck |= (1 << i);
                        if (lowest_present_cck > i)
@@ -4998,11 +5001,6 @@ iwm_auth(struct iwm_softc *sc)
        if (error)
                return error;
 
-       if ((error = iwm_mvm_mac_ctxt_add(sc, in)) != 0) {
-               DPRINTF(("%s: failed to add MAC\n", DEVNAME(sc)));
-               return error;
-       }
-
        if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0],
            in->in_ni.ni_chan, 1, 1)) != 0) {
                DPRINTF(("%s: failed add phy ctxt\n", DEVNAME(sc)));
@@ -5455,6 +5453,7 @@ int
 iwm_init_hw(struct iwm_softc *sc)
 {
        struct ieee80211com *ic = &sc->sc_ic;
+       struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
        int error, i, qid;
 
        if ((error = iwm_preinit(sc)) != 0)
@@ -5518,6 +5517,12 @@ iwm_init_hw(struct iwm_softc *sc)
                iwm_enable_txq(sc, qid, qid);
        }
 
+       /* Add the MAC context. */
+       if ((error = iwm_mvm_mac_ctxt_add(sc, in)) != 0) {
+               printf("%s: failed to add MAC\n", DEVNAME(sc));
+               goto error;
+       }
+
        return 0;
 
  error:
@@ -5754,6 +5759,11 @@ iwm_ioctl(struct ifnet *ifp, u_long cmd,
                        error = 0;
                break;
 
+       case SIOCSIFLLADDR:
+               IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
+                   ((struct arpcom *)ifp)->ac_enaddr);
+               break;
+
        default:
                error = ieee80211_ioctl(ifp, cmd, data);
        }
@@ -6370,9 +6380,14 @@ iwm_preinit(struct iwm_softc *sc)
                memset(&ic->ic_sup_rates[IEEE80211_MODE_11A], 0,
                    sizeof(ic->ic_sup_rates[IEEE80211_MODE_11A]));
 
-       /* Reattach net80211 so MAC address and channel map are picked up. */
-       ieee80211_ifdetach(ifp);
-       ieee80211_ifattach(ifp);
+       /* Configure channel information obtained from firmware. */
+       ieee80211_channel_init(ifp);
+
+       /* Configure MAC address. */
+       error = if_setlladdr(ifp, ic->ic_myaddr);
+       if (error)
+               printf("%s: could not set MAC address (error %d)\n",
+                   DEVNAME(sc), error);
 
        ic->ic_node_alloc = iwm_node_alloc;
 
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.380
diff -u -p -r1.380 if.c
--- net/if.c    13 Sep 2015 18:15:03 -0000      1.380
+++ net/if.c    26 Sep 2015 13:41:27 -0000
@@ -1568,6 +1568,22 @@ if_put(struct ifnet *ifp)
        atomic_dec_int(&ifp->if_refcnt);
 }
 
+int
+if_setlladdr(struct ifnet *ifp, caddr_t lladdr)
+{
+       struct sockaddr_dl *sdl;
+
+       sdl = (struct sockaddr_dl *)ifp->if_sadl;
+       if (sdl == NULL)
+               return (EINVAL);
+
+       bcopy(lladdr, (caddr_t)((struct arpcom *)ifp)->ac_enaddr,
+           ETHER_ADDR_LEN);
+       bcopy(lladdr, LLADDR(sdl), ETHER_ADDR_LEN);
+
+       return (0);
+}
+
 /*
  * Interface ioctls.
  */
@@ -1969,11 +1985,7 @@ ifioctl(struct socket *so, u_long cmd, c
                case IFT_CARP:
                case IFT_XETHER:
                case IFT_ISO88025:
-                       bcopy((caddr_t)ifr->ifr_addr.sa_data,
-                           (caddr_t)((struct arpcom *)ifp)->ac_enaddr,
-                           ETHER_ADDR_LEN);
-                       bcopy((caddr_t)ifr->ifr_addr.sa_data,
-                           LLADDR(sdl), ETHER_ADDR_LEN);
+                       if_setlladdr(ifp, (caddr_t)ifr->ifr_addr.sa_data);
                        error = (*ifp->if_ioctl)(ifp, cmd, data);
                        if (error == ENOTTY)
                                error = 0;
Index: net/if.h
===================================================================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.167
diff -u -p -r1.167 if.h
--- net/if.h    11 Sep 2015 13:02:28 -0000      1.167
+++ net/if.h    26 Sep 2015 13:41:27 -0000
@@ -469,6 +469,7 @@ void        ifnewlladdr(struct ifnet *);
 void   if_congestion(void);
 int    if_congested(void);
 __dead void    unhandled_af(int);
+int    if_setlladdr(struct ifnet *, caddr_t);
 
 #endif /* _KERNEL */
 
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.226
diff -u -p -r1.226 if_ethersubr.c
--- net/if_ethersubr.c  17 Sep 2015 04:53:27 -0000      1.226
+++ net/if_ethersubr.c  26 Sep 2015 13:41:28 -0000
@@ -121,8 +121,10 @@ didn't get a copy, you may request one f
 #include <netmpls/mpls.h>
 #endif /* MPLS */
 
-u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
+u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+u_int8_t etheranyaddr[ETHER_ADDR_LEN] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 #define senderr(e) { error = (e); goto bad;}
 
 int
Index: net80211/ieee80211.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211.c,v
retrieving revision 1.45
diff -u -p -r1.45 ieee80211.c
--- net80211/ieee80211.c        11 Sep 2015 13:02:28 -0000      1.45
+++ net80211/ieee80211.c        26 Sep 2015 13:41:28 -0000
@@ -72,24 +72,12 @@ void ieee80211_setbasicrates(struct ieee
 int ieee80211_findrate(struct ieee80211com *, enum ieee80211_phymode, int);
 
 void
-ieee80211_ifattach(struct ifnet *ifp)
+ieee80211_channel_init(struct ifnet *ifp)
 {
        struct ieee80211com *ic = (void *)ifp;
        struct ieee80211_channel *c;
        int i;
 
-       memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr,
-               ETHER_ADDR_LEN);
-       ether_ifattach(ifp);
-
-       ifp->if_output = ieee80211_output;
-
-#if NBPFILTER > 0
-       bpfattach(&ic->ic_rawbpf, ifp, DLT_IEEE802_11,
-           sizeof(struct ieee80211_frame_addr4));
-#endif
-       ieee80211_crypto_attach(ifp);
-
        /*
         * Fill in 802.11 available channel set, mark
         * all available channels as active, and pick
@@ -130,6 +118,26 @@ ieee80211_ifattach(struct ifnet *ifp)
                ic->ic_curmode = IEEE80211_MODE_AUTO;
        ic->ic_des_chan = IEEE80211_CHAN_ANYC;  /* any channel is ok */
        ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
+}
+
+void
+ieee80211_ifattach(struct ifnet *ifp)
+{
+       struct ieee80211com *ic = (void *)ifp;
+
+       memcpy(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr,
+               ETHER_ADDR_LEN);
+       ether_ifattach(ifp);
+
+       ifp->if_output = ieee80211_output;
+
+#if NBPFILTER > 0
+       bpfattach(&ic->ic_rawbpf, ifp, DLT_IEEE802_11,
+           sizeof(struct ieee80211_frame_addr4));
+#endif
+       ieee80211_crypto_attach(ifp);
+
+       ieee80211_channel_init(ifp);
 
        /* IEEE 802.11 defines a MTU >= 2290 */
        ifp->if_capabilities |= IFCAP_VLAN_MTU;
Index: net80211/ieee80211_var.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_var.h,v
retrieving revision 1.63
diff -u -p -r1.63 ieee80211_var.h
--- net80211/ieee80211_var.h    11 Sep 2015 13:02:28 -0000      1.63
+++ net80211/ieee80211_var.h    26 Sep 2015 13:41:28 -0000
@@ -380,6 +380,7 @@ extern struct ieee80211com_head ieee8021
 
 void   ieee80211_ifattach(struct ifnet *);
 void   ieee80211_ifdetach(struct ifnet *);
+void   ieee80211_channel_init(struct ifnet *);
 void   ieee80211_media_init(struct ifnet *, ifm_change_cb_t, ifm_stat_cb_t);
 int    ieee80211_media_change(struct ifnet *);
 void   ieee80211_media_status(struct ifnet *, struct ifmediareq *);
Index: netinet/if_ether.h
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.h,v
retrieving revision 1.59
diff -u -p -r1.59 if_ether.h
--- netinet/if_ether.h  13 Sep 2015 10:42:32 -0000      1.59
+++ netinet/if_ether.h  26 Sep 2015 13:41:28 -0000
@@ -186,6 +186,7 @@ struct sockaddr_inarp {
 
 #ifdef _KERNEL
 extern u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN];
+extern u_int8_t etheranyaddr[ETHER_ADDR_LEN];
 extern u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
 extern u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
 extern struct niqueue arpintrq;

Reply via email to