freebsd11_wlan: Copy Haiku-specific files from FreeBSD 9 directory.

Again, unmodified.
This commit is contained in:
Augustin Cavalier 2018-06-11 19:47:52 -04:00
parent 293a2cae7a
commit 3c410aba97
7 changed files with 1239 additions and 0 deletions

View File

@ -0,0 +1,65 @@
SubDir HAIKU_TOP src libs compat freebsd_wlan net80211 ;
UseHeaders [ FDirName $(SUBDIR) .. .. freebsd_network ] : true ;
UseHeaders [ FDirName $(SUBDIR) .. .. freebsd_network compat ] : true ;
UseHeaders [ FDirName $(SUBDIR) .. ] : true ;
UseHeaders [ FDirName $(SUBDIR) ] : true ;
UsePrivateHeaders net system ;
UsePrivateKernelHeaders ;
# Enabling C++ structures in C only code
Includes [ FGristFiles kernel_c++_structs.h ]
: <src!system!kernel>kernel_c++_struct_sizes.h ;
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
-Wno-format -Wno-unused -Wno-uninitialized ;
SubDirC++Flags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ]
-Wno-format -Wno-unused -Wno-uninitialized ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) .. crypto rijndael ] ;
KernelStaticLibrary libfreebsd_wlan.a :
ieee80211.c
ieee80211_action.c
ieee80211_adhoc.c
ieee80211_ageq.c
ieee80211_amrr.c
ieee80211_crypto.c
ieee80211_crypto_ccmp.c
ieee80211_crypto_none.c
ieee80211_crypto_tkip.c
ieee80211_crypto_wep.c
ieee80211_dfs.c
ieee80211_haiku.cpp
ieee80211_ht.c
ieee80211_input.c
ieee80211_ioctl.c
ieee80211_hostap.c
ieee80211_monitor.c
ieee80211_node.c
ieee80211_output.c
ieee80211_phy.c
ieee80211_power.c
ieee80211_proto.c
ieee80211_radiotap.c
ieee80211_ratectl.c
ieee80211_ratectl_none.c
ieee80211_regdomain.c
ieee80211_rssadapt.c
ieee80211_scan_sta.c
ieee80211_scan.c
ieee80211_sta.c
ieee80211_wds.c
# Rijndael (aka AES) cryptographic support for crypto_ccmp
rijndael-alg-fst.c
rijndael-api.c
# NOT SUPPORTED YET ieee80211_acl.c
# NOT SUPPORTED YET ieee80211_ddb.c
# NOT SUPPORTED YET ieee80211_hwmp.c
# NOT SUPPORTED YET ieee80211_mesh.c
# NOT SUPPORTED YET ieee80211_superg.c
# NOT SUPPORTED YET ieee80211_tdma.c
ieee80211_xauth.c
;

View File

@ -0,0 +1,753 @@
/*
* Copyright 2009, Colin Günther, coling@gmx.de.
* All rights reserved. Distributed under the terms of the MIT License.
*/
/*-
* Copyright (c) 2003-2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* IEEE 802.11 support (Haiku-specific code)
*/
#include "ieee80211_haiku.h"
extern "C" {
# include <sys/kernel.h>
# include <sys/mbuf.h>
# include <sys/bus.h>
# include <sys/sockio.h>
# include <net/if.h>
# include <net/if_media.h>
# include <net/if_types.h>
# include <net/if_var.h>
# include "ieee80211_var.h"
};
#include <SupportDefs.h>
#include <util/KMessage.h>
#include <ether_driver.h>
#include <bosii_driver.h>
#include <net_notifications.h>
#include <shared.h>
#define TRACE_WLAN
#ifdef TRACE_WLAN
# define TRACE(x...) dprintf(x);
#else
# define TRACE(x...) ;
#endif
#define MC_ALIGN(m, len) \
do { \
(m)->m_data += (MCLBYTES - (len)) &~ (sizeof(long) - 1);\
} while (/* CONSTCOND */ 0)
static net_notifications_module_info* sNotificationModule;
static struct ifnet*
get_ifnet(device_t device, int& i)
{
int unit = device_get_unit(device);
for (i = 0; i < MAX_DEVICES; i++) {
if (gDevices[i] != NULL && gDevices[i]->if_dunit == unit)
return gDevices[i];
}
return NULL;
}
status_t
init_wlan_stack(void)
{
ieee80211_phy_init();
ieee80211_auth_setup();
ieee80211_ht_init();
get_module(NET_NOTIFICATIONS_MODULE_NAME,
(module_info**)&sNotificationModule);
return B_OK;
}
void
uninit_wlan_stack(void)
{
if (sNotificationModule != NULL)
put_module(NET_NOTIFICATIONS_MODULE_NAME);
}
status_t
start_wlan(device_t device)
{
int i;
struct ifnet* ifp = get_ifnet(device, i);
if (ifp == 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
if (vap == NULL) {
gDevices[i] = ifp;
return B_ERROR;
}
// ic_vap_create() established that gDevices[i] links to vap->iv_ifp now
KASSERT(gDevices[i] == vap->iv_ifp,
("start_wlan: gDevices[i] != vap->iv_ifp"));
vap->iv_ifp->scan_done_sem = create_sem(0, "wlan scan done");
// We aren't connected to a WLAN, yet.
if_link_state_change(vap->iv_ifp, LINK_STATE_DOWN);
dprintf("%s: wlan started.\n", __func__);
return B_OK;
}
status_t
stop_wlan(device_t device)
{
int i;
struct ifnet* ifp = get_ifnet(device, i);
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;
struct ieee80211com* ic = vap->iv_ic;
ic->ic_vap_delete(vap);
// 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;
}
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)
{
struct ifnet* ifp = (struct ifnet*)cookie;
switch (op) {
case BOSII_DEVICE:
return B_OK;
case BOSII_DETECT_NETWORKS:
{
struct ieee80211req request;
struct ieee80211_scan_req scanRequest;
if_printf(ifp, "%s: BOSII_DETECT_NETWORKS\n", __func__);
memset(&scanRequest, 0, sizeof(scanRequest));
scanRequest.sr_flags = IEEE80211_IOC_SCAN_ACTIVE
| IEEE80211_IOC_SCAN_NOPICK
| IEEE80211_IOC_SCAN_ONCE;
scanRequest.sr_duration = 10000; // 10 s
scanRequest.sr_nssid = 0;
memset(&request, 0, sizeof(request));
request.i_type = IEEE80211_IOC_SCAN_REQ;
request.i_data = &scanRequest;
request.i_len = sizeof(scanRequest);
ifp->if_ioctl(ifp, SIOCS80211, (caddr_t)&request);
acquire_sem_etc(ifp->scan_done_sem, 1, B_RELATIVE_TIMEOUT,
10000000); // 10 s
return B_OK;
}
case BOSII_GET_DETECTED_NETWORKS:
{
struct ieee80211req request;
struct ifreq ifRequest;
struct route_entry* networkRequest = &ifRequest.ifr_route;
if_printf(ifp, "%s: BOSII_GET_DETECTED_NETWORKS\n", __func__);
if (length < sizeof(struct ieee80211req_scan_result))
return B_BAD_VALUE;
if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) < B_OK)
return B_BAD_ADDRESS;
memset(&request, 0, sizeof(request));
request.i_type = IEEE80211_IOC_SCAN_RESULTS;
request.i_len = length;
request.i_data = networkRequest->destination;
// After return value of request.i_data is copied into user
// space, already.
if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK)
return B_BAD_ADDRESS;
// Tell the user space how much data was copied
networkRequest->mtu = request.i_len;
if (user_memcpy(&((struct ifreq*)arg)->ifr_route.mtu,
&networkRequest->mtu, sizeof(networkRequest->mtu)) < B_OK)
return B_BAD_ADDRESS;
return B_OK;
}
case BOSII_JOIN_NETWORK:
{
struct ieee80211req request;
struct ifreq ifRequest;
struct route_entry* networkRequest = &ifRequest.ifr_route;
struct ieee80211req_scan_result network;
if_printf(ifp, "%s: BOSII_JOIN_NETWORK\n", __func__);
if (length < sizeof(struct ifreq))
return B_BAD_VALUE;
if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) != B_OK
|| user_memcpy(&network, networkRequest->source,
sizeof(ieee80211req_scan_result)) != B_OK)
return B_BAD_ADDRESS;
memset(&request, 0, sizeof(ieee80211req));
request.i_type = IEEE80211_IOC_SSID;
request.i_val = 0;
request.i_len = network.isr_ssid_len;
request.i_data = (uint8*)networkRequest->source
+ network.isr_ie_off;
if (ifp->if_ioctl(ifp, SIOCS80211, (caddr_t)&request) < B_OK)
return B_ERROR;
// wait for network join
return B_OK;
}
case BOSII_GET_ASSOCIATED_NETWORK:
{
struct ieee80211req request;
struct ifreq ifRequest;
struct route_entry* networkRequest = &ifRequest.ifr_route;
if_printf(ifp, "%s: BOSII_GET_ASSOCIATED_NETWORK\n", __func__);
if (length < sizeof(struct ieee80211req_sta_req))
return B_BAD_VALUE;
if (user_memcpy(&ifRequest, arg, sizeof(ifRequest)) < B_OK)
return B_BAD_ADDRESS;
// Only want station information about associated network.
memset(&request, 0, sizeof(request));
request.i_type = IEEE80211_IOC_BSSID;
request.i_len = IEEE80211_ADDR_LEN;
request.i_data = ((struct ieee80211req_sta_req*)networkRequest->
destination)->is_u.macaddr;
if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK)
return B_BAD_ADDRESS;
request.i_type = IEEE80211_IOC_STA_INFO;
request.i_len = length;
request.i_data = networkRequest->destination;
// After return value of request.i_data is copied into user
// space, already.
if (ifp->if_ioctl(ifp, SIOCG80211, (caddr_t)&request) < B_OK)
return B_BAD_ADDRESS;
// Tell the user space how much data was copied
networkRequest->mtu = request.i_len;
if (user_memcpy(&((struct ifreq*)arg)->ifr_route.mtu,
&networkRequest->mtu, sizeof(networkRequest->mtu)) != B_OK)
return B_BAD_ADDRESS;
return B_OK;
}
case SIOCG80211:
case SIOCS80211:
{
// Allowing FreeBSD based WLAN ioctls to pass, as those will become
// the future Haiku WLAN ioctls anyway.
// FreeBSD drivers assume that the request structure has already
// been copied into kernel space
struct ieee80211req request;
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)
return status;
if (op == SIOCG80211 && user_memcpy(arg, &request,
sizeof(struct ieee80211req)) != B_OK)
return B_BAD_ADDRESS;
return B_OK;
}
case SIOCSIFFLAGS:
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
case SIOCSIFMTU:
// Requests that make it here always come from the kernel
return ifp->if_ioctl(ifp, op, (caddr_t)arg);
}
return B_BAD_VALUE;
}
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)
{
uint8_t* dp = (uint8_t*)p;
while (n > 0) {
uint32_t v = arc4random();
size_t nb = n > sizeof(uint32_t) ? sizeof(uint32_t) : n;
bcopy(&v, dp, n > sizeof(uint32_t) ? sizeof(uint32_t) : n);
dp += sizeof(uint32_t), n -= nb;
}
}
struct mbuf*
ieee80211_getmgtframe(uint8_t** frm, int headroom, int pktlen)
{
struct mbuf* m;
u_int len;
len = roundup2(headroom + pktlen, 4);
KASSERT(len <= MCLBYTES, ("802.11 mgt frame too large: %u", len));
if (len < MINCLSIZE) {
m = m_gethdr(M_NOWAIT, MT_DATA);
if (m != NULL)
MH_ALIGN(m, len);
} else {
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (m != NULL)
MC_ALIGN(m, len);
}
if (m != NULL) {
m->m_data += headroom;
*frm = (uint8_t*)m->m_data;
}
return m;
}
/*
* Decrements the reference-counter and
* tests whether it became zero. If so, sets it to one.
*
* @return 1 reference-counter became zero
* @return 0 reference-counter didn't became zero
*/
int
ieee80211_node_dectestref(struct ieee80211_node* ni)
{
atomic_subtract_int(&ni->ni_refcnt, 1);
return atomic_cmpset_int(&ni->ni_refcnt, 0, 1);
}
void
ieee80211_drain_ifq(struct ifqueue* ifq)
{
struct ieee80211_node* ni;
struct mbuf* m;
for (;;) {
IF_DEQUEUE(ifq, m);
if (m == NULL)
break;
ni = (struct ieee80211_node*)m->m_pkthdr.rcvif;
KASSERT(ni != NULL, ("frame w/o node"));
ieee80211_free_node(ni);
m->m_pkthdr.rcvif = NULL;
m_freem(m);
}
}
void
ieee80211_flush_ifq(struct ifqueue* ifq, struct ieee80211vap* vap)
{
struct ieee80211_node* ni;
struct mbuf* m;
struct mbuf** mprev;
IF_LOCK(ifq);
mprev = &ifq->ifq_head;
while ((m = *mprev) != NULL) {
ni = (struct ieee80211_node*)m->m_pkthdr.rcvif;
if (ni != NULL && ni->ni_vap == vap) {
*mprev = m->m_nextpkt;
// remove from list
ifq->ifq_len--;
m_freem(m);
ieee80211_free_node(ni);
// reclaim ref
} else
mprev = &m->m_nextpkt;
}
// recalculate tail ptr
m = ifq->ifq_head;
for (; m != NULL && m->m_nextpkt != NULL; m = m->m_nextpkt);
ifq->ifq_tail = m;
IF_UNLOCK(ifq);
}
int
ieee80211_add_callback(struct mbuf* m,
void (*func)(struct ieee80211_node*, void*, int), void* arg)
{
struct m_tag* mtag;
struct ieee80211_cb* cb;
mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_CALLBACK,
sizeof(struct ieee80211_cb), M_NOWAIT);
if (mtag == NULL)
return 0;
cb = (struct ieee80211_cb*)(mtag+1);
cb->func = func;
cb->arg = arg;
m_tag_prepend(m, mtag);
m->m_flags |= M_TXCB;
return 1;
}
void
ieee80211_process_callback(struct ieee80211_node* ni, struct mbuf* m,
int status)
{
struct m_tag* mtag;
mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, NULL);
if (mtag != NULL) {
struct ieee80211_cb* cb = (struct ieee80211_cb*)(mtag+1);
cb->func(ni, cb->arg, status);
}
}
void
ieee80211_sysctl_vattach(struct ieee80211vap* vap)
{
vap->iv_debug = IEEE80211_MSG_XRATE
| IEEE80211_MSG_NODE
| IEEE80211_MSG_ASSOC
| IEEE80211_MSG_AUTH
| IEEE80211_MSG_STATE
| IEEE80211_MSG_POWER
| IEEE80211_MSG_WME
| IEEE80211_MSG_DOTH
| IEEE80211_MSG_INACT
| IEEE80211_MSG_ROAM
| IEEE80211_MSG_RATECTL;
}
void
ieee80211_sysctl_vdetach(struct ieee80211vap* vap)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_vap_destroy(struct ieee80211vap* vap)
{
struct ieee80211com* ic = vap->iv_ic;
ic->ic_vap_delete(vap);
dprintf("%s: done.\n", __func__);
}
void
ieee80211_load_module(const char* modname)
{
dprintf("%s not implemented, yet: modname %s\n", __func__, modname);
}
void
ieee80211_notify_node_join(struct ieee80211_node* ni, int newassoc)
{
struct ieee80211vap* vap = ni->ni_vap;
struct ifnet* ifp = vap->iv_ifp;
if (ni == vap->iv_bss)
if_link_state_change(ifp, LINK_STATE_UP);
TRACE("%s\n", __FUNCTION__);
if (sNotificationModule != NULL) {
char messageBuffer[512];
KMessage message;
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR);
message.AddInt32("opcode", B_NETWORK_WLAN_JOINED);
message.AddString("interface", ifp->device_name);
// TODO: add data about the node
sNotificationModule->send_notification(&message);
}
}
void
ieee80211_notify_node_leave(struct ieee80211_node* ni)
{
struct ieee80211vap* vap = ni->ni_vap;
struct ifnet* ifp = vap->iv_ifp;
if (ni == vap->iv_bss)
if_link_state_change(ifp, LINK_STATE_DOWN);
TRACE("%s\n", __FUNCTION__);
if (sNotificationModule != NULL) {
char messageBuffer[512];
KMessage message;
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR);
message.AddInt32("opcode", B_NETWORK_WLAN_LEFT);
message.AddString("interface", ifp->device_name);
// TODO: add data about the node
sNotificationModule->send_notification(&message);
}
}
void
ieee80211_notify_scan_done(struct ieee80211vap* vap)
{
release_sem_etc(vap->iv_ifp->scan_done_sem, 1,
B_DO_NOT_RESCHEDULE | B_RELEASE_ALL);
TRACE("%s\n", __FUNCTION__);
if (sNotificationModule != NULL) {
char messageBuffer[512];
KMessage message;
message.SetTo(messageBuffer, sizeof(messageBuffer), B_NETWORK_MONITOR);
message.AddInt32("opcode", B_NETWORK_WLAN_SCANNED);
message.AddString("interface", vap->iv_ifp->device_name);
sNotificationModule->send_notification(&message);
}
}
void
ieee80211_notify_replay_failure(struct ieee80211vap* vap,
const struct ieee80211_frame* wh, const struct ieee80211_key* k,
u_int64_t rsc, int tid)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_michael_failure(struct ieee80211vap* vap,
const struct ieee80211_frame* wh, u_int keyix)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_wds_discover(struct ieee80211_node* ni)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_csa(struct ieee80211com* ic,
const struct ieee80211_channel* c, int mode, int count)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_radar(struct ieee80211com* ic,
const struct ieee80211_channel* c)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_cac(struct ieee80211com* ic,
const struct ieee80211_channel* c, enum ieee80211_notify_cac_event type)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_node_deauth(struct ieee80211_node* ni)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_node_auth(struct ieee80211_node* ni)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_country(struct ieee80211vap* vap,
const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t cc[2])
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_notify_radio(struct ieee80211com* ic, int state)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_sysctl_attach(struct ieee80211com* ic)
{
dprintf("%s not implemented, yet.\n", __func__);
}
void
ieee80211_sysctl_detach(struct ieee80211com* ic)
{
dprintf("%s not implemented, yet.\n", __func__);
}

View File

@ -0,0 +1,395 @@
/*-
* Copyright (c) 2003-2008 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_
#define _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_
#include <stdint.h>
#ifdef _KERNEL
# ifdef __cplusplus
// Those includes are needed to avoid C/C++ function export clashes
# include <new>
# include <thread.h>
extern "C" {
# endif
#define INVARIANTS 1
#include <sys/kernel.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#define IEEE80211_CRYPTO_MODULE(name, version) \
void \
ieee80211_crypto_##name##_load() { \
ieee80211_crypto_register(&name); \
} \
\
\
void \
ieee80211_crypto_##name##_unload() \
{ \
ieee80211_crypto_unregister(&name); \
}
/*
* Common state locking definitions.
*/
typedef struct {
char name[16]; /* e.g. "ath0_com_lock" */
struct mtx mtx;
} ieee80211_com_lock_t;
#define IEEE80211_LOCK_INIT(_ic, _name) do { \
ieee80211_com_lock_t *cl = &(_ic)->ic_comlock; \
snprintf(cl->name, sizeof(cl->name), "%s_com_lock", _name); \
mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF | MTX_RECURSE); \
} while (0)
#define IEEE80211_LOCK_OBJ(_ic) (&(_ic)->ic_comlock.mtx)
#define IEEE80211_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_LOCK_OBJ(_ic))
#define IEEE80211_LOCK(_ic) mtx_lock(IEEE80211_LOCK_OBJ(_ic))
#define IEEE80211_UNLOCK(_ic) mtx_unlock(IEEE80211_LOCK_OBJ(_ic))
#define IEEE80211_LOCK_ASSERT(_ic) \
mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED)
/*
* Node locking definitions.
*/
typedef struct {
char name[16]; /* e.g. "ath0_node_lock" */
struct mtx mtx;
} ieee80211_node_lock_t;
#define IEEE80211_NODE_LOCK_INIT(_nt, _name) do { \
ieee80211_node_lock_t *nl = &(_nt)->nt_nodelock; \
snprintf(nl->name, sizeof(nl->name), "%s_node_lock", _name); \
mtx_init(&nl->mtx, nl->name, NULL, MTX_DEF | MTX_RECURSE); \
} while (0)
#define IEEE80211_NODE_LOCK_OBJ(_nt) (&(_nt)->nt_nodelock.mtx)
#define IEEE80211_NODE_LOCK_DESTROY(_nt) \
mtx_destroy(IEEE80211_NODE_LOCK_OBJ(_nt))
#define IEEE80211_NODE_LOCK(_nt) \
mtx_lock(IEEE80211_NODE_LOCK_OBJ(_nt))
#define IEEE80211_NODE_IS_LOCKED(_nt) \
mtx_owned(IEEE80211_NODE_LOCK_OBJ(_nt))
#define IEEE80211_NODE_UNLOCK(_nt) \
mtx_unlock(IEEE80211_NODE_LOCK_OBJ(_nt))
#define IEEE80211_NODE_LOCK_ASSERT(_nt) \
mtx_assert(IEEE80211_NODE_LOCK_OBJ(_nt), MA_OWNED)
/*
* Node table iteration locking definitions; this protects the
* scan generation # used to iterate over the station table
* while grabbing+releasing the node lock.
*/
typedef struct {
char name[16]; /* e.g. "ath0_scan_lock" */
struct mtx mtx;
} ieee80211_scan_lock_t;
#define IEEE80211_NODE_ITERATE_LOCK_INIT(_nt, _name) do { \
ieee80211_scan_lock_t *sl = &(_nt)->nt_scanlock; \
snprintf(sl->name, sizeof(sl->name), "%s_scan_lock", _name); \
mtx_init(&sl->mtx, sl->name, NULL, MTX_DEF); \
} while (0)
#define IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt) (&(_nt)->nt_scanlock.mtx)
#define IEEE80211_NODE_ITERATE_LOCK_DESTROY(_nt) \
mtx_destroy(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
#define IEEE80211_NODE_ITERATE_LOCK(_nt) \
mtx_lock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
#define IEEE80211_NODE_ITERATE_UNLOCK(_nt) \
mtx_unlock(IEEE80211_NODE_ITERATE_LOCK_OBJ(_nt))
/*
* Power-save queue definitions.
*/
typedef struct mtx ieee80211_psq_lock_t;
#define IEEE80211_PSQ_INIT(_psq, _name) \
mtx_init(&(_psq)->psq_lock, _name, "802.11 ps q", MTX_DEF)
#define IEEE80211_PSQ_DESTROY(_psq) mtx_destroy(&(_psq)->psq_lock)
#define IEEE80211_PSQ_LOCK(_psq) mtx_lock(&(_psq)->psq_lock)
#define IEEE80211_PSQ_UNLOCK(_psq) mtx_unlock(&(_psq)->psq_lock)
#ifndef IF_PREPEND_LIST
#define _IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \
(mtail)->m_nextpkt = (ifq)->ifq_head; \
if ((ifq)->ifq_tail == NULL) \
(ifq)->ifq_tail = (mtail); \
(ifq)->ifq_head = (mhead); \
(ifq)->ifq_len += (mcount); \
} while (0)
#define IF_PREPEND_LIST(ifq, mhead, mtail, mcount) do { \
IF_LOCK(ifq); \
_IF_PREPEND_LIST(ifq, mhead, mtail, mcount); \
IF_UNLOCK(ifq); \
} while (0)
#endif /* IF_PREPEND_LIST */
/*
* Age queue definitions.
*/
typedef struct mtx ieee80211_ageq_lock_t;
#define IEEE80211_AGEQ_INIT(_aq, _name) \
mtx_init(&(_aq)->aq_lock, _name, "802.11 age q", MTX_DEF)
#define IEEE80211_AGEQ_DESTROY(_aq) mtx_destroy(&(_aq)->aq_lock)
#define IEEE80211_AGEQ_LOCK(_aq) mtx_lock(&(_aq)->aq_lock)
#define IEEE80211_AGEQ_UNLOCK(_aq) mtx_unlock(&(_aq)->aq_lock)
/*
* Scan table definitions.
*/
typedef struct mtx ieee80211_scan_table_lock_t;
#define IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \
mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF)
#define IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_lock)
#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock)
#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock)
/*
* Node reference counting definitions.
*
* ieee80211_node_initref initialize the reference count to 1
* ieee80211_node_incref add a reference
* ieee80211_node_decref remove a reference
* ieee80211_node_dectestref remove a reference and return 1 if this
* is the last reference, otherwise 0
* ieee80211_node_refcnt reference count for printing (only)
*/
#include <machine/atomic.h>
#define ieee80211_node_initref(_ni) \
do { ((_ni)->ni_refcnt = 1); } while (0)
#define ieee80211_node_incref(_ni) \
atomic_add_int(&(_ni)->ni_refcnt, 1)
#define ieee80211_node_decref(_ni) \
atomic_subtract_int(&(_ni)->ni_refcnt, 1)
struct ieee80211_node;
int ieee80211_node_dectestref(struct ieee80211_node *ni);
#define ieee80211_node_refcnt(_ni) (_ni)->ni_refcnt
struct ifqueue;
struct ieee80211vap;
void ieee80211_drain_ifq(struct ifqueue *);
void ieee80211_flush_ifq(struct ifqueue *, struct ieee80211vap *);
void ieee80211_vap_destroy(struct ieee80211vap *);
#define IFNET_IS_UP_RUNNING(_ifp) \
(((_ifp)->if_flags & IFF_UP) && \
((_ifp)->if_drv_flags & IFF_DRV_RUNNING))
#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)
struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
/* tx path usage */
#define M_ENCAP M_PROTO1 /* 802.11 encap done */
#define M_EAPOL M_PROTO3 /* PAE/EAPOL frame */
#define M_PWR_SAV M_PROTO4 /* bypass PS handling */
#define M_MORE_DATA M_PROTO5 /* more data frames to follow */
#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_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)
/* rx path usage */
#define M_AMPDU M_PROTO1 /* A-MPDU subframe */
#define M_WEP M_PROTO2 /* WEP done by hardware */
#if 0
#define M_AMPDU_MPDU M_PROTO8 /* A-MPDU re-order done */
#endif
#define M_80211_RX (M_AMPDU|M_WEP|M_AMPDU_MPDU)
/*
* Store WME access control bits in the vlan tag.
* This is safe since it's done after the packet is classified
* (where we use any previous tag) and because it's passed
* directly in to the driver and there's no chance someone
* else will clobber them on us.
*/
#define M_WME_SETAC(m, ac) \
((m)->m_pkthdr.ether_vtag = (ac))
#define M_WME_GETAC(m) ((m)->m_pkthdr.ether_vtag)
/*
* Mbufs on the power save queue are tagged with an age and
* timed out. We reuse the hardware checksum field in the
* mbuf packet header to store this data.
*/
#define M_AGE_SET(m,v) (m->m_pkthdr.csum_data = v)
#define M_AGE_GET(m) (m->m_pkthdr.csum_data)
#define M_AGE_SUB(m,adj) (m->m_pkthdr.csum_data -= adj)
/*
* Store the sequence number.
*/
#define M_SEQNO_SET(m, seqno) \
((m)->m_pkthdr.tso_segsz = (seqno))
#define M_SEQNO_GET(m) ((m)->m_pkthdr.tso_segsz)
#define MTAG_ABI_NET80211 1132948340 /* net80211 ABI */
struct ieee80211_cb {
void (*func)(struct ieee80211_node *, void *, int status);
void *arg;
};
#define NET80211_TAG_CALLBACK 0 /* xmit complete callback */
int ieee80211_add_callback(struct mbuf *m,
void (*func)(struct ieee80211_node *, void *, int), void *arg);
void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
void get_random_bytes(void *, size_t);
struct ieee80211com;
void ieee80211_sysctl_attach(struct ieee80211com *);
void ieee80211_sysctl_detach(struct ieee80211com *);
void ieee80211_sysctl_vattach(struct ieee80211vap *);
void ieee80211_sysctl_vdetach(struct ieee80211vap *);
void ieee80211_load_module(const char *);
/*
* A "policy module" is an adjunct module to net80211 that provides
* functionality that typically includes policy decisions. This
* modularity enables extensibility and vendor-supplied functionality.
*/
#define _IEEE80211_POLICY_MODULE(policy, name, version) \
typedef void (*policy##_setup)(int); \
SET_DECLARE(policy##_set, policy##_setup);
/*
* Authenticator modules handle 802.1x/WPA authentication.
*/
#define IEEE80211_AUTH_MODULE(name, version) \
_IEEE80211_POLICY_MODULE(auth, name, version)
#define IEEE80211_AUTH_ALG(name, alg, v) \
static void \
name##_modevent(int type) \
{ \
if (type == MOD_LOAD) \
ieee80211_authenticator_register(alg, &v); \
else \
ieee80211_authenticator_unregister(alg); \
} \
TEXT_SET(auth_set, name##_modevent)
/*
* Scanner modules provide scanning policy.
*/
#define IEEE80211_SCANNER_MODULE(name, version)
#define IEEE80211_SCANNER_ALG(name, alg, v)
void ieee80211_scan_sta_init(void);
void ieee80211_scan_sta_uninit(void);
/*
* Rate control modules provide tx rate control support.
*/
#define IEEE80211_RATECTL_MODULE(alg, version) \
_IEEE80211_POLICY_MODULE(ratectl, alg, version); \
#define IEEE80211_RATECTL_ALG(name, alg, v) \
void \
ieee80211_ratectl_##name##_load() { \
ieee80211_ratectl_register(alg, &v); \
} \
\
\
void \
ieee80211_ratectl_##name##_unload() \
{ \
ieee80211_ratectl_unregister(alg); \
}
struct ieee80211req;
typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *,
struct ieee80211req *);
SET_DECLARE(ieee80211_ioctl_getset, ieee80211_ioctl_getfunc);
#define IEEE80211_IOCTL_GET(_name, _get) TEXT_SET(ieee80211_ioctl_getset, _get)
typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *,
struct ieee80211req *);
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
* user applications to specify pretty much everything in
* an Atheros tx descriptor. XXX need to generalize.
*
* XXX cannot be more than 14 bytes as it is copied to a sockaddr's
* XXX sa_data area.
*/
struct ieee80211_bpf_params {
uint8_t ibp_vers; /* version */
#define IEEE80211_BPF_VERSION 0
uint8_t ibp_len; /* header length in bytes */
uint8_t ibp_flags;
#define IEEE80211_BPF_SHORTPRE 0x01 /* tx with short preamble */
#define IEEE80211_BPF_NOACK 0x02 /* tx with no ack */
#define IEEE80211_BPF_CRYPTO 0x04 /* tx with h/w encryption */
#define IEEE80211_BPF_FCS 0x10 /* frame incldues FCS */
#define IEEE80211_BPF_DATAPAD 0x20 /* frame includes data padding */
#define IEEE80211_BPF_RTS 0x40 /* tx with RTS/CTS */
#define IEEE80211_BPF_CTS 0x80 /* tx with CTS only */
uint8_t ibp_pri; /* WME/WMM AC+tx antenna */
uint8_t ibp_try0; /* series 1 try count */
uint8_t ibp_rate0; /* series 1 IEEE tx rate */
uint8_t ibp_power; /* tx power (device units) */
uint8_t ibp_ctsrate; /* IEEE tx rate for CTS */
uint8_t ibp_try1; /* series 2 try count */
uint8_t ibp_rate1; /* series 2 IEEE tx rate */
uint8_t ibp_try2; /* series 3 try count */
uint8_t ibp_rate2; /* series 3 IEEE tx rate */
uint8_t ibp_try3; /* series 4 try count */
uint8_t ibp_rate3; /* series 4 IEEE tx rate */
};
#endif /* _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ */

View File

@ -0,0 +1,6 @@
#ifndef _FBSD_COMPAT_NET80211_OPT_INET_H_
#define _FBSD_COMPAT_NET80211_OPT_INET_H_
#define INET 1
#endif /* _FBSD_COMPAT_NET80211_OPT_INET_H_ */

View File

@ -0,0 +1,6 @@
#ifndef _FBSD_COMPAT_NET80211_OPT_INET6_H_
#define _FBSD_COMPAT_NET80211_OPT_INET6_H_
//#define INET6 1
#endif /* _FBSD_COMPAT_NET80211_OPT_INET6_H_ */

View File

@ -0,0 +1,6 @@
#ifndef _FBSD_COMPAT_NET80211_OPT_IPX_H_
#define _FBSD_COMPAT_NET80211_OPT_IPX_H_
//define IPX 1
#endif /* _FBSD_COMPAT_NET80211_OPT_IPX_H_ */

View File

@ -0,0 +1,8 @@
#ifndef _FBSD_COMPAT_NET80211_OPT_WLAN_H_
#define _FBSD_COMPAT_NET80211_OPT_WLAN_H_
#define IEEE80211_DEBUG 1
//#define IEEE80211_AMDPU_AGE 1
//#define IEEE80211_SUPPORT_MESH 1
#endif /* _FBSD_COMPAT_NET80211_OPT_WLAN_H_ */