From af8988cdb6664339b2958b32863554c70d2fe76f Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Mon, 25 Jun 2018 22:19:39 -0400 Subject: [PATCH] freebsd11_wlan: Adapt net80211 code for Haiku's usage. Changes mostly ported from the FreeBSD 9 code, but some of it is new. Hopefully in the future, this diff can be reused almost wholesale, instead of having to re-create it as was done in past upgrades. --- src/libs/compat/Jamfile | 1 + .../freebsd11_wlan/net80211/ieee80211.c | 17 ++++++++++- .../freebsd11_wlan/net80211/ieee80211.h | 2 ++ .../net80211/ieee80211_crypto.c | 10 +++++++ .../freebsd11_wlan/net80211/ieee80211_ht.c | 2 +- .../freebsd11_wlan/net80211/ieee80211_ht.h | 1 + .../freebsd11_wlan/net80211/ieee80211_hwmp.c | 2 +- .../freebsd11_wlan/net80211/ieee80211_ioctl.c | 29 ++++++++++++++++++- .../freebsd11_wlan/net80211/ieee80211_ioctl.h | 27 ++++++++++++++++- .../freebsd11_wlan/net80211/ieee80211_mesh.c | 2 +- .../freebsd11_wlan/net80211/ieee80211_mesh.h | 2 ++ .../net80211/ieee80211_output.c | 9 ++++-- .../freebsd11_wlan/net80211/ieee80211_phy.c | 2 +- .../freebsd11_wlan/net80211/ieee80211_phy.h | 3 +- .../freebsd11_wlan/net80211/ieee80211_proto.c | 2 +- .../freebsd11_wlan/net80211/ieee80211_proto.h | 5 ++-- .../net80211/ieee80211_ratectl.c | 26 +++++++++++++++++ .../net80211/ieee80211_ratectl.h | 13 +++++++++ .../freebsd11_wlan/net80211/ieee80211_scan.c | 17 +++++++++++ .../net80211/ieee80211_scan_sta.c | 16 ++++++++++ .../net80211/ieee80211_scan_sw.c | 2 +- .../freebsd11_wlan/net80211/ieee80211_var.h | 2 ++ 22 files changed, 178 insertions(+), 14 deletions(-) diff --git a/src/libs/compat/Jamfile b/src/libs/compat/Jamfile index 1b4bd3b639..335d905250 100644 --- a/src/libs/compat/Jamfile +++ b/src/libs/compat/Jamfile @@ -3,3 +3,4 @@ SubDir HAIKU_TOP src libs compat ; SubInclude HAIKU_TOP src libs compat freebsd_network ; SubInclude HAIKU_TOP src libs compat freebsd_wlan ; SubInclude HAIKU_TOP src libs compat freebsd11_network ; +SubInclude HAIKU_TOP src libs compat freebsd11_wlan ; diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c index 8ca766b7f3..4b1aec43fc 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: releng/11.1/sys/net80211/ieee80211.c 300232 2016-05-19 21:08 #include #include #include +#include #include #include @@ -259,7 +260,7 @@ ic_printf(struct ieee80211com *ic, const char * fmt, ...) } static LIST_HEAD(, ieee80211com) ic_head = LIST_HEAD_INITIALIZER(ic_head); -static struct mtx ic_list_mtx; +struct mtx ic_list_mtx; MTX_SYSINIT(ic_list, &ic_list_mtx, "ieee80211com list", MTX_DEF); static int @@ -273,6 +274,7 @@ sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS) error = sysctl_wire_old_buffer(req, 0); if (error) return (error); +#ifndef __HAIKU__ sbuf_new_for_sysctl(&sb, NULL, 8, req); sbuf_clear_flags(&sb, SBUF_INCLUDENUL); sp = ""; @@ -284,6 +286,7 @@ sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS) mtx_unlock(&ic_list_mtx); error = sbuf_finish(&sb); sbuf_delete(&sb); +#endif return (error); } @@ -308,8 +311,10 @@ ieee80211_ifattach(struct ieee80211com *ic) taskqueue_thread_enqueue, &ic->ic_tq); taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq", ic->ic_name); +#ifndef __HAIKU__ ic->ic_ierrors = counter_u64_alloc(M_WAITOK); ic->ic_oerrors = counter_u64_alloc(M_WAITOK); +#endif /* * Fill in 802.11 available channel set, mark all * available channels as active, and pick a default @@ -337,6 +342,9 @@ ieee80211_ifattach(struct ieee80211com *ic) ieee80211_scan_attach(ic); ieee80211_regdomain_attach(ic); ieee80211_dfs_attach(ic); +#if defined(__HAIKU__) + ieee80211_ratectl_attach(ic); +#endif ieee80211_sysctl_attach(ic); @@ -371,6 +379,9 @@ ieee80211_ifdetach(struct ieee80211com *ic) ieee80211_waitfor_parent(ic); ieee80211_sysctl_detach(ic); +#if defined(__HAIKU__) + ieee80211_ratectl_detach(ic); +#endif ieee80211_dfs_detach(ic); ieee80211_regdomain_detach(ic); ieee80211_scan_detach(ic); @@ -384,8 +395,10 @@ ieee80211_ifdetach(struct ieee80211com *ic) ieee80211_power_detach(ic); ieee80211_node_detach(ic); +#ifndef __HAIKU__ counter_u64_free(ic->ic_ierrors); counter_u64_free(ic->ic_oerrors); +#endif taskqueue_free(ic->ic_tq); IEEE80211_TX_LOCK_DESTROY(ic); @@ -444,12 +457,14 @@ ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt) rv = if_get_counter_default(ifp, cnt); switch (cnt) { +#ifndef __HAIKU__ case IFCOUNTER_OERRORS: rv += counter_u64_fetch(ic->ic_oerrors); break; case IFCOUNTER_IERRORS: rv += counter_u64_fetch(ic->ic_ierrors); break; +#endif default: break; } diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.h index c79cb4b77c..3e436d459a 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.h @@ -32,6 +32,8 @@ * 802.11 protocol definitions. */ +extern struct mtx ic_list_mtx; + #define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ /* is 802.11 address multicast/broadcast? */ #define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01) diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_crypto.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_crypto.c index 3a781600dc..ca49d87491 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_crypto.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_crypto.c @@ -142,6 +142,11 @@ ieee80211_crypto_attach(struct ieee80211com *ic) { /* NB: we assume everything is pre-zero'd */ ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none; +#if defined(__HAIKU__) + ieee80211_crypto_ccmp_load(); + ieee80211_crypto_tkip_load(); + ieee80211_crypto_wep_load(); +#endif } /* @@ -150,6 +155,11 @@ ieee80211_crypto_attach(struct ieee80211com *ic) void ieee80211_crypto_detach(struct ieee80211com *ic) { +#if defined(__HAIKU__) + ieee80211_crypto_ccmp_unload(); + ieee80211_crypto_tkip_unload(); + ieee80211_crypto_wep_unload(); +#endif } /* diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.c index fa4bb7a101..3c70026a6f 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.c @@ -170,7 +170,7 @@ static ieee80211_send_action_func ht_send_action_ba_addba; static ieee80211_send_action_func ht_send_action_ba_delba; static ieee80211_send_action_func ht_send_action_ht_txchwidth; -static void +void ieee80211_ht_init(void) { /* diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.h index dcd2992ac2..4c73a63850 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.h @@ -30,6 +30,7 @@ /* * 802.11n protocol implementation definitions. */ +void ieee80211_ht_init(void); #define IEEE80211_AGGR_BAWMAX 64 /* max block ack window size */ /* threshold for aging overlapping non-HT bss */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_hwmp.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_hwmp.c index ba2f884336..7901c92c5f 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_hwmp.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_hwmp.c @@ -208,7 +208,7 @@ SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, inact, CTLTYPE_INT | CTLFLAG_RW, "mesh route inactivity timeout (ms)"); -static void +void ieee80211_hwmp_init(void) { /* Default values as per amendment */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.c index 6103e10f6c..4e75f0cdc6 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.c @@ -278,8 +278,12 @@ get_scan_result(void *arg, const struct ieee80211_scan_entry *se) sr->isr_len = len; sr->isr_ie_off = sizeof(struct ieee80211req_scan_result); sr->isr_ie_len = ielen; +#ifdef __HAIKU__ + memcpy(&sr->isr_chan, se->se_chan, sizeof(sr->isr_chan)); +#else sr->isr_freq = se->se_chan->ic_freq; sr->isr_flags = se->se_chan->ic_flags; +#endif sr->isr_rssi = se->se_rssi; sr->isr_noise = se->se_noise; sr->isr_intval = se->se_intval; @@ -397,8 +401,12 @@ get_sta_info(void *arg, struct ieee80211_node *ni) si->isi_len = len; si->isi_ie_off = sizeof(struct ieee80211req_sta_info); si->isi_ie_len = ielen; +#ifdef __HAIKU__ + memcpy(&si->isi_chan, ni->ni_chan, sizeof(si->isi_chan)); +#else si->isi_freq = ni->ni_chan->ic_freq; si->isi_flags = ni->ni_chan->ic_flags; +#endif si->isi_state = ni->ni_flags; si->isi_authmode = ni->ni_authmode; vap->iv_ic->ic_node_getsignal(ni, &si->isi_rssi, &si->isi_noise); @@ -1599,8 +1607,25 @@ ieee80211_ioctl_setmlme(struct ieee80211vap *vap, struct ieee80211req *ireq) return error; if (vap->iv_opmode == IEEE80211_M_STA && mlme.im_op == IEEE80211_MLME_ASSOC) +#ifndef __HAIKU__ return setmlme_assoc_sta(vap, mlme.im_macaddr, - vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid); + vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid); +#else + /* The wpa_supplicant (rightfully) supplies the SSID with this request. + However, with the code above it gets ignored and the desired SSID, + as set by IEEE80211_IOC_SSID is used instead. This still works if + the wpa_supplicant is the only client in use and IEEE80211_IOC_SSID + is never used, as then the mlme.im_macaddr is used as the only + identifying element. If we used IEEE80211_IOC_SSID before though, + for example because we joined an open network from the net_server + directly, there will always be a mismatch between the desired SSID + and the one the wpa_supplicant tries to associate with using this + MLME request. No association is then possible. As there is no + obvious reason why the request supplied SSID shouldn't be used, we + simply do so. */ + return setmlme_assoc_sta(vap, mlme.im_macaddr, + mlme.im_ssid_len, mlme.im_ssid); +#endif else if ((vap->iv_opmode == IEEE80211_M_IBSS || vap->iv_opmode == IEEE80211_M_AHDEMO) && mlme.im_op == IEEE80211_MLME_ASSOC) @@ -3351,7 +3376,9 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * 3. In monitor (or adhoc-demo) mode. */ if (ifp->if_bridge == NULL || +#ifndef __HAIKU__ (ifp->if_flags & IFF_PPROMISC) != 0 || +#endif vap->iv_opmode == IEEE80211_M_MONITOR || (vap->iv_opmode == IEEE80211_M_AHDEMO && (vap->iv_caps & IEEE80211_C_TDMA) == 0)) { diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.h index 36b0b55b21..69799c498e 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.h @@ -422,8 +422,12 @@ struct ieee80211req_sta_info { uint16_t isi_len; /* total length (mult of 4) */ uint16_t isi_ie_off; /* offset to IE data */ uint16_t isi_ie_len; /* IE length */ +#ifdef __HAIKU__ + struct ieee80211_channel isi_chan; /* Handing out the conmplete channel info */ +#else uint16_t isi_freq; /* MHz */ uint32_t isi_flags; /* channel flags */ +#endif uint32_t isi_state; /* state flags */ uint8_t isi_authmode; /* authentication algorithm */ int8_t isi_rssi; /* receive signal strength */ @@ -578,7 +582,7 @@ struct ieee80211req_sta_vlan { uint16_t sv_vlan; }; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__HAIKU__) /* * FreeBSD-style ioctls. */ @@ -731,6 +735,23 @@ struct ieee80211req { #define IEEE80211_IOC_QUIET_OFFSET 207 /* Quiet Offset */ #define IEEE80211_IOC_QUIET_DUR 208 /* Quiet Duration */ #define IEEE80211_IOC_QUIET_COUNT 209 /* Quiet Count */ + +#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. @@ -802,8 +823,12 @@ struct ieee80211req_scan_result { uint16_t isr_len; /* total length (mult of 4) */ uint16_t isr_ie_off; /* offset to SSID+IE data */ uint16_t isr_ie_len; /* IE length */ +#ifdef __HAIKU__ + struct ieee80211_channel isr_chan; /* Handing out the conmplete channel info */ +#else uint16_t isr_freq; /* MHz */ uint16_t isr_flags; /* channel flags */ +#endif int8_t isr_noise; int8_t isr_rssi; uint16_t isr_intval; /* beacon interval */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.c index 7148d830f7..fe0bb1aad1 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.c @@ -545,7 +545,7 @@ mesh_gatemode_cb(void *arg) mesh_gatemode_setup(vap); } -static void +void ieee80211_mesh_init(void) { diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.h index cc6e0ca5e3..a71b4b92cc 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.h @@ -40,6 +40,8 @@ /* * 802.11s Information Elements. */ +void ieee80211_mesh_init(void); + /* Mesh Configuration */ #define IEEE80211_MESH_CONF_SZ (7) struct ieee80211_meshconf_ie { diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_output.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_output.c index 846dddb31a..6d22921500 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_output.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_output.c @@ -581,8 +581,13 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, * Hand to the 802.3 code if not tagged as * a raw 802.11 frame. */ +#ifdef __HAIKU__ + if (!dst || dst->sa_family != AF_IEEE80211) + return ieee80211_vap_xmitpkt(vap, m); +#else if (dst->sa_family != AF_IEEE80211) return vap->iv_output(ifp, m, dst, ro); +#endif #ifdef MAC error = mac_ifnet_check_transmit(ifp, m); if (error) @@ -629,7 +634,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, * Permit packets w/ bpf params through regardless * (see below about sa_len). */ - if (dst->sa_len == 0) + if (dst && dst->sa_len == 0) senderr(EHOSTUNREACH); ni = ieee80211_ref_node(vap->iv_bss); } @@ -665,7 +670,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, * NB: we assume sa_data is suitably aligned to cast. */ ret = ieee80211_raw_output(vap, ni, m, - (const struct ieee80211_bpf_params *)(dst->sa_len ? + (const struct ieee80211_bpf_params *)((dst && dst->sa_len) ? dst->sa_data : NULL)); IEEE80211_TX_UNLOCK(ic); return (ret); diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.c index e390cfe95d..7a0009786b 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.c @@ -347,7 +347,7 @@ ieee80211_setup_ratetable(struct ieee80211_rate_table *rt) } /* Setup all rate tables */ -static void +void ieee80211_phy_init(void) { static struct ieee80211_rate_table * const ratetables[] = { diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.h index 9a262557d6..312c97fbb6 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.h @@ -32,6 +32,7 @@ /* * IEEE 802.11 PHY-related definitions. */ +void ieee80211_phy_init(void); /* * Contention window (slots). @@ -128,7 +129,7 @@ ieee80211_rate2phytype(const struct ieee80211_rate_table *rt, uint8_t rate) uint8_t rix = rt->rateCodeToIndex[rate & IEEE80211_RATE_VAL]; KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate)); - return rt->info[rix].phy; + return (enum ieee80211_phytype)rt->info[rix].phy; } static __inline__ int diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.c index d3237a94a6..645267999a 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.c @@ -447,7 +447,7 @@ static const struct ieee80211_authenticator auth_internal = { /* * Setup internal authenticators once; they are never unregistered. */ -static void +void ieee80211_auth_setup(void) { ieee80211_authenticator_register(IEEE80211_AUTH_OPEN, &auth_internal); diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.h index 89b9f2b6fe..1a0bf498a8 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.h @@ -31,6 +31,7 @@ /* * 802.11 protocol implementation definitions. */ +void ieee80211_auth_setup(void); enum ieee80211_state { IEEE80211_S_INIT = 0, /* default state */ @@ -165,7 +166,7 @@ void ieee80211_addbasicrates(struct ieee80211_rateset *, static __inline int ieee80211_hdrsize(const void *data) { - const struct ieee80211_frame *wh = data; + const struct ieee80211_frame *wh = (struct ieee80211_frame *)data; int size = sizeof(struct ieee80211_frame); /* NB: we don't handle control frames */ @@ -184,7 +185,7 @@ ieee80211_hdrsize(const void *data) static __inline int ieee80211_anyhdrsize(const void *data) { - const struct ieee80211_frame *wh = data; + const struct ieee80211_frame *wh = (struct ieee80211_frame *)data; if ((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) { switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) { diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.c index e8b525f308..23d94c3df6 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.c @@ -53,6 +53,30 @@ static const char *ratectl_modnames[IEEE80211_RATECTL_MAX] = { MALLOC_DEFINE(M_80211_RATECTL, "80211ratectl", "802.11 rate control"); +#if defined(__HAIKU__) +/* + * Setup ratectl support for a device/shared instance. + */ +void +ieee80211_ratectl_attach(struct ieee80211com *ic) +{ + ieee80211_ratectl_none_load(); + ieee80211_ratectl_amrr_load(); + ieee80211_ratectl_rssadapt_load(); +} + +/* + * Teardown ratectl support. + */ +void +ieee80211_ratectl_detach(struct ieee80211com *ic) +{ + ieee80211_ratectl_none_unload(); + ieee80211_ratectl_amrr_unload(); + ieee80211_ratectl_rssadapt_unload(); +} +#endif + void ieee80211_ratectl_register(int type, const struct ieee80211_ratectl *ratectl) { @@ -90,6 +114,7 @@ ieee80211_ratectl_sysctl_stats(SYSCTL_HANDLER_ARGS) error = sysctl_wire_old_buffer(req, 0); if (error) return (error); +#ifndef __HAIKU__ sbuf_new_for_sysctl(&sb, NULL, 8, req); sbuf_clear_flags(&sb, SBUF_INCLUDENUL); @@ -101,6 +126,7 @@ ieee80211_ratectl_sysctl_stats(SYSCTL_HANDLER_ARGS) error = sbuf_finish(&sb); sbuf_delete(&sb); +#endif return (error); } diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.h index 2bd6b00af1..2cafb71fda 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.h @@ -25,6 +25,8 @@ * $FreeBSD: releng/11.1/sys/net80211/ieee80211_ratectl.h 296925 2016-03-16 02:07:04Z adrian $ */ +#include + enum ieee80211_ratealgs { IEEE80211_RATECTL_AMRR = 0, IEEE80211_RATECTL_RSSADAPT = 1, @@ -61,6 +63,17 @@ void ieee80211_ratectl_unregister(int); void ieee80211_ratectl_init(struct ieee80211vap *); void ieee80211_ratectl_set(struct ieee80211vap *, int); +#if defined (__HAIKU__) +void ieee80211_ratectl_attach(struct ieee80211com *ic); +void ieee80211_ratectl_detach(struct ieee80211com *ic); +void ieee80211_ratectl_none_load(void); +void ieee80211_ratectl_none_unload(void); +void ieee80211_ratectl_amrr_load(void); +void ieee80211_ratectl_amrr_unload(void); +void ieee80211_ratectl_rssadapt_load(void); +void ieee80211_ratectl_rssadapt_unload(void); +#endif + MALLOC_DECLARE(M_80211_RATECTL); static __inline void diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan.c index 273ff593b6..67572a0384 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan.c @@ -80,6 +80,10 @@ ieee80211_scan_attach(struct ieee80211com *ic) ieee80211_swscan_attach(ic); else ic->ic_scan_methods->sc_attach(ic); + +#if defined(__HAIKU__) + ieee80211_scan_sta_init(); +#endif } void @@ -93,6 +97,10 @@ ieee80211_scan_detach(struct ieee80211com *ic) * I'll do that later. */ ic->ic_scan_methods->sc_detach(ic); + +#if defined(__HAIKU__) + ieee80211_scan_sta_uninit(); +#endif } static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = { @@ -375,6 +383,15 @@ ieee80211_check_scan(struct ieee80211vap *vap, int flags, flags |= IEEE80211_SCAN_FLUSH; } +#ifdef __HAIKU__ + /* We never want to join if not explicitly looking for an SSID */ + if (nssid == 0 && (flags & IEEE80211_SCAN_NOJOIN) == 0) { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, + "%s: setting nojoin due to no configured ssid\n", __func__); + flags |= IEEE80211_SCAN_NOJOIN; + } +#endif + /* * XXX TODO: separate things out a bit better. */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sta.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sta.c index 69c782fe2a..c69bb4056f 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sta.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sta.c @@ -1933,3 +1933,19 @@ static const struct ieee80211_scanner mesh_default = { }; IEEE80211_SCANNER_ALG(mesh, IEEE80211_M_MBSS, mesh_default); #endif /* IEEE80211_SUPPORT_MESH */ + +#if defined(__HAIKU__) +void +ieee80211_scan_sta_init() +{ + ieee80211_scanner_register(IEEE80211_M_STA, &sta_default); + ieee80211_scanner_register(IEEE80211_M_IBSS, &adhoc_default); +} + +void +ieee80211_scan_sta_uninit() +{ + ieee80211_scanner_unregister(IEEE80211_M_STA, &sta_default); + ieee80211_scanner_unregister(IEEE80211_M_IBSS, &adhoc_default); +} +#endif /* __HAIKU__ */ diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sw.c b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sw.c index e4000460a8..5e45e2a948 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sw.c +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sw.c @@ -617,7 +617,7 @@ scan_start(void *arg, int pending) /* Enable station power save mode */ vap->iv_sta_ps(vap, 1); /* Wait until null data frame will be ACK'ed */ - mtx_sleep(vap, IEEE80211_LOCK_OBJ(ic), PCATCH, + msleep(vap, IEEE80211_LOCK_OBJ(ic), PCATCH, "sta_ps", msecs_to_ticks(10)); if (ss_priv->ss_iflags & ISCAN_ABORT) { scan_done(ss, 0); diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_var.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_var.h index f52afc5370..97c05ef390 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_var.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_var.h @@ -38,6 +38,8 @@ #include #elif defined(__linux__) #include +#elif defined(__HAIKU__) +#include #else #error "No support for your operating system!" #endif