diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.cpp b/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.cpp index d4910cdef5..b1f936febb 100644 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.cpp +++ b/src/libs/compat/freebsd_wlan/net80211/ieee80211_haiku.cpp @@ -191,6 +191,34 @@ stop_wlan(device_t device) } +status_t +wlan_open(void* cookie) +{ + dprintf("wlan_open(%p)\n", cookie); + struct ifnet* ifp = (struct ifnet*)cookie; + + ifp->if_init(ifp->if_softc); + + ifp->if_flags |= IFF_UP; + ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); + + return B_OK; +} + + +status_t +wlan_close(void* cookie) +{ + dprintf("wlan_close(%p)\n", cookie); + struct ifnet* ifp = (struct ifnet*)cookie; + + ifp->if_flags &= ~IFF_UP; + ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); + + return release_sem_etc(ifp->scan_done_sem, 1, B_RELEASE_ALL); +} + + status_t wlan_control(void* cookie, uint32 op, void* arg, size_t length) { @@ -344,6 +372,11 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t length) if (user_memcpy(&request, arg, sizeof(struct ieee80211req)) != B_OK) return B_BAD_ADDRESS; + if (request.i_type == IEEE80211_IOC_HAIKU_COMPAT_WLAN_UP) + return wlan_open(cookie); + else if (request.i_type == IEEE80211_IOC_HAIKU_COMPAT_WLAN_DOWN) + return wlan_close(cookie); + TRACE("wlan_control: %ld, %d\n", op, request.i_type); status_t status = ifp->if_ioctl(ifp, op, (caddr_t)&request); if (status != B_OK) @@ -367,18 +400,6 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t length) } -status_t -wlan_close(void* cookie) -{ - struct ifnet* ifp = (struct ifnet*)cookie; - - ifp->if_flags &= ~IFF_UP; - ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL); - - return release_sem_etc(ifp->scan_done_sem, 1, B_RELEASE_ALL); -} - - status_t wlan_if_l2com_alloc(void* data) { diff --git a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.h b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.h index f1a1dcd69a..551d1877a4 100644 --- a/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.h +++ b/src/libs/compat/freebsd_wlan/net80211/ieee80211_ioctl.h @@ -719,6 +719,22 @@ struct ieee80211req { #define IEEE80211_IOC_TDMA_SLOTLEN 203 /* TDMA: slot length (usecs) */ #define IEEE80211_IOC_TDMA_BINTERVAL 204 /* TDMA: beacon intvl (slots) */ +#ifdef __HAIKU__ +/* + These are here to allow overcoming a difference between Haiku and + FreeBSD drivers. In FreeBSD a device can be set into the down state + but is still fully configurable using the ioctl interface. The Haiku + network stack on the other hand opens and closes the driver on the + transition form up to down and vice versa. This difference can become + problematic with ported software that depends on the original behaviour. + Therefore IEEE80211_IOC_HAIKU_COMPAT_WLAN_{UP|DOWN} provide a way to + achieve the behaviour of setting and clearing IFF_UP without opening + or closing the driver itself. +*/ +#define IEEE80211_IOC_HAIKU_COMPAT_WLAN_UP 0x6000 +#define IEEE80211_IOC_HAIKU_COMPAT_WLAN_DOWN 0x6001 +#endif /* __HAIKU__ */ + /* * Parameters for controlling a scan requested with * IEEE80211_IOC_SCAN_REQ.