diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp index 54e7ce714b..3302422a27 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp @@ -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) { diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h index c2735078f1..023ca91097 100644 --- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h +++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h @@ -35,8 +35,8 @@ # ifdef __cplusplus // Those includes are needed to avoid C/C++ function export clashes -# include -# include +# include +# include 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_ */