Thanks for the pointers; updated diff below to set the MAC in
bwfm_init() if preinit has already run.

Works on boot with "lladdr random" as the first line in hostname.bwfm0,
and also changing the lladdr after boot with ifconfig.

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
@@ -451,6 +451,16 @@ bwfm_init(struct ifnet *ifp)
                        return;
                }
                sc->sc_initialized = 1;
+       } else {
+               /* Update MAC in case the upper layers changed it. */
+               IEEE80211_ADDR_COPY(ic->ic_myaddr,
+                   ((struct arpcom *)ifp)->ac_enaddr);
+               if (bwfm_fwvar_var_set_data(sc, "cur_etheraddr",
+                   ic->ic_myaddr, sizeof(ic->ic_myaddr))) {
+                       printf("%s: could not write MAC address\n",
+                           DEVNAME(sc));
+                       return;
+               }
        }
 
        /* Select default channel */


"Theo de Raadt" <dera...@openbsd.org> writes:

> 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.
>> 

Reply via email to