freebsd11_wlan: Adapt _haiku module for FreeBSD 11.

Mostly just additions of new primitives and hook functions that are
relatively straightforward and mostly copied from FreeBSD. The one
notable set of changes is the ones relating to gDevices, as the hacks
we used previously to hide the base device are now no longer needed
(as the previous commit noted.)
This commit is contained in:
Augustin Cavalier 2018-06-25 22:17:58 -04:00
parent 2ed3d6d1b5
commit ace07f7051
2 changed files with 275 additions and 55 deletions

View File

@ -1,5 +1,6 @@
/*
* Copyright 2009, Colin Günther, coling@gmx.de.
* Copyright 2018, Haiku, Inc.
* All rights reserved. Distributed under the terms of the MIT License.
*/
@ -96,6 +97,7 @@ get_ifnet(device_t device, int& i)
status_t
init_wlan_stack(void)
{
mtx_init(&ic_list_mtx, "ieee80211com list", NULL, MTX_DEF);
ieee80211_phy_init();
ieee80211_auth_setup();
ieee80211_ht_init();
@ -118,35 +120,22 @@ uninit_wlan_stack(void)
status_t
start_wlan(device_t device)
{
int i;
struct ifnet* ifp = get_ifnet(device, i);
if (ifp == NULL)
struct ieee80211com* ic = ieee80211_find_com(device->nameunit);
if (ic == NULL)
return B_BAD_VALUE;
// TODO: review this and find a cleaner solution!
// This ensures that the cloned device gets
// the same index assigned as the base device
// Resulting in the same device name
// e.g.: /dev/net/atheros/0 instead of
// /dev/net/atheros/1
gDevices[i] = NULL;
struct ieee80211com* ic = (ieee80211com*)ifp->if_l2com;
struct ieee80211vap* vap = ic->ic_vap_create(ic, "wlan",
device_get_unit(device),
IEEE80211_M_STA, // mode
0, // flags
NULL, // BSSID
IF_LLADDR(ifp)); // MAC address
ic->ic_macaddr); // MAC address
if (vap == NULL) {
gDevices[i] = ifp;
if (vap == NULL)
return B_ERROR;
}
// ic_vap_create() established that gDevices[i] links to vap->iv_ifp now
KASSERT(gDevices[i] == vap->iv_ifp,
KASSERT(gDevices[gDeviceCount - 1] == vap->iv_ifp,
("start_wlan: gDevices[i] != vap->iv_ifp"));
vap->iv_ifp->scan_done_sem = create_sem(0, "wlan scan done");
@ -168,12 +157,6 @@ stop_wlan(device_t device)
if (ifp == NULL)
return B_BAD_VALUE;
if (ifp->if_type == IFT_IEEE80211) {
// This happens when there was an error in starting the wlan before,
// resulting in never creating a clone device
return B_OK;
}
delete_sem(ifp->scan_done_sem);
struct ieee80211vap* vap = (ieee80211vap*)ifp->if_softc;
@ -184,9 +167,6 @@ stop_wlan(device_t device)
// ic_vap_delete freed gDevices[i]
KASSERT(gDevices[i] == NULL, ("stop_wlan: gDevices[i] != NULL"));
// assign the base device ifp again
gDevices[i] = ic->ic_ifp;
return B_OK;
}
@ -400,19 +380,6 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t length)
}
status_t
wlan_if_l2com_alloc(void* data)
{
struct ifnet* ifp = (struct ifnet*)data;
ifp->if_l2com = _kernel_malloc(sizeof(struct ieee80211com), M_ZERO);
if (ifp->if_l2com == NULL)
return B_NO_MEMORY;
((struct ieee80211com*)(ifp->if_l2com))->ic_ifp = ifp;
return B_OK;
}
void
get_random_bytes(void* p, size_t n)
{
@ -553,6 +520,128 @@ ieee80211_process_callback(struct ieee80211_node* ni, struct mbuf* m,
}
int
ieee80211_add_xmit_params(struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct m_tag *mtag;
struct ieee80211_tx_params *tx;
mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
sizeof(struct ieee80211_tx_params), M_NOWAIT);
if (mtag == NULL)
return (0);
tx = (struct ieee80211_tx_params *)(mtag+1);
memcpy(&tx->params, params, sizeof(struct ieee80211_bpf_params));
m_tag_prepend(m, mtag);
return (1);
}
int
ieee80211_get_xmit_params(struct mbuf *m,
struct ieee80211_bpf_params *params)
{
struct m_tag *mtag;
struct ieee80211_tx_params *tx;
mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
NULL);
if (mtag == NULL)
return (-1);
tx = (struct ieee80211_tx_params *)(mtag + 1);
memcpy(params, &tx->params, sizeof(struct ieee80211_bpf_params));
return (0);
}
/*
* Add RX parameters to the given mbuf.
*
* Returns 1 if OK, 0 on error.
*/
int
ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs)
{
struct m_tag *mtag;
struct ieee80211_rx_params *rx;
mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
sizeof(struct ieee80211_rx_stats), M_NOWAIT);
if (mtag == NULL)
return (0);
rx = (struct ieee80211_rx_params *)(mtag + 1);
memcpy(&rx->params, rxs, sizeof(*rxs));
m_tag_prepend(m, mtag);
return (1);
}
int
ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
{
struct m_tag *mtag;
struct ieee80211_rx_params *rx;
mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
NULL);
if (mtag == NULL)
return (-1);
rx = (struct ieee80211_rx_params *)(mtag + 1);
memcpy(rxs, &rx->params, sizeof(*rxs));
return (0);
}
/*
* Transmit a frame to the parent interface.
*/
int
ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
{
int error;
/*
* Assert the IC TX lock is held - this enforces the
* processing -> queuing order is maintained
*/
IEEE80211_TX_LOCK_ASSERT(ic);
error = ic->ic_transmit(ic, m);
if (error) {
struct ieee80211_node *ni;
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
/* XXX number of fragments */
if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
ieee80211_free_mbuf(m);
}
return (error);
}
/*
* Transmit a frame to the VAP interface.
*/
int
ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m)
{
struct ifnet *ifp = vap->iv_ifp;
/*
* When transmitting via the VAP, we shouldn't hold
* any IC TX lock as the VAP TX path will acquire it.
*/
IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
return (ifp->if_transmit(ifp, m));
}
void
ieee80211_sysctl_vattach(struct ieee80211vap* vap)
{

View File

@ -35,8 +35,8 @@
# ifdef __cplusplus
// Those includes are needed to avoid C/C++ function export clashes
# include <new>
# include <thread.h>
# include <new>
# include <thread.h>
extern "C" {
# endif
@ -80,6 +80,51 @@ typedef struct {
#define IEEE80211_UNLOCK(_ic) mtx_unlock(IEEE80211_LOCK_OBJ(_ic))
#define IEEE80211_LOCK_ASSERT(_ic) \
mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED)
#define IEEE80211_UNLOCK_ASSERT(_ic) \
mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_NOTOWNED)
/*
* Transmit lock.
*
* This is a (mostly) temporary lock designed to serialise all of the
* transmission operations throughout the stack.
*/
typedef struct {
char name[16]; /* e.g. "ath0_tx_lock" */
struct mtx mtx;
} ieee80211_tx_lock_t;
#define IEEE80211_TX_LOCK_INIT(_ic, _name) do { \
ieee80211_tx_lock_t *cl = &(_ic)->ic_txlock; \
snprintf(cl->name, sizeof(cl->name), "%s_tx_lock", _name); \
mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF); \
} while (0)
#define IEEE80211_TX_LOCK_OBJ(_ic) (&(_ic)->ic_txlock.mtx)
#define IEEE80211_TX_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_TX_LOCK_OBJ(_ic))
#define IEEE80211_TX_LOCK(_ic) mtx_lock(IEEE80211_TX_LOCK_OBJ(_ic))
#define IEEE80211_TX_UNLOCK(_ic) mtx_unlock(IEEE80211_TX_LOCK_OBJ(_ic))
#define IEEE80211_TX_LOCK_ASSERT(_ic) \
mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_OWNED)
#define IEEE80211_TX_UNLOCK_ASSERT(_ic) \
mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED)
/*
* Stageq / ni_tx_superg lock
*/
typedef struct {
char name[16]; /* e.g. "ath0_ff_lock" */
struct mtx mtx;
} ieee80211_ff_lock_t;
#define IEEE80211_FF_LOCK_INIT(_ic, _name) do { \
ieee80211_ff_lock_t *fl = &(_ic)->ic_fflock; \
snprintf(fl->name, sizeof(fl->name), "%s_ff_lock", _name); \
mtx_init(&fl->mtx, fl->name, NULL, MTX_DEF); \
} while (0)
#define IEEE80211_FF_LOCK_OBJ(_ic) (&(_ic)->ic_fflock.mtx)
#define IEEE80211_FF_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_FF_LOCK_OBJ(_ic))
#define IEEE80211_FF_LOCK(_ic) mtx_lock(IEEE80211_FF_LOCK_OBJ(_ic))
#define IEEE80211_FF_UNLOCK(_ic) mtx_unlock(IEEE80211_FF_LOCK_OBJ(_ic))
#define IEEE80211_FF_LOCK_ASSERT(_ic) \
mtx_assert(IEEE80211_FF_LOCK_OBJ(_ic), MA_OWNED)
/*
* Node locking definitions.
@ -172,6 +217,34 @@ typedef struct mtx ieee80211_scan_table_lock_t;
#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock)
#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock)
typedef struct mtx ieee80211_scan_iter_lock_t;
#define IEEE80211_SCAN_ITER_LOCK_INIT(_st, _name) \
mtx_init(&(_st)->st_scanlock, _name, "802.11 scangen", MTX_DEF)
#define IEEE80211_SCAN_ITER_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_scanlock)
#define IEEE80211_SCAN_ITER_LOCK(_st) mtx_lock(&(_st)->st_scanlock)
#define IEEE80211_SCAN_ITER_UNLOCK(_st) mtx_unlock(&(_st)->st_scanlock)
/*
* Mesh node/routing definitions.
*/
typedef struct mtx ieee80211_rte_lock_t;
#define MESH_RT_ENTRY_LOCK_INIT(_rt, _name) \
mtx_init(&(rt)->rt_lock, _name, "802.11s route entry", MTX_DEF)
#define MESH_RT_ENTRY_LOCK_DESTROY(_rt) \
mtx_destroy(&(_rt)->rt_lock)
#define MESH_RT_ENTRY_LOCK(rt) mtx_lock(&(rt)->rt_lock)
#define MESH_RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED)
#define MESH_RT_ENTRY_UNLOCK(rt) mtx_unlock(&(rt)->rt_lock)
typedef struct mtx ieee80211_rt_lock_t;
#define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock)
#define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
#define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock)
#define MESH_RT_LOCK_INIT(ms, name) \
mtx_init(&(ms)->ms_rt_lock, name, "802.11s routing table", MTX_DEF)
#define MESH_RT_LOCK_DESTROY(ms) \
mtx_destroy(&(ms)->ms_rt_lock)
/*
* Node reference counting definitions.
*
@ -208,10 +281,10 @@ void ieee80211_vap_destroy(struct ieee80211vap *);
#define msecs_to_ticks(ms) (((ms)*hz)/1000)
#define ticks_to_msecs(t) (1000*(t) / hz)
#define ticks_to_secs(t) ((t) / hz)
#define time_after(a,b) ((long long)(b) - (long long)(a) < 0)
#define time_before(a,b) time_after(b,a)
#define time_after_eq(a,b) ((long long)(a) - (long long)(b) >= 0)
#define time_before_eq(a,b) time_after_eq(b,a)
#define ieee80211_time_after(a,b) ((long)(b) - (long)(a) < 0)
#define ieee80211_time_before(a,b) ieee80211_time_after(b,a)
#define ieee80211_time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
#define ieee80211_time_before_eq(a,b) ieee80211_time_after_eq(b,a)
struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
@ -223,6 +296,9 @@ struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
#define M_FF M_PROTO6 /* fast frame */
#define M_TXCB M_PROTO7 /* do tx complete callback */
#define M_AMPDU_MPDU M_PROTO8 /* ok for A-MPDU aggregation */
#define M_FRAG M_PROTO9 /* frame fragmentation */
#define M_FIRSTFRAG M_PROTO10 /* first frame fragment */
#define M_LASTFRAG M_PROTO11 /* last frame fragment */
#define M_80211_TX \
(M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_ENCAP|M_EAPOL|M_PWR_SAV|\
M_MORE_DATA|M_FF|M_TXCB|M_AMPDU_MPDU)
@ -268,7 +344,9 @@ struct ieee80211_cb {
void (*func)(struct ieee80211_node *, void *, int status);
void *arg;
};
#define NET80211_TAG_CALLBACK 0 /* xmit complete callback */
#define NET80211_TAG_CALLBACK 0 /* xmit complete callback */
#define NET80211_TAG_XMIT_PARAMS 1 /* See below; this is after the bpf_params definition */
#define NET80211_TAG_RECV_PARAMS 2
int ieee80211_add_callback(struct mbuf *m,
void (*func)(struct ieee80211_node *, void *, int), void *arg);
@ -278,6 +356,9 @@ void get_random_bytes(void *, size_t);
struct ieee80211com;
int ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m);
int ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m);
void ieee80211_sysctl_attach(struct ieee80211com *);
void ieee80211_sysctl_detach(struct ieee80211com *);
void ieee80211_sysctl_vattach(struct ieee80211vap *);
@ -327,7 +408,7 @@ void ieee80211_scan_sta_uninit(void);
*/
#define IEEE80211_RATECTL_MODULE(alg, version) \
_IEEE80211_POLICY_MODULE(ratectl, alg, version); \
#define IEEE80211_RATECTL_ALG(name, alg, v) \
void \
ieee80211_ratectl_##name##_load() { \
@ -336,8 +417,7 @@ void ieee80211_scan_sta_uninit(void);
\
\
void \
ieee80211_ratectl_##name##_unload() \
{ \
ieee80211_ratectl_##name##_unload() { \
ieee80211_ratectl_unregister(alg); \
}
@ -353,11 +433,6 @@ typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *,
SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc);
#define IEEE80211_IOCTL_SET(_name, _set) TEXT_SET(ieee80211_ioctl_setset, _set)
#ifdef __cplusplus
}
#endif
#endif /* _KERNEL */
/*
* Structure prepended to raw packets sent through the bpf
* interface when set to DLT_IEEE802_11_RADIO. This allows
@ -392,4 +467,60 @@ struct ieee80211_bpf_params {
uint8_t ibp_rate3; /* series 4 IEEE tx rate */
};
int ieee80211_add_xmit_params(struct mbuf *m, const struct ieee80211_bpf_params *params);
int ieee80211_get_xmit_params(struct mbuf *m, struct ieee80211_bpf_params *params);
#define IEEE80211_MAX_CHAINS 3
#define IEEE80211_MAX_EVM_PILOTS 6
struct ieee80211_tx_params {
struct ieee80211_bpf_params params;
};
#define IEEE80211_R_NF 0x0000001 /* global NF value valid */
#define IEEE80211_R_RSSI 0x0000002 /* global RSSI value valid */
#define IEEE80211_R_C_CHAIN 0x0000004 /* RX chain count valid */
#define IEEE80211_R_C_NF 0x0000008 /* per-chain NF value valid */
#define IEEE80211_R_C_RSSI 0x0000010 /* per-chain RSSI value valid */
#define IEEE80211_R_C_EVM 0x0000020 /* per-chain EVM valid */
#define IEEE80211_R_C_HT40 0x0000040 /* RX'ed packet is 40mhz, pilots 4,5 valid */
#define IEEE80211_R_FREQ 0x0000080 /* Freq value populated, MHz */
#define IEEE80211_R_IEEE 0x0000100 /* IEEE value populated */
#define IEEE80211_R_BAND 0x0000200 /* Frequency band populated */
struct ieee80211_rx_stats {
uint32_t r_flags; /* IEEE80211_R_* flags */
uint8_t c_chain; /* number of RX chains involved */
int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */
int16_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */
int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */
int16_t c_rssi_ext[IEEE80211_MAX_CHAINS]; /* per-chain RSSI */
uint8_t nf; /* global NF */
uint8_t rssi; /* global RSSI */
uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
/* per-chain, per-pilot EVM values */
uint16_t c_freq;
uint8_t c_ieee;
};
struct ieee80211_rx_params {
struct ieee80211_rx_stats params;
};
int ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs);
int ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs);
#ifdef __cplusplus
}
#endif
#endif /* _KERNEL */
#define IEEE80211_MALLOC malloc
#define IEEE80211_FREE free
/* XXX TODO: get rid of WAITOK, fix all the users of it? */
#define IEEE80211_M_NOWAIT M_NOWAIT
#define IEEE80211_M_WAITOK M_WAITOK
#define IEEE80211_M_ZERO M_ZERO
#endif /* _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ */