Yes, the normal pattern is to update the driver soft state, and
then do perform a backside "down / up" transition.

Stefan Sperling <s...@stsp.name> wrote:

> On Sat, Feb 17, 2024 at 06:27:40PM -1000, Todd Carson wrote:
> > 
> > On a Raspberry Pi 4 running a recent snapshot, I found that the built-in
> > bwfm interface would fail to receive non-broadcast traffic after
> > changing the MAC address with ifconfig (for example by having
> > "lladdr random" in hostname.bwfm0).
> > 
> > It looks like this was happening because the new MAC address was set in
> > the kernel network stack but the bwfm driver wasn't doing anything
> > to write the address to the device.
> > 
> > The below diff fixes it for me.
> > I don't have any other bwfm devices to test.
> 
> An alternative approach is to memcpy the stack's MAC into ic_myaddr
> whenever the interface comes up. E.g. iwx does this in iwx_preinit():
> 
>       if (sc->attached) {
>               /* Update MAC in case the upper layers changed it. */
>               IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
>                   ((struct arpcom *)ifp)->ac_enaddr);
>               return 0;
>       }
> 
> This way the new value of ic_myaddr is propagated to firmware as
> part of the usual startup process.
> 
> A possible problem with your approach is that the bwfm_fwvar_set_data()
> call might occur while the interface is still down and no firmware has
> been loaded. It looks like you handle this case by returning EIO, which
> means a hostname.bwfm0 file like the following would run into this I/O
> error on the first line during boot:
> 
>   lladdr random
>   nwid foo wpakey bar
>   inet autoconf
> 
> With the approach taken by iwx(4) such files will work without errors
> and the random MAC will be set in the stack only at first, while being
> passed to the device when hardware comes up.
> 
> > diff /usr/src
> > commit - 6c24eb55e021991196003dc7f0a643e806b14295
> > path + /usr/src
> > blob - dfa7a1973d2ab6be7e4b2fbd869b38c441d4eae0
> > file + sys/dev/ic/bwfm.c
> > --- sys/dev/ic/bwfm.c
> > +++ sys/dev/ic/bwfm.c
> > @@ -827,6 +827,17 @@ bwfm_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data
> >                     error = 0;
> >             }
> >             break;
> > +   case SIOCSIFLLADDR:
> > +           ifr = (struct ifreq *)data;
> > +           error = 0;
> > +           if (bwfm_fwvar_var_set_data(sc, "cur_etheraddr",
> > +               ifr->ifr_addr.sa_data, ETHER_ADDR_LEN)) {
> > +                   error = EIO;
> > +           } else {
> > +                   memcpy(ic->ic_myaddr, ifr->ifr_addr.sa_data,
> > +                       sizeof(ic->ic_myaddr));
> > +           }
> > +           break;
> >     case SIOCGIFMEDIA:
> >     case SIOCG80211NODE:
> >     case SIOCG80211ALLNODES:
> > 
> > 
> 

Reply via email to