wifi_drv: Port of the Linux wireless stack

This commit is contained in:
Josef Söntgen 2014-11-22 15:13:43 +01:00 committed by Christian Helmuth
parent 2eaa55e6b1
commit 703e3622ff
77 changed files with 17685 additions and 4 deletions

View File

@ -82,3 +82,38 @@ LXIP is a port of the Linux TCP/IP stack to Genode. It is build as a shared
library named 'lxip.lib.so'. The IP stack can be interfaced using Genode's
version of 'libc' by linking your application to 'lxip_libc' plugin in your
'target.mk' file.
WIFI
####
The wifi_drv component is a port of the Linux mac802.11 stack, including the
iwlwifi driver as well as libnl and wpa_supplicant, to Genode.
Configuration snippet:
!<start name="wifi_drv">
! <resource name="RAM" quantum="32M"/>
! <provides><service name="Nic"/></provides>
! <config>
! <libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc">
! <vfs>
! <dir name="dev"> <log/> <rtc/>
! <jitterentropy name="random"/>
! <jitterentropy name="urandom"/>
! </dir>
! <inline name="wpa_supplicant.conf">
!network={
! id_str="foobar"
! ssid="foobar"
! key_mgmt=WPA-PSK
! psk="foobarfoobar"
!}
! </inline>
! </vfs>
! </libc>
! </config>
! <route>
! <service name="Rtc"> <any-child /> </service>
! <any-service> <parent/> <any-child /> </any-service>
! </route>
!</start

View File

@ -0,0 +1,105 @@
/*
* \brief Socket interface for calling the Linux WIFI stack
* \author Josef Soentgen
* \date 2012-08-02
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _WIFI__SOCKET_CALL_H_
#define _WIFI__SOCKET_CALL_H_
namespace Wifi {
struct Socket;
struct Sockaddr;
struct Msghdr;
struct Socket_call;
struct Poll_socket_fd;
/*
* XXX We need the WIFI_ prefix because SOL_SOCKET and friends are
* preprocessor macros.
*/
enum Flags { WIFI_F_NONE, WIFI_F_MSG_ERRQUEUE };
enum Sockopt_level { WIFI_SOL_SOCKET, WIFI_SOL_NETLINK };
enum Sockopt_name {
/* SOL_SOCKET */
WIFI_SO_SNDBUF,
WIFI_SO_RCVBUF,
WIFI_SO_PASSCRED,
WIFI_SO_WIFI_STATUS,
/* SOL_NETLINK */
WIFI_NETLINK_ADD_MEMBERSHIP,
WIFI_NETLINK_DROP_MEMBERSHIP,
WIFI_NETLINK_PKTINFO,
};
enum Poll_mask {
WIFI_POLLIN = 0x1,
WIFI_POLLOUT = 0x2,
WIFI_POLLEX = 0x4,
};
enum { MAX_POLL_SOCKETS = 16, };
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ssize_t;
}
struct Wifi::Sockaddr { };
struct Wifi::Msghdr
{
enum { MAX_IOV_LEN = 8 };
struct Iov {
void *iov_base;
size_t iov_len;
};
void *msg_name;
unsigned msg_namelen;
Iov msg_iov[MAX_IOV_LEN];
unsigned msg_iovlen;
/* XXX recvmsg msg_flags ? */
void *msg_control;
unsigned msg_controllen;
};
struct Wifi::Socket_call
{
Socket* socket(int domain, int type, int protocol);
int close(Socket *);
int bind(Socket *, Sockaddr const *addr, unsigned addrlen);
int getsockname(Socket *, Sockaddr *addr, unsigned *addrlen);
int poll_all(Poll_socket_fd *, unsigned, int);
ssize_t recvmsg(Socket*, Msghdr *, Flags flags);
ssize_t sendmsg(Socket*, Msghdr const *, Flags flags);
int setsockopt(Socket*, Sockopt_level level, Sockopt_name optname,
void const *optval, unsigned optlen);
void non_block(Socket *, bool);
/**
* Special ioctl related functions
*/
void get_mac_address(unsigned char *addr);
};
struct Wifi::Poll_socket_fd
{
Socket *s;
void *pfd;
int events;
int revents;
};
#endif /* _WIFI__SOCKET_CALL_H_ */

View File

@ -0,0 +1,11 @@
NL_CONTRIB_INC_DIR := $(call select_from_ports,dde_linux)/src/lib/libnl
INC_DIR += $(NL_CONTRIB_INC_DIR)/include
LIBNL_INC_DIR = $(REP_DIR)/src/lib/libnl/include
INC_DIR += $(LIBNL_INC_DIR)
ifneq ($(filter 32bit,$(SPECS)),)
INC_DIR += $(LIBNL_INC_DIR)/32bit
endif
ifneq ($(filter 64bit,$(SPECS)),)
INC_DIR += $(LIBNL_INC_DIR)/64bit
endif

View File

@ -0,0 +1,65 @@
LIB_DIR = $(REP_DIR)/src/lib/libnl
LIB_INC_DIR = $(LIB_DIR)/include
LIBS += libc
LIBNL_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/libnl
INC_DIR += $(LIB_INC_DIR)
INC_DIR += $(LIBNL_CONTRIB_DIR)/include
SRC_CC += lxcc_emul.cc socket.cc if.cc
# libnl
SRC_C += $(addprefix lib/, attr.c cache.c cache_mngt.c data.c error.c handlers.c \
hashtable.c msg.c nl.c object.c socket.c utils.c)
# libnl-genl
SRC_C += $(addprefix lib/genl/, ctrl.c family.c genl.c mngt.c)
CC_OPT += -DSYSCONFDIR=\"/\"
CC_C_OPT += -include $(LIB_INC_DIR)/libnl_emul.h
# libnl-route
#SRC_C += $(wildcard lib/fib_lookup/*.c) \
# $(wildcard lib/route/act/*.c) \
# $(wildcard lib/route/cls/*.c) \
# $(wildcard lib/route/link/*.c) \
# $(wildcard lib/route/qdisc/*.c) \
# $(wildcard lib/route/*.c)
# libnl-netfilter
#SRC_C += $(wildcard lib/netfilter/*.c)
# libnl-diag
#SRC_C += $(wildcard lib/idiag/*.c)
#
# Generate links for emulated header files in build directory
#
EMUL_INC := $(shell pwd)/include
EMUL_INC_LIST := $(addprefix linux/, netdevice.h ethtool.h atm.h socket.h in_route.h) \
$(addprefix asm/, byteorder.h)
EMUL_INCLUDES := $(addprefix $(EMUL_INC)/,$(EMUL_INC_LIST))
INC_DIR += $(EMUL_INC)
#
# Eagerly create directory. Otherwise it will not be picked up from
# INC_DIR because $(wildcard ...) does not return non-existent dirs.
#
$(shell mkdir -p $(EMUL_INC))
#
# Make sure to create the header symlinks prior building
#
$(SRC_C:.c=.o) $(SRC_CC:.cc=.o): $(EMUL_INCLUDES)
$(EMUL_INCLUDES):
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)ln -s $(LIB_INC_DIR)/libnl_emul.h $@
vpath %.c $(LIBNL_CONTRIB_DIR)
vpath %.c $(LIB_DIR)
vpath %.cc $(LIB_DIR)
# vi: set ft=make :

View File

@ -0,0 +1,161 @@
LIB_DIR = $(REP_DIR)/src/lib/wifi
LIB_INC_DIR = $(LIB_DIR)/include
SHARED_LIB = yes
# FIXME should we *really* add dde_kit to this shared library?
LIBS += dde_kit libc-setjmp libc
LD_OPT += --version-script=$(LIB_DIR)/symbol.map
SRC_CC += dummies.cc init.cc lxcc_emul.cc pci_driver.cc timer.cc irq.cc \
work.cc nic.cc socket_call.cc scheduler.cc event.cc
SRC_C += lxc_emul.c socket.c
CC_WARN =
CC_OPT += -fno-builtin-toupper
CC_C_OPT += -include $(LIB_INC_DIR)/lx_emul.h
CC_C_OPT += -Wall -Wno-unused-variable -Wno-unused-function -Wno-uninitialized
CC_C_OPT += -Wno-unused-but-set-variable -Wno-pointer-sign -Wno-cast-qual
CC_CXX_OPT += -Wall -fpermissive
WIFI_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/wifi
DRIVERS_DIR := $(WIFI_CONTRIB_DIR)/drivers
WIFI_DIR := $(WIFI_CONTRIB_DIR)/net
#
# The order of include-search directories is important, we need to look into
# 'contrib' before falling back to our custom 'lx_emul.h' header.
#
INC_DIR += $(LIB_INC_DIR)
INC_DIR += $(WIFI_CONTRIB_DIR)/include $(WIFI_CONTRIB_DIR)/include/uapi \
INC_DIR += $(LIB_DIR)
CC_OPT += -U__linux__ -D __KERNEL__ -DCONFIG_PCI
#CC_OPT += -DCONFIG_INET
CC_OPT += -DCONFIG_NET -DCONFIG_NET_NS -DCONFIG_WLAN #-D__MAC80211_DRIVER_TRACE
# needed for firmware loading
CC_OPT += -DCONFIG_FW_LOADER
# bling bling
CC_OPT += -DCONFIG_LEDS_TRIGGERS -DCONFIG_MAC80211_LEDS
# mesh
CC_OPT += -DCONFIG_MAC80211_MESH
# power management
CC_OPT += -DCONFIG_PM -DCONFIG_PM_SLEEP
# rfkill
CC_OPT += -DCONFIG_RFKILL
# choose default pid algorithm
CC_OPT += -DCONFIG_MAC80211_RC_PID -DCONFIG_MAC80211_RC_DEFAULT=\"pid\"
#
# Suffix of global 'module_init' function
#
MOD_SUFFIX =
CC_OPT += -DMOD_SUFFIX=$(MOD_SUFFIX)
SRC_C += lib/ctype.c
SRC_C += lib/crc32.c
# crypto
SRC_C += $(addprefix crypto/, $(notdir $(wildcard $(WIFI_CONTRIB_DIR)/crypto/*.c)))
# net
SRC_C += net/core/datagram.c
SRC_C += net/core/rtnetlink.c
SRC_C += net/core/skbuff.c
SRC_C += net/core/sock.c
SRC_C += net/ethernet/eth.c
SRC_C += net/netlink/af_netlink.c
SRC_C += net/netlink/genetlink.c
SRC_C += net/packet/af_packet.c
# netlink
SRC_C += lib/average.c
SRC_C += lib/nlattr.c
SRC_C += lib/rbtree.c
# wifi mac80211
SRC_C += $(addprefix net/mac80211/, $(notdir $(wildcard $(WIFI_DIR)/mac80211/*.c)))
# wifi rfkill
SRC_C += $(addprefix net/rfkill/, $(notdir $(wildcard $(WIFI_DIR)/rfkill/*.c)))
INC_DIR += $(WIFI_DIR)/rfkill
# wifi cfg80211
SRC_C += $(addprefix net/wireless/, $(notdir $(wildcard $(WIFI_DIR)/wireless/*.c)))
INC_DIR += $(WIFI_DIR)/wireless
# led driver
SRC_C += $(addprefix drivers/leds/, $(notdir $(wildcard $(DRIVERS_DIR)/leds/*.c)))
CC_OPT += -DCONFIG_LEDS_TRIGGERS
CC_OPT += -D__CHECK_ENDIAN__
# iwlwifi driver
DRV_DIR_IWLWIFI := drivers/net/wireless/iwlwifi
SRC_C += $(addprefix $(DRV_DIR_IWLWIFI)/, $(notdir $(wildcard $(WIFI_CONTRIB_DIR)/$(DRV_DIR_IWLWIFI)/*.c)))
SRC_C += $(addprefix $(DRV_DIR_IWLWIFI)/dvm/, $(notdir $(wildcard $(WIFI_CONTRIB_DIR)/$(DRV_DIR_IWLWIFI)/dvm/*.c)))
SRC_C += $(addprefix $(DRV_DIR_IWLWIFI)/mvm/, $(notdir $(wildcard $(WIFI_CONTRIB_DIR)/$(DRV_DIR_IWLWIFI)/mvm/*.c)))
SRC_C += $(addprefix $(DRV_DIR_IWLWIFI)/pcie/, $(notdir $(wildcard $(WIFI_CONTRIB_DIR)/$(DRV_DIR_IWLWIFI)/pcie/*.c)))
INC_DIR += $(WIFI_CONTRIB_DIR)/$(DRV_DIR_IWLWIFI)
CC_OPT += -DCONFIG_IWLMVM -DCONFIG_IWLDVM
CC_OPT += -DCONFIG_IWLWIFI_DEBUG
# iwlegacy driver
DRV_DIR_IWLEGACY := drivers/net/wireless/iwlegacy
SRC_C += $(addprefix $(DRV_DIR_IWLEGACY)/, $(notdir $(wildcard $(WIFI_CONTRIB_DIR)/$(DRV_DIR_IWLEGACY)/*.c)))
INC_DIR += $(WIFI_CONTRIB_DIR)/$(DRV_DIR_IWLEGACY)
CC_OPT += -DCONFIG_IWL3945 -DCONFIG_IWL4965
CC_OPT += -DCONFIG_IWLEGACY_DEBUG
#
# Determine the header files included by the contrib code. For each
# of these header files we create a symlink to 'lx_emul.h'.
#
GEN_INCLUDES := $(shell grep -rh "^\#include .*\/" $(WIFI_CONTRIB_DIR) |\
sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" |\
sort | uniq)
#
# Filter out original Linux headers that exist in the contrib directory
#
NO_GEN_INCLUDES := $(shell cd $(WIFI_CONTRIB_DIR)/; find include -name "*.h" |\
sed "s/.\///" | sed "s/.*include\///")
GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES))
#
# Put Linux headers in 'GEN_INC' dir, since some include use "../../" paths use
# three level include hierarchy
#
GEN_INC := $(shell pwd)/include/include/include
$(shell mkdir -p $(GEN_INC))
GEN_INCLUDES := $(addprefix $(GEN_INC)/,$(GEN_INCLUDES))
INC_DIR += $(GEN_INC)
#
# Make sure to create the header symlinks prior building
#
$(SRC_C:.c=.o) $(SRC_CC:.cc=.o): $(GEN_INCLUDES)
$(GEN_INCLUDES):
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)ln -s $(LIB_INC_DIR)/lx_emul.h $@
vpath %.c $(DRIVERS_DIR)
vpath %.c $(WIFI_CONTRIB_DIR)/drivers/net/wireless/
vpath %.c $(WIFI_DIR)
vpath %.c $(WIFI_CONTRIB_DIR)
vpath %.c $(LIB_DIR)
vpath %.cc $(LIB_DIR)
vpath %.cc $(LIB_DIR)/signal
# vi: set ft=make :

View File

@ -0,0 +1,32 @@
LIB_DIR := $(REP_DIR)/src/lib/wpa_driver_nl80211
LIB_INC_DIR := $(LIB_DIR)/include
INC_DIR += $(LIB_INC_DIR)
LIBS += libc libnl
SHARED_LIB = yes
LD_OPT += --version-script=$(LIB_DIR)/symbol.map
SRC_CC += dummies.cc ioctl.cc
WS_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/app/wpa_supplicant
# l2_packet
SRC_C += src/l2_packet/l2_packet_linux.c
INC_DIR += $(WS_CONTRIB_DIR)/src/l2_packet
# nl80211 driver
SRC_C_drivers = drivers.c \
driver_nl80211.c \
netlink.c \
rfkill.c
SRC_C += $(addprefix src/drivers/, $(SRC_C_drivers))
INC_DIR += $(WS_CONTRIB_DIR)/src/drivers \
$(WS_CONTRIB_DIR)/src/utils \
$(WS_CONTRIB_DIR)/src
CC_OPT += -DCONFIG_DRIVER_NL80211
CC_OPT += -DCONFIG_LIBNL20
vpath %.c $(WS_CONTRIB_DIR)
vpath %.cc $(LIB_DIR)

View File

@ -0,0 +1,106 @@
WS_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/app/wpa_supplicant
WS_DIR := $(REP_DIR)/src/lib/wpa_supplicant
LIBS += libc libcrypto libssl wpa_driver_nl80211 vfs_jitterentropy
SHARED_LIB = yes
LD_OPT += --version-script=$(WS_DIR)/symbol.map
CC_OPT += -Wno-unused-function
CC_CXX_OPT += -fpermissive
SRC_C += main.c
# wpa_supplicant
SRC_C_wpa_supplicant = blacklist.c \
bss.c \
config.c \
config_file.c \
eap_register.c \
events.c \
notify.c \
scan.c \
sme.c \
wpa_supplicant.c \
wpas_glue.c
SRC_C += $(addprefix wpa_supplicant/, $(SRC_C_wpa_supplicant))
INC_DIR += $(WS_CONTRIB_DIR)/wpa_supplicant
CC_OPT += -DCONFIG_BACKEND_FILE -DCONFIG_NO_CONFIG_WRITE \
-DCONFIG_SME
INC_DIR += $(WS_CONTRIB_DIR)/src/
# common
SRC_C_common = ieee802_11_common.c wpa_common.c
SRC_C += $(addprefix src/common/, $(SRC_C_common))
INC_DIR += $(WS_CONTRIB_DIR)/src/common
# crypto
SRC_C_crypto = aes-unwrap.c \
crypto_openssl.c \
md5.c \
ms_funcs.c \
random.c \
sha1-prf.c \
sha1-tlsprf.c \
tls_openssl.c
SRC_C += $(addprefix src/crypto/, $(SRC_C_crypto))
INC_DIR += $(WS_CONTRIB_DIR)/src/crypto
SRC_C += src/drivers/driver_common.c
# eap_common
SRC_C_eap_common = chap.c \
eap_common.c \
eap_peap_common.c
SRC_C += $(addprefix src/eap_common/, $(SRC_C_eap_common))
INC_DIR += $(WS_CONTRIB_DIR)/src/eap_common
# eap_peer
SRC_C_eap_peer = eap.c \
eap_gtc.c \
eap_leap.c \
eap_md5.c \
eap_methods.c \
eap_mschapv2.c \
eap_otp.c \
eap_peap.c \
eap_tls.c \
eap_tls_common.c \
eap_ttls.c \
mschapv2.c
SRC_C += $(addprefix src/eap_peer/, $(SRC_C_eap_peer))
INC_DIR += $(WS_CONTRIB_DIR)/src/eap_peer
CC_OPT += -DEAP_TLS -DEAP_PEAP -DEAP_TTLS -DEAP_MD5 -DEAP_MSCHAPv2 \
-DEAP_OTP -DEAP_LEAP
# eapol_supp
SRC_C += src/eapol_supp/eapol_supp_sm.c
INC_DIR += $(WS_CONTRIB_DIR)/src/eapol_supp
CC_OPT += -DIEEE8021X_EAPOL
# rsn_supp
SRC_C_rsn_supp = peerkey.c \
pmksa_cache.c \
preauth.c \
wpa.c \
wpa_ie.c
SRC_C += $(addprefix src/rsn_supp/, $(SRC_C_rsn_supp))
INC_DIR += $(WS_CONTRIB_DIR)/src/rsn_supp
CC_OPT += -DCONFIG_PEERKEY
# utils
SRC_C_utils = base64.c \
common.c \
eloop.c \
os_unix.c \
radiotap.c \
wpa_debug.c \
wpabuf.c
SRC_C += $(addprefix src/utils/, $(SRC_C_utils))
INC_DIR += $(WS_CONTRIB_DIR)/src/utils
CC_OPT += -DCONFIG_ELOOP_POLL
vpath %.c $(WS_CONTRIB_DIR)
vpath %.c $(WS_DIR)

View File

@ -0,0 +1,3 @@
include $(REP_DIR)/lib/mk/libnl.inc
INC_DIR += $(LIB_INC_DIR)/32bit $(LIB_INC_DIR)/x86_32 $(LIB_INC_DIR)/x86

View File

@ -0,0 +1,3 @@
include $(REP_DIR)/lib/mk/wifi.inc
INC_DIR += $(LIB_INC_DIR)/32bit $(LIB_INC_DIR)/x86_32 $(LIB_INC_DIR)/x86

View File

@ -0,0 +1,3 @@
include $(REP_DIR)/lib/mk/libnl.inc
INC_DIR += $(LIB_INC_DIR)/64bit $(LIB_INC_DIR)/x86_64 $(LIB_INC_DIR)/x86

View File

@ -0,0 +1,3 @@
include $(REP_DIR)/lib/mk/wifi.inc
INC_DIR += $(LIB_INC_DIR)/64bit $(LIB_INC_DIR)/x86_64 $(LIB_INC_DIR)/x86

View File

@ -0,0 +1,52 @@
include/netlink-private/netlink.h | 1 +
lib/handlers.c | 4 ++--
lib/msg.c | 4 ++--
3 files changed, 5 insertions(+), 4 deletions(-)
--- a/include/netlink-private/netlink.h
+++ b/include/netlink-private/netlink.h
@@ -100,6 +100,7 @@ struct trans_list {
fprintf(stderr, "BUG at file position %s:%d:%s\n", \
__FILE__, __LINE__, __PRETTY_FUNCTION__); \
assert(0); \
+ while (7); \
} while (0)
#define BUG_ON(condition) \
--- a/lib/handlers.c
+++ b/lib/handlers.c
@@ -81,8 +81,8 @@ static int nl_error_handler_verbose(struct sockaddr_nl *who,
FILE *ofd = arg ? arg : stderr;
char buf[256];
- fprintf(ofd, "-- Error received: %s\n-- Original message: ",
- strerror_r(-e->error, buf, sizeof(buf)));
+ strerror_r(-e->error, buf, sizeof(buf));
+ fprintf(ofd, "-- Error received: %s\n-- Original message: ", buf);
print_header_content(ofd, &e->msg);
fprintf(ofd, "\n");
--- a/lib/msg.c
+++ b/lib/msg.c
@@ -916,8 +916,8 @@ static void dump_error_msg(struct nl_msg *msg, FILE *ofd)
char buf[256];
struct nl_msg *errmsg;
- fprintf(ofd, " .error = %d \"%s\"\n", err->error,
- strerror_r(-err->error, buf, sizeof(buf)));
+ strerror_r(-err->error, buf, sizeof(buf));
+ fprintf(ofd, " .error = %d \"%s\"\n", err->error, buf);
fprintf(ofd, " [ORIGINAL MESSAGE] %zu octets\n", sizeof(*hdr));
errmsg = nlmsg_inherit(&err->msg);
--- a/include/netlink/netlink-compat.h
+++ b/include/netlink/netlink-compat.h
@@ -13,7 +13,7 @@
#define NETLINK_COMPAT_H_
#if !defined _LINUX_SOCKET_H && !defined _BITS_SOCKADDR_H
-typedef unsigned short sa_family_t;
+//typedef unsigned short sa_family_t;
#endif
#ifndef IFNAMSIZ

View File

@ -0,0 +1,883 @@
drivers/net/wireless/iwlwifi/iwl-debug.c | 18 +-
drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +-
drivers/net/wireless/iwlwifi/pcie/drv.c | 628 ++++++++++++++++---------------
net/core/sock.c | 2 +
net/packet/af_packet.c | 6 +
net/wireless/core.h | 2 +-
net/wireless/sysfs.c | 2 +-
wifi/include/linux/ieee80211.h | 2 +-
wifi/include/net/cfg80211.h | 5 +-
wifi/include/net/netlink.h | 8 +-
wifi/include/net/sock.h | 4 +-
11 files changed, 349 insertions(+), 330 deletions(-)
--- a/drivers/net/wireless/iwlwifi/iwl-debug.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.c
@@ -80,7 +80,9 @@ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \
\
va_start(args, fmt); \
vaf.va = &args; \
- dev_ ##fn(dev, "%pV", &vaf); \
+ char buf[256]; \
+ vsnprintf(buf, sizeof(buf), vaf.fmt, *vaf.va); \
+ dev_ ##fn(dev, "%s", buf); \
trace_iwlwifi_ ##fn(&vaf); \
va_end(args); \
}
@@ -103,10 +105,12 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
va_start(args, fmt);
vaf.va = &args;
if (!trace_only) {
+ char buf[256];
+ vsnprintf(buf, sizeof(buf), vaf.fmt, *vaf.va);
if (rfkill_prefix)
- dev_err(dev, "(RFKILL) %pV", &vaf);
+ dev_err(dev, "(RFKILL) %s", buf);
else
- dev_err(dev, "%pV", &vaf);
+ dev_err(dev, "%s", buf);
}
trace_iwlwifi_err(&vaf);
va_end(args);
@@ -127,9 +131,11 @@ void __iwl_dbg(struct device *dev,
vaf.va = &args;
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_have_debug_level(level) &&
- (!limit || net_ratelimit()))
- dev_dbg(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U',
- function, &vaf);
+ (!limit || net_ratelimit())) {
+ char buf[256];
+ vsnprintf(buf, sizeof(buf), vaf.fmt, *vaf.va);
+ dev_dbg(dev, "%c %s %s", in_interrupt() ? 'I' : 'U', function, buf);
+ }
#endif
trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf);
va_end(args);
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -64,7 +64,7 @@
#ifndef __IWL_MVM_H__
#define __IWL_MVM_H__
-#include <linux/list.h>
+/* #include <linux/list.h> */
#include <linux/spinlock.h>
#include <linux/leds.h>
#include <linux/in6.h>
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -78,318 +78,322 @@
/* Hardware specific file defines the PCI IDs table for that hardware module */
static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
-#if IS_ENABLED(CONFIG_IWLDVM)
- {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */
-
-/* 5300 Series WiFi */
- {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */
-
-/* 5350 Series WiFi/WiMax */
- {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */
-
-/* 5150 Series Wifi/WiMax */
- {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */
-
- {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */
- {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */
- {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */
-
-/* 6x00 Series */
- {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)},
- {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)},
- {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)},
- {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)},
- {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)},
- {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_3agn_cfg)},
- {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
- {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
-
-/* 6x05 Series */
- {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_2agn_sff_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */
- {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */
-
-/* 6x30 Series */
- {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)},
- {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)},
- {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)},
-
-/* 6x50 WiFi/WiMax Series */
- {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)},
- {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)},
-
-/* 6150 WiFi/WiMax Series */
- {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)},
- {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)},
-
-/* 1000 Series WiFi */
- {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)},
- {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)},
- {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)},
- {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)},
- {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)},
- {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)},
-
-/* 100 Series WiFi */
- {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)},
- {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
- {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)},
- {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)},
- {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)},
- {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)},
-
-/* 130 Series WiFi */
- {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)},
- {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)},
- {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)},
-
-/* 2x00 Series */
- {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0890, 0x4822, iwl2000_2bgn_d_cfg)},
-
-/* 2x30 Series */
- {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)},
- {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)},
-
-/* 6x35 Series */
- {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)},
- {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6035_2agn_sff_cfg)},
- {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)},
- {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6035_2agn_sff_cfg)},
- {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)},
- {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)},
- {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)},
- {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)},
-
-/* 105 Series */
- {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_bgn_d_cfg)},
-
-/* 135 Series */
- {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
- {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
-#endif /* CONFIG_IWLDVM */
-
-#if IS_ENABLED(CONFIG_IWLMVM)
-/* 7260 Series */
- {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x406A, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0x4272, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0x426A, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4472, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x446A, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg_high_temp)},
- {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg_high_temp)},
- {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg_high_temp)},
- {IWL_PCI_DEVICE(0x08B1, 0x4570, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4560, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x5072, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x5170, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x5770, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC072, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC06A, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC770, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC760, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0xC272, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0xC26A, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC472, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC570, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC560, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0xC370, iwl7260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC360, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC02A, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)},
-
-/* 3160 Series */
- {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x0072, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x0172, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)},
- {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B4, 0x0272, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x0472, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B4, 0x0370, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x8072, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x8172, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)},
- {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x1070, iwl3160_2ac_cfg)},
- {IWL_PCI_DEVICE(0x08B3, 0x1170, iwl3160_2ac_cfg)},
-
-/* 7265 Series */
- {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_n_cfg)},
- {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)},
- {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
- {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5020, iwl7265_2n_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x502A, iwl7265_2n_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5420, iwl7265_2n_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5090, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5190, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5590, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)},
-#endif /* CONFIG_IWLMVM */
+ {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, /* x201 */
+ {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, /* x220 */
+ {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, /* plumbum */
+
+//#if IS_ENABLED(CONFIG_IWLDVM)
+// {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1304, iwl5100_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bgn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bgn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1221, iwl5100_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1321, iwl5100_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1224, iwl5100_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1324, iwl5100_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1225, iwl5100_bgn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1325, iwl5100_bgn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1226, iwl5100_abg_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4237, 0x1211, iwl5100_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4237, 0x1311, iwl5100_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4237, 0x1214, iwl5100_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4237, 0x1314, iwl5100_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4237, 0x1215, iwl5100_bgn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4237, 0x1315, iwl5100_bgn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4237, 0x1316, iwl5100_abg_cfg)}, /* Half Mini Card */
+//
+///* 5300 Series WiFi */
+// {IWL_PCI_DEVICE(0x4235, 0x1021, iwl5300_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4235, 0x1121, iwl5300_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4235, 0x1024, iwl5300_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4235, 0x1124, iwl5300_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4235, 0x1001, iwl5300_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4235, 0x1101, iwl5300_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4235, 0x1004, iwl5300_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4235, 0x1104, iwl5300_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4236, 0x1011, iwl5300_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4236, 0x1111, iwl5300_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x4236, 0x1014, iwl5300_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x4236, 0x1114, iwl5300_agn_cfg)}, /* Half Mini Card */
+//
+///* 5350 Series WiFi/WiMax */
+// {IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)}, /* Mini Card */
+//
+///* 5150 Series Wifi/WiMax */
+// {IWL_PCI_DEVICE(0x423C, 0x1201, iwl5150_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x423C, 0x1301, iwl5150_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x423C, 0x1206, iwl5150_abg_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */
+//
+// {IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */
+// {IWL_PCI_DEVICE(0x423D, 0x1216, iwl5150_abg_cfg)}, /* Mini Card */
+// {IWL_PCI_DEVICE(0x423D, 0x1316, iwl5150_abg_cfg)}, /* Half Mini Card */
+//
+///* 6x00 Series */
+// {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)},
+// {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_3agn_cfg)},
+// {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)},
+// {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_3agn_cfg)},
+// {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)},
+// {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)},
+// {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_3agn_cfg)},
+// {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
+//
+///* 6x05 Series */
+// {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)},
+// {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)},
+// {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_2agn_sff_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)},
+// {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */
+// {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */
+//
+///* 6x30 Series */
+// {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x008A, 0x5307, iwl1030_bg_cfg)},
+// {IWL_PCI_DEVICE(0x008A, 0x5325, iwl1030_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x008A, 0x5327, iwl1030_bg_cfg)},
+// {IWL_PCI_DEVICE(0x008B, 0x5315, iwl1030_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x008B, 0x5317, iwl1030_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6030_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6030_2bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6030_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6030_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6030_2bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6030_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6030_2bg_cfg)},
+// {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6030_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6030_2bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6030_2abg_cfg)},
+//
+///* 6x50 WiFi/WiMax Series */
+// {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0087, 0x1306, iwl6050_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x0087, 0x1321, iwl6050_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0087, 0x1326, iwl6050_2abg_cfg)},
+// {IWL_PCI_DEVICE(0x0089, 0x1311, iwl6050_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x0089, 0x1316, iwl6050_2abg_cfg)},
+//
+///* 6150 WiFi/WiMax Series */
+// {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)},
+//
+///* 1000 Series WiFi */
+// {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0083, 0x1305, iwl1000_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0083, 0x1225, iwl1000_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0083, 0x1325, iwl1000_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0084, 0x1215, iwl1000_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0084, 0x1315, iwl1000_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0083, 0x1206, iwl1000_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0083, 0x1306, iwl1000_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0083, 0x1226, iwl1000_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)},
+//
+///* 100 Series WiFi */
+// {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)},
+// {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x08AF, 0x1017, iwl100_bg_cfg)},
+// {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x08AE, 0x1027, iwl100_bg_cfg)},
+//
+///* 130 Series WiFi */
+// {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)},
+// {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)},
+//
+///* 2x00 Series */
+// {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0890, 0x4822, iwl2000_2bgn_d_cfg)},
+//
+///* 2x30 Series */
+// {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)},
+//
+///* 6x35 Series */
+// {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6035_2agn_sff_cfg)},
+// {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6035_2agn_sff_cfg)},
+// {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)},
+// {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)},
+// {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)},
+//
+///* 105 Series */
+// {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0894, 0x0822, iwl105_bgn_d_cfg)},
+//
+///* 135 Series */
+// {IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
+// {IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
+//#endif /* CONFIG_IWLDVM */
+//
+//#if IS_ENABLED(CONFIG_IWLMVM)
+///* 7260 Series */
+// {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x406A, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0x4272, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0x426A, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4472, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x446A, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg_high_temp)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg_high_temp)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg_high_temp)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4570, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4560, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x5072, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x5170, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x5770, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC072, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC06A, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC770, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC760, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0xC272, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0xC26A, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC472, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC570, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC560, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0xC370, iwl7260_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC360, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC02A, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)},
+//
+///* 3160 Series */
+// {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x0072, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x0172, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B4, 0x0272, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x0472, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B4, 0x0370, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x8072, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x8172, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)},
+// {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x1070, iwl3160_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x08B3, 0x1170, iwl3160_2ac_cfg)},
+//
+///* 7265 Series */
+// {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_n_cfg)},
+// {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)},
+// {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
+// {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5020, iwl7265_2n_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x502A, iwl7265_2n_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5420, iwl7265_2n_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5090, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5190, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5590, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)},
+// {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)},
+//#endif /* CONFIG_IWLMVM */
{0}
};
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -142,6 +142,8 @@
#include <net/busy_poll.h>
+#include <net/timewait_sock.h>
+
static DEFINE_MUTEX(proto_list_mutex);
static LIST_HEAD(proto_list);
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -93,6 +93,8 @@
#include <net/inet_common.h>
#endif
+#include <linux/if_ether.h>
+
#include "internal.h"
/*
@@ -3508,6 +3510,7 @@ static int packet_notifier(struct notifier_block *this,
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct net *net = dev_net(dev);
+#if 0
rcu_read_lock();
sk_for_each_rcu(sk, &net->packet.sklist) {
struct packet_sock *po = pkt_sk(sk);
@@ -3548,6 +3551,7 @@ static int packet_notifier(struct notifier_block *this,
}
}
rcu_read_unlock();
+#endif
return NOTIFY_DONE;
}
@@ -4062,8 +4066,10 @@ static int __net_init packet_net_init(struct net *net)
mutex_init(&net->packet.sklist_lock);
INIT_HLIST_HEAD(&net->packet.sklist);
+#ifdef CONFIG_PROC_FS
if (!proc_create("packet", 0, net->proc_net, &packet_seq_fops))
return -ENOMEM;
+#endif
return 0;
}
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -82,7 +82,7 @@ struct cfg80211_registered_device {
/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
- struct wiphy wiphy __aligned(NETDEV_ALIGN);
+ struct wiphy wiphy __attribute__((__aligned__(32)));
};
static inline
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -156,7 +156,7 @@ struct class ieee80211_class = {
.resume = wiphy_resume,
#endif
.ns_type = &net_ns_type_operations,
- .namespace = wiphy_namespace,
+ ._namespace = wiphy_namespace,
};
int wiphy_sysfs_init(void)
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2231,7 +2231,7 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr,
size_t len)
{
- struct ieee80211_mgmt *mgmt = (void *)hdr;
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)hdr;
if (len < IEEE80211_MIN_ACTION_SIZE)
return false;
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -191,6 +191,7 @@ struct ieee80211_channel {
* @IEEE80211_RATE_SUPPORTS_10MHZ: Rate can be used in 10 MHz mode
*/
enum ieee80211_rate_flags {
+ IEEE80211_RATE_NULL = 0,
IEEE80211_RATE_SHORT_PREAMBLE = 1<<0,
IEEE80211_RATE_MANDATORY_A = 1<<1,
IEEE80211_RATE_MANDATORY_B = 1<<2,
@@ -465,7 +466,7 @@ ieee80211_chandef_rate_flags(struct cfg80211_chan_def *chandef)
default:
break;
}
- return 0;
+ return IEEE80211_RATE_NULL;
}
/**
@@ -2990,7 +2991,7 @@ struct wiphy {
const struct nl80211_vendor_cmd_info *vendor_events;
int n_vendor_commands, n_vendor_events;
- char priv[0] __aligned(NETDEV_ALIGN);
+ char priv[0] __attribute__ ((__aligned__(32)));//__aligned(NETDEV_ALIGN);
};
static inline struct net *wiphy_net(struct wiphy *wiphy)
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -308,7 +308,7 @@ static inline int nlmsg_len(const struct nlmsghdr *nlh)
static inline struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh,
int hdrlen)
{
- unsigned char *data = nlmsg_data(nlh);
+ unsigned char *data = (unsigned char *)nlmsg_data(nlh);
return (struct nlattr *) (data + NLMSG_ALIGN(hdrlen));
}
@@ -717,7 +717,7 @@ static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
static inline struct nlattr *
nla_find_nested(const struct nlattr *nla, int attrtype)
{
- return nla_find(nla_data(nla), nla_len(nla), attrtype);
+ return nla_find((const struct nlattr *)nla_data(nla), nla_len(nla), attrtype);
}
/**
@@ -733,7 +733,7 @@ static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
const struct nlattr *nla,
const struct nla_policy *policy)
{
- return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
+ return nla_parse(tb, maxtype, (const struct nlattr *)nla_data(nla), nla_len(nla), policy);
}
/**
@@ -1161,7 +1161,7 @@ static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start)
static inline int nla_validate_nested(const struct nlattr *start, int maxtype,
const struct nla_policy *policy)
{
- return nla_validate(nla_data(start), nla_len(start), maxtype, policy);
+ return nla_validate((const struct nlattr *)nla_data(start), nla_len(start), maxtype, policy);
}
/**
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1854,7 +1854,7 @@ static inline int skb_add_data_nocache(struct sock *sk, struct sk_buff *skb,
{
int err, offset = skb->len;
- err = skb_do_copy_data_nocache(sk, skb, from, skb_put(skb, copy),
+ err = skb_do_copy_data_nocache(sk, skb, from, (char *)skb_put(skb, copy),
copy, offset);
if (err)
__skb_trim(skb, offset);
@@ -1869,7 +1869,7 @@ static inline int skb_copy_to_page_nocache(struct sock *sk, char __user *from,
{
int err;
- err = skb_do_copy_data_nocache(sk, skb, from, page_address(page) + off,
+ err = skb_do_copy_data_nocache(sk, skb, from, (char *)(page_address(page) + off),
copy, skb->len);
if (err)
return err;
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -2309,7 +2309,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
rate_scale_index_msk = rate_mask;
if (!((1 << index) & rate_scale_index_msk)) {
- IWL_ERR(priv, "Current Rate is not valid\n");
+ // IWL_ERR(priv, "Current Rate is not valid\n");
if (lq_sta->search_better_tbl) {
/* revert to active table if search table is not valid*/
tbl->lq_type = LQ_NONE;

View File

@ -0,0 +1,101 @@
diff --git a/crypto/ccm.c b/crypto/ccm.c
index 1df8421..a5ee033 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -52,7 +52,8 @@ static inline struct crypto_ccm_req_priv_ctx *crypto_ccm_reqctx(
{
unsigned long align = crypto_aead_alignmask(crypto_aead_reqtfm(req));
- return (void *)PTR_ALIGN((u8 *)aead_request_ctx(req), align + 1);
+ u8 *p = (u8 *) aead_request_ctx(req);
+ return (void *)PTR_ALIGN(p, (align + 1));
}
static int set_msg_len(u8 *block, unsigned int msglen, int csize)
@@ -681,8 +682,10 @@ static struct aead_request *crypto_rfc4309_crypt(struct aead_request *req)
struct crypto_aead *aead = crypto_aead_reqtfm(req);
struct crypto_rfc4309_ctx *ctx = crypto_aead_ctx(aead);
struct crypto_aead *child = ctx->child;
- u8 *iv = PTR_ALIGN((u8 *)(subreq + 1) + crypto_aead_reqsize(child),
- crypto_aead_alignmask(child) + 1);
+
+ unsigned long m = crypto_aead_alignmask(child) + 1;
+ u8 *p = (u8 *)(subreq + 1) + crypto_aead_reqsize(child);
+ u8 *iv = PTR_ALIGN(p, m);
/* L' */
iv[0] = 3;
diff --git a/crypto/ctr.c b/crypto/ctr.c
index f2b94f2..b345689 100644
--- a/crypto/ctr.c
+++ b/crypto/ctr.c
@@ -59,7 +59,9 @@ static void crypto_ctr_crypt_final(struct blkcipher_walk *walk,
unsigned long alignmask = crypto_cipher_alignmask(tfm);
u8 *ctrblk = walk->iv;
u8 tmp[bsize + alignmask];
- u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
+ u8 *p = (u8*)(tmp + 0);
+ unsigned long m = alignmask + 1;
+ u8 *keystream = PTR_ALIGN(p, m);
u8 *src = walk->src.virt.addr;
u8 *dst = walk->dst.virt.addr;
unsigned int nbytes = walk->nbytes;
@@ -108,7 +110,9 @@ static int crypto_ctr_crypt_inplace(struct blkcipher_walk *walk,
u8 *ctrblk = walk->iv;
u8 *src = walk->src.virt.addr;
u8 tmp[bsize + alignmask];
- u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
+ unsigned long m = alignmask + 1;
+ u8 *p = (u8*)(tmp + 0);
+ u8 *keystream = PTR_ALIGN(p , m);
do {
/* create keystream */
@@ -281,8 +285,11 @@ static int crypto_rfc3686_crypt(struct ablkcipher_request *req)
struct crypto_rfc3686_ctx *ctx = crypto_ablkcipher_ctx(tfm);
struct crypto_ablkcipher *child = ctx->child;
unsigned long align = crypto_ablkcipher_alignmask(tfm);
+
+ unsigned long m = align + 1;
+ u8 *p = (u8*) ablkcipher_request_ctx(req);
struct crypto_rfc3686_req_ctx *rctx =
- (void *)PTR_ALIGN((u8 *)ablkcipher_request_ctx(req), align + 1);
+ (void *)PTR_ALIGN(p, m);
struct ablkcipher_request *subreq = &rctx->subreq;
u8 *iv = rctx->iv;
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -201,8 +201,10 @@ void __ablkcipher_walk_complete(struct ablkcipher_walk *walk);
static inline void *crypto_tfm_ctx_aligned(struct crypto_tfm *tfm)
{
- return PTR_ALIGN(crypto_tfm_ctx(tfm),
- crypto_tfm_alg_alignmask(tfm) + 1);
+ void *p = crypto_tfm_ctx(tfm);
+ unsigned int m = crypto_tfm_alg_alignmask(tfm) + 1;
+
+ return PTR_ALIGN(p, m);
}
static inline struct crypto_instance *crypto_tfm_alg_instance(
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -90,6 +90,8 @@ out:
crypto_alg_put(&param->larval->alg);
kfree(param);
module_put_and_exit(0);
+
+ return 0;
}
static int cryptomgr_schedule_probe(struct crypto_larval *larval)
@@ -228,6 +230,8 @@ skiptest:
kfree(param);
module_put_and_exit(0);
+
+ return 0;
}
static int cryptomgr_schedule_test(struct crypto_alg *alg)

View File

@ -0,0 +1,82 @@
--- a/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -121,7 +121,7 @@ int iwl_calib_set(struct iwl_priv *priv,
struct iwl_calib_result *res, *tmp;
res = kmalloc(sizeof(*res) + len - sizeof(struct iwl_calib_hdr),
- GFP_ATOMIC);
+ GFP_ATOMIC | GFP_LX_DMA);
if (!res)
return -ENOMEM;
memcpy(&res->hdr, cmd, len);
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -672,7 +672,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
ctx = iwl_rxon_ctx_from_vif(vif);
if (!priv->scan_cmd) {
- priv->scan_cmd = kmalloc(scan_cmd_size, GFP_KERNEL);
+ priv->scan_cmd = kmalloc(scan_cmd_size, GFP_KERNEL | GFP_LX_DMA);
if (!priv->scan_cmd) {
IWL_DEBUG_SCAN(priv,
"fail to allocate memory for scan\n");
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1593,7 +1593,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
sizeof(struct iwl_device_cmd)
+ trans->dev_cmd_headroom,
sizeof(void *),
- SLAB_HWCACHE_ALIGN,
+ SLAB_HWCACHE_ALIGN | SLAB_LX_DMA,
NULL);
if (!trans->dev_cmd_pool) {
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -492,7 +492,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
txq->entries = kcalloc(slots_num,
sizeof(struct iwl_pcie_txq_entry),
- GFP_KERNEL);
+ GFP_KERNEL | GFP_LX_DMA);
if (!txq->entries)
goto error;
@@ -501,7 +501,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
for (i = 0; i < slots_num; i++) {
txq->entries[i].cmd =
kmalloc(sizeof(struct iwl_device_cmd),
- GFP_KERNEL);
+ GFP_KERNEL | GFP_LX_DMA);
if (!txq->entries[i].cmd)
goto error;
}
@@ -840,7 +840,7 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
}
trans_pcie->txq = kcalloc(trans->cfg->base_params->num_of_queues,
- sizeof(struct iwl_txq), GFP_KERNEL);
+ sizeof(struct iwl_txq), GFP_KERNEL | GFP_LX_DMA);
if (!trans_pcie->txq) {
IWL_ERR(trans, "Not enough memory for txq\n");
ret = -ENOMEM;
@@ -1255,7 +1255,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
}
dup_buf = kmemdup(cmddata[i], cmdlen[i],
- GFP_ATOMIC);
+ GFP_ATOMIC | GFP_LX_DMA);
if (!dup_buf)
return -ENOMEM;
} else {
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -125,6 +125,8 @@ static void *__kmalloc_reserve(size_t size, gfp_t flags, int node,
void *obj;
bool ret_pfmemalloc = false;
+ flags |= GFP_LX_DMA;
+
/*
* Try a regular allocation, when that fails and we're not entitled
* to the reserves, fail.

View File

@ -0,0 +1,83 @@
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1187,6 +1187,7 @@ static int wpa_config_parse_password(const struct parse_data *data,
}
+#if 0
static char * wpa_config_write_password(const struct parse_data *data,
struct wpa_ssid *ssid)
{
@@ -1221,6 +1222,7 @@ static char * wpa_config_write_password(const struct parse_data *data,
return buf;
}
#endif /* IEEE8021X_EAPOL */
+#endif
static int wpa_config_parse_wep_key(u8 *key, size_t *len, int line,
@@ -2264,6 +2266,7 @@ int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
}
+#ifndef NO_CONFIG_WRITE
/**
* wpa_config_get_all - Get all options from network configuration
* @ssid: Pointer to network configuration data
@@ -2326,7 +2329,6 @@ err:
}
-#ifndef NO_CONFIG_WRITE
/**
* wpa_config_get - Get a variable in network configuration
* @ssid: Pointer to network configuration data
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -20,11 +20,12 @@
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include <linux/rtnetlink.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h>
-#include <linux/errqueue.h>
+//#include <netpacket/packet.h>
+//#include <linux/filter.h>
+//#include <linux/errqueue.h>
#include "nl80211_copy.h"
+
#include "common.h"
#include "eloop.h"
#include "utils/list.h"
@@ -10924,7 +10925,7 @@ static void * nl80211_global_init(void)
if (wpa_driver_nl80211_init_nl_global(global) < 0)
goto err;
- global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
+ global->ioctl_sock = 42;
if (global->ioctl_sock < 0) {
wpa_printf(MSG_ERROR, "nl80211: socket(PF_INET,SOCK_DGRAM) failed: %s",
strerror(errno));
--- a/src/drivers/netlink.c
+++ b/src/drivers/netlink.c
@@ -13,6 +13,8 @@
#include "priv_netlink.h"
#include "netlink.h"
+#define PF_NETLINK 16
+#define AF_NETLINK PF_NETLINK
struct netlink_data {
struct netlink_config *cfg;
--- a/src/utils/eloop.c
+++ b/src/utils/eloop.c
@@ -23,7 +23,7 @@
#endif
#ifdef CONFIG_ELOOP_POLL
-#include <poll.h>
+#include <sys/poll.h>
#endif /* CONFIG_ELOOP_POLL */
#ifdef CONFIG_ELOOP_EPOLL

View File

@ -1 +1 @@
47adfa6b4fe8f41b3863e3e80a753d97ad0fb701
7f4e92802b6293f4816c0f366111b554109eec99

View File

@ -1,6 +1,13 @@
LICENSE := GPL
VERSION := 1
DOWNLOADS := dwc_otg.git usb.archive lxip.archive
DOWNLOADS := dwc_otg.git usb.archive lxip.archive wifi.archive \
libnl.archive wpa_supplicant.archive
#
# Tools
#
FLEX ?= flex
YACC ?= bison
#
# The git checkout checks for the existence of SRC_DIR, which is created by the
@ -8,7 +15,6 @@ DOWNLOADS := dwc_otg.git usb.archive lxip.archive
#
usb.archive: dwc_otg.git
#
# USB
#
@ -20,7 +26,6 @@ DIR(usb) := $(SRC_DIR_USB)
TAR_OPT(usb) := --strip-components=1 --files-from $(REP_DIR)/usb.list
HASH_INPUT += $(REP_DIR)/usb.list
#
# Raspberry Pi USB controller
#
@ -28,6 +33,15 @@ URL(dwc_otg) := https://github.com/nfeske/dwc_otg.git
REV(dwc_otg) := r2
DIR(dwc_otg) := $(SRC_DIR_USB)/drivers/usb/host/dwc_otg
#
# mac80211 stack, iwlwifi and iwslegacy sources
#
SRC_DIR_WIFI := src/lib/wifi
URL(wifi) := ${URL(usb)}
SHA(wifi) := ${SHA(usb)}
DIR(wifi) := $(SRC_DIR_WIFI)
TAR_OPT(wifi) := --strip-components=1 --files-from $(REP_DIR)/wifi.list
HASH_INPUT += $(REP_DIR)/wifi.list
#
# IP stack sources
@ -41,11 +55,40 @@ TAR_OPT(lxip) := --strip-components=1 --files-from $(REP_DIR)/lxip.list
HASH_INPUT += $(REP_DIR)/lxip.list
# libnl sources
#
URL(libnl) := http://www.infradead.org/~tgr/libnl/files/libnl-3.2.25.tar.gz
SHA(libnl) := b7a4981f7edf7398256d35fd3c0b87bc84ae27d1
DIR(libnl) := src/lib/libnl
default: generate_libnl_files
generate_libnl_files: $(DOWNLOADS)
@$(MSG_PREFIX)"generate libnl files "
$(VERBOSE)$(FLEX) --header-file=${DIR(libnl)}/lib/route/pktloc_grammar.h \
-o ${DIR(libnl)}/lib/route/pktloc_grammar.c \
${DIR(libnl)}/lib/route/pktloc_grammar.l
$(VERBOSE)$(YACC) -d -o ${DIR(libnl)}/lib/route/pktloc_syntax.c \
${DIR(libnl)}/lib/route/pktloc_syntax.y
$(VERBOSE)$(FLEX) --header-file=${DIR(libnl)}/lib/route/cls/ematch_grammar.h \
-o ${DIR(libnl)}/lib/route/cls/ematch_grammar.c \
${DIR(libnl)}/lib/route/cls/ematch_grammar.l
$(VERBOSE)$(YACC) -d -o ${DIR(libnl)}/lib/route/cls/ematch_syntax.c \
${DIR(libnl)}/lib/route/cls/ematch_syntax.y
#
# wpa_supplicant sources
#
URL(wpa_supplicant) := http://w1.fi/releases/wpa_supplicant-2.2.tar.gz
SHA(wpa_supplicant) := 0c2ff4fd2e2f6325147cca0357d6c9f524efa26a
DIR(wpa_supplicant) := src/app/wpa_supplicant
#
# Patches
#
PATCHES := $(addprefix patches/,$(notdir $(wildcard $(REP_DIR)/patches/*.patch)))
# USB
USB_OPT = -p1 -d$(SRC_DIR_USB)
PATCH_OPT(patches/usb_ax88179.patch) := $(USB_OPT)
PATCH_OPT(patches/usb_csum.patch) := $(USB_OPT)
@ -54,6 +97,7 @@ PATCH_OPT(patches/usb_mem.patch) := $(USB_OPT)
PATCH_OPT(patches/usb_usbnet.patch) := $(USB_OPT)
PATCH_OPT(patches/usb_xchi-quirks.patch) := $(USB_OPT)
#IP stack
LXIP_OPT = -p1 -d$(SRC_DIR_LXIP)
PATCH_OPT(patches/lxip_icmp.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_ip_config.patch) := $(LXIP_OPT)
@ -61,4 +105,16 @@ PATCH_OPT(patches/lxip_skbuff.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_tcp.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_netlink.patch) := $(LXIP_OPT)
# WIFI
WIFI_OPT = -p1 -d$(SRC_DIR_WIFI)
PATCH_OPT(patches/wifi.patch) := $(WIFI_OPT)
PATCH_OPT(patches/wifi_crypto.patch) := $(WIFI_OPT)
PATCH_OPT(patches/wifi_mem.patch) := $(WIFI_OPT)
# libnl
PATCH_OPT(patches/libnl.patch) := -p1 -d ${DIR(libnl)}
# WPA supplicant
PATCH_OPT(patches/wpa_supplicant.patch) := -p1 -d ${DIR(wpa_supplicant)}
# vi: set ft=make :

View File

@ -0,0 +1,168 @@
#
# Build
#
set build_components {
core init
drivers/pci drivers/timer drivers/wifi
drivers/rtc
test/lwip/http_srv
}
lappend_if [have_spec acpi] build_components drivers/acpi
lappend_if [have_spec pci] build_components drivers/pci/device_pd
lappend_if [have_spec platform_arndale] build_components drivers/platform
lappend_if [have_spec gpio] build_components drivers/gpio
build $build_components
create_boot_directory
#
# Generate config
#
set config {
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="RAM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="CAP"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="SIGNAL"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="rtc_drv">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Rtc"/> </provides>
</start>
<start name="test-lwip_httpsrv">
<resource name="RAM" quantum="5M"/>
<config>
<libc stdout="/dev/log" stderr="/dev/log">
<vfs> <dir name="dev"> <log/> </dir> </vfs>
</libc>
</config>
</start>
<start name="wifi_drv">
<resource name="RAM" quantum="32M"/>
<provides>
<service name="Nic"/>
</provides>
<config mac80211_only="no">
<libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc">
<vfs>
<dir name="dev"> <log/> <rtc/>
<jitterentropy name="random"/>
<jitterentropy name="urandom"/>
</dir>
<inline name="wpa_supplicant.conf">
network={
id_str="foobar"
ssid="foobar"
key_mgmt=NONE
#key_mgmt=WPA-PSK
#psk="foobarfoobar"
}
</inline>
</vfs>
</libc>
</config>
<route>
<service name="Rtc"> <any-child /> </service>
<any-service> <parent/> <any-child /> </any-service>
</route>
</start>}
append_if [have_spec acpi] config {
<start name="acpi">
<resource name="RAM" quantum="16M"/>
<binary name="acpi_drv"/>
<provides>
<service name="PCI"/>
<service name="IRQ" />
</provides>
<route>
<service name="PCI"> <any-child /> </service>
<any-service> <parent/> <any-child /> </any-service>
</route>
</start>}
append_if [have_spec platform_arndale] config {
<start name="platform_drv">
<resource name="RAM" quantum="1M"/>
<provides><service name="Regulator"/></provides>
</start>}
append_if [have_spec gpio] config {
<start name="gpio_drv">
<resource name="RAM" quantum="4M"/>
<provides><service name="Gpio"/></provides>
<config/>
</start>}
append_if [expr ![have_spec acpi] && [have_spec pci]] config {
<start name="pci_drv">
<resource name="RAM" quantum="3M"/>
<provides> <service name="PCI"/> </provides>
</start> }
append config {
</config>
}
install_config $config
if {![file exists bin/iwlwifi-6000-6.ucode] ||
![file exists bin/iwlwifi-6000g2a-6.ucode] ||
![file exists bin/iwlwifi-6000g2b-6.ucode]} {
puts ""
puts "The iwlwifi driver needs specific firmware images to work. Please download"
puts "the firmware from http://wireless.kernel.org/en/users/Drivers/iwlwifi and put"
puts "the appropiate firmware into './bin'."
exit 1
}
#
# Boot modules
#
# generic modules
set boot_modules {
core init timer rtc_drv vfs_jitterentropy.lib.so
ld.lib.so
libc.lib.so libcrypto.lib.so libssl.lib.so
wpa_driver_nl80211.lib.so wpa_supplicant.lib.so
wifi.lib.so
wifi_drv
test-lwip_httpsrv lwip.lib.so
iwlwifi-6000-6.ucode
iwlwifi-6000g2a-6.ucode
iwlwifi-6000g2b-6.ucode
}
lappend_if [have_spec acpi] boot_modules acpi_drv
lappend_if [have_spec pci] boot_modules pci_drv
lappend_if [have_spec nova] boot_modules pci_device_pd
lappend_if [have_spec platform_arndale] boot_modules platform_drv
lappend_if [have_spec gpio] boot_modules gpio_drv
build_boot_image $boot_modules
run_genode_until forever
# vi: set ft=tcl :

View File

@ -0,0 +1,53 @@
/*
* \brief Startup Wifi driver
* \author Josef Soentgen
* \date 2014-03-03
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/env.h>
#include <base/sleep.h>
#include <os/server.h>
/* local includes */
#include "wpa.h"
extern void wifi_init(Server::Entrypoint &, Genode::Lock &);
static Genode::Lock &wpa_startup_lock()
{
static Genode::Lock _l(Genode::Lock::LOCKED);
return _l;
}
struct Main
{
Server::Entrypoint &_ep;
Wpa_thread *_wpa;
Main(Server::Entrypoint &ep)
:
_ep(ep)
{
_wpa = new (Genode::env()->heap()) Wpa_thread(wpa_startup_lock());
_wpa->start();
wifi_init(ep, wpa_startup_lock());
}
};
namespace Server {
char const *name() { return "wifi_drv_ep"; }
size_t stack_size() { return 32 * 1024 * sizeof(long); }
void construct(Entrypoint &ep) { static Main server(ep); }
}

View File

@ -0,0 +1,8 @@
TARGET = wifi_drv
SRC_CC = main.cc
# needed for firmware.h
INC_DIR += $(REP_DIR)/src/lib/wifi/include
LIBS = wifi wpa_supplicant server

View File

@ -0,0 +1,44 @@
/*
* \brief Wpa_supplicant thread of the wifi driver
* \author Josef Soentgen
* \date 2014-03-03
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _WIFI__WPA_H_
#define _WIFI__WPA_H_
/* Genode includes */
#include <base/sleep.h>
/* entry function */
extern "C" int wpa_main(void);
class Wpa_thread : public Genode::Thread<8 * 1024 * sizeof(long)>
{
private:
Genode::Lock &_lock;
int _exit;
public:
Wpa_thread(Genode::Lock &lock)
: Thread("wpa_supplicant"), _lock(lock), _exit(-1) { }
void entry()
{
/* wait until the wifi driver is up and running */
_lock.lock();
_exit = wpa_main();
Genode::sleep_forever();
}
};
#endif /* _WIFI__WPA_H_ */

View File

@ -0,0 +1,23 @@
#include <sys/socket.h>
#include <net/if.h>
#include <util/string.h>
#define WLAN_DEV "wlan0"
extern "C" {
unsigned int if_nametoindex(const char *ifname)
{
/* we make sure the index is always 1 in the wifi driver */
return 1;
}
char *if_indextoname(unsigned int ifindex, char *ifname)
{
Genode::memcpy(ifname, WLAN_DEV, Genode::strlen(WLAN_DEV));
return ifname;
}
} /* extern "C" */

View File

@ -0,0 +1,24 @@
/*
* \brief Emulation of the Linux userland API
* \author Josef Soentgen
* \date 2014-07-25
*
* The content of this file, in particular data structures, is partially
* derived from Linux headers.
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _32BIT__PLATFORM__TYPES_H_
#define _32BIT__PLATFORM__TYPES_H_
typedef long long int64_t;
typedef unsigned long long uint64_t;
#endif /* _32BIT__PLATFORM__TYPES_H_ */

View File

@ -0,0 +1,24 @@
/*
* \brief Emulation of the Linux userland API
* \author Josef Soentgen
* \date 2014-07-25
*
* The content of this file, in particular data structures, is partially
* derived from Linux headers.
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _64BIT__PLATFORM__TYPES_H_
#define _64BIT__PLATFORM__TYPES_H_
typedef long int64_t;
typedef unsigned long uint64_t;
#endif /* _64BIT__PLATFORM__TYPES_H_ */

View File

@ -0,0 +1,28 @@
/*
* \brief Libnl configuration
* \author Christian Helmuth
* \date 2014-08-26
*
* In conjunction with defs.h.in.
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _DEFS_H_
#define _DEFS_H_
/* Define to 1 to disable pthreads */
#define DISABLE_PTHREADS 1
/* Define to 1 to enable debugging */
#define NL_DEBUG 1
/* Version number of package */
#define VERSION "3.2.25"
#endif /* _DEFS_H_ */

View File

@ -0,0 +1,3 @@
#ifndef __LITTLE_ENDIAN
#define __LITTLE_ENDIAN 1234
#endif

View File

@ -0,0 +1,90 @@
/*
* \brief Emulation of the Linux userland API
* \author Josef Soentgen
* \author Christian Helmuth
* \date 2014-07-25
*
* The content of this file, in particular data structures, is partially
* derived from Linux headers.
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _LIBNL_EMUL_H_
#define _LIBNL_EMUL_H_
/*********************
** asm/byteorder.h **
*********************/
#define __LITTLE_ENDIAN_BITFIELD 1
/*******************
** linux/types.h **
*******************/
#include <linux/types.h>
/**********************
** uapi/linux/in6.h **
**********************/
struct in6_addr {
union {
__u8 u6_addr8[16];
#if __UAPI_DEF_IN6_ADDR_ALT
__be16 u6_addr16[8];
__be32 u6_addr32[4];
#endif
} in6_u;
#define s6_addr in6_u.u6_addr8
#if __UAPI_DEF_IN6_ADDR_ALT
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
#endif
};
struct sockaddr_in6 {
unsigned short int sin6_family; /* AF_INET6 */
__be16 sin6_port; /* Transport layer port # */
__be32 sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
__u32 sin6_scope_id; /* scope id (new in RFC2553) */
};
/*
* Socket types should be taken from libc
*/
#define _BITS_SOCKADDR_H
/***********************
** uapi/asm/socket.h **
***********************/
#define SO_PASSCRED 16
/********************
** linux/socket.h **
********************/
struct ucred {
__u32 pid;
__u32 uid;
__u32 gid;
};
#define AF_NETLINK 16
#define SCM_CREDENTIALS 0x02
#endif /* _LIBNL_EMUL_H_ */

View File

@ -0,0 +1,20 @@
#ifndef _LINUX_TYPES_H
#define _LINUX_TYPES_H
#include <platform/types.h>
typedef signed char __s8;
typedef unsigned char __u8;
typedef signed short __s16;
typedef unsigned short __u16;
typedef signed int __s32;
typedef unsigned int __u32;
typedef int64_t __s64;
typedef uint64_t __u64;
typedef __u16 __be16;
typedef __u32 __be32;
typedef __u16 __sum16;
#endif /* _LINUX_TYPES_H */

View File

@ -0,0 +1,352 @@
/**
* \brief Linux emulation code
* \author Josef Soentgen
* \date 2014-07-28
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode */
#include <base/printf.h>
#include <util/string.h>
/**************
** stdlib.h **
**************/
static char getenv_NLDBG[] = "1";
static char getenv_HZ[] = "100";
static char getenv_TICKS_PER_USEC[] = "10000";
extern "C" char *getenv(const char *name)
{
if (Genode::strcmp(name, "NLDBG") == 0) return getenv_NLDBG;
if (Genode::strcmp(name, "HZ") == 0) return getenv_HZ;
if (Genode::strcmp(name, "TICKS_PER_USEC") == 0) return getenv_TICKS_PER_USEC;
return nullptr;
}
#if 0
#include <base/env.h>
#include <base/printf.h>
#include <base/snprintf.h>
#include <dataspace/client.h>
#include <timer_session/connection.h>
#include <rom_session/connection.h>
#include <util/string.h>
#include <lx_emul.h>
extern "C" {
/*************
** errno.h **
*************/
int errno;
/*************
** stdio.h **
*************/
FILE *stdout;
FILE *stderr;
void *malloc(size_t size)
{
/* align on pointer size */
size = size + ((sizeof(Genode::addr_t)-1) & ~(sizeof(Genode::addr_t)-1));
size_t rsize = size + sizeof (Genode::addr_t);
void *addr = 0;
if (!Genode::env()->heap()->alloc(size, &addr))
return 0;
*(Genode::addr_t*)addr = rsize;
return ((Genode::addr_t*)addr) + 1;
}
void *calloc(size_t nmemb, size_t size)
{
#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size) {
return NULL;
}
size *= nmemb;
void *addr = malloc(size);
Genode::memset(addr, 0, size);
return addr;
}
void free(void *ptr)
{
if (!ptr)
return;
Genode::addr_t *addr = ((Genode::addr_t*)ptr) - 1;
Genode::env()->heap()->free(addr, *addr);
}
void *realloc(void *ptr, Genode::size_t size)
{
if (!size)
free(ptr);
void *n = malloc(size);
size_t s = *((size_t *)ptr - 1);
Genode::memcpy(n, ptr, Genode::min(s, size));
free(ptr);
return n;
}
/**************
** stdlib.h **
**************/
static char getenv_HZ[] = "100";
static char getenv_TICKS_PER_USEC[] = "10000";
char *getenv(const char *name)
{
/* these values must match the ones of lx_emul wifi */
if (Genode::strcmp(name, "HZ") == 0) return getenv_HZ;
if (Genode::strcmp(name, "TICKS_PER_USEC") == 0) return getenv_TICKS_PER_USEC;
return nullptr;
}
long int strtol(const char *nptr, char **endptr, int base)
{
long res = 0;
Genode::ascii_to<long>(nptr, &res, base);
return res;
}
double strtod(const char *nptr, char **endptr)
{
double res = 0;
Genode::ascii_to<double>(nptr, &res, 0);
return res;
}
/********************
** linux/string.h **
********************/
size_t strcspn(const char *s, const char *reject)
{
for (char const *p = s; *p; p++) {
char c = *p;
for (char const *r = reject; *r; r++) {
char d = *r;
if (c == d)
return (p - 1 - s);
}
}
return 0;
}
char *strdup(const char *s)
{
size_t len = strlen(s);
char *p = (char *) malloc(len + 1);
return strncpy(p, s, len + 1);
}
size_t strlen(const char *s)
{
return Genode::strlen(s);
}
int strcasecmp(const char* s1, const char *s2)
{
return Genode::strcmp(s1, s2);
}
int strcmp(const char* s1, const char *s2)
{
return Genode::strcmp(s1, s2);
}
int strncmp(const char *s1, const char *s2, size_t len)
{
return Genode::strcmp(s1, s2, len);
}
char *strchr(const char *p, int ch)
{
char c;
c = ch;
for (;; ++p) {
if (*p == c)
return ((char *)p);
if (*p == '\0')
break;
}
return 0;
}
void *memchr(const void *s, int c, size_t n)
{
const unsigned char *p = reinterpret_cast<const unsigned char*>(s);
while (n-- != 0) {
if ((unsigned char)c == *p++) {
return (void *)(p - 1);
}
}
return NULL;
}
char *strnchr(const char *p, size_t count, int ch)
{
char c;
c = ch;
for (; count; ++p, count--) {
if (*p == c)
return ((char *)p);
if (*p == '\0')
break;
}
return 0;
}
char *strncat(char *dst, const char *src, size_t n)
{
char *p = dst;
while (*p++) ;
while ((*p = *src) && (n-- > 0)) {
++src;
++p;
}
return dst;
}
char *strcpy(char *dst, const char *src)
{
char *p = dst;
while ((*dst = *src)) {
++src;
++dst;
}
return p;
}
char *strncpy(char *dst, const char* src, size_t n)
{
return Genode::strncpy(dst, src, n);
}
int snprintf(char *str, size_t size, const char *format, ...)
{
va_list list;
va_start(list, format);
Genode::String_console sc(str, size);
sc.vprintf(format, list);
va_end(list);
return sc.len();
}
int vsnprintf(char *str, size_t size, const char *format, va_list args)
{
Genode::String_console sc(str, size);
sc.vprintf(format, args);
return sc.len();
}
int asprintf(char **strp, const char *fmt, ...)
{
/* XXX for now, let's hope strings are not getting longer than 256 bytes */
enum { MAX_STRING_LENGTH = 256 };
char *p = (char*)malloc(MAX_STRING_LENGTH);
if (!p)
return -1;
va_list args;
va_start(args, fmt);
Genode::String_console sc(p, MAX_STRING_LENGTH);
sc.vprintf(fmt, args);
va_end(args);
return strlen(p);;
}
/**************
** unistd.h **
**************/
int getpagesize(void) {
return 4096; }
pid_t getpid(void) {
return 42; }
/************
** time.h **
************/
extern unsigned long jiffies;
time_t time(time_t *t)
{
dde_kit_printf("%s:%d from: %p\n", __func__, __LINE__, __builtin_return_address(0));
return jiffies;
}
} /* extern "C" */
#endif

View File

@ -0,0 +1,494 @@
/**
* \brief Linux emulation code
* \author Josef Soentgen
* \date 2014-07-28
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/env.h>
#include <base/printf.h>
#include <base/snprintf.h>
#include <util/list.h>
#include <util/string.h>
#include <util/misc_math.h>
/* Libc includes */
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/poll.h>
#include <wifi/socket_call.h>
extern "C" {
#include <libnl_emul.h>
#include <linux/netlink.h>
}
/* from netlink-private/netlink.h */
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
/* uapi/asm-generic/socket.h */
#ifndef SO_WIFI_STATUS
#define SO_WIFI_STATUS 41
#endif
/* bits/socket.h */
#ifndef MSG_ERRQUEUE
#define MSG_ERRQUEUE 0x2000
#endif
static const bool trace = true;
#define TRACE() \
do { if (trace) \
PDBG("called from: %p", __builtin_return_address(0)); \
} while (0)
using namespace Wifi;
extern Socket_call socket_call;
struct Socket_fd : public Genode::List<Socket_fd>::Element
{
Socket *s;
int fd;
Socket_fd(Socket *s, int fd) : s(s), fd(fd) { }
};
class Socket_registry
{
private :
/* abritary value (it goes to eleven!) */
enum { SOCKETS_INITIAL_VALUE = 11, };
static unsigned _sockets;
static Genode::List<Socket_fd> *_list() /* XXX ptr array instead of list? */
{
static Genode::List<Socket_fd> _l;
return &_l;
}
public:
static int insert(Socket *s)
{
Socket_fd *sfd = new (Genode::env()->heap()) Socket_fd(s, ++_sockets);
_list()->insert(sfd);
return sfd->fd;
}
static void remove(Socket *s)
{
for (Socket_fd *sfd = _list()->first(); sfd; sfd = sfd->next())
if (sfd->s == s) {
_list()->remove(sfd);
destroy(Genode::env()->heap(), sfd);
break;
}
}
static Socket *find(int fd)
{
for (Socket_fd *sfd = _list()->first(); sfd; sfd = sfd->next())
if (sfd->fd == fd)
return sfd->s;
return 0;
}
};
unsigned Socket_registry::_sockets = Socket_registry::SOCKETS_INITIAL_VALUE;
extern "C" {
/******************
** sys/socket.h **
******************/
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
Socket *s = Socket_registry::find(sockfd);
if (!s) {
errno = EBADF;
return -1;
}
/* FIXME convert to/from Sockaddr */
int const err = socket_call.bind(s, (Wifi::Sockaddr const *)addr, addrlen);
if (err < 0) {
errno = -err;
return -1;
}
return err;
}
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
Socket *s = Socket_registry::find(sockfd);
if (!s) {
errno = EBADF;
return -1;
}
/* FIXME convert to/from Sockaddr */
int const err = socket_call.getsockname(s, (Wifi::Sockaddr *)addr, addrlen);
if (err < 0) {
errno = -err;
return -1;
}
return err;
}
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen)
{
Socket *s = Socket_registry::find(sockfd);
if (!s) {
PERR("sockfd %d not in registry", sockfd);
errno = EBADF;
return -1;
}
Wifi::Msghdr w_msg;
w_msg.msg_name = (void*)src_addr;
w_msg.msg_namelen = *addrlen;
w_msg.msg_iovlen = 1;
w_msg.msg_iov[0].iov_base = buf;
w_msg.msg_iov[0].iov_len = len;
/* FIXME convert to/from Sockaddr */
/* FIXME flags values */
int const err = socket_call.recvmsg(s, &w_msg, Wifi::WIFI_F_NONE);
if (err < 0) {
errno = -err;
return -1;
}
return err;
}
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
{
Socket *s = Socket_registry::find(sockfd);
if (!s) {
errno = EBADF;
return -1;
}
if (msg->msg_iovlen > Wifi::Msghdr::MAX_IOV_LEN) {
PERR("%s: %d exceeds maximum iov length (%d)",
__func__, msg->msg_iovlen, Wifi::Msghdr::MAX_IOV_LEN);
errno = EINVAL;
return -1;
}
/* XXX support multiple flags */
Wifi::Flags w_flags = Wifi::WIFI_F_NONE;
if (flags & MSG_ERRQUEUE)
w_flags = Wifi::WIFI_F_MSG_ERRQUEUE;
Wifi::Msghdr w_msg;
w_msg.msg_name = msg->msg_name;
w_msg.msg_namelen = msg->msg_namelen;
w_msg.msg_iovlen = msg->msg_iovlen;
for (unsigned i = 0; i < w_msg.msg_iovlen; ++i) {
w_msg.msg_iov[i].iov_base = msg->msg_iov[i].iov_base;
w_msg.msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
}
w_msg.msg_control = msg->msg_control;
w_msg.msg_controllen = msg->msg_controllen;
int const err = socket_call.recvmsg(s, &w_msg, w_flags);
if (err < 0) {
errno = -err;
return -1;
}
if (err > 0 && msg->msg_name)
msg->msg_namelen = w_msg.msg_namelen;
return err;
}
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
{
return sendto(sockfd, buf, len, flags, 0, 0);
}
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
{
Socket *s = Socket_registry::find(sockfd);
if (!s) {
errno = EBADF;
return -1;
}
if (msg->msg_iovlen > Wifi::Msghdr::MAX_IOV_LEN) {
PERR("%s: %d exceeds maximum iov length (%d)",
__func__, msg->msg_iovlen, Wifi::Msghdr::MAX_IOV_LEN);
errno = EINVAL;
return -1;
}
if (msg->msg_controllen != 0) {
PERR("%s: msg_control not supported", __func__);
errno = EINVAL;
return -1;
}
if (flags != 0) {
PERR("%s: flags not supported", __func__);
errno = EOPNOTSUPP;
return -1;
}
Wifi::Msghdr w_msg;
w_msg.msg_name = msg->msg_name;
w_msg.msg_namelen = msg->msg_namelen;
w_msg.msg_iovlen = msg->msg_iovlen;
for (unsigned i = 0; i < w_msg.msg_iovlen; ++i) {
w_msg.msg_iov[i].iov_base = msg->msg_iov[i].iov_base;
w_msg.msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
}
int const err = socket_call.sendmsg(s, &w_msg, Wifi::WIFI_F_NONE);
if (err < 0) {
errno = -err;
return -1;
}
return err;
}
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
{
Socket *s = Socket_registry::find(sockfd);
if (!s)
return -1;
Wifi::Msghdr w_msg;
w_msg.msg_name = (void*)dest_addr;
w_msg.msg_namelen = addrlen;
w_msg.msg_iovlen = 1;
w_msg.msg_iov[0].iov_base = const_cast<void*>(buf);
w_msg.msg_iov[0].iov_len = len;
/* FIXME convert to/from Sockaddr */
/* FIXME flags values */
int const err = socket_call.sendmsg(s, &w_msg, Wifi::WIFI_F_NONE);
if (err < 0) {
errno = -err;
return -1;
}
return err;
}
namespace { struct Invalid_arg { }; }
static Sockopt_level sockopt_level(int const in)
{
switch (in) {
case SOL_SOCKET: return Wifi::WIFI_SOL_SOCKET;
case SOL_NETLINK: return Wifi::WIFI_SOL_NETLINK;
default: throw Invalid_arg();
}
}
static Sockopt_name sockopt_name(int const level, int const in)
{
switch (level) {
case SOL_SOCKET:
switch (in) {
case SO_SNDBUF: return Wifi::WIFI_SO_SNDBUF;
case SO_RCVBUF: return Wifi::WIFI_SO_RCVBUF;
case SO_PASSCRED: return Wifi::WIFI_SO_PASSCRED;
case SO_WIFI_STATUS: return Wifi::WIFI_SO_WIFI_STATUS;
default: throw Invalid_arg();
}
case SOL_NETLINK:
switch (in) {
case NETLINK_ADD_MEMBERSHIP: return Wifi::WIFI_NETLINK_ADD_MEMBERSHIP;
case NETLINK_DROP_MEMBERSHIP: return Wifi::WIFI_NETLINK_DROP_MEMBERSHIP;
case NETLINK_PKTINFO: return Wifi::WIFI_NETLINK_PKTINFO;
default: throw Invalid_arg();
}
default: throw Invalid_arg();
}
}
int setsockopt(int sockfd, int level, int optname, const void *optval,
socklen_t optlen)
{
Socket *s = Socket_registry::find(sockfd);
if (!s)
return -1;
/* FIXME optval values */
int const err = socket_call.setsockopt(s,
sockopt_level(level),
sockopt_name(level, optname),
optval, optlen);
if (err < 0) {
errno = -err;
return 1;
}
return err;
}
int socket(int domain, int type, int protocol)
{
/* FIXME domain, type, protocol values */
Socket *s = socket_call.socket(domain, type, protocol);
if (!s)
return -1;
return Socket_registry::insert(s);
}
/**************
** unistd.h **
**************/
int close(int fd)
{
Socket *s = Socket_registry::find(fd);
if (!s)
return -1;
Socket_registry::remove(s); /* XXX all further operations on s shall fail */
int const err = socket_call.close(s);
if (err < 0) {
errno = -err;
return -1;
}
return err;
}
/*************
** fnctl.h **
*************/
int fcntl(int fd, int cmd, ... /* arg */ )
{
Socket *s = Socket_registry::find(fd);
if (!s)
return -1;
long arg;
va_list ap;
va_start(ap, cmd);
arg = va_arg(ap, long);
va_end(ap);
switch (cmd) {
case F_SETFL:
if (arg == O_NONBLOCK) {
socket_call.non_block(s, true);
return 0;
}
default:
PWRN("fcntl: unknown request: %d", cmd);
break;
}
return -1;
}
/****************
** sys/poll.h **
****************/
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
Poll_socket_fd sockets[Wifi::MAX_POLL_SOCKETS];
unsigned num = 0;
for (nfds_t i = 0; i < nfds; i++) {
Socket *s = Socket_registry::find(fds[i].fd);
if (!s) continue;
Genode::memset(&sockets[num], 0, sizeof(Poll_socket_fd));
sockets[num].s = s;
sockets[num].pfd = &fds[i];
if (fds[i].events & POLLIN)
sockets[num].events |= Wifi::WIFI_POLLIN;
if (fds[i].events & POLLOUT)
sockets[num].events |= Wifi::WIFI_POLLOUT;
if (fds[i].events & POLLPRI)
sockets[num].events |= Wifi::WIFI_POLLEX;
num++;
}
int nready = socket_call.poll_all(sockets, num, timeout);
if (!nready)
return 0;
if (nready < 0)
return -1;
for (unsigned i = 0; i < num; i++) {
int revents = sockets[i].revents;
struct pollfd *pfd = static_cast<struct pollfd*>(sockets[i].pfd);
pfd->revents = 0;
if (revents & Wifi::WIFI_POLLIN)
pfd->revents |= POLLIN;
if (revents & Wifi::WIFI_POLLOUT)
pfd->revents |= POLLOUT;
if (revents & Wifi::WIFI_POLLEX)
pfd->revents |= POLLPRI;
}
return nready;
}
} /* extern "C" */

View File

@ -0,0 +1,563 @@
/**
* \brief Dummy functions
* \author Josef Soentgen
* \date 2014-03-03
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
extern "C" {
typedef long DUMMY;
enum {
SHOW_DUMMY = 0,
SHOW_SKIP = 0,
SHOW_RET = 0,
};
#define DUMMY(retval, name) \
DUMMY name(void) { \
if (SHOW_DUMMY) \
PDBG( #name " called (from %p) not implemented", __builtin_return_address(0)); \
return retval; \
}
#define DUMMY_SKIP(retval, name) \
DUMMY name(void) { \
if (SHOW_SKIP) \
PLOG( #name " called (from %p) skipped", __builtin_return_address(0)); \
return retval; \
}
#define DUMMY_RET(retval, name) \
DUMMY name(void) { \
if (SHOW_RET) \
PWRN( #name " called (from %p) return %d", __builtin_return_address(0), retval); \
return retval; \
}
/* return sucessful */
DUMMY_RET(0, netdev_kobject_init)
DUMMY_RET(0, vlan_tx_nonzero_tag_present)
DUMMY_RET(0, vlan_tx_tag_present)
DUMMY_RET(1, capable)
DUMMY_RET(1, rcu_read_lock_bh_held)
DUMMY_RET(1, softirq_count);
DUMMY_RET(1, try_module_get)
DUMMY_RET(0, security_sk_alloc)
DUMMY_RET(0, net_ratelimit)
DUMMY_RET(0, static_key_false)
DUMMY_RET(1, dma_supported)
DUMMY_RET(1, ns_capable)
DUMMY_RET(0, sock_tx_timestamp)
/* not needed */
DUMMY_SKIP(-1, might_sleep)
DUMMY_SKIP(-1, read_lock_bh)
DUMMY_SKIP(-1, read_unlock_bh)
DUMMY_SKIP(-1, rwlock_init)
DUMMY_SKIP(-1, spin_lock_irqsave)
DUMMY_SKIP(-1, spin_unlock_irqrestore)
DUMMY_SKIP(-1, write_lock_bh)
DUMMY_SKIP(-1, write_unlock_bh)
DUMMY_SKIP(0, debugfs_create_dir)
DUMMY_SKIP(0, debugfs_remove_recursive)
DUMMY_SKIP(0, debugfs_rename)
DUMMY_SKIP(0, destroy_workqueue)
DUMMY_SKIP(0, device_create)
DUMMY_SKIP(0, device_initialize)
DUMMY_SKIP(0, down_read)
DUMMY_SKIP(0, down_write)
DUMMY_SKIP(0, free_irq)
DUMMY_SKIP(0, init_rwsem)
DUMMY_SKIP(0, iounmap)
DUMMY_SKIP(0, kparam_block_sysfs_write)
DUMMY_SKIP(0, kparam_unblock_sysfs_write)
DUMMY_SKIP(0, pci_disable_device)
DUMMY_SKIP(0, pci_disable_link_state)
DUMMY_SKIP(0, pci_disable_msi)
DUMMY_SKIP(0, pci_enable_device)
DUMMY_SKIP(0, pci_enable_msi)
DUMMY_SKIP(0, pci_release_regions)
DUMMY_SKIP(0, pci_request_regions)
DUMMY_SKIP(0, pci_set_master)
DUMMY_SKIP(0, put_device)
DUMMY_SKIP(0, scm_destroy)
DUMMY_SKIP(0, scm_recv)
DUMMY_SKIP(0, scm_send)
DUMMY_SKIP(0, security_netlink_send)
DUMMY_SKIP(0, sk_filter)
DUMMY_SKIP(0, sk_filter_release_rcu)
DUMMY_SKIP(-1, sk_filter_size)
DUMMY_SKIP(0, spin_lock)
DUMMY_SKIP(0, spin_lock_bh)
DUMMY_SKIP(0, spin_lock_init)
DUMMY_SKIP(0, spin_lock_irq)
DUMMY_SKIP(0, spin_unlock)
DUMMY_SKIP(0, spin_unlock_bh)
DUMMY_SKIP(0, spin_unlock_irq)
DUMMY_SKIP(0, up_read)
DUMMY_SKIP(0, up_write)
DUMMY_SKIP(1, in_interrupt) /* XXX * */
DUMMY_SKIP(0, in_softirq) /* XXX */
DUMMY_SKIP(0, is_vmalloc_addr) /* XXX */
DUMMY_SKIP(0, in_irq) /* XXX */
DUMMY_SKIP(0, local_bh_disable)
DUMMY_SKIP(0, local_bh_enable)
DUMMY_SKIP(0, dma_unmap_page)
/*FIXME*/DUMMY(0, dma_set_coherent_mask)
/*FIXME*/DUMMY(0, dma_set_mask)
DUMMY(-1, dma_sync_single_for_cpu)
DUMMY(-1, dma_sync_single_for_device)
/* XXX DUMMY_SKIP safe? */
DUMMY_SKIP(0, dma_unmap_single)
DUMMY_SKIP(0, kunmap)
DUMMY_SKIP(0, kunmap_atomic)
DUMMY_SKIP(-1, dump_stack)
DUMMY_SKIP(-1, gfp_pfmemalloc_allowed)
DUMMY_SKIP(-1, prefetchw)
DUMMY_SKIP(-1, write_lock_irq)
DUMMY_SKIP(-1, write_lock_irqsave)
DUMMY_SKIP(-1, write_unlock_irq)
DUMMY_SKIP(-1, write_unlock_irqrestore)
DUMMY_SKIP(0, read_lock)
DUMMY_SKIP(0, read_unlock)
DUMMY_SKIP(0, sysfs_create_group)
DUMMY_SKIP(0, sysfs_remove_group)
DUMMY_SKIP(0, sysfs_create_link)
DUMMY_SKIP(0, sysfs_remove_link)
DUMMY_SKIP(0, module_put)
DUMMY(0, device_release_driver)
DUMMY(-1, __vlan_put_tag)
DUMMY(-1, dev_printk_emit)
DUMMY(-1, gen_kill_estimator)
DUMMY(-1, generic_pipe_buf_confirm)
DUMMY(-1, generic_pipe_buf_map)
DUMMY(-1, generic_pipe_buf_unmap)
DUMMY(-1, linkwatch_fire_event)
DUMMY(-1, mod_delayed_work)
DUMMY(-1, need_resched)
DUMMY(-1, open_softirq)
DUMMY(-1, raw_notifier_chain_unregister)
DUMMY(-1, system_wq)
DUMMY(-1, vlan_do_receive)
DUMMY(-1, vlan_untag)
DUMMY(-1, yield)
DUMMY(0, IS_ERR)
DUMMY(0, __raise_softirq_irqoff)
DUMMY(0, __this_cpu_read)
DUMMY(-1, add_device_randomness)
DUMMY(0, add_uevent_var)
DUMMY(0, atomic64_read)
DUMMY(0, bitmap_empty)
DUMMY(0, call_rcu)
DUMMY(0, csum_block_add)
DUMMY(0, csum_fold)
DUMMY(0, csum_partial)
DUMMY(0, device_del)
DUMMY(0, device_rename)
DUMMY(0, device_unregister)
DUMMY(0, do_posix_clock_monotonic_gettime)
DUMMY(0, do_softirq)
DUMMY(0, flush_delayed_work)
DUMMY(0, flush_work)
DUMMY(0, flush_workqueue)
DUMMY(0, genl_dump_check_consistent)
DUMMY(0, genl_info_net)
DUMMY(0, genlmsg_cancel)
DUMMY(0, genlmsg_end)
DUMMY(0, genlmsg_multicast)
DUMMY(0, genlmsg_multicast_netns)
DUMMY(0, genlmsg_reply)
DUMMY(0, genlmsg_unicast)
DUMMY(0, get_cpu)
DUMMY(0, get_random_bytes)
DUMMY(0, get_seconds)
DUMMY(0, hweight16)
DUMMY(0, hweight64)
DUMMY(0, idr_alloc)
DUMMY(0, idr_destroy)
DUMMY(0, idr_find)
DUMMY(0, idr_for_each)
DUMMY(0, idr_init)
DUMMY(0, idr_remove)
DUMMY(0, init_timer_deferrable)
DUMMY(0, ip_hdr)
DUMMY(0, ipv4_get_dsfield)
DUMMY(0, ipv6_get_dsfield)
DUMMY(0, ipv6_hdr)
DUMMY(0, irqs_disabled)
DUMMY(0, isalpha)
DUMMY(0, jhash_2words)
DUMMY(0, kmem_cache_destroy)
DUMMY(0, kobject_uevent)
DUMMY(0, kobject_uevent_env)
DUMMY(0, kstrtoul)
DUMMY(0, linkwatch_init_dev)
DUMMY(0, local_softirq_pending)
DUMMY(0, mb)
DUMMY(0, misc_register)
DUMMY(0, mmiowb)
DUMMY(0, net_dmaengine_put)
DUMMY(0, net_info_ratelimited)
DUMMY(0, net_ns_type_operations)
DUMMY(0, netdev_pick_tx)
DUMMY(0, netdev_register_kobject)
DUMMY(0, netdev_unregister_kobject)
DUMMY(0, netpoll_poll_lock)
DUMMY(0, netpoll_poll_unlock)
DUMMY(0, netpoll_receive_skb)
DUMMY(0, netpoll_rx)
DUMMY(0, netpoll_rx_disable)
DUMMY(0, netpoll_rx_enable)
DUMMY(0, nla_data)
DUMMY(0, nla_get_be32)
DUMMY(0, nla_get_flag)
DUMMY(0, nla_get_s8)
DUMMY(0, nla_get_u16)
DUMMY(0, nla_get_u32)
DUMMY(0, nla_get_u64)
DUMMY(0, nla_get_u8)
DUMMY(0, nla_len)
DUMMY(0, nla_nest_end)
DUMMY(0, nla_nest_start)
DUMMY(0, nla_parse_nested)
DUMMY(0, nla_put_be32)
DUMMY(0, nla_put_flag)
DUMMY(0, nla_put_string)
DUMMY(0, nla_put_u16)
DUMMY(0, nla_put_u32)
DUMMY(0, nla_put_u64)
DUMMY(0, nla_put_u8)
DUMMY(0, nla_type)
DUMMY(0, nlmsg_free)
DUMMY(0, nlmsg_new)
DUMMY(0, nlmsg_parse)
DUMMY(0, nonseekable_open)
DUMMY(0, ntohs)
DUMMY(0, pci_pme_capable)
DUMMY(0, pm_qos_add_notifier)
DUMMY(0, pm_qos_remove_notifier)
DUMMY(0, pm_qos_request)
DUMMY(0, poll_wait)
DUMMY(0, preempt_disable)
DUMMY(0, preempt_enable)
DUMMY(0, put_cpu)
DUMMY(0, put_unaligned_be16)
DUMMY(0, put_unaligned_le16)
DUMMY(0, put_unaligned_le64)
DUMMY(0, qdisc_all_tx_empty)
DUMMY(0, raise_softirq_irqoff)
DUMMY(0, rcu_barrier)
DUMMY(0, rcu_read_lock_bh)
DUMMY(0, rcu_read_lock_held)
DUMMY(0, rcu_read_unlock_bh)
DUMMY(-1, release_net)
DUMMY(0, rtnl_dereference)
DUMMY(-1, seq_printf)
DUMMY(0, smp_mb)
DUMMY(0, smp_mb__before_clear_bit)
DUMMY(0, smp_processor_id)
DUMMY(0, smp_rmb)
DUMMY(0, sock_net)
DUMMY(0, sock_release)
DUMMY(0, spin_trylock)
DUMMY(0, sscanf)
DUMMY(0, synchronize_irq)
DUMMY(0, synchronize_rcu_expedited)
DUMMY(0, tasklet_disable)
DUMMY(0, tasklet_enable)
DUMMY(0, tasklet_kill)
DUMMY(0, tcp_hdrlen)
DUMMY(0, this_cpu_dec)
DUMMY(0, this_cpu_inc)
DUMMY(0, toupper)
DUMMY(0, wait_event_interruptible)
DUMMY(0, work_busy)
DUMMY(0, class_register)
DUMMY(0, class_unregister)
DUMMY(0, debugfs_remove)
DUMMY(0, dev_set_uevent_suppress)
DUMMY(0, ethtool_op_get_link)
DUMMY(0, genl_register_family_with_ops)
DUMMY(0, genl_register_mc_group)
DUMMY(0, init_utsname)
DUMMY(0, platform_device_unregister)
DUMMY(0, atomic_notifier_chain_register)
DUMMY(0, __get_free_pages)
DUMMY(0, __get_free_page)
DUMMY(0, __set_current_state)
DUMMY(0, add_wait_queue)
DUMMY(0, add_wait_queue_exclusive)
DUMMY(0, atomic_notifier_call_chain)
DUMMY(0, cond_resched)
DUMMY(0, current)
DUMMY(0, debug_check_no_locks_freed)
DUMMY(0, get_user)
DUMMY(0, jhash_1word)
DUMMY(0, kernel_sendmsg)
DUMMY(0, put_cmsg)
DUMMY(0, put_cred)
DUMMY(0, put_pid)
DUMMY(0, remove_wait_queue)
DUMMY(0, schedule)
DUMMY(-1, security_sk_free)
DUMMY(0, set_current_state)
DUMMY(0, signal_pending)
DUMMY(0, smp_wmb)
DUMMY(0, sock_update_classid)
DUMMY(0, sock_update_netprioidx)
DUMMY(0, sock_wake_async)
DUMMY(0, static_key_slow_dec)
DUMMY(0, task_tgid_vnr)
DUMMY(0, totalram_pages)
DUMMY(0, wake_up_interruptible_poll)
DUMMY(-1, __this_cpu_write)
DUMMY(-1, csum_block_add_ext)
DUMMY(-1, csum_partial_ext)
DUMMY(-1, genl_register_family_with_ops_groups)
DUMMY(-1, ktime_sub)
DUMMY(-1, sg_init_one)
DUMMY(-1, sg_init_table)
DUMMY(-1, sg_set_buf)
DUMMY(-1, vlan_hw_offload_capable)
DUMMY(-1, vlan_tx_tag_get_id)
DUMMY(-1, vzalloc)
DUMMY(-1, tsk_restore_flags)
DUMMY(-1, put_user)
DUMMY(-1, write_seqcount_begin)
DUMMY(-1, write_seqcount_end)
DUMMY(-1, net_dmaengine_get)
DUMMY(-1, audit_enabled)
DUMMY(-1, audit_get_sessionid)
DUMMY(-1, audit_get_loginuid)
DUMMY(-1, init_user_ns)
DUMMY(-1, from_kgid)
DUMMY(-1, from_kuid)
DUMMY(-1, pci_num_vf)
DUMMY(-1, audit_log)
DUMMY(-1, linkwatch_forget_dev)
DUMMY(-1, linkwatch_run_queue)
DUMMY(-1, on_each_cpu)
DUMMY(-1, kobject_put)
DUMMY(-1, mq_qdisc_ops)
DUMMY(-1, get_net_ns_by_pid)
DUMMY(-1, get_net_ns_by_fd)
DUMMY(-1, unregister_pernet_device)
DUMMY(0, __hw_addr_init)
DUMMY(0, __hw_addr_sync)
DUMMY(0, __hw_addr_unsync)
DUMMY(0, dev_alloc_name)
DUMMY(0, dev_change_net_namespace)
DUMMY(0, dev_close)
DUMMY(0, dev_kfree_skb_any)
DUMMY(0, dev_net_set)
DUMMY(0, dev_open)
DUMMY_SKIP(0, dev_hold)
DUMMY_SKIP(0, dev_put)
DUMMY(0, dst_release)
DUMMY(0, free_netdev)
DUMMY(0, net_disable_timestamp)
DUMMY(0, netdev_set_default_ethtool_ops)
DUMMY(0, netif_rx_ni)
DUMMY(0, netif_start_subqueue)
DUMMY(0, netif_stop_subqueue)
DUMMY(0, netif_tx_start_all_queues)
DUMMY(0, netif_tx_stop_all_queues)
DUMMY(0, netif_wake_subqueue)
DUMMY(0, next_net_device)
DUMMY(0, synchronize_net)
DUMMY(0, unregister_netdevice_many)
DUMMY(0, unregister_netdevice_notifier)
DUMMY(0, unregister_netdevice_queue)
DUMMY(-1, task_pid_nr)
DUMMY(-1, pid_vnr)
DUMMY(-1, from_kuid_munged)
DUMMY(-1, from_kgid_munged)
DUMMY(-1, sk_get_filter)
DUMMY(-1, sk_detach_filter)
DUMMY(-1, cond_resched_softirq)
DUMMY(-1, prefetch)
DUMMY(-1, security_socket_getpeersec_stream)
DUMMY(-1, net_enable_timestamp)
DUMMY(-1, __lock_sock)
DUMMY(-1, bpf_tell_extensions)
DUMMY(0, atomic64_set)
DUMMY(0, device_can_wakeup)
DUMMY(0, device_reprobe)
DUMMY(0, device_set_wakeup_enable)
DUMMY(0, ip_fast_csum)
DUMMY(0, iwl_mvm_sf_update)
DUMMY(0, prandom_u32)
DUMMY(0, request_firmware)
DUMMY(0, tcp_v4_check)
DUMMY(0, netif_rx)
DUMMY(0, sk_attach_filter)
DUMMY(0, __class_create)
DUMMY(0, __module_get)
DUMMY(0, __sock_recv_timestamp)
DUMMY(0, __sock_recv_wifi_status)
DUMMY(0, _sigprocmask)
DUMMY(0, acpi_match_device)
DUMMY(0, atomic_notifier_chain_unregister)
DUMMY(0, can_checksum_protocol)
DUMMY(0, class_destroy)
DUMMY(0, clk_disable)
DUMMY(0, clk_enable)
DUMMY(0, csum_ipv6_magic)
DUMMY(0, csum_partial_copy)
DUMMY(0, csum_sub)
DUMMY(0, csum_tcpudp_nofold)
DUMMY(0, devm_clk_get)
DUMMY(0, devm_gpiod_get_index)
DUMMY(0, devm_kzalloc)
DUMMY(0, file_inode)
DUMMY(0, gpiod_direction_output)
DUMMY(0, gpiod_set_value)
DUMMY(0, hex_dump_to_buffer)
DUMMY(0, __ilog2_u32)
DUMMY(0, __ilog2_u64)
DUMMY(0, input_close_device)
DUMMY(0, input_open_device)
DUMMY(0, input_register_handle)
DUMMY(0, input_register_handler)
DUMMY(0, input_unregister_handle)
DUMMY(0, input_unregister_handler)
DUMMY(0, ip_hdrlen)
DUMMY(0, ipv6_authlen)
DUMMY(0, ipv6_optlen)
DUMMY(0, ktime_to_timespec)
DUMMY(0, ktime_to_timeval)
DUMMY(0, misc_deregister)
DUMMY(0, net_gso_ok)
DUMMY(0, nosteal_pipe_buf_ops)
DUMMY(0, pci_unregister_driver)
DUMMY(0, platform_get_drvdata)
DUMMY(0, platform_set_drvdata)
DUMMY(0, regulator_disable)
DUMMY(0, regulator_enable)
DUMMY(0, regulator_get_exclusive)
DUMMY(0, regulator_is_enabled)
DUMMY(0, regulator_put)
DUMMY(0, rfkill_epo)
DUMMY(0, rfkill_get_global_sw_state)
DUMMY(0, rfkill_is_epo_lock_active)
DUMMY(0, rfkill_remove_epo_lock)
DUMMY(0, rfkill_restore_states)
DUMMY(0, rfkill_switch_all)
DUMMY(0, send_sigurg)
DUMMY(0, sg_mark_end)
DUMMY(0, sg_set_page)
DUMMY(0, simple_strtoul)
DUMMY(0, skb_gro_len)
DUMMY(0, skb_gro_offset)
DUMMY(0, skb_network_protocol)
DUMMY(0, spin_lock_nested)
DUMMY(0, splice_to_pipe)
DUMMY(0, static_key_slow_inc)
DUMMY(0, tcp_hdr)
DUMMY(0, textsearch_find)
DUMMY(0, udp_hdr)
DUMMY(0, virt_to_page)
DUMMY(0, xfrm_sk_clone_policy)
DUMMY(0, xfrm_sk_free_policy)
DUMMY(0, strncpy)
DUMMY(0, __ethtool_get_settings)
DUMMY(0, __netif_tx_lock_bh)
DUMMY(0, __netif_tx_unlock_bh)
DUMMY(0, __skb_get_hash)
DUMMY(0, __sock_recv_ts_and_drops)
DUMMY(0, cpu_relax)
DUMMY(0, dev_get_by_index_rcu)
DUMMY(0, dev_get_by_name)
DUMMY(0, dev_get_by_name_rcu)
DUMMY(0, dev_mc_add)
DUMMY(0, dev_mc_del)
DUMMY(0, dev_remove_pack)
DUMMY(0, dev_set_allmulti)
DUMMY(0, dev_set_promiscuity)
DUMMY(0, dev_uc_add)
DUMMY(0, dev_uc_del)
DUMMY(0, dev_xmit_complete)
DUMMY(0, ethtool_cmd_speed)
DUMMY(0, flush_dcache_page)
DUMMY(0, getnstimeofday)
DUMMY(0, ip_check_defrag)
DUMMY(0, ktime_to_timespec_cond)
DUMMY(0, netdev_get_tx_queue)
DUMMY(0, netif_skb_features)
DUMMY(0, netif_supports_nofcs)
DUMMY(0, netif_xmit_frozen_or_stopped)
DUMMY(0, offset_in_page)
DUMMY(0, prandom_u32_max)
DUMMY(0, raw_smp_processor_id)
DUMMY(0, sk_run_filter)
DUMMY(0, skb_flow_dissect)
DUMMY(0, sock_unregister)
DUMMY(0, txq_trans_update)
DUMMY(0, unregister_pernet_subsys)
DUMMY(0, vm_insert_page)
DUMMY(0, vmalloc_to_page)
DUMMY(0, __dev_change_flags)
DUMMY(0, __dev_get_by_name)
DUMMY(0, __dev_notify_flags)
DUMMY(0, call_netdevice_notifiers)
DUMMY(0, dev_base_lock)
DUMMY(0, dev_change_carrier)
DUMMY(0, dev_change_flags)
DUMMY(0, dev_change_name)
DUMMY(0, dev_get_flags)
DUMMY(0, dev_get_phys_port_id)
DUMMY(0, dev_get_stats)
DUMMY(0, dev_mc_add_excl)
DUMMY(0, dev_set_alias)
DUMMY(0, dev_set_group)
DUMMY(0, dev_set_mac_address)
DUMMY(0, dev_set_mtu)
DUMMY(0, dev_uc_add_excl)
DUMMY(0, is_link_local_ether_addr)
DUMMY(0, jiffies_to_clock_t)
DUMMY(0, netdev_boot_setup)
DUMMY(0, netdev_master_upper_dev_get)
DUMMY(0, netdev_state_change)
DUMMY(0, netdev_unregistering_wq)
DUMMY(0, netif_dormant)
DUMMY(0, autoremove_wake_function)
DUMMY(0, get_user_pages_fast)
DUMMY(0, iov_length)
DUMMY(0, memcpy_toiovecend)
DUMMY(0, netdev_rx_csum_fault)
DUMMY(0, release_pages)
DUMMY(0, sk_busy_loop)
DUMMY(0, sk_can_busy_loop)
DUMMY(0, sg_next)
DUMMY(0, complete_all)
DUMMY(0, module_put_and_exit)
DUMMY(0, simple_strtol)
DUMMY(0, alg_test)
DUMMY(0, alloc_workqueue)
} /* extern "C" */

View File

@ -0,0 +1,198 @@
/*
* \brief Completions and events
* \author Christian Helmuth
* \author Josef Soentgen
* \date 2014-10-14
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/sleep.h>
/* local includes */
#include <lx.h>
#include <scheduler.h>
#include <extern_c_begin.h>
# include <lx_emul.h>
#include <extern_c_end.h>
static bool const verbose = false;
#define PWRNV(...) do { if (verbose) PWRN(__VA_ARGS__); } while (0)
extern "C" {
/************************
** linux/completion.h **
************************/
typedef Lx::Task::List_element Wait_le;
typedef Lx::Task::List Wait_list;
void init_waitqueue_head(wait_queue_head_t *wq)
{
wq->list = new (Genode::env()->heap()) Wait_list;
}
int waitqueue_active(wait_queue_head_t *wq)
{
Wait_list *list = static_cast<Wait_list*>(wq->list);
if (!list)
return 0;
return list->first() ? 1 : 0;
}
void __wake_up(wait_queue_head_t *wq, bool all)
{
Wait_list *list = static_cast<Wait_list *>(wq->list);
if (!list) {
PWRNV("wait_queue_head_t is empty, wq: %p called from: %p", wq, __builtin_return_address(0));
return;
}
Wait_le *le = list->first();
do {
if (!le)
return;
le->object()->unblock();
} while (all && (le = le->next()));
}
void wake_up_interruptible_sync_poll(wait_queue_head_t *wq, int)
{
__wake_up(wq, false);
}
void __wait_event(wait_queue_head_t wq)
{
Wait_list *list = static_cast<Wait_list *>(wq.list);
if (!list) {
PERR("__wait_event(): empty list in wq: %p", &wq);
Genode::sleep_forever();
}
Lx::Task *task = Lx::scheduler().current();
task->wait_enqueue(list);
task->block_and_schedule();
task->wait_dequeue(list);
}
void init_completion(struct completion *work)
{
work->done = 0;
}
void complete(struct completion *work)
{
work->done = 1;
}
static void __wait_completion(struct completion *work)
{
// PERR("%s:%d: FIXME", __func__, __LINE__);
}
unsigned long wait_for_completion_timeout(struct completion *work,
unsigned long timeout)
{
__wait_completion(work);
return 1;
}
int wait_for_completion_interruptible(struct completion *work)
{
__wait_completion(work);
return 0;
}
long wait_for_completion_interruptible_timeout(struct completion *work,
unsigned long timeout)
{
__wait_completion(work);
return 1;
}
void wait_for_completion(struct completion *work)
{
__wait_completion(work);
}
/******************
** linux/wait.h **
******************/
void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *w, int state)
{
if (!q) {
PWRNV("prepare_to_wait: wait_queue_head_t is 0, ignore, called from: %p",
__builtin_return_address(0));
return;
}
Wait_list *list = static_cast<Wait_list *>(q->list);
Lx::Task *task = Lx::scheduler().current();
task->wait_enqueue(list);
}
void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *w, int state)
{
prepare_to_wait(q, w, state);
}
void finish_wait(wait_queue_head_t *q, wait_queue_t *w)
{
if (!q) {
PWRNV("finish_wait: wait_queue_head_t is 0, ignore, called from: %p",
__builtin_return_address(0));
return;
}
Wait_list *list = static_cast<Wait_list *>(q->list);
Lx::Task *task = Lx::scheduler().current();
task->wait_dequeue(list);
}
/*******************
** linux/timer.h **
*******************/
signed long schedule_timeout_uninterruptible(signed long timeout)
{
// PERR("%s:%d: FIXME", __func__, __LINE__);
return 0;
}
int wake_up_process(struct task_struct *tsk)
{
// PERR("%s:%d: FIXME does task: %p needs to be woken up?", __func__, __LINE__, tsk);
return 0;
}
} /* extern "C" */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
/*
* \brief Include before including Linux headers in C++
* \author Christian Helmuth
* \date 2014-08-21
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#define extern_c_begin
extern "C" {
/* some warnings should only be switched of for Linux headers */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-arith"
#pragma GCC diagnostic ignored "-Wsign-compare"
/* deal with C++ keywords used for identifiers etc. */
#define private private_
#define class class_
#define new new_

View File

@ -0,0 +1,20 @@
/*
* \brief Include after including Linux headers in C++
* \author Christian Helmuth
* \date 2014-08-21
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#undef new
#undef class
#undef private
#pragma GCC diagnostic pop
} /* extern "C" */

View File

@ -0,0 +1,26 @@
/*
* \brief List for firmware images and their sizes
* \author Josef Soentgen
* \date 2014-03-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _FIRMWARE_LIST_H_
#define _FIRMWARE_LIST_H_
typedef __SIZE_TYPE__ size_t;
struct Firmware_list
{
char const *name;
size_t size;
};
#endif /* _FIRMWARE_LIST_H_ */

View File

@ -0,0 +1 @@
#include <uapi/linux/gen_stats.h>

View File

@ -0,0 +1 @@
#include <uapi/linux/hdlc/ioctl.h>

View File

@ -0,0 +1 @@
#include <uapi/linux/if_bridge.h>

View File

@ -0,0 +1 @@
#include <uapi/linux/if_packet.h>

View File

@ -0,0 +1 @@
#include <uapi/linux/neighbour.h>

View File

@ -0,0 +1 @@
#include <uapi/linux/nl80211.h>

View File

@ -0,0 +1,2 @@
#include <uapi/asm-generic/socket.h>
#include <uapi/linux/sockios.h>

View File

@ -0,0 +1,99 @@
/*
* \brief Slightly improved list
* \author Christian Helmuth
* \date 2014-09-25
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _LIST_H_
#define _LIST_H_
#include <util/list.h>
namespace Lx {
template <typename> class List;
template <typename> class List_element;
}
template <typename LT>
class Lx::List : private Genode::List<LT>
{
private:
typedef Genode::List<LT> Base;
public:
using Base::Element;
void append(LT const *le)
{
LT *at = nullptr;
for (LT *l = first(); l; l = l->next())
at = l;
Base::insert(le, at);
}
void prepend(LT const *le)
{
Base::insert(le);
}
void insert_before(LT const *le, LT const *at)
{
if (at == first()) {
prepend(le);
return;
}
for (LT *l = first(); l; l = l->next())
if (l->next() == at)
at = l;
Base::insert(le, at);
}
/****************************
** Genode::List interface **
****************************/
LT *first() { return Base::first(); }
LT const *first() const { return Base::first(); }
void insert(LT const *le, LT const *at = 0)
{
Base::insert(le, at);
}
void remove(LT const *le)
{
Base::remove(le);
}
};
template <typename T>
class Lx::List_element : public Lx::List<List_element<T> >::Element
{
private:
T *_object;
public:
List_element(T *object) : _object(object) { }
T *object() const { return _object; }
};
#endif /* _LIST_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,214 @@
/*
* \brief Nic-session implementation for network devices
* \author Sebastian Sumpf
* \date 2012-07-05
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _NIC__COMPONENT_H_
#define _NIC__COMPONENT_H_
/* Genode includes */
#include <nic/packet_allocator.h>
#include <nic_session/rpc_object.h>
#include <root/component.h>
#include <timer_session/connection.h>
/* local includes */
#include <nic/dispatch.h>
#include <extern_c_begin.h>
# include <linux/skbuff.h>
#include <extern_c_end.h>
namespace Nic {
using namespace Genode; /* FIXME */
struct Session_component;
struct Device;
typedef Genode::Root_component<Session_component, Single_client> Root_component;
struct Root;
}
struct Nic::Device
{
/**
* Transmit data to driver
*/
virtual bool tx(addr_t virt, size_t size) = 0;
/**
* Return mac address of device
*/
virtual Mac_address mac_address() = 0;
/**
* Return link state (true if link detected)
*/
virtual bool link_state() = 0;
/**
* Set session belonging to this driver
*/
virtual void session(Session_component *s) = 0;
Device() { }
virtual ~Device() { }
};
class Nic::Session_component : public Nic::Packet_allocator,
public Packet_session_component<Session_rpc_object>
{
private:
Device &_device; /* device this session is using */
Tx::Sink *_tx_sink; /* client packet sink */
bool _tx_alloc; /* get next packet from client or use _tx_packet */
Packet_descriptor _tx_packet; /* saved packet in case of driver errors */
Signal_context_capability _link_state_sigh;
void _send_packet_avail_signal() {
Signal_transmitter(_tx.sigh_packet_avail()).submit(); }
protected:
void _process_packets(unsigned)
{
int tx_cnt = 0;
/* submit received packets to lower layer */
while (_tx_sink->packet_avail()) {
Packet_descriptor packet = _tx_alloc ? _tx_sink->get_packet() : _tx_packet;
addr_t virt = (addr_t)_tx_sink->packet_content(packet);
/* send to driver */
if (!(_device.tx(virt, packet.size()))) {
_send_packet_avail_signal();
_tx_alloc = false;
_tx_packet = packet;
return;
}
_tx_alloc = true;
tx_cnt++;
/* acknowledge to client */
_tx_sink->acknowledge_packet(packet);
}
/* release acknowledged packets */
_rx_ack(false);
if (_tx_sink->packet_avail())
_send_packet_avail_signal();
}
void _rx_ack(bool block = true)
{
while (_rx.source()->ack_avail() || block) {
Packet_descriptor packet = _rx.source()->get_acked_packet();
/* free packet buffer */
_rx.source()->release_packet(packet);
block = false;
}
}
public:
/**
* Constructor
*/
Session_component(Dataspace_capability tx_ds,
Dataspace_capability rx_ds,
Server::Entrypoint &ep,
Device &device)
:
Nic::Packet_allocator(Genode::env()->heap()),
Packet_session_component(tx_ds, rx_ds, this, ep),
_device(device),
_tx_sink(Session_rpc_object::_tx.sink()),
_tx_alloc(true)
{ _device.session(this); }
/**
* Send packet to client (called from driver)
*/
void rx(addr_t packet, size_t psize, addr_t frag, size_t fsize)
{
size_t size = psize + fsize;
while (true) {
try {
Packet_descriptor p =_rx.source()->alloc_packet(size);
Genode::memcpy(_rx.source()->packet_content(p), (void*)packet, psize);
if (fsize)
Genode::memcpy(_rx.source()->packet_content(p)+psize, (void*)frag, fsize);
_rx.source()->submit_packet(p);
} catch (...) {
/* ack or block */
_rx_ack();
continue;
}
break;
}
_rx_ack(false);
}
/**
* Link state changed (called from driver)
*/
void link_state_changed()
{
if (_link_state_sigh.valid())
Genode::Signal_transmitter(_link_state_sigh).submit();
}
/***************************
** Nic-session interface **
***************************/
Mac_address mac_address() override
{
return _device.mac_address();
}
bool link_state() // override
{
return _device.link_state();
}
void link_state_sigh(Genode::Signal_context_capability sigh)
{
_link_state_sigh = sigh;
}
};
/**
* Root component, handling new session requests
*/
struct Nic::Root : Packet_root<Root_component, Session_component, Device, CACHED>
{
Root(Server::Entrypoint &ep, Allocator *md_alloc, Device &device)
: Packet_root(ep, md_alloc, device) { }
};
#endif /* _NIC__COMPONENT_H_ */

View File

@ -0,0 +1,143 @@
/**
* \brief Packet-stream-session components
* \author Sebastian Sumpf
* \author Norman Feske
* \date 2012-07-06
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _SIGNAL__DISPATCHER_H_
#define _SIGNAL__DISPATCHER_H_
/* Genode includes */
#include <base/signal.h>
/* local includes */
#include <lx.h>
/**
* Session components that overrides signal handlers
*/
template <typename SESSION_RPC_OBJECT>
class Packet_session_component : public SESSION_RPC_OBJECT
{
private:
Genode::Signal_rpc_member<Packet_session_component> _tx_ready_to_ack_dispatcher;
Genode::Signal_rpc_member<Packet_session_component> _tx_packet_avail_dispatcher;
Genode::Signal_rpc_member<Packet_session_component> _rx_ack_avail_dispatcher;
Genode::Signal_rpc_member<Packet_session_component> _rx_ready_to_submit_dispatcher;
void _tx_ready_to_ack(unsigned)
{
_process_packets(0);
}
void _tx_packet_avail(unsigned)
{
_process_packets(0);
}
void _rx_ack_avail(unsigned)
{
_process_packets(0);
}
void _rx_ready_to_submit(unsigned)
{
_process_packets(0);
}
protected:
virtual void _process_packets(unsigned) = 0;
public:
Packet_session_component(Genode::Dataspace_capability tx_ds,
Genode::Dataspace_capability rx_ds,
Genode::Range_allocator *rx_buffer_alloc,
Server::Entrypoint &ep)
:
SESSION_RPC_OBJECT(tx_ds, rx_ds, rx_buffer_alloc, ep.rpc_ep()),
_tx_ready_to_ack_dispatcher(ep, *this, &Packet_session_component::_tx_ready_to_ack),
_tx_packet_avail_dispatcher(ep, *this, &Packet_session_component::_tx_packet_avail),
_rx_ack_avail_dispatcher(ep, *this, &Packet_session_component::_rx_ack_avail),
_rx_ready_to_submit_dispatcher(ep, *this, &Packet_session_component::_rx_ready_to_submit)
{
SESSION_RPC_OBJECT::_tx.sigh_ready_to_ack(_tx_ready_to_ack_dispatcher);
SESSION_RPC_OBJECT::_tx.sigh_packet_avail(_tx_packet_avail_dispatcher);
SESSION_RPC_OBJECT::_rx.sigh_ack_avail(_rx_ack_avail_dispatcher);
SESSION_RPC_OBJECT::_rx.sigh_ready_to_submit(_rx_ready_to_submit_dispatcher);
}
};
/**
* Root component, handling new session requests
*/
template <typename ROOT_COMPONENT,
typename SESSION_COMPONENT,
typename DEVICE,
Genode::Cache_attribute CACHEABILITY>
class Packet_root : public ROOT_COMPONENT
{
private:
Server::Entrypoint &_ep;
DEVICE &_device;
protected:
/**
* Always returns the singleton block-session component
*/
SESSION_COMPONENT *_create_session(const char *args)
{
using namespace Genode;
size_t ram_quota =
Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
size_t tx_buf_size =
Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
size_t rx_buf_size =
Arg_string::find_arg(args, "rx_buf_size").ulong_value(0);
/* delete ram quota by the memory needed for the session */
size_t session_size = max((size_t)4096,
sizeof(SESSION_COMPONENT)
+ sizeof(Allocator_avl));
if (ram_quota < session_size)
throw Root::Quota_exceeded();
/*
* Check if donated ram quota suffices for both communication
* buffers. Also check both sizes separately to handle a
* possible overflow of the sum of both sizes.
*/
if (tx_buf_size > ram_quota - session_size) {
PERR("insufficient 'ram_quota', got %zd, need %zd",
ram_quota, tx_buf_size + session_size);
throw Root::Quota_exceeded();
}
return new (ROOT_COMPONENT::md_alloc())
SESSION_COMPONENT(Lx::backend_alloc(tx_buf_size, CACHEABILITY),
Lx::backend_alloc(rx_buf_size, CACHEABILITY),
_ep, _device);
}
public:
Packet_root(Server::Entrypoint &ep, Genode::Allocator *md_alloc, DEVICE &device)
: ROOT_COMPONENT(&ep.rpc_ep(), md_alloc),
_ep(ep), _device(device) { }
};
#endif /* _SIGNAL__DISPATCHER_H_ */

View File

@ -0,0 +1,249 @@
/*
* \brief User-level scheduling
* \author Sebastian Sumpf
* \author Josef Soentgen
* \author Christian Helmuth
* \date 2012-04-25
*/
/*
* Copyright (C) 2012-2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _SCHEDULER_H_
#define _SCHEDULER_H_
/* Genode includes */
#include <base/env.h>
#include <base/lock.h>
#include <base/sleep.h>
/* libc includes */
#include <setjmp.h>
/* local includes */
#include <list.h>
namespace Lx {
class Scheduler;
class Task;
Scheduler &scheduler();
};
/**
* Allows pseudo-parallel execution of functions
*/
class Lx::Task : public Lx::List<Lx::Task>::Element
{
public:
/**
* TODO generalize - higher is more important
*/
enum Priority { PRIORITY_0, PRIORITY_1, PRIORITY_2, PRIORITY_3 };
/**
* Runtime state
*
* INIT
* |
* [run]
* v
* BLOCKED <--[block]--- RUNNING ---[mutex_block]--> MUTEX_BLOCKED
* --[unblock]-> <-[mutex_unblock]--
*
* Transitions between BLOCKED and MUTEX_BLOCKED are not possible.
*/
enum State { STATE_INIT, STATE_RUNNING, STATE_BLOCKED, STATE_MUTEX_BLOCKED, STATE_WAIT_BLOCKED };
/**
* List element type
*/
typedef Lx::List_element<Lx::Task> List_element;
/**
* List type
*/
typedef Lx::List<List_element> List;
private:
State _state = STATE_INIT;
/* sub-classes may overwrite the runnable condition */
virtual bool _runnable() const;
void *_stack = nullptr; /* stack pointer */
jmp_buf _env; /* execution state */
jmp_buf _saved_env; /* saved state of thread calling run() */
Priority _priority;
Scheduler &_scheduler; /* scheduler this task is attached to */
void (*_func)(void *); /* function to call*/
void *_arg; /* argument for function */
char const *_name; /* name of task */
List_element _mutex_le { this }; /* list element for mutex_blocked state */
List *_wait_list { 0 };
List_element _wait_le { this };
bool _wait_le_enqueued { false };
public:
Task(void (*func)(void*), void *arg, char const *name,
Priority priority, Scheduler &scheduler);
virtual ~Task();
State state() const { return _state; }
Priority priority() const { return _priority; }
void wait_enqueue(List *list)
{
if (_wait_le_enqueued) {
PERR("%p already queued in %p", this, _wait_list);
Genode::sleep_forever();
}
_wait_le_enqueued = true;
_wait_list = list;
_wait_list->append(&_wait_le);
}
void wait_dequeue(List *list)
{
if (!_wait_le_enqueued) {
PERR("%p not queued", this);
Genode::sleep_forever();
}
if (_wait_list != list) {
PERR("especially not in list %p", list);
Genode::sleep_forever();
}
_wait_list->remove(&_wait_le);
_wait_list = 0;
_wait_le_enqueued = false;
}
/*******************************
** Runtime state transitions **
*******************************/
void block()
{
if (_state == STATE_RUNNING) {
_state = STATE_BLOCKED;
}
}
void unblock()
{
if (_state == STATE_BLOCKED) {
_state = STATE_RUNNING;
}
}
void mutex_block(List *list)
{
if (_state == STATE_RUNNING) {
_state = STATE_MUTEX_BLOCKED;
list->append(&_mutex_le);
}
}
void mutex_unblock(List *list)
{
if (_state == STATE_MUTEX_BLOCKED) {
_state = STATE_RUNNING;
list->remove(&_mutex_le);
}
}
/**
* Run task until next preemption point
*
* \return true if run, false if not runnable
*/
bool run();
/**
* Request scheduling (of other tasks)
*
* Note, this task may not be blocked when calling schedule() depending
* on the use case.
*/
void schedule();
/**
* Shortcut to enter blocking state and request scheduling
*/
void block_and_schedule()
{
block();
schedule();
}
/**
* Return the name of the task (mainly for debugging purposes)
*/
char const *name() { return _name; }
};
/**
* Scheduler
*
* FIXME The old mechanism for removal via check_dead() was removed and has to
* be reimplemented later.
*/
class Lx::Scheduler
{
private:
Lx::List<Lx::Task> _present_list;
Genode::Lock _present_list_mutex;
Task *_current = nullptr; /* currently scheduled task */
bool _run_task(Task *);
public:
Scheduler();
~Scheduler();
/**
* Return currently scheduled task
*/
Task *current();
/**
* Add new task to the present list
*/
void add(Task *);
/**
* Schedule all present tasks
*
* Returns if no task is runnable.
*/
void schedule();
/**
* Log current state of tasks in present list (debug)
*
* Log lines are prefixed with 'prefix'
*/
void log_state(char const *prefix);
};
#endif /* _SCHEDULER_H_ */

View File

@ -0,0 +1,27 @@
/**
* \brief Platform specific code
* \author Sebastian Sumpf
* \date 2012-06-10
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _X86_32__PLATFORM_H_
#define _X86_32__PLATFORM_H_
static inline
void platform_execute(void *sp, void *func, void *arg)
{
asm volatile ("movl %2, 0(%0);"
"movl %1, -0x4(%0);"
"movl %0, %%esp;"
"call *-4(%%esp);"
: : "r" (sp), "r" (func), "r" (arg));
}
#endif /* _X86_32__PLATFORM_H_ */

View File

@ -0,0 +1,27 @@
/**
* \brief Platform specific types
* \author Josef Soentgen
* \date 2014-10-17
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _X86_32__TYPES_H_
#define _X86_32__TYPES_H_
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef __SIZE_TYPE__ size_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#endif /* _X86_32__TYPES_H_ */

View File

@ -0,0 +1,29 @@
/**
* \brief Platform specific code
* \author Sebastian Sumpf
* \author Alexander Boettcher
* \date 2012-06-10
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _X86_64__PLATFORM_H_
#define _X86_64__PLATFORM_H_
static inline
void platform_execute(void *sp, void *func, void *arg)
{
asm volatile ("movq %2, %%rdi;"
"movq %1, 0(%0);"
"movq %0, %%rsp;"
"call *0(%%rsp);"
: "+r" (sp), "+r" (func), "+r" (arg) : : "memory");
}
#endif /* _X86_64__PLATFORM_H_ */

View File

@ -0,0 +1,27 @@
/**
* \brief Platform specific types
* \author Josef Soentgen
* \date 2014-10-17
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _X86_64__TYPES_H_
#define _X86_64__TYPES_H_
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef __SIZE_TYPE__ size_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#endif /* _X86_64__TYPES_H_ */

View File

@ -0,0 +1,157 @@
/*
* \brief Linux wireless stack
* \author Josef Soentgen
* \date 2014-03-03
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <os/config.h>
#include <os/server.h>
/* local includes */
#include <firmware_list.h>
#include <lx.h>
#include <extern_c_begin.h>
# include <lx_emul.h>
#include <extern_c_end.h>
extern "C" void core_netlink_proto_init(void);
extern "C" void core_sock_init(void);
extern "C" void module_packet_init(void);
extern "C" void subsys_genl_init(void);
extern "C" void subsys_rfkill_init(void);
extern "C" void subsys_cfg80211_init(void);
extern "C" void subsys_ieee80211_init(void);
extern "C" void module_iwl_drv_init(void);
extern "C" void subsys_cryptomgr_init(void);
extern "C" void module_crypto_ccm_module_init(void);
extern "C" void module_crypto_ctr_module_init(void);
extern "C" void module_aes_init(void);
extern "C" void module_arc4_init(void);
extern "C" void module_chainiv_module_init(void);
extern "C" void module_krng_mod_init(void);
static bool mac80211_only = false;
struct pernet_operations loopback_net_ops;
struct net init_net;
LIST_HEAD(net_namespace_list);
Firmware_list fw_list[] = {
{ "iwlwifi-1000-3.ucode", 335056 },
{ "iwlwifi-1000-5.ucode", 337520 },
{ "iwlwifi-105-6.ucode", 689680 },
{ "iwlwifi-135-6.ucode", 701228 },
{ "iwlwifi-2000-6.ucode", 695876 },
{ "iwlwifi-2030-6.ucode", 707392 },
{ "iwlwifi-3160-7.ucode", 670484 },
{ "iwlwifi-3160-8.ucode", 667284 },
{ "iwlwifi-3160-9.ucode", 666792 },
{ "iwlwifi-3945-2.ucode", 150100 },
{ "iwlwifi-4965-2.ucode", 187972 },
{ "iwlwifi-5000-1.ucode", 345008 },
{ "iwlwifi-5000-2.ucode", 353240 },
{ "iwlwifi-5000-5.ucode", 340696 },
{ "iwlwifi-5150-2.ucode", 337400 },
{ "iwlwifi-6000-4.ucode", 454608 },
/**
* Actually, there is no -6 firmware. The last one is revision 4,
* but certain devices support up to revision 6 and want to use
* this one. Our fw loading mechanism sadly will not work in this
* case, therefore we add -6 to the fw whitelist have to provide
* a renamed image.
*/
{ "iwlwifi-6000-6.ucode", 454608 }, /* XXX same as -4 */
{ "iwlwifi-6000g2a-5.ucode", 444128 },
{ "iwlwifi-6000g2a-6.ucode", 677296 },
{ "iwlwifi-6000g2b-5.ucode", 460236 },
{ "iwlwifi-6000g2b-6.ucode", 679436 },
{ "iwlwifi-6050-4.ucode", 463692 },
{ "iwlwifi-6050-5.ucode", 469780 },
{ "iwlwifi-7260-7.ucode", 683236 },
{ "iwlwifi-7260-8.ucode", 679780 },
{ "iwlwifi-7260-9.ucode", 679380 },
{ "iwlwifi-7265-8.ucode", 690452 }
};
size_t fw_list_len = sizeof(fw_list) / sizeof(fw_list[0]);
static Genode::Lock *_wpa_lock;
static void run_linux(void *)
{
core_sock_init();
core_netlink_proto_init();
module_packet_init();
subsys_genl_init();
subsys_rfkill_init();
subsys_cfg80211_init();
subsys_ieee80211_init();
subsys_cryptomgr_init();
module_crypto_ccm_module_init();
module_crypto_ctr_module_init();
module_aes_init();
module_arc4_init();
module_chainiv_module_init();
module_krng_mod_init();
if (!mac80211_only) {
module_iwl_drv_init();
}
PINF("+-----------------------+");
PINF("| iwl driver loaded |");
PINF("+-----------------------+");
_wpa_lock->unlock();
while (1) {
Lx::scheduler().current()->block_and_schedule();
}
}
void wifi_init(Server::Entrypoint &ep, Genode::Lock &lock)
{
/**
* For testing testing only the wireless stack with wpa_supplicant,
* amongst other on linux, we do not want to load the iwlwifi drivers.
*/
if (Genode::config()->xml_node().has_attribute("mac80211_only"))
mac80211_only = Genode::config()->xml_node().attribute("mac80211_only").has_value("yes");
if (mac80211_only)
PINF("Initalizing only mac80211 stack without any driver!");
_wpa_lock = &lock;
INIT_LIST_HEAD(&init_net.dev_base_head);
/* add init_net namespace to namespace list */
list_add_tail_rcu(&init_net.list, &net_namespace_list);
Lx::timer_init(ep);
Lx::irq_init(ep);
Lx::work_init(ep);
Lx::socket_init(ep);
Lx::nic_init(ep);
/* Linux task (handles the initialization only currently) */
static Lx::Task linux(run_linux, nullptr, "linux",
Lx::Task::PRIORITY_0, Lx::scheduler());
/* give all task a first kick before returning */
Lx::scheduler().schedule();
}

View File

@ -0,0 +1,340 @@
/*
* \brief Signal context for IRQ's
* \author Josef Soentgen
* \author Christian Helmuth
* \date 2014-10-14
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
#include <base/tslab.h>
#include <timer_session/connection.h>
#include <irq_session/connection.h>
/* local includes */
#include <lx.h>
#include <extern_c_begin.h>
# include <lx_emul.h>
#include <extern_c_end.h>
namespace {
/**
* Helper utilty for composing IRQ related names
*/
struct Name_composer
{
char name[16];
Name_composer(unsigned irq) {
Genode::snprintf(name, sizeof(name), "irq_%02x", irq); }
};
}
/**
* Task for interrupts
*
* Allows flagging of IRQs from other threads.
*/
struct Irq_task
{
private:
Lx::Task _task;
public:
Irq_task(void (*func)(void *), void *args, char const *name)
: _task(func, args, name, Lx::Task::PRIORITY_3, Lx::scheduler()) { }
void unblock() { _task.unblock(); }
char const *name() { return _task.name(); }
};
/**
* This contains the Linux-driver handlers
*/
struct Lx_irq_handler : public Lx::List<Lx_irq_handler>::Element
{
void *dev; /* Linux device */
irq_handler_t handler; /* Linux handler */
irq_handler_t thread_fn; /* Linux thread function */
Lx_irq_handler(void *dev, irq_handler_t handler, irq_handler_t thread_fn)
: dev(dev), handler(handler), thread_fn(thread_fn) { }
};
/**
* IRQ handling thread
*/
template <typename T>
class Irq_thread : public Genode::Thread<1024 * sizeof(Genode::addr_t)>
{
private:
unsigned _irq_number;
Genode::Irq_connection _irq;
bool _enabled;
/* XXX replace by functor? */
T &_obj;
void (T::*_member)(void *);
void *_priv;
public:
Irq_thread(unsigned irq, T &obj, void (T::*member)(void*), void *priv,
char const *name)
:
Thread(name),
_irq_number(irq), _irq(_irq_number), _enabled(false),
_obj(obj), _member(member), _priv(priv)
{
start();
}
void enable() { _enabled = true; }
void entry()
{
while (1) {
_irq.wait_for_irq();
if (_enabled) (_obj.*_member)(_priv);
}
}
};
namespace Lx {
class Irq;
}
static void run_irq(void *args);
/**
* Lx::Irq
*/
class Lx::Irq
{
public:
/**
* Context encapsulates the handling of an IRQ
*/
class Context : public Lx::List<Context>::Element
{
private:
Name_composer _name;
unsigned int _irq; /* IRQ number */
Lx::List<Lx_irq_handler> _handler; /* List of registered handlers */
Irq_task _task;
Irq_thread<Context> _thread;
Genode::Lock _irq_sync { Genode::Lock::LOCKED };
Genode::Signal_transmitter _sender;
Genode::Signal_rpc_member<Context> _dispatcher;
/**
* IRQ handling thread callback
*/
void _handle_irq(void *)
{
_sender.submit();
/* wait for interrupt to get acked at device side */
_irq_sync.lock();
}
/**
* Call one IRQ handler
*/
bool _handle_one(Lx_irq_handler *h)
{
bool handled = false;
/* XXX the handler as well as the thread_fn are called in a synchronouse fashion */
switch (h->handler(_irq, h->dev)) {
case IRQ_WAKE_THREAD:
{
h->thread_fn(_irq, h->dev);
}
case IRQ_HANDLED:
handled = true;
break;
case IRQ_NONE:
break;
}
return handled;
}
/**
* Signal handler
*/
void _handle(unsigned)
{
_task.unblock();
/* kick off scheduling */
Lx::scheduler().schedule();
}
public:
/**
* Constructor
*/
Context(Server::Entrypoint &ep, unsigned irq)
:
_name(irq),
_irq(irq),
_task(run_irq, this, _name.name),
_thread(irq, *this, &Context::_handle_irq, 0, _name.name),
_dispatcher(ep, *this, &Context::_handle)
{
_sender.context(_dispatcher);
_thread.enable();
}
/**
* Return IRQ number
*/
unsigned irq() { return _irq; }
/**
* Handle IRQ
*/
void handle_irq()
{
bool handled = false;
/* report IRQ to all clients */
for (Lx_irq_handler *h = _handler.first(); h; h = h->next()) {
if ((handled = _handle_one(h)))
break;
}
/* interrupt should be acked at device now */
_irq_sync.unlock();
}
/**
* Add linux handler to context
*/
void add_handler(Lx_irq_handler *h) { _handler.append(h); }
};
private:
Server::Entrypoint &_ep;
Lx::List<Context> _list;
Genode::Tslab<Context,
3 * sizeof(Context)> _context_alloc;
Genode::Tslab<Lx_irq_handler,
3 * sizeof(Lx_irq_handler)> _handler_alloc;
/**
* Find context for given IRQ number
*/
Context *_find_context(unsigned int irq)
{
for (Context *i = _list.first(); i; i = i->next())
if (i->irq() == irq)
return i;
return 0;
}
public:
/**
* Constructor
*/
Irq(Server::Entrypoint &ep)
:
_ep(ep),
_context_alloc(Genode::env()->heap()),
_handler_alloc(Genode::env()->heap())
{ }
/**
* Request an IRQ
*/
void request_irq(unsigned int irq, irq_handler_t handler, void *dev,
irq_handler_t thread_fn = 0)
{
Context *ctx = _find_context(irq);
/* if this IRQ is not registered */
if (!ctx)
ctx = new (&_context_alloc) Context(_ep, irq);
/* register Linux handler */
Lx_irq_handler *h = new (&_handler_alloc)
Lx_irq_handler(dev, handler, thread_fn);
ctx->add_handler(h);
}
};
static Lx::Irq *_lx_irq;
void Lx::irq_init(Server::Entrypoint &ep)
{
static Lx::Irq irq_context(ep);
_lx_irq = &irq_context;
}
static void run_irq(void *args)
{
Lx::Irq::Context *ctx = static_cast<Lx::Irq::Context*>(args);
while (1) {
Lx::scheduler().current()->block_and_schedule();
ctx->handle_irq();
}
}
extern "C" {
/***********************
** linux/interrupt.h **
***********************/
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev)
{
_lx_irq->request_irq(irq, handler, dev);
return 0;
}
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
irq_handler_t thread_fn,
unsigned long flags, const char *name,
void *dev)
{
_lx_irq->request_irq(irq, handler, dev, thread_fn);
return 0;
}
} /* extern "C" */

View File

@ -0,0 +1,65 @@
/*
* \brief Lx env
* \author Josef Soentgen
* \date 2014-10-17
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _LX_H_
#define _LX_H_
/* Genode includes */
#include <os/server.h>
/* local includes */
#include <scheduler.h>
#define DEBUG_COMPLETION 0
#define DEBUG_DMA 0
#define DEBUG_DRIVER 0
#define DEBUG_IRQ 0
#define DEBUG_KREF 0
#define DEBUG_PRINTK 1
#define DEBUG_DEV_DBG 1
#define DEBUG_PCI 0
#define DEBUG_SKB 0
#define DEBUG_SLAB 0
#define DEBUG_TIMER 0
#define DEBUG_THREAD 0
#define DEBUG_TRACE 0
#define DEBUG_MUTEX 0
#define DEBUG_SCHEDULING 0
#define DEBUG_WORK 0
namespace Lx
{
void timer_init(Server::Entrypoint &);
void timer_update_jiffies();
void work_init(Server::Entrypoint &);
void socket_init(Server::Entrypoint &);
void nic_init(Server::Entrypoint &);
void irq_init(Server::Entrypoint &);
Genode::Ram_dataspace_capability backend_alloc(Genode::addr_t, Genode::Cache_attribute);
void backend_free(Genode::Ram_dataspace_capability);
void printf(char const *fmt, ...);
void debug_printf(int level, char const *fmt, ...);
void get_mac_address(unsigned char *);
}
#endif /* _LX_H_ */

View File

@ -0,0 +1,128 @@
/**
* \brief Linux emulation code
* \author Josef Soentgen
* \date 2014-03-07
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <asm-generic/atomic64.h>
#include <linux/netdevice.h>
#include <net/sock.h>
/****************************
** asm-generic/getorder.h **
****************************/
int get_order(unsigned long size)
{
int order;
size--;
size >>= PAGE_SHIFT;
order = __builtin_ctzl(size);
return order;
}
/****************************
** asm-generic/atomic64.h **
****************************/
/**
* This is not atomic on 32bit systems but this is not a problem
* because we will not be preempted.
*/
long long atomic64_add_return(long long i, atomic64_t *p)
{
p->counter += i;
return p->counter;
}
/**********************************
** linux/bitops.h, asm/bitops.h **
**********************************/
unsigned int hweight32(unsigned int w)
{
w -= (w >> 1) & 0x55555555;
w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
w = (w + (w >> 4)) & 0x0f0f0f0f;
return (w * 0x01010101) >> 24;
}
/*****************************
** linux/platform_device.h **
*****************************/
int platform_device_add_resources(struct platform_device *pdev,
const struct resource *res, unsigned int num)
{
if (!res || !num) {
pdev->resource = NULL;
pdev->num_resources = 0;
}
struct resource *r = NULL;
if (res) {
r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
if (!r)
return -ENOMEM;
}
kfree(pdev->resource);
pdev->resource = r;
pdev->num_resources = num;
return 0;
}
struct platform_device *platform_device_register_simple(const char *name, int id,
const struct resource *res,
unsigned int num)
{
struct platform_device *pdev = kzalloc(sizeof (struct platform_device), GFP_KERNEL);
if (!pdev)
return 0;
size_t len = strlen(name);
pdev->name = kzalloc(len + 1, GFP_KERNEL);
if (!pdev->name)
goto pdev_out;
memcpy(pdev->name, name, len);
pdev->name[len] = 0;
pdev->id = id;
int err = platform_device_add_resources(pdev, res, num);
if (err)
goto pdev_name_out;
return pdev;
pdev_name_out:
kfree(pdev->name);
pdev_out:
kfree(pdev);
return 0;
}
/***********************
** linux/netdevice.h **
***********************/
void netdev_run_todo() {
__rtnl_unlock();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,585 @@
/*
* \brief Glue code for Linux network drivers
* \author Sebastian Sumpf
* \author Josef Soentgen
* \date 2012-07-05
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/rpc_server.h>
#include <base/snprintf.h>
#include <cap_session/connection.h>
#include <nic/xml_node.h>
#include <nic_session/nic_session.h>
#include <os/config.h>
#include <util/xml_node.h>
/* local includes */
#include <lx.h>
#include <nic/component.h>
#include <extern_c_begin.h>
# include <lx_emul.h>
# include <net/cfg80211.h>
#include <extern_c_end.h>
enum {
HEAD_ROOM = 128, /* XXX guessed value but works */
};
/**
* Net_device to session glue code
*/
class Nic_device : public Nic::Device
{
public: /* FIXME */
struct net_device *_ndev;
Nic::Session_component *_session = nullptr;
bool _has_link = false;
public:
Nic_device(struct net_device *ndev) : _ndev(ndev) { }
void rx(sk_buff *skb)
{
/* get mac header back */
skb_push(skb, ETH_HLEN);
void *packet = skb->data;
size_t packet_size = ETH_HLEN;
void *frag = 0;
size_t frag_size = 0;
/**
* If received packets are too large (as of now 128 bytes) the actually
* payload is put into a fragment. Otherwise the payload is stored directly
* in the sk_buff.
*/
if (skb_shinfo(skb)->nr_frags) {
if (skb_shinfo(skb)->nr_frags > 1)
PERR("more than 1 fragment in skb");
skb_frag_t *f = &skb_shinfo(skb)->frags[0];
frag = skb_frag_address(f);
frag_size = skb_frag_size(f);
}
else
packet_size += skb->len;
_session->rx((Genode::addr_t)packet, packet_size, (Genode::addr_t)frag, frag_size);
}
/**
* Report link state
*/
void link_state(bool link)
{
/* only report changes of the link state */
if (link == _has_link)
return;
_has_link = link;
if (_session)
_session->link_state_changed();
}
/**********************
** Device interface **
**********************/
void session(Nic::Session_component *s) override { _session = s; }
Nic::Mac_address mac_address() override
{
Nic::Mac_address m;
Genode::memcpy(&m, _ndev->perm_addr, ETH_ALEN);
return m;
}
bool link_state() override { return _has_link; }
bool tx(Genode::addr_t virt, Genode::size_t size) override
{
struct sk_buff *skb = ::alloc_skb(size + HEAD_ROOM, GFP_KERNEL);
skb_reserve(skb, HEAD_ROOM);
unsigned char *data = skb_put(skb, size);
Genode::memcpy(data, (void*)virt, size);
_ndev->netdev_ops->ndo_start_xmit(skb, _ndev);
return true;
}
};
static Nic_device *_nic = 0;
static Server::Entrypoint *_ep;
void Lx::nic_init(Server::Entrypoint &ep) {
_ep = &ep; }
void Lx::get_mac_address(unsigned char *addr)
{
Genode::memcpy(addr, _nic->_ndev->perm_addr, ETH_ALEN);
}
namespace Lx {
class Notifier;
}
class Lx::Notifier
{
private:
struct Block : public Genode::List<Block>::Element
{
struct notifier_block *nb;
Block(struct notifier_block *nb) : nb(nb) { }
};
Lx::List<Block> _list;
Genode::Tslab<Block, 32 * sizeof(Block)> _block_alloc;
public:
Notifier() : _block_alloc(Genode::env()->heap()) { }
void register_block(struct notifier_block *nb)
{
Block *b = new (&_block_alloc) Block(nb);
_list.insert(b);
}
void unregister_block(struct notifier_block *nb)
{
for (Block *b = _list.first(); b; b = b->next())
if (b->nb == nb) {
_list.remove(b);
destroy(&_block_alloc, b);
break;
}
}
int call_all_blocks(unsigned long val, void *v)
{
int rv = NOTIFY_DONE;
for (Block *b = _list.first(); b; b = b->next()) {
rv = b->nb->notifier_call(b->nb, val, v);
if (rv & NOTIFY_STOP_MASK)
break;
}
return rv;
}
};
/* XXX move blocking_notifier_call to proper location */
/**********************
** linux/notifier.h **
**********************/
static Lx::Notifier &blocking_notifier()
{
static Lx::Notifier inst;
return inst;
}
int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
struct notifier_block *nb)
{
blocking_notifier().register_block(nb);
return 0;
}
int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
struct notifier_block *nb)
{
blocking_notifier().unregister_block(nb);
return 0;
}
int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
unsigned long val, void *v)
{
return blocking_notifier().call_all_blocks(val, v);
}
/***********************
** linux/netdevice.h **
***********************/
static Lx::Notifier &net_notifier()
{
static Lx::Notifier inst;
return inst;
}
extern "C" int register_netdevice_notifier(struct notifier_block *nb)
{
/**
* In Linux the nb is actually called upon on registration. We do not
* that semantic because we add a net_device only after all notifiers
* were registered.
*/
net_notifier().register_block(nb);
return 0;
}
extern "C" int unregster_netdevice_notifier(struct notifier_block *nb)
{
net_notifier().unregister_block(nb);
return 0;
}
extern "C" struct net_device * netdev_notifier_info_to_dev(struct netdev_notifier_info *info)
{
/* we always pass a net_device pointer to this function */
return reinterpret_cast<net_device *>(info);
}
struct Proto_hook : public Lx::List<Proto_hook>::Element
{
struct packet_type &pt;
Proto_hook(struct packet_type *pt) : pt(*pt) { }
};
class Proto_hook_list
{
private:
Lx::List<Proto_hook> _list;
Genode::Allocator &_alloc;
public:
Proto_hook_list(Genode::Allocator &alloc) : _alloc(alloc) { }
void insert(struct packet_type *pt) {
_list.insert(new (&_alloc) Proto_hook(pt)); }
void remove(struct packet_type *pt)
{
for (Proto_hook *ph = _list.first(); ph; ph = ph->next())
if (&ph->pt == pt) {
_list.remove(ph);
destroy(&_alloc, ph);
break;
}
}
Proto_hook* first() { return _list.first(); }
};
static Proto_hook_list& proto_hook_list()
{
static Proto_hook_list inst(*Genode::env()->heap());
return inst;
}
extern "C" void dev_add_pack(struct packet_type *pt)
{
proto_hook_list().insert(pt);
}
extern "C" void __dev_remove_pack(struct packet_type *pt)
{
proto_hook_list().remove(pt);
}
extern "C" struct net_device *__dev_get_by_index(struct net *net, int ifindex)
{
if (!_nic || !_nic->_ndev) {
PERR("no net device registered!");
return 0;
}
return _nic->_ndev;
}
extern "C" struct net_device *dev_get_by_index(struct net *net, int ifindex)
{
return __dev_get_by_index(net, ifindex);
}
extern "C" int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *daddr,
const void *saddr, unsigned int len)
{
if (!dev->header_ops || !dev->header_ops->create)
return 0;
return dev->header_ops->create(skb, dev, type, daddr, saddr, len);
}
extern "C" int dev_parse_header(const struct sk_buff *skb, unsigned char *haddr)
{
struct net_device const *dev = skb->dev;
if (!dev->header_ops || dev->header_ops->parse)
return 0;
return dev->header_ops->parse(skb, haddr);
}
extern "C" int dev_queue_xmit(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
struct net_device_ops const *ops = dev->netdev_ops;
int rv = NETDEV_TX_OK;
if (skb->next)
PWRN("more skb's queued");
rv = ops->ndo_start_xmit(skb, dev);
return rv;
}
extern "C" size_t LL_RESERVED_SPACE(struct net_device *dev)
{
return dev->hard_header_len ?
(dev->hard_header_len + (HH_DATA_MOD - 1)) & ~(HH_DATA_MOD - 1) : 0;
}
extern "C" int register_netdevice(struct net_device *ndev)
{
static bool already_registered = false;
if (already_registered) {
PERR("We don't support multiple network devices in one driver instance");
return -ENODEV;
}
static Nic_device nic_device(ndev);
static Nic::Root nic_root(*_ep, Genode::env()->heap(), nic_device);
/*
* XXX This is just a starting point for removing all the static stuff from
* this file...
*/
ndev->lx_nic_device = (void *)&nic_device;
_nic = &nic_device;
already_registered = true;
ndev->state |= 1UL << __LINK_STATE_START;
netif_carrier_off(ndev);
/* execute all notifier blocks */
net_notifier().call_all_blocks(NETDEV_REGISTER, ndev);
net_notifier().call_all_blocks(NETDEV_UP, ndev);
ndev->ifindex = 1;
/* set mac adress */
Genode::memcpy(ndev->perm_addr, ndev->ieee80211_ptr->wiphy->perm_addr, ETH_ALEN);
int err = ndev->netdev_ops->ndo_open(ndev);
if (err) {
PERR("ndev->netdev_ops->ndo_open(ndev): %d", err);
return err;
}
if (ndev->netdev_ops->ndo_set_rx_mode)
ndev->netdev_ops->ndo_set_rx_mode(ndev);
Genode::env()->parent()->announce(_ep->rpc_ep().manage(&nic_root));
list_add_tail_rcu(&ndev->dev_list, &init_net.dev_base_head);
return 0;
}
extern "C" int netif_running(const struct net_device *dev)
{
return dev->state & (1UL << __LINK_STATE_START);
}
extern "C" int netif_device_present(struct net_device *dev) { return 1; }
extern "C" int netif_carrier_ok(const struct net_device *dev)
{
return !(dev->state & (1UL << __LINK_STATE_NOCARRIER));
}
extern "C" void netif_carrier_on(struct net_device *dev)
{
dev->state &= ~(1UL << __LINK_STATE_NOCARRIER);
Nic_device *nic = (Nic_device *)dev->lx_nic_device;
nic->link_state(true);
}
extern "C" void netif_carrier_off(struct net_device *dev)
{
if (!dev)
PERR("!dev %p", __builtin_return_address(0));
dev->state |= 1UL << __LINK_STATE_NOCARRIER;
Nic_device *nic = (Nic_device *)dev->lx_nic_device;
nic->link_state(false);
}
extern "C" int netif_receive_skb(struct sk_buff *skb)
{
/**
* XXX check original linux implementation if it is really
* necessary to free the skb if it was not handled.
*/
/* send EAPOL related frames only to the wpa_supplicant */
if (ntohs(skb->protocol) == ETH_P_PAE) {
/* XXX call only AF_PACKET hook */
for (Proto_hook* ph = proto_hook_list().first(); ph; ph = ph->next()) {
ph->pt.func(skb, _nic->_ndev, &ph->pt, _nic->_ndev);
}
return NET_RX_SUCCESS;
}
if (_nic && _nic->_session) {
_nic->rx(skb);
}
dev_kfree_skb(skb);
return NET_RX_SUCCESS;
}
extern "C" u16 netdev_cap_txqueue(struct net_device *dev, u16 queue_index)
{
if (queue_index > dev-> real_num_tx_queues) {
PERR("error: queue_index %d out of range (%d max) called from: %p",
queue_index, dev->real_num_tx_queues, __builtin_return_address(0));
return 0;
}
return queue_index;
}
extern "C" struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
void (*setup)(struct net_device *),
unsigned int txqs, unsigned int rxqs)
{
struct net_device *dev;
size_t alloc_size;
struct net_device *p;
alloc_size = ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
/* ensure 32-byte alignment of whole construct */
alloc_size += NETDEV_ALIGN - 1;
p = (net_device *)kzalloc(alloc_size, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
if (!p)
return NULL;
dev = PTR_ALIGN(p, NETDEV_ALIGN);
dev->gso_max_size = GSO_MAX_SIZE;
dev->gso_max_segs = GSO_MAX_SEGS;
setup(dev);
/* actually set by dev_open() */
dev->flags |= IFF_UP;
/* XXX our dev is always called wlan0 */
strcpy(dev->name, "wlan0");
dev->dev_addr = (unsigned char *)kzalloc(ETH_ALEN, GFP_KERNEL);
if (!dev->dev_addr)
return 0;
if (sizeof_priv) {
/* ensure 32-byte alignment of private area */
dev->priv = kzalloc(sizeof_priv, GFP_KERNEL);
if (!dev->priv)
return 0;
}
dev->num_tx_queues = txqs;
dev->real_num_tx_queues = txqs;
struct netdev_queue *tx = (struct netdev_queue*)
kcalloc(txqs, sizeof(struct netdev_queue),
GFP_KERNEL | GFP_LX_DMA);
if (!tx) {
PERR("could not allocate ndev_queues");
}
dev->_tx = tx;
for (unsigned i = 0; i < txqs; i++) {
tx[i].dev = dev;
tx[i].numa_node = NUMA_NO_NODE;
}
return dev;
}
/**********************
** linux/inerrupt.h **
**********************/
/*************************
** linux/etherdevice.h **
*************************/
int is_valid_ether_addr(const u8 *addr)
{
/* is multicast */
if ((addr[0] & 0x1))
return 0;
/* zero */
if (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]))
return 0;
return 1;
}

View File

@ -0,0 +1,477 @@
/*
* \brief Emulate 'pci_dev' structure
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
* \author Josef Soentgen
* \date 2012-04-02
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode inludes */
#include <ram_session/client.h>
#include <base/object_pool.h>
#include <pci_session/connection.h>
#include <pci_device/client.h>
#include <io_mem_session/connection.h>
/* local includes */
#include <lx.h>
#include <extern_c_begin.h>
# include <lx_emul.h>
#include <extern_c_end.h>
static bool const verbose = false;
#define PDBGV(...) do { if (verbose) PDBG(__VA_ARGS__); } while (0)
struct bus_type pci_bus_type;
/**
* Scan PCI bus and probe for HCDs
*/
class Pci_driver
{
private:
pci_driver *_drv; /* Linux PCI driver */
Pci::Device_capability _cap; /* PCI cap */
pci_device_id const *_id; /* matched id for this driver */
public:
pci_dev *_dev; /* Linux PCI device */
private:
/* offset used in PCI config space */
enum Pci_config { IRQ = 0x3c, REV = 0x8, CMD = 0x4,
STATUS = 0x4, CAP = 0x34 };
enum Pci_cap { CAP_LIST = 0x10, CAP_EXP = 0x10,
CAP_EXP_FLAGS = 0x2, CAP_EXP_DEVCAP = 0x4 };
/**
* Fill Linux device informations
*/
bool _setup_pci_device()
{
using namespace Pci;
Device_client client(_cap);
if (client.device_id() != _id->device)
return false;
_dev = new (Genode::env()->heap()) pci_dev;
_dev->vendor = client.vendor_id();
_dev->device = client.device_id();
_dev->class_ = client.class_code();
_dev->revision = client.config_read(REV, Device::ACCESS_8BIT);
_dev->dev.driver = &_drv->driver;
/* dummy dma mask used to mark device as DMA capable */
static u64 dma_mask = ~(u64)0;
_dev->dev.dma_mask = &dma_mask;
_dev->dev.coherent_dma_mask = ~0;
/* read interrupt line */
_dev->irq = client.config_read(IRQ, Device::ACCESS_8BIT);
/* hide ourselfs in bus structure */
_dev->bus = (struct pci_bus *)this;
/* setup resources */
bool io = false;
for (int i = 0; i < Device::NUM_RESOURCES; i++) {
Device::Resource res = client.resource(i);
if (res.type() == Device::Resource::INVALID)
continue;
_dev->resource[i].start = res.base();
_dev->resource[i].end = res.base() + res.size() - 1;
_dev->resource[i].flags = res.type() == Device::Resource::IO
? IORESOURCE_IO : 0;
PDBGV("base: %x size: %x type: %u",
res.base(), res.size(), res.type());
/* request I/O memory (write combined) */
if (res.type() == Device::Resource::MEMORY)
PDBGV("I/O memory [%x-%x)", res.base(),
res.base() + res.size());
}
/* enable bus master and io bits */
uint16_t cmd = client.config_read(CMD, Device::ACCESS_16BIT);
cmd |= io ? 0x1 : 0;
/* enable bus master */
cmd |= 0x4;
client.config_write(CMD, cmd, Device::ACCESS_16BIT);
/* get pci express capability */
_dev->pcie_cap = 0;
uint16_t status = client.config_read(STATUS, Device::ACCESS_32BIT) >> 16;
if (status & CAP_LIST) {
uint8_t offset = client.config_read(CAP, Device::ACCESS_8BIT);
while (offset != 0x00) {
uint8_t value = client.config_read(offset, Device::ACCESS_8BIT);
if (value == CAP_EXP)
_dev->pcie_cap = offset;
offset = client.config_read(offset + 1, Device::ACCESS_8BIT);
}
}
if (_dev->pcie_cap) {
uint16_t reg_val = client.config_read(_dev->pcie_cap, Device::ACCESS_16BIT);
_dev->pcie_flags_reg = reg_val;
}
return true;
}
/**
* Probe device with driver
*/
bool _probe()
{
/* only probe if the device matches */
if (!_setup_pci_device())
return false;
/* PDBG("probe: %p 0x%x", _dev, _id); */
if (!_drv->probe(_dev, _id)) {
return true;
}
return false;
}
template <typename T>
Pci::Device::Access_size _access_size(T t)
{
switch (sizeof(T))
{
case 1:
return Pci::Device::ACCESS_8BIT;
case 2:
return Pci::Device::ACCESS_16BIT;
default:
return Pci::Device::ACCESS_32BIT;
}
}
public:
Pci_driver(pci_driver *drv, Pci::Device_capability cap,
pci_device_id const * id)
: _drv(drv), _cap(cap), _id(id), _dev(0)
{
if (!_probe())
throw -1;
}
~Pci_driver()
{
if (!_dev)
return;
destroy(Genode::env()->heap(), _dev);
}
/**
* Read/write data from/to config space
*/
template <typename T>
void config_read(unsigned int devfn, T *val)
{
Pci::Device_client client(_cap);
*val = client.config_read(devfn, _access_size(*val));
}
template <typename T>
void config_write(unsigned int devfn, T val)
{
Pci::Device_client client(_cap);
client.config_write(devfn, val, _access_size(val));
}
};
/********************************
** Backend memory definitions **
********************************/
struct Memory_object_base : Genode::Object_pool<Memory_object_base>::Entry
{
Memory_object_base(Genode::Ram_dataspace_capability cap)
: Genode::Object_pool<Memory_object_base>::Entry(cap) {}
virtual ~Memory_object_base() {};
virtual void free() = 0;
Genode::Ram_dataspace_capability ram_cap()
{
using namespace Genode;
return reinterpret_cap_cast<Ram_dataspace>(cap());
}
};
struct Ram_object : Memory_object_base
{
Ram_object(Genode::Ram_dataspace_capability cap)
: Memory_object_base(cap) {}
void free();
};
struct Dma_object : Memory_object_base
{
Dma_object(Genode::Ram_dataspace_capability cap)
: Memory_object_base(cap) {}
void free();
};
/*********************
** Linux interface **
*********************/
static Pci::Device_capability pci_device_cap;
static Pci::Connection *pci()
{
static Pci::Connection _pci;
return &_pci;
}
static Genode::Object_pool<Memory_object_base> memory_pool;
extern "C" int pci_register_driver(struct pci_driver *drv)
{
drv->driver.name = drv->name;
pci_device_id const *id = drv->id_table;
if (!id)
return -ENODEV;
using namespace Genode;
unsigned found = 0;
while (id->device) {
if (id->class_ == (unsigned)PCI_ANY_ID) {
id++;
continue;
}
Pci::Device_capability cap = pci()->first_device(id->class_,
id->class_mask);
while (cap.valid()) {
Pci_driver *pci_drv = 0;
try {
/*
* Assign cap already here, since for probing already DMA
* buffer is required and allocated by
* Genode::Mem::alloc_dma_buffer(size_t size)
*/
pci_device_cap = cap;
/* trigger that the device get be assigned to the wifi driver */
pci()->config_extended(cap);
/* probe device */
pci_drv = new (env()->heap()) Pci_driver(drv, cap, id);
pci()->on_destruction(Pci::Connection::KEEP_OPEN);
found++;
} catch (...) {
destroy(env()->heap(), pci_drv);
pci_drv = 0;
}
if (found)
break;
Pci::Device_capability free_up = cap;
cap = pci()->next_device(cap, id->class_, id->class_mask);
if (!pci_drv)
pci()->release_device(free_up);
}
id++;
/* XXX */
if (found)
break;
}
return found ? 0 : -ENODEV;
}
extern "C" size_t pci_resource_start(struct pci_dev *dev, unsigned bar)
{
if (bar >= DEVICE_COUNT_RESOURCE)
return 0;
return dev->resource[bar].start;
}
extern "C" size_t pci_resource_len(struct pci_dev *dev, unsigned bar)
{
size_t start = pci_resource_start(dev, bar);
if (!start)
return 0;
return (dev->resource[bar].end - start) + 1;
}
extern "C" void *pci_ioremap_bar(struct pci_dev *dev, int bar)
{
using namespace Genode;
size_t start = pci_resource_start(dev, bar);
size_t size = pci_resource_len(dev, bar);
if (!start)
return 0;
Io_mem_connection *io_mem;
try {
io_mem = new (env()->heap()) Io_mem_connection(start, size, 0);
} catch (...) {
PERR("Failed to request I/O memory: [%zx,%lx)", start, start + size);
return 0;
}
if (!io_mem->dataspace().valid()) {
PERR("I/O memory not accessible");
return 0;
}
addr_t map_addr = env()->rm_session()->attach(io_mem->dataspace());
map_addr |= start & 0xfff;
return (void*)map_addr;
}
extern "C" unsigned int pci_resource_flags(struct pci_dev *dev, unsigned bar)
{
if (bar >= DEVICE_COUNT_RESOURCE)
return 0;
return dev->resource[bar].flags;
}
extern "C" int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int, int where, u8 *val)
{
Pci_driver *drv = (Pci_driver *)bus;
drv->config_read(where, val);
return 0;
}
extern "C" int pci_bus_read_config_word(struct pci_bus *bus, unsigned int, int where, u16 *val)
{
Pci_driver *drv = (Pci_driver *)bus;
drv->config_read(where, val);
return 0;
}
extern "C" int pci_bus_write_config_word(struct pci_bus *bus, unsigned int, int where, u16 val)
{
Pci_driver *drv = (Pci_driver *)bus;
drv->config_write(where, val);
return 0;
}
extern "C" int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int, int where, u8 val)
{
Pci_driver *drv = (Pci_driver *)bus;
drv->config_write(where, val);
return 0;
}
extern "C" const char *pci_name(const struct pci_dev *pdev)
{
/* simply return driver name */
return "dummy";
}
extern "C" int pcie_capability_read_word(struct pci_dev *pdev, int pos, u16 *val)
{
Pci_driver *drv = (Pci_driver *)pdev->bus;
switch (pos) {
case PCI_EXP_LNKCTL:
drv->config_read(pdev->pcie_cap + PCI_EXP_LNKCTL, val);
return 0;
break;
default:
break;
}
return 1;
}
void Ram_object::free() { Genode::env()->ram_session()->free(ram_cap()); }
void Dma_object::free() { pci()->free_dma_buffer(pci_device_cap, ram_cap()); }
Genode::Ram_dataspace_capability
Lx::backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached)
{
using namespace Genode;
Memory_object_base *o;
Genode::Ram_dataspace_capability cap;
if (cached == CACHED) {
cap = env()->ram_session()->alloc(size);
o = new (env()->heap()) Ram_object(cap);
} else {
cap = pci()->alloc_dma_buffer(pci_device_cap, size);
o = new (env()->heap()) Dma_object(cap);
}
memory_pool.insert(o);
return cap;
}
void Lx::backend_free(Genode::Ram_dataspace_capability cap)
{
using namespace Genode;
Memory_object_base *o = memory_pool.lookup_and_lock(cap);
if (!o)
return;
o->free();
memory_pool.remove_locked(o);
destroy(env()->heap(), o);
}

View File

@ -0,0 +1,262 @@
/*
* \brief User-level scheduling
* \author Sebastian Sumpf
* \author Josef Soentgen
* \author Christian Helmuth
* \date 2012-04-25
*
* We use a pseudo-thread implementation based on setjmp/longjmp.
*/
/*
* Copyright (C) 2012-2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/sleep.h>
/* local includes */
#include <lx.h>
#include <platform/platform.h>
#include <scheduler.h>
#define PDBGV(...) \
do { if (DEBUG_SCHEDULING) PDBG(__VA_ARGS__); } while (0)
/**********
** Task **
**********/
bool Lx::Task::_runnable() const
{
switch (_state) {
case STATE_INIT: return true;
case STATE_RUNNING: return true;
case STATE_BLOCKED: return false;
case STATE_MUTEX_BLOCKED: return false;
case STATE_WAIT_BLOCKED: return false;
}
PERR("state %d not handled by switch", _state);
Genode::sleep_forever();
}
bool Lx::Task::run()
{
if (!_runnable())
return false;
/*
* Save the execution environment. The scheduled task returns to this point
* after execution, i.e., at the next preemption point.
*/
if (_setjmp(_saved_env))
return true;
if (_state == STATE_INIT) {
/* setup execution environment and call task's function */
_state = STATE_RUNNING;
Genode::Thread_base *th = Genode::Thread_base::myself();
enum { STACK_SIZE = 32 * 1024 }; /* FIXME make stack size configurable */
_stack = th->alloc_secondary_stack(_name, STACK_SIZE);
/* switch stack and call '_func(_arg)' */
platform_execute(_stack, (void *)_func, _arg);
} else {
/* restore execution environment */
_longjmp(_env, 1);
}
/* never reached */
PERR("Unexpected return of Task");
Genode::sleep_forever();
}
void Lx::Task::schedule()
{
/*
* Save the execution environment. The task will resume from here on next
* schedule.
*/
if (_setjmp(_env)) {
return;
}
/* return to thread calling run() */
_longjmp(_saved_env, 1);
}
Lx::Task::Task(void (*func)(void*), void *arg, char const *name,
Priority priority, Scheduler &scheduler)
:
_priority(priority), _scheduler(scheduler),
_func(func), _arg(arg), _name(name)
{
scheduler.add(this);
PDBGV("name: '%s' func: %p arg: %p prio: %u t: %p", name, func, arg, priority, this);
}
Lx::Task::~Task()
{
// scheduler.remove(this);
if (_stack)
Genode::Thread_base::myself()->free_secondary_stack(_stack);
}
/***************
** Scheduler **
***************/
Lx::Scheduler & Lx::scheduler()
{
static Lx::Scheduler inst;
return inst;
}
Lx::Task *Lx::Scheduler::current()
{
if (!_current) {
PERR("BUG: _current is zero!");
Genode::sleep_forever();
}
return _current;
}
void Lx::Scheduler::add(Task *task)
{
Lx::Task *p = _present_list.first();
for ( ; p; p = p->next()) {
if (p->priority() <= task->priority()) {
_present_list.insert_before(task, p);
break;
}
}
if (!p)
_present_list.append(task);
}
void Lx::Scheduler::schedule()
{
bool at_least_one = false;
/*
* Iterate over all tasks and run first runnable.
*
* (1) If one runnable tasks was run start over from beginning of
* list.
*
* (2) If no task is runnable quit scheduling (break endless
* loop).
*/
while (true) {
/* update jiffies before running task */
Lx::timer_update_jiffies();
bool was_run = false;
for (Task *t = _present_list.first(); t; t = t->next()) {
/* update current before running task */
_current = t;
if ((was_run = t->run())) {
at_least_one = true;
break;
}
}
if (!was_run)
break;
}
if (!at_least_one) {
PWRN("schedule() called without runnable tasks");
log_state("SCHEDULE");
}
/* clear current as no task is running */
_current = nullptr;
}
#include <timer_session/connection.h>
namespace {
struct Logger : Genode::Thread<0x4000>
{
Timer::Connection _timer;
Lx::Scheduler &_scheduler;
unsigned const _interval;
Logger(Lx::Scheduler &scheduler, unsigned interval_seconds)
:
Genode::Thread<0x4000>("logger"),
_scheduler(scheduler), _interval(interval_seconds)
{
start();
}
void entry()
{
PWRN("Scheduler::Logger is up");
_timer.msleep(1000 * _interval);
while (true) {
_scheduler.log_state("LOGGER");
_timer.msleep(2000);
}
}
};
}
#define ANSI_ESC_RESET "\033[00m"
#define ANSI_ESC_BLACK "\033[30m"
#define ANSI_ESC_RED "\033[31m"
#define ANSI_ESC_YELLOW "\033[33m"
static char const *state_color(Lx::Task::State state)
{
switch (state) {
case Lx::Task::STATE_INIT: return ANSI_ESC_RESET;
case Lx::Task::STATE_RUNNING: return ANSI_ESC_RED;
case Lx::Task::STATE_BLOCKED: return ANSI_ESC_YELLOW;
case Lx::Task::STATE_MUTEX_BLOCKED: return ANSI_ESC_YELLOW;
case Lx::Task::STATE_WAIT_BLOCKED: return ANSI_ESC_YELLOW;
}
return ANSI_ESC_BLACK;
}
void Lx::Scheduler::log_state(char const *prefix)
{
unsigned i;
Lx::Task *t;
for (i = 0, t = _present_list.first(); t; t = t->next(), ++i) {
Genode::printf("%s [%u] prio: %u state: %s%u" ANSI_ESC_RESET " %s\n",
prefix, i, t->priority(), state_color(t->state()),
t->state(), t->name());
}
}
Lx::Scheduler::Scheduler()
{
if (DEBUG_SCHEDULING)
new (Genode::env()->heap()) Logger(*this, 10);
}
Lx::Scheduler::~Scheduler() { }

View File

@ -0,0 +1,110 @@
/**
* \brief Linux emulation code
* \author Sebastian Sumpf
* \date 2014-03-07
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <linux/netdevice.h>
#include <net/sock.h>
/****************
** net/sock.h **
****************/
static const struct net_proto_family *net_families[NPROTO];
int sock_register(const struct net_proto_family *ops)
{
if (ops->family >= NPROTO) {
printk("protocol %d >= NPROTO (%d)\n", ops->family, NPROTO);
return -ENOBUFS;
}
net_families[ops->family] = ops;
pr_info("NET: Registered protocol family %d\n", ops->family);
return 0;
}
struct socket *sock_alloc(void)
{
return (struct socket *)kmalloc(sizeof(struct socket), 0);
}
int sock_create_lite(int family, int type, int protocol, struct socket **res)
{
struct socket *sock = sock_alloc();
if (!sock)
return -ENOMEM;
sock->type = type;
*res = sock;
return 0;
}
int sock_create_kern(int family, int type, int proto,
struct socket **res)
{
struct socket *sock;
const struct net_proto_family *pf;
int err;
if (family < 0 || family > NPROTO)
return -EAFNOSUPPORT;
if (type < 0 || type > SOCK_MAX)
return -EINVAL;
pf = net_families[family];
if (!pf) {
printk("No protocol found for family %d\n", family);
return -ENOPROTOOPT;
}
if (!(sock = (struct socket *)kzalloc(sizeof(struct socket), 0))) {
printk("Could not allocate socket\n");
return -ENFILE;
}
sock->type = type;
err = pf->create(&init_net, sock, proto, 1);
if (err) {
kfree(sock);
return err;
}
*res = sock;
return 0;
}
void log_sock(struct socket *socket)
{
printk("\nNEW socket %p sk %p fsk %lx &sk %p &fsk %p\n\n",
socket, socket->sk, socket->flags, &socket->sk, &socket->flags);
}
static void sock_init(void)
{
skb_init();
}
core_initcall(sock_init);

View File

@ -0,0 +1,634 @@
/**
* \brief Linux emulation code
* \author Josef Soentgen
* \date 2014-08-04
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
/* local includes */
#include <lx.h>
#include <extern_c_begin.h>
# include <lx_emul.h>
# include <linux/socket.h>
# include <linux/net.h>
# include <net/sock.h>
#include <extern_c_end.h>
#include <wifi/socket_call.h>
static void run_socketcall(void *);
/* XXX move Wifi::Socket definition to better location */
struct Wifi::Socket
{
void *socket = nullptr;
bool non_block = false;
Socket() { }
explicit Socket(void *s) : socket(s) { }
};
struct Call
{
enum Opcode {
NONE, SOCKET, CLOSE,
BIND, GETSOCKNAME, RECVMSG, SENDMSG, SENDTO, SETSOCKOPT,
GET_MAC_ADDRESS, POLL_ALL, NON_BLOCK,
};
Opcode opcode = NONE;
Wifi::Socket *handle = nullptr;
union {
struct
{
int domain;
int type;
int protocol;
void *result;
} socket;
struct { /* no args */ } close;
struct
{
sockaddr const *addr;
int addrlen;
} bind;
struct
{
sockaddr *addr;
int *addrlen;
} getsockname;
struct
{
msghdr msg;
int flags;
iovec iov[Wifi::Msghdr::MAX_IOV_LEN];
} recvmsg;
struct
{
msghdr msg;
int flags;
iovec iov[Wifi::Msghdr::MAX_IOV_LEN];
} sendmsg;
struct {
int level;
int optname;
void const *optval;
uint32_t optlen;
} setsockopt;
struct
{
unsigned char *addr;
} get_mac_address;
struct
{
Wifi::Poll_socket_fd *sockets;
unsigned num;
int timeout;
} poll_all;
struct
{
bool value;
} non_block;
};
int err = 0;
};
static Call _call;
static Genode::Semaphore _block;
namespace Lx {
class Socket;
}
/**
* Context for socket calls
*/
class Lx::Socket
{
private:
Genode::Signal_transmitter _sender;
Genode::Signal_rpc_member<Lx::Socket> _dispatcher;
Lx::Task _task;
struct socket *_call_socket()
{
struct socket *sock = static_cast<struct socket*>(_call.handle->socket);
if (!sock)
PERR("BUG: sock is zero");
return sock;
}
void _do_socket()
{
struct socket *s;
int res = sock_create_kern(_call.socket.domain, _call.socket.type,
_call.socket.protocol, &s);
if (!res) {
_call.socket.result = s;
_call.err = 0;
return;
}
PERR("sock_create_kern failed, res: %d", res);
_call.socket.result = nullptr;
_call.err = res;
}
void _do_close()
{
struct socket *sock = _call_socket();
_call.err = sock->ops->release(sock);
}
void _do_bind()
{
struct socket *sock = _call_socket();
_call.err = sock->ops->bind(sock,
const_cast<struct sockaddr *>(_call.bind.addr),
_call.bind.addrlen);
}
void _do_getsockname()
{
struct socket *sock = _call_socket();
int addrlen = *_call.getsockname.addrlen;
_call.err = sock->ops->getname(sock, _call.getsockname.addr, &addrlen, 0);
*_call.getsockname.addrlen = addrlen;
}
void _do_recvmsg()
{
struct socket *sock = _call_socket();
struct msghdr *msg = &_call.recvmsg.msg;
/* needed by AF_NETLINK */
struct sock_iocb siocb;
Genode::memset(&siocb, 0, sizeof(struct sock_iocb));
struct kiocb kiocb;
Genode::memset(&kiocb, 0, sizeof(struct kiocb));
kiocb.private_ = &siocb;
if (_call.handle->non_block)
msg->msg_flags |= MSG_DONTWAIT;
size_t iovlen = 0;
for (size_t i = 0; i < msg->msg_iovlen; i++)
iovlen += msg->msg_iov[i].iov_len;
_call.err = sock->ops->recvmsg(&kiocb, sock, msg, iovlen, _call.recvmsg.flags);
}
void _do_sendmsg()
{
struct socket *sock = _call_socket();
struct msghdr *msg = const_cast<msghdr *>(&_call.sendmsg.msg);
/* needed by AF_NETLINK */
struct sock_iocb siocb;
Genode::memset(&siocb, 0, sizeof(struct sock_iocb));
struct kiocb kiocb;
Genode::memset(&kiocb, 0, sizeof(struct kiocb));
kiocb.private_ = &siocb;
if (_call.handle->non_block)
msg->msg_flags |= MSG_DONTWAIT;
size_t iovlen = 0;
for (size_t i = 0; i < msg->msg_iovlen; i++)
iovlen += msg->msg_iov[i].iov_len;
_call.err = sock->ops->sendmsg(&kiocb, sock, msg, iovlen);
}
void _do_setsockopt()
{
struct socket *sock = _call_socket();
/* taken from kernel_setsockopt() in net/socket.c */
if (_call.setsockopt.level == SOL_SOCKET)
_call.err = sock_setsockopt(sock,
_call.setsockopt.level,
_call.setsockopt.optname,
(char *)_call.setsockopt.optval,
_call.setsockopt.optlen);
else
_call.err = sock->ops->setsockopt(sock,
_call.setsockopt.level,
_call.setsockopt.optname,
(char *)_call.setsockopt.optval,
_call.setsockopt.optlen);
}
void _do_get_mac_address()
{
Lx::get_mac_address(_call.get_mac_address.addr);
}
void _do_poll_all()
{
Wifi::Poll_socket_fd *sockets = _call.poll_all.sockets;
unsigned num = _call.poll_all.num;
int timeout = _call.poll_all.timeout;
enum {
POLLIN_SET = (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR),
POLLOUT_SET = (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR),
POLLEX_SET = (POLLPRI)
};
int nready = 0;
bool timeout_triggered = false;
bool woken_up = false;
do {
/**
* Timeout was triggered, exit early.
*/
if (timeout_triggered)
break;
/**
* Poll each socket and check if there is something of interest.
*/
for (unsigned i = 0; i < num; i++) {
struct socket *sock = static_cast<struct socket*>(sockets[i].s->socket);
int mask = sock->ops->poll(0, sock, 0);
sockets[i].revents = 0;
if (mask & POLLIN_SET)
sockets[i].revents |= sockets[i].events & Wifi::WIFI_POLLIN ? Wifi::WIFI_POLLIN : 0;
if (mask & POLLOUT_SET)
sockets[i].revents |= sockets[i].events & Wifi::WIFI_POLLOUT ? Wifi::WIFI_POLLOUT : 0;
if (mask & POLLEX_SET)
sockets[i].revents |= sockets[i].events & Wifi::WIFI_POLLEX ? Wifi::WIFI_POLLEX : 0;
if (sockets[i].revents)
nready++;
}
/**
* We were woken up but there is still nothing of interest.
*/
if (woken_up)
break;
/**
* Exit the loop if either a socket is ready or there is
* no timeout given.
*/
if (nready || !timeout)
break;
/**
* In case of a timeout add all sockets to an artificial wait list
* so at least one is woken up an sk_data_ready() call.
*/
Lx::Task *task = Lx::scheduler().current();
struct socket_wq wq[num];
Lx::Task::List wait_list;
task->wait_enqueue(&wait_list);
for (unsigned i = 0; i < num; i++) {
struct socket *sock = static_cast<struct socket*>(sockets[i].s->socket);
wq[i].wait.list = &wait_list;
sock->sk->sk_wq = &wq[i];
}
long t = jiffies + msecs_to_jiffies(timeout);
timeout_triggered = !schedule_timeout(t);
task->wait_dequeue(&wait_list);
for (unsigned i = 0; i < num; i++) {
struct socket *sock = static_cast<struct socket*>(sockets[i].s->socket);
sock->sk->sk_wq = 0;
}
woken_up = true;
} while (1);
_call.err = nready;
}
void _do_non_block()
{
_call.handle->non_block = _call.non_block.value;
}
void _handle(unsigned)
{
_task.unblock();
Lx::scheduler().schedule();
}
public:
Socket(Server::Entrypoint &ep)
:
_dispatcher(ep, *this, &Lx::Socket::_handle),
_task(run_socketcall, nullptr, "socketcall",
Lx::Task::PRIORITY_0, Lx::scheduler())
{
_sender.context(_dispatcher);
}
void exec_call()
{
switch (_call.opcode) {
case Call::BIND: _do_bind(); break;
case Call::CLOSE: _do_close(); break;
case Call::GETSOCKNAME: _do_getsockname(); break;
case Call::POLL_ALL: _do_poll_all(); break;
case Call::RECVMSG: _do_recvmsg(); break;
case Call::SENDMSG: _do_sendmsg(); break;
case Call::SETSOCKOPT: _do_setsockopt(); break;
case Call::SOCKET: _do_socket(); break;
case Call::GET_MAC_ADDRESS: _do_get_mac_address(); break;
case Call::NON_BLOCK: _do_non_block(); break;
default:
_call.err = -EINVAL;
PWRN("unknown opcode: %u", _call.opcode);
break;
}
_call.opcode = Call::NONE;
_block.up();
}
void submit_and_block()
{
_sender.submit();
_block.down();
}
};
static Lx::Socket *_socket;
void Lx::socket_init(Server::Entrypoint &ep)
{
static Lx::Socket socket_ctx(ep);
_socket = &socket_ctx;
}
static void run_socketcall(void *)
{
while (1) {
Lx::scheduler().current()->block_and_schedule();
_socket->exec_call();
}
}
/**************************
** Socket_call instance **
**************************/
Wifi::Socket_call socket_call;
/***************************
** Socket_call interface **
***************************/
using namespace Wifi;
Wifi::Socket *Socket_call::socket(int domain, int type, int protocol)
{
/* FIXME domain, type, protocol values */
_call.opcode = Call::SOCKET;
_call.socket.domain = domain;
_call.socket.type = type;
_call.socket.protocol = protocol;
_socket->submit_and_block();
if (_call.socket.result == 0)
return 0;
Wifi::Socket *s = new (Genode::env()->heap()) Wifi::Socket(_call.socket.result);
return s;
}
int Socket_call::close(Socket *s)
{
_call.opcode = Call::CLOSE;
_call.handle = s;
_socket->submit_and_block();
if (_call.err)
PWRN("error %d on close()", _call.err);
destroy(Genode::env()->heap(), s);
return 0;
}
int Socket_call::bind(Socket *s, Wifi::Sockaddr const *addr, unsigned addrlen)
{
/* FIXME convert to/from Sockaddr */
_call.opcode = Call::BIND;
_call.handle = s;
_call.bind.addr = (sockaddr const *)addr;
_call.bind.addrlen = addrlen;
_socket->submit_and_block();
return _call.err;
}
int Socket_call::getsockname(Socket *s, Wifi::Sockaddr *addr, unsigned *addrlen)
{
/* FIXME convert to/from Sockaddr */
/* FIXME unsigned * -> int * */
_call.opcode = Call::GETSOCKNAME;
_call.handle = s;
_call.getsockname.addr = (sockaddr *)addr;
_call.getsockname.addrlen = (int *)addrlen;
_socket->submit_and_block();
return _call.err;
}
int Socket_call::poll_all(Poll_socket_fd *s, unsigned num, int timeout)
{
_call.opcode = Call::POLL_ALL;
_call.handle = 0;
_call.poll_all.sockets = s;
_call.poll_all.num = num;
_call.poll_all.timeout = timeout;
_socket->submit_and_block();
return _call.err;
}
static int msg_flags(Wifi::Flags in)
{
int out = Wifi::WIFI_F_NONE;
if (in & Wifi::WIFI_F_MSG_ERRQUEUE)
out |= MSG_ERRQUEUE;
return out;
};
Wifi::ssize_t Socket_call::recvmsg(Socket *s, Wifi::Msghdr *msg, Wifi::Flags flags)
{
_call.opcode = Call::RECVMSG;
_call.handle = s;
_call.recvmsg.msg.msg_name = msg->msg_name;
_call.recvmsg.msg.msg_namelen = msg->msg_namelen;
_call.recvmsg.msg.msg_iov = _call.recvmsg.iov;
_call.recvmsg.msg.msg_iovlen = msg->msg_iovlen;
_call.recvmsg.msg.msg_control = msg->msg_control;
_call.recvmsg.msg.msg_controllen = msg->msg_controllen;
_call.recvmsg.flags = msg_flags(flags);
for (unsigned i = 0; i < msg->msg_iovlen; ++i) {
_call.recvmsg.iov[i].iov_base = msg->msg_iov[i].iov_base;
_call.recvmsg.iov[i].iov_len = msg->msg_iov[i].iov_len;
}
_socket->submit_and_block();
msg->msg_namelen = _call.recvmsg.msg.msg_namelen;
return _call.err;
}
Wifi::ssize_t Socket_call::sendmsg(Socket *s, Wifi::Msghdr const *msg, Wifi::Flags flags)
{
_call.opcode = Call::SENDMSG;
_call.handle = s;
_call.sendmsg.msg.msg_name = msg->msg_name;
_call.sendmsg.msg.msg_namelen = msg->msg_namelen;
_call.sendmsg.msg.msg_iov = _call.sendmsg.iov;
_call.sendmsg.msg.msg_iovlen = msg->msg_iovlen;
_call.sendmsg.msg.msg_control = 0;
_call.sendmsg.msg.msg_controllen = 0;
_call.sendmsg.flags = msg_flags(flags);
for (unsigned i = 0; i < msg->msg_iovlen; ++i) {
_call.sendmsg.iov[i].iov_base = msg->msg_iov[i].iov_base;
_call.sendmsg.iov[i].iov_len = msg->msg_iov[i].iov_len;
}
_socket->submit_and_block();
return _call.err;
}
static int sockopt_level(Sockopt_level const in)
{
switch (in) {
case Wifi::WIFI_SOL_SOCKET: return SOL_SOCKET;
case Wifi::WIFI_SOL_NETLINK: return SOL_NETLINK;
}
return -1;
}
static int sockopt_name(Sockopt_level const level, Sockopt_name const in)
{
switch (level) {
case Wifi::WIFI_SOL_SOCKET:
switch (in) {
case Wifi::WIFI_SO_SNDBUF: return SO_SNDBUF;
case Wifi::WIFI_SO_RCVBUF: return SO_RCVBUF;
case Wifi::WIFI_SO_PASSCRED: return SO_PASSCRED;
case Wifi::WIFI_SO_WIFI_STATUS: return SO_WIFI_STATUS;
default: return -1;
}
case Wifi::WIFI_SOL_NETLINK:
switch (in) {
case Wifi::WIFI_NETLINK_ADD_MEMBERSHIP: return NETLINK_ADD_MEMBERSHIP;
case Wifi::WIFI_NETLINK_DROP_MEMBERSHIP: return NETLINK_DROP_MEMBERSHIP;
case Wifi::WIFI_NETLINK_PKTINFO: return NETLINK_PKTINFO;
default: return -1;
}
}
return -1;
}
int Socket_call::setsockopt(Socket *s,
Wifi::Sockopt_level level, Wifi::Sockopt_name optname,
const void *optval, uint32_t optlen)
{
/* FIXME optval values */
_call.opcode = Call::SETSOCKOPT;
_call.handle = s;
_call.setsockopt.level = sockopt_level(level);
_call.setsockopt.optname = sockopt_name(level, optname);
_call.setsockopt.optval = optval;
_call.setsockopt.optlen = optlen;
_socket->submit_and_block();
return _call.err;
}
void Socket_call::non_block(Socket *s, bool value)
{
_call.opcode = Call::NON_BLOCK;
_call.handle = s;
_call.non_block.value = value;
_socket->submit_and_block();
}
void Socket_call::get_mac_address(unsigned char *addr)
{
_call.opcode = Call::GET_MAC_ADDRESS;
_call.handle = 0;
_call.get_mac_address.addr = addr;
_socket->submit_and_block();
}

View File

@ -0,0 +1,20 @@
/*
*
*/
{
global:
/* initialize function */
_*wifi_init*;
/* Wifi::Socket_call interface */
*Socket_call*;
/* Wifi::Socket_call instance */
socket_call;
/* used by libnl's time() */
jiffies;
local:
*;
};

View File

@ -0,0 +1,347 @@
/*
* \brief Signal context for timer events
* \author Josef Soentgen
* \date 2014-10-10
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/env.h>
#include <base/heap.h>
#include <base/printf.h>
#include <base/tslab.h>
#include <timer_session/connection.h>
/* local includes */
#include <list.h>
#include <lx.h>
#include <extern_c_begin.h>
# include <lx_emul.h>
#include <extern_c_end.h>
unsigned long jiffies;
static void run_timer(void*);
namespace Lx {
class Timer;
}
/**
* Lx::Timer
*/
class Lx::Timer
{
public:
/**
* Context encapsulates a regular linux timer_list
*/
struct Context : public Lx::List<Context>::Element
{
enum { INVALID_TIMEOUT = ~0UL };
struct timer_list *timer;
bool pending { false };
unsigned long timeout { INVALID_TIMEOUT }; /* absolute in jiffies */
bool programmed { false };
Context(struct timer_list *timer) : timer(timer) { }
};
private:
::Timer::Connection _timer_conn;
Lx::List<Context> _list;
Lx::Task _timer_task;
Genode::Signal_rpc_member<Lx::Timer> _dispatcher;
Genode::Tslab<Context, 32 * sizeof(Context)> _timer_alloc;
/**
* Lookup local timer
*/
Context *_find_context(struct timer_list const *timer)
{
for (Context *c = _list.first(); c; c = c->next())
if (c->timer == timer)
return c;
return 0;
}
/**
* Program the first timer in the list
*/
void _program_first_timer()
{
Context *ctx = _list.first();
if (!ctx)
return;
if (!ctx->programmed) {
ctx->programmed = true;
/* calculate relative microseconds for trigger */
unsigned long us = ctx->timeout > jiffies ?
jiffies_to_msecs(ctx->timeout - jiffies) * 1000 : 0;
_timer_conn.trigger_once(us);
}
}
/**
* Schedule timer
*/
void _schedule_timer(Context *ctx, unsigned long expires)
{
_list.remove(ctx);
ctx->timeout = expires;
ctx->pending = true;
Context *c = _list.first();
do {
if (!c) {
_list.insert(ctx);
break;
}
if (ctx->timeout < c->timeout) {
_list.insert_before(ctx, c);
break;
}
c = c->next();
} while (c);
_program_first_timer();
}
/**
* Handle trigger_once signal
*/
void _handle(unsigned)
{
_timer_task.unblock();
Lx::scheduler().schedule();
}
public:
/**
* Constructor
*/
Timer(Server::Entrypoint &ep)
:
_timer_task(run_timer, nullptr, "timer", Lx::Task::PRIORITY_2,
Lx::scheduler()),
_dispatcher(ep, *this, &Lx::Timer::_handle),
_timer_alloc(Genode::env()->heap())
{
_timer_conn.sigh(_dispatcher);
}
/**
* Add new linux timer
*/
void add(struct timer_list *timer)
{
Context *t = new (&_timer_alloc) Context(timer);
_list.append(t);
}
/**
* Delete linux timer
*/
int del(struct timer_list *timer)
{
Context *ctx = _find_context(timer);
/**
* If the timer expired it was already cleaned up after its
* execution.
*/
if (!ctx)
return 0;
int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0;
_list.remove(ctx);
destroy(&_timer_alloc, ctx);
return rv;
}
/**
* Initial scheduling of linux timer
*/
int schedule(struct timer_list *timer, unsigned long expires)
{
Context *ctx = _find_context(timer);
if (!ctx) {
PERR("schedule unknown timer %p", timer);
return -1; /* XXX better use 0 as rv? */
}
/*
* If timer was already active return 1, otherwise 0. The return
* value is needed by mod_timer().
*/
int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0;
_schedule_timer(ctx, expires);
return rv;
}
/**
* Schedule next linux timer
*/
void schedule_next() { _program_first_timer(); }
/**
* Check if the timer is currently pending
*/
bool pending(struct timer_list const *timer)
{
Context *ctx = _find_context(timer);
if (!ctx) {
return false;
}
return ctx->pending;
}
Context *find(struct timer_list const *timer) {
return _find_context(timer); }
/**
* Update jiffie counter
*/
void update_jiffies()
{
jiffies = msecs_to_jiffies(_timer_conn.elapsed_ms());
}
/**
* Get first timer context
*/
Context* first() { return _list.first(); }
};
static Lx::Timer *_lx_timer;
void Lx::timer_init(Server::Entrypoint &ep)
{
/* XXX safer way preventing possible nullptr access? */
static Lx::Timer lx_timer(ep);
_lx_timer = &lx_timer;
/* initialize value explicitly */
jiffies = 0UL;
}
void Lx::timer_update_jiffies() {
_lx_timer->update_jiffies(); }
static void run_timer(void *)
{
while (1) {
Lx::scheduler().current()->block_and_schedule();
while (Lx::Timer::Context *ctx = _lx_timer->first()) {
if (ctx->timeout > jiffies)
break;
ctx->timer->function(ctx->timer->data);
_lx_timer->del(ctx->timer);
}
_lx_timer->schedule_next();
}
}
/*******************
** linux/timer.h **
*******************/
void init_timer(struct timer_list *timer) { }
int mod_timer(struct timer_list *timer, unsigned long expires)
{
if (!_lx_timer->find(timer))
_lx_timer->add(timer);
return _lx_timer->schedule(timer, expires);
}
void setup_timer(struct timer_list *timer,void (*function)(unsigned long),
unsigned long data)
{
timer->function = function;
timer->data = data;
init_timer(timer);
}
int timer_pending(const struct timer_list *timer)
{
bool pending = _lx_timer->pending(timer);
return pending;
}
int del_timer(struct timer_list *timer)
{
int rv = _lx_timer->del(timer);
_lx_timer->schedule_next();
return rv;
}
/*******************
** linux/sched.h **
*******************/
static void unblock_task(unsigned long task)
{
Lx::Task *t = (Lx::Task *)task;
t->unblock();
}
signed long schedule_timeout(signed long timeout)
{
long start = jiffies;
struct timer_list timer;
setup_timer(&timer, unblock_task, (unsigned long)Lx::scheduler().current());
mod_timer(&timer, timeout);
Lx::scheduler().current()->block_and_schedule();
del_timer(&timer);
timeout -= (jiffies - start);
return timeout < 0 ? 0 : timeout;
}

View File

@ -0,0 +1,281 @@
/*
* \brief Workqueue implementation
* \author Josef Soentgen
* \date 2014-10-14
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/sleep.h>
#include <base/tslab.h>
#include <util/fifo.h>
/* local includes */
#include <lx.h>
#include <extern_c_begin.h>
# include <lx_emul.h>
#include <extern_c_end.h>
static void run_work(void *);
static void run_delayed_work(void *);
namespace Lx {
class Work;
}
/**
* Lx::Work
*/
class Lx::Work
{
public:
/**
* Context encapsulates a normal work item
*/
struct Context : public Lx::List<Context>::Element
{
void *work;
enum Type { NORMAL, DELAYED, TASKLET } type;
void exec() {
switch (type) {
case NORMAL:
{
work_struct *w = static_cast<work_struct *>(work);
w->func(w);
}
break;
case DELAYED:
{
delayed_work *w = static_cast<delayed_work *>(work);
w->work.func(&(w)->work);
}
break;
case TASKLET:
{
tasklet_struct *tasklet = static_cast<tasklet_struct *>(work);
tasklet->func(tasklet->data);
}
break;
}
}
Context(delayed_work *w) : work(w), type(DELAYED) { }
Context(work_struct *w) : work(w), type(NORMAL) { }
Context(tasklet_struct *w) : work(w), type(TASKLET) { }
};
private:
Lx::Task _task;
Lx::List<Context> _list;
Genode::Tslab<Context, 64 * sizeof(Context)> _work_alloc;
public:
Work(void (*func)(void*), char const *name)
:
_task(func, nullptr, name, Lx::Task::PRIORITY_2, Lx::scheduler()),
_work_alloc(Genode::env()->heap())
{ }
/**
* Unblock corresponding task
*/
void unblock() { _task.unblock(); }
/**
* Schedule work item
*/
template <typename WORK>
void schedule(WORK *work)
{
Context *c = new (&_work_alloc) Context(work);
_list.append(c);
}
/**
* Execute all available work items
*/
void exec()
{
while (Context *c = _list.first()) {
c->exec();
_list.remove(c);
destroy(&_work_alloc, c);
}
}
/**
* Cancel work item
*/
bool cancel_work(struct work_struct *work, bool sync = false)
{
for (Context *c = _list.first(); c; c = c->next()) {
if (c->work == work) {
if (sync)
c->exec();
_list.remove(c);
destroy(&_work_alloc, c);
return true;
}
}
return false;
}
};
static Lx::Work *_lx_work;
static Lx::Work *_lx_delayed_work;
void Lx::work_init(Server::Entrypoint &ep)
{
static Lx::Work work_ctx(run_work, "work");
_lx_work = &work_ctx;
static Lx::Work delayed_work_ctx(run_delayed_work, "delayed_work");
_lx_delayed_work = &delayed_work_ctx;
}
static void run_work(void *)
{
while (1) {
Lx::scheduler().current()->block_and_schedule();
_lx_work->exec();
}
}
static void run_delayed_work(void *)
{
while (1) {
Lx::scheduler().current()->block_and_schedule();
_lx_delayed_work->exec();
}
}
extern "C" {
/***********************
** linux/workquque.h **
***********************/
int schedule_delayed_work(struct delayed_work *work, unsigned long delay)
{
_lx_delayed_work->schedule(work);
_lx_delayed_work->unblock();
return 0;
}
int schedule_work(struct work_struct *work)
{
_lx_work->schedule(work);
_lx_work->unblock();
return 1;
}
bool cancel_delayed_work(struct delayed_work *dwork)
{
int pending = timer_pending(&dwork->timer);
del_timer(&dwork->timer);
/* if the timer is still pending dwork was not executed */
return pending;
}
bool cancel_delayed_work_sync(struct delayed_work *dwork)
{
bool pending = cancel_delayed_work(dwork);
if (pending) {
PERR("WARN: delayed_work %p is executed directly in current '%s' routine",
dwork, Lx::scheduler().current()->name());
dwork->work.func(&dwork->work);
}
return pending;
}
static void execute_delayed_work(unsigned long dwork)
{
_lx_delayed_work->schedule((struct delayed_work *)dwork);
_lx_delayed_work->unblock();
}
bool queue_delayed_work(struct workqueue_struct *wq,
struct delayed_work *dwork, unsigned long delay)
{
/* treat delayed work without delay like any other work */
if (delay == 0) {
execute_delayed_work((unsigned long)dwork);
} else {
setup_timer(&dwork->timer, execute_delayed_work, (unsigned long)dwork);
mod_timer(&dwork->timer, delay);
}
return true;
}
bool cancel_work_sync(struct work_struct *work)
{
return _lx_work->cancel_work(work, true);
}
bool queue_work(struct workqueue_struct *wq, struct work_struct *work)
{
_lx_work->schedule(work);
_lx_work->unblock();
return true;
}
/***********************
** linux/interrupt.h **
***********************/
void tasklet_init(struct tasklet_struct *t, void (*f)(unsigned long), unsigned long d)
{
t->func = f;
t->data = d;
}
void tasklet_schedule(struct tasklet_struct *tasklet)
{
_lx_work->schedule(tasklet);
}
void tasklet_hi_schedule(struct tasklet_struct *tasklet)
{
tasklet_schedule(tasklet);
}
} /* extern "C" */

View File

@ -0,0 +1,53 @@
/**
* \brief Dummy functions
* \author Josef Soentgen
* \date 2014-10-02
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
extern "C" {
typedef long DUMMY;
enum {
SHOW_DUMMY = 0,
SHOW_SKIP = 0,
SHOW_RET = 0,
};
#define DUMMY(retval, name) \
DUMMY name(void) { \
if (SHOW_DUMMY) \
PDBG( #name " called (from %p) not implemented", __builtin_return_address(0)); \
return retval; \
}
#define DUMMY_SKIP(retval, name) \
DUMMY name(void) { \
if (SHOW_SKIP) \
PLOG( #name " called (from %p) skipped", __builtin_return_address(0)); \
return retval; \
}
#define DUMMY_RET(retval, name) \
DUMMY name(void) { \
if (SHOW_RET) \
PWRN( #name " called (from %p) return %d", __builtin_return_address(0), retval); \
return retval; \
}
DUMMY(0, getprotobyname)
DUMMY(0, getprotobynumber)
DUMMY(0, nl_addr_get_binary_addr)
DUMMY(0, nl_addr_get_len)
DUMMY(0, nl_hash_any)
DUMMY(0, rint)
} /* extern "C" */

View File

@ -0,0 +1,232 @@
#ifndef _LX_USER_EMUL_H_
#define _LX_USER_EMUL_H_
/**************************
** asm-generic/socket.h **
**************************/
/* enum { */
/* SOL_SOCKET = 1, */
/* }; */
enum {
SO_PRIORITY = 12,
SO_ATTACH_FILTER = 26,
};
/*******************
** bits/ioctls.h **
*******************/
enum {
/* SIOCGIFFLAGS = 0x8913, */
/* SIOCSIFFLAGS = 0x8914, */
/* SIOCGIFADDR = 0x8915, */
SIOCSIFHWADDR = 0x8924,
SIOCGIFHWADDR = 0x8927,
/* SIOCGIFINDEX = 0x8933, */
};
/*******************
** bits/socket.h **
*******************/
enum {
PF_NETLINK = 16,
PF_PACKET = 17,
};
enum {
MSG_ERRQUEUE = 0x2000,
};
enum {
SOL_PACKET = 263,
};
/******************
** bits/types.h **
******************/
typedef char *__caddr_t;
/********************
** linux/socket.h **
********************/
enum {
AF_BRIDGE = 7,
AF_NETLINK = 16,
AF_PACKET = 17,
};
/**********************
** linux/errqueue.h **
**********************/
struct sock_extended_err
{
unsigned int ee_errno;
unsigned char ee_origin;
unsigned char ee_type;
unsigned char ee_code;
unsigned char ee_pad;
unsigned int ee_info;
unsigned int ee_data;
};
/********************
** linux/filter.h **
********************/
enum {
BPF_LD = 0x00,
BPF_ALU = 0x04,
BPF_JMP = 0x05,
BPF_RET = 0x06,
BPF_MISC = 0x07,
BPF_W = 0x00,
BPF_H = 0x08,
BPF_B = 0x10,
BPF_IND = 0x40,
BPF_LEN = 0x80,
BPF_ADD = 0x00,
BPF_OR = 0x40,
BPF_AND = 0x50,
BPF_LSH = 0x60,
BPF_RSH = 0x70,
BPF_JA = 0x00,
BPF_JEQ = 0x10,
BPF_K = 0x00,
BPF_X = 0x08,
BPF_ABS = 0x20,
BPF_TAX = 0x00,
};
#define BPF_CLASS(code) ((code) & 0x07)
#ifndef BPF_STMT
#define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k }
#endif
#ifndef BPF_JUMP
#define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k }
#endif
struct sock_filter
{
unsigned short code;
unsigned char jt;
unsigned char jf;
unsigned int k;
};
struct sock_fprog
{
unsigned short len;
struct sock_filter *filter;
};
/***********************
** linux/if_packet.h **
***********************/
struct sockaddr_ll {
unsigned short sll_family;
unsigned short sll_protocol; /* BE 16b */
int sll_ifindex;
unsigned short sll_hatype;
unsigned char sll_pkttype;
unsigned char sll_halen;
unsigned char sll_addr[8];
};
/**************
** net/if.h **
**************/
enum {
IFF_UP = 0x01,
IFF_RUNNING = 0x40,
};
struct ifmap
{
unsigned long int mem_start;
unsigned long int mem_end;
unsigned short int base_addr;
unsigned char irq;
unsigned char dma;
unsigned char port;
/* 3 bytes spare */
};
struct ifreq
{
#define IFHWADDRLEN 6
#define IF_NAMESIZE 16
#define IFNAMSIZ IF_NAMESIZE
union
{
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
} ifr_ifrn;
union
{
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short int ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
__caddr_t ifru_data;
} ifr_ifru;
#define ifr_name ifr_ifrn.ifrn_name /* interface name */
#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
#define ifr_addr ifr_ifru.ifru_addr /* address */
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
#define ifr_metric ifr_ifru.ifru_ivalue /* metric */
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
#define ifr_map ifr_ifru.ifru_map /* device map */
#define ifr_slave ifr_ifru.ifru_slave /* slave device */
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
#define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
#define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
#define ifr_qlen ifr_ifru.ifru_ivalue /* Queue length */
#define ifr_newname ifr_ifru.ifru_newname /* New name */
#define ifr_settings ifr_ifru.ifru_settings /* Device/proto settings*/
};
unsigned int if_nametoindex(const char *ifname);
char *if_indextoname(unsigned int ifindex, char *ifname);
/******************
** net/if_arp.h **
******************/
enum {
ARPHRD_ETHER = 1,
};
#endif /* _LX_USER_EMUL_H_ */

View File

@ -0,0 +1 @@
../lx_user_emul.h

View File

@ -0,0 +1 @@
../lx_user_emul.h

View File

@ -0,0 +1 @@
../lx_user_emul.h

View File

@ -0,0 +1,100 @@
/**
* \brief Ioctl functions
* \author Josef Soentgen
* \date 2014-10-02
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
/* libc includes */
#include <sys/sockio.h>
#include <sys/socket.h>
/* local includes */
#include <wifi/socket_call.h>
#include <lx_user_emul.h>
extern Wifi::Socket_call socket_call;
extern "C" {
int ioctl(int fd, unsigned long request, ...)
{
long arg;
va_list ap;
va_start(ap, request);
arg = va_arg(ap, long);
va_end(ap);
struct ifreq *ifr = (struct ifreq *)(arg);
switch (request) {
case SIOCGIFADDR:
PERR("ioctl: request SIOCGIFADDR not implemented.");
return -1;
case SIOCGIFINDEX:
ifr->ifr_ifindex = 1;
return 0;
case SIOCGIFHWADDR:
socket_call.get_mac_address((unsigned char*)ifr->ifr_hwaddr.sa_data);
return 0;
}
PWRN("ioctl: request %lu not handled by switch", request);
return -1;
}
int linux_set_iface_flags(int sock, const char *ifname, int dev_up)
{
return 0;
}
int linux_iface_up(int sock, const char *ifname)
{
/* in our case the interface is by definition always up */
return 1;
}
int linux_get_ifhwaddr(int sock, const char *ifname, unsigned char *addr)
{
socket_call.get_mac_address(addr);
return 0;
}
int linux_set_ifhwaddr(int sock, const char *ifname, const unsigned char *addr)
{
return -1;
}
int linux_br_add(int sock, const char *brname) { return -1; }
int linux_br_del(int sock, const char *brname) { return -1; }
int linux_br_add_if(int sock, const char *brname, const char *ifname) {
return -1; }
int linux_br_del_if(int sock, const char *brname, const char *ifname) {
return -1; }
int linux_br_get(char *brname, const char *ifname) { return -1; }
} /* extern "C" */

View File

@ -0,0 +1,18 @@
/*
*
*/
{
global:
/* array containing all drivers, from drivers.c */
wpa_drivers;
/* ethernet frame handlin, from l2_packet_linux.c */
l2_packet_*;
poll;
local:
*;
};

View File

@ -0,0 +1,43 @@
/*
* WPA Supplicant / Example program entrypoint
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "includes.h"
#include "common.h"
#include "wpa_supplicant_i.h"
int wpa_main()
{
struct wpa_interface iface;
int exitcode = 0;
struct wpa_params params;
struct wpa_global *global;
memset(&params, 0, sizeof(params));
params.wpa_debug_level = MSG_INFO;
global = wpa_supplicant_init(&params);
if (global == NULL)
return -1;
memset(&iface, 0, sizeof(iface));
iface.ifname = "wlan0";
iface.confname = "/wpa_supplicant.conf";
if (wpa_supplicant_add_iface(global, &iface) == NULL)
exitcode = -1;
if (exitcode == 0)
exitcode = wpa_supplicant_run(global);
wpa_supplicant_deinit(global);
return exitcode;
}

View File

@ -0,0 +1,23 @@
/*
*
*/
{
global:
/* needed by wifi_drv */
wpa_main;
/* needed by wpa_driver_nl80211 */
__hide_aliasing_typecast;
eloop_*;
get_hdr_bssid;
ieee80211_freq_to_chan;
ieee80211_radiotap_*;
os_*;
wpa_*;
wpabuf_*;
local:
*;
};

330
repos/dde_linux/wifi.list Normal file
View File

@ -0,0 +1,330 @@
linux-3.14.5/crypto/ablkcipher.c
linux-3.14.5/crypto/aead.c
linux-3.14.5/crypto/aes_generic.c
linux-3.14.5/crypto/algapi.c
linux-3.14.5/crypto/algboss.c
linux-3.14.5/crypto/api.c
linux-3.14.5/crypto/arc4.c
linux-3.14.5/crypto/blkcipher.c
linux-3.14.5/crypto/ccm.c
linux-3.14.5/crypto/chainiv.c
linux-3.14.5/crypto/cipher.c
linux-3.14.5/crypto/compress.c
linux-3.14.5/crypto/crypto_wq.c
linux-3.14.5/crypto/ctr.c
linux-3.14.5/crypto/internal.h
linux-3.14.5/crypto/krng.c
linux-3.14.5/crypto/memneq.c
linux-3.14.5/crypto/rng.c
linux-3.14.5/crypto/scatterwalk.c
linux-3.14.5/drivers/leds/led-class.c
linux-3.14.5/drivers/leds/led-core.c
linux-3.14.5/drivers/leds/led-triggers.c
linux-3.14.5/drivers/leds/leds.h
linux-3.14.5/drivers/net/wireless/iwlegacy/3945-mac.c
linux-3.14.5/drivers/net/wireless/iwlegacy/3945-rs.c
linux-3.14.5/drivers/net/wireless/iwlegacy/3945.c
linux-3.14.5/drivers/net/wireless/iwlegacy/3945.h
linux-3.14.5/drivers/net/wireless/iwlegacy/4965-calib.c
linux-3.14.5/drivers/net/wireless/iwlegacy/4965-mac.c
linux-3.14.5/drivers/net/wireless/iwlegacy/4965-rs.c
linux-3.14.5/drivers/net/wireless/iwlegacy/4965.c
linux-3.14.5/drivers/net/wireless/iwlegacy/4965.h
linux-3.14.5/drivers/net/wireless/iwlegacy/commands.h
linux-3.14.5/drivers/net/wireless/iwlegacy/common.c
linux-3.14.5/drivers/net/wireless/iwlegacy/common.h
linux-3.14.5/drivers/net/wireless/iwlegacy/csr.h
linux-3.14.5/drivers/net/wireless/iwlegacy/iwl-spectrum.h
linux-3.14.5/drivers/net/wireless/iwlegacy/prph.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/agn.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/calib.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/calib.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/commands.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/dev.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/devices.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/led.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/led.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/lib.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/mac80211.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/main.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/power.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/power.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/rs.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/rs.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/rx.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/rxon.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/scan.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/sta.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/tt.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/tt.h
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/tx.c
linux-3.14.5/drivers/net/wireless/iwlwifi/dvm/ucode.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-1000.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-2000.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-5000.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-6000.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-7000.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-config.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-csr.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-debug.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-debug.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-devtrace.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-drv.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-drv.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-fh.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-fw-file.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-fw.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-io.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-io.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-modparams.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-op-mode.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-phy-db.c
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-phy-db.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-prph.h
linux-3.14.5/drivers/net/wireless/iwlwifi/iwl-trans.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/binding.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/constants.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/d3.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw-api.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/fw.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/led.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/mac80211.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/mvm.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/nvm.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/ops.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/power.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/quota.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/rs.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/rs.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/rx.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/scan.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/sta.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/sta.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/testmode.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/time-event.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/time-event.h
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/tt.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/tx.c
linux-3.14.5/drivers/net/wireless/iwlwifi/mvm/utils.c
linux-3.14.5/drivers/net/wireless/iwlwifi/pcie/drv.c
linux-3.14.5/drivers/net/wireless/iwlwifi/pcie/internal.h
linux-3.14.5/drivers/net/wireless/iwlwifi/pcie/rx.c
linux-3.14.5/drivers/net/wireless/iwlwifi/pcie/trans.c
linux-3.14.5/drivers/net/wireless/iwlwifi/pcie/tx.c
linux-3.14.5/include/asm-generic/atomic64.h
linux-3.14.5/include/asm-generic/bitops/__ffs.h
linux-3.14.5/include/asm-generic/bitops/__fls.h
linux-3.14.5/include/asm-generic/bitops/ffs.h
linux-3.14.5/include/asm-generic/bitops/fls.h
linux-3.14.5/include/asm-generic/bitops/fls64.h
linux-3.14.5/include/asm-generic/bitops/non-atomic.h
linux-3.14.5/include/asm-generic/pci-dma-compat.h
linux-3.14.5/include/crypto/aead.h
linux-3.14.5/include/crypto/aes.h
linux-3.14.5/include/crypto/algapi.h
linux-3.14.5/include/crypto/crypto_wq.h
linux-3.14.5/include/crypto/ctr.h
linux-3.14.5/include/crypto/internal/aead.h
linux-3.14.5/include/crypto/internal/rng.h
linux-3.14.5/include/crypto/internal/skcipher.h
linux-3.14.5/include/crypto/rng.h
linux-3.14.5/include/crypto/scatterwalk.h
linux-3.14.5/include/crypto/skcipher.h
linux-3.14.5/include/linux/crypto.h
linux-3.14.5/include/linux/cryptouser.h
linux-3.14.5/include/linux/ctype.h
linux-3.14.5/include/linux/errqueue.h
linux-3.14.5/include/linux/genetlink.h
linux-3.14.5/include/linux/hashtable.h
linux-3.14.5/include/linux/ieee80211.h
linux-3.14.5/include/linux/if_ether.h
linux-3.14.5/include/linux/if_link.h
linux-3.14.5/include/linux/input.h
linux-3.14.5/include/linux/jhash.h
linux-3.14.5/include/linux/leds.h
linux-3.14.5/include/linux/list.h
linux-3.14.5/include/linux/list_nulls.h
linux-3.14.5/include/linux/lockdep.h
linux-3.14.5/include/linux/log2.h
linux-3.14.5/include/linux/mod_devicetable.h
linux-3.14.5/include/linux/net.h
linux-3.14.5/include/linux/netdev_features.h
linux-3.14.5/include/linux/netlink.h
linux-3.14.5/include/linux/pci_ids.h
linux-3.14.5/include/linux/rbtree.h
linux-3.14.5/include/linux/rbtree_augmented.h
linux-3.14.5/include/linux/rfkill-gpio.h
linux-3.14.5/include/linux/rfkill-regulator.h
linux-3.14.5/include/linux/rfkill.h
linux-3.14.5/include/linux/rtnetlink.h
linux-3.14.5/include/linux/skbuff.h
linux-3.14.5/include/linux/socket.h
linux-3.14.5/include/linux/swab.h
linux-3.14.5/include/net/cfg80211.h
linux-3.14.5/include/net/dsfield.h
linux-3.14.5/include/net/dst.h
linux-3.14.5/include/net/dst_ops.h
linux-3.14.5/include/net/genetlink.h
linux-3.14.5/include/net/ieee80211_radiotap.h
linux-3.14.5/include/net/inet_frag.h
linux-3.14.5/include/net/mac80211.h
linux-3.14.5/include/net/neighbour.h
linux-3.14.5/include/net/netlink.h
linux-3.14.5/include/net/netns/ipv4.h
linux-3.14.5/include/net/netns/mib.h
linux-3.14.5/include/net/regulatory.h
linux-3.14.5/include/net/request_sock.h
linux-3.14.5/include/net/rtnetlink.h
linux-3.14.5/include/net/snmp.h
linux-3.14.5/include/net/sock.h
linux-3.14.5/include/net/tcp_states.h
linux-3.14.5/include/net/timewait_sock.h
linux-3.14.5/include/trace/events/skb.h
linux-3.14.5/include/trace/events/sock.h
linux-3.14.5/include/uapi/asm-generic/socket.h
linux-3.14.5/include/uapi/linux/byteorder/little_endian.h
linux-3.14.5/include/uapi/linux/errqueue.h
linux-3.14.5/include/uapi/linux/genetlink.h
linux-3.14.5/include/uapi/linux/if_bridge.h
linux-3.14.5/include/uapi/linux/if_ether.h
linux-3.14.5/include/uapi/linux/if_link.h
linux-3.14.5/include/uapi/linux/if_packet.h
linux-3.14.5/include/uapi/linux/input.h
linux-3.14.5/include/uapi/linux/neighbour.h
linux-3.14.5/include/uapi/linux/net.h
linux-3.14.5/include/uapi/linux/netlink.h
linux-3.14.5/include/uapi/linux/nl80211.h
linux-3.14.5/include/uapi/linux/pci_regs.h
linux-3.14.5/include/uapi/linux/rfkill.h
linux-3.14.5/include/uapi/linux/rtnetlink.h
linux-3.14.5/include/uapi/linux/snmp.h
linux-3.14.5/include/uapi/linux/socket.h
linux-3.14.5/include/uapi/linux/sockios.h
linux-3.14.5/include/uapi/linux/swab.h
linux-3.14.5/lib/average.c
linux-3.14.5/lib/crc32.c
linux-3.14.5/lib/crc32defs.h
linux-3.14.5/lib/ctype.c
linux-3.14.5/lib/nlattr.c
linux-3.14.5/lib/rbtree.c
linux-3.14.5/net/core/datagram.c
linux-3.14.5/net/core/rtnetlink.c
linux-3.14.5/net/core/skbuff.c
linux-3.14.5/net/core/sock.c
linux-3.14.5/net/ethernet/eth.c
linux-3.14.5/net/mac80211/aes_ccm.c
linux-3.14.5/net/mac80211/aes_ccm.h
linux-3.14.5/net/mac80211/aes_cmac.c
linux-3.14.5/net/mac80211/aes_cmac.h
linux-3.14.5/net/mac80211/agg-rx.c
linux-3.14.5/net/mac80211/agg-tx.c
linux-3.14.5/net/mac80211/cfg.c
linux-3.14.5/net/mac80211/cfg.h
linux-3.14.5/net/mac80211/chan.c
linux-3.14.5/net/mac80211/debug.h
linux-3.14.5/net/mac80211/debugfs.h
linux-3.14.5/net/mac80211/debugfs_key.h
linux-3.14.5/net/mac80211/debugfs_netdev.h
linux-3.14.5/net/mac80211/debugfs_sta.h
linux-3.14.5/net/mac80211/driver-ops.h
linux-3.14.5/net/mac80211/event.c
linux-3.14.5/net/mac80211/ht.c
linux-3.14.5/net/mac80211/ibss.c
linux-3.14.5/net/mac80211/ieee80211_i.h
linux-3.14.5/net/mac80211/iface.c
linux-3.14.5/net/mac80211/key.c
linux-3.14.5/net/mac80211/key.h
linux-3.14.5/net/mac80211/led.c
linux-3.14.5/net/mac80211/led.h
linux-3.14.5/net/mac80211/main.c
linux-3.14.5/net/mac80211/mesh.c
linux-3.14.5/net/mac80211/mesh.h
linux-3.14.5/net/mac80211/mesh_hwmp.c
linux-3.14.5/net/mac80211/mesh_pathtbl.c
linux-3.14.5/net/mac80211/mesh_plink.c
linux-3.14.5/net/mac80211/mesh_ps.c
linux-3.14.5/net/mac80211/mesh_sync.c
linux-3.14.5/net/mac80211/michael.c
linux-3.14.5/net/mac80211/michael.h
linux-3.14.5/net/mac80211/mlme.c
linux-3.14.5/net/mac80211/offchannel.c
linux-3.14.5/net/mac80211/pm.c
linux-3.14.5/net/mac80211/rate.c
linux-3.14.5/net/mac80211/rate.h
linux-3.14.5/net/mac80211/rc80211_pid.h
linux-3.14.5/net/mac80211/rc80211_pid_algo.c
linux-3.14.5/net/mac80211/rx.c
linux-3.14.5/net/mac80211/scan.c
linux-3.14.5/net/mac80211/spectmgmt.c
linux-3.14.5/net/mac80211/sta_info.c
linux-3.14.5/net/mac80211/sta_info.h
linux-3.14.5/net/mac80211/status.c
linux-3.14.5/net/mac80211/tkip.c
linux-3.14.5/net/mac80211/tkip.h
linux-3.14.5/net/mac80211/trace.c
linux-3.14.5/net/mac80211/trace.h
linux-3.14.5/net/mac80211/tx.c
linux-3.14.5/net/mac80211/util.c
linux-3.14.5/net/mac80211/vht.c
linux-3.14.5/net/mac80211/wep.c
linux-3.14.5/net/mac80211/wep.h
linux-3.14.5/net/mac80211/wme.c
linux-3.14.5/net/mac80211/wme.h
linux-3.14.5/net/mac80211/wpa.c
linux-3.14.5/net/mac80211/wpa.h
linux-3.14.5/net/netlink/af_netlink.c
linux-3.14.5/net/netlink/af_netlink.h
linux-3.14.5/net/netlink/genetlink.c
linux-3.14.5/net/packet/af_packet.c
linux-3.14.5/net/packet/internal.h
linux-3.14.5/net/rfkill/core.c
linux-3.14.5/net/rfkill/input.c
linux-3.14.5/net/rfkill/rfkill-gpio.c
linux-3.14.5/net/rfkill/rfkill-regulator.c
linux-3.14.5/net/rfkill/rfkill.h
linux-3.14.5/net/wireless/ap.c
linux-3.14.5/net/wireless/chan.c
linux-3.14.5/net/wireless/core.c
linux-3.14.5/net/wireless/core.h
linux-3.14.5/net/wireless/debugfs.h
linux-3.14.5/net/wireless/ethtool.c
linux-3.14.5/net/wireless/ethtool.h
linux-3.14.5/net/wireless/ibss.c
linux-3.14.5/net/wireless/mesh.c
linux-3.14.5/net/wireless/mlme.c
linux-3.14.5/net/wireless/nl80211.c
linux-3.14.5/net/wireless/nl80211.h
linux-3.14.5/net/wireless/radiotap.c
linux-3.14.5/net/wireless/rdev-ops.h
linux-3.14.5/net/wireless/reg.c
linux-3.14.5/net/wireless/reg.h
linux-3.14.5/net/wireless/regdb.h
linux-3.14.5/net/wireless/scan.c
linux-3.14.5/net/wireless/sme.c
linux-3.14.5/net/wireless/sysfs.c
linux-3.14.5/net/wireless/sysfs.h
linux-3.14.5/net/wireless/trace.c
linux-3.14.5/net/wireless/trace.h
linux-3.14.5/net/wireless/util.c
linux-3.14.5/net/wireless/wext-compat.h