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