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.
This commit is contained in:
Augustin Cavalier
2018-06-27 20:14:36 -04:00
parent ace07f7051
commit af8988cdb6
22 changed files with 178 additions and 14 deletions
+1
View File
@@ -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 ;
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: releng/11.1/sys/net80211/ieee80211.c 300232 2016-05-19 21:08
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>
#include <net/vnet.h>
#include <net/ethernet.h>
#include <net80211/ieee80211_var.h>
@@ -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;
}
@@ -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)
@@ -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
}
/*
@@ -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)
{
/*
@@ -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 */
@@ -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 */
@@ -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)) {
@@ -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 */
@@ -545,7 +545,7 @@ mesh_gatemode_cb(void *arg)
mesh_gatemode_setup(vap);
}
static void
void
ieee80211_mesh_init(void)
{
@@ -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 {
@@ -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);
@@ -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[] = {
@@ -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
@@ -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);
@@ -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) {
@@ -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);
}
@@ -25,6 +25,8 @@
* $FreeBSD: releng/11.1/sys/net80211/ieee80211_ratectl.h 296925 2016-03-16 02:07:04Z adrian $
*/
#include <sys/sbuf.h>
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
@@ -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.
*/
@@ -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__ */
@@ -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);
@@ -38,6 +38,8 @@
#include <net80211/ieee80211_freebsd.h>
#elif defined(__linux__)
#include <net80211/ieee80211_linux.h>
#elif defined(__HAIKU__)
#include <net80211/ieee80211_haiku.h>
#else
#error "No support for your operating system!"
#endif