On Mon, Apr 15, 2019 at 04:48:02PM +0200, Stefan Sperling wrote: > ieee80211_media_change() will return ENETRESET if the interface is > switched into 11a/b/g/n mode from any other mode. > ifmedia_ioctl() considers this an error and reverts ifmedia's state > to the previous setting, even though net80211 has actually succeeded. > The result is that if_media and net80211 have conflicting ideas about the > current media mode of the interface, which can be observed with ifconfig.
Diff makes sense to me. Currently we have some drivers with media_change functions returning the errno from ieee80211_media_change (iwn, iwm) and some just returning 0 at the end (run, rtwn, ral). The ones returning 0 are mostly ignoring possible errors from x_init() so I'm leaning towards making them more like iwn/m. > > The commands below were run while the interface is down. > Note how 'ifconfig mode' needs to be run twice to get consistent results: > > # ifconfig iwm0 | grep media: > media: IEEE802.11 autoselect > # ifconfig iwm0 mode 11b > # ifconfig iwm0 | grep media: > media: IEEE802.11 autoselect (autoselect mode 11b) > # ifconfig iwm0 mode 11b > # ifconfig iwm0 | grep media: > media: IEEE802.11 autoselect mode 11b > # ifconfig iwm0 mode 11g > # ifconfig iwm0 | grep media: > media: IEEE802.11 autoselect mode 11b (autoselect mode 11g) > # ifconfig iwm0 mode 11g > # ifconfig iwm0 | grep media: > media: IEEE802.11 autoselect mode 11g > > The diff below fixes this issue for me: > > # ifconfig iwm0 | grep media: > media: IEEE802.11 autoselect > # ifconfig iwm0 mode 11b > # ifconfig iwm0 | grep media: > media: IEEE802.11 autoselect mode 11b > # ifconfig iwm0 mode 11g > # ifconfig iwm0 | grep media: > media: IEEE802.11 autoselect mode 11g > > OK? > > diff 23a4e4a1e8913390694e35727d2131b2938cb472 /usr/src > blob - 5168b074cbdd5a95f9945134cdd47c0649ad76a1 > file + sys/net/if_media.c > --- sys/net/if_media.c > +++ sys/net/if_media.c > @@ -277,7 +277,7 @@ ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, st > ifm->ifm_cur = match; > ifm->ifm_media = newmedia; > error = (*ifm->ifm_change)(ifp); > - if (error) { > + if (error && error != ENETRESET) { > ifm->ifm_cur = oldentry; > ifm->ifm_media = oldmedia; > } >