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 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 version of 'libc' by linking your application to 'lxip_libc' plugin in your
'target.mk' file. '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 LICENSE := GPL
VERSION := 1 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 # 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.archive: dwc_otg.git
# #
# USB # USB
# #
@ -20,7 +26,6 @@ DIR(usb) := $(SRC_DIR_USB)
TAR_OPT(usb) := --strip-components=1 --files-from $(REP_DIR)/usb.list TAR_OPT(usb) := --strip-components=1 --files-from $(REP_DIR)/usb.list
HASH_INPUT += $(REP_DIR)/usb.list HASH_INPUT += $(REP_DIR)/usb.list
# #
# Raspberry Pi USB controller # Raspberry Pi USB controller
# #
@ -28,6 +33,15 @@ URL(dwc_otg) := https://github.com/nfeske/dwc_otg.git
REV(dwc_otg) := r2 REV(dwc_otg) := r2
DIR(dwc_otg) := $(SRC_DIR_USB)/drivers/usb/host/dwc_otg 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 # 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 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
# #
PATCHES := $(addprefix patches/,$(notdir $(wildcard $(REP_DIR)/patches/*.patch))) PATCHES := $(addprefix patches/,$(notdir $(wildcard $(REP_DIR)/patches/*.patch)))
# USB
USB_OPT = -p1 -d$(SRC_DIR_USB) USB_OPT = -p1 -d$(SRC_DIR_USB)
PATCH_OPT(patches/usb_ax88179.patch) := $(USB_OPT) PATCH_OPT(patches/usb_ax88179.patch) := $(USB_OPT)
PATCH_OPT(patches/usb_csum.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_usbnet.patch) := $(USB_OPT)
PATCH_OPT(patches/usb_xchi-quirks.patch) := $(USB_OPT) PATCH_OPT(patches/usb_xchi-quirks.patch) := $(USB_OPT)
#IP stack
LXIP_OPT = -p1 -d$(SRC_DIR_LXIP) LXIP_OPT = -p1 -d$(SRC_DIR_LXIP)
PATCH_OPT(patches/lxip_icmp.patch) := $(LXIP_OPT) PATCH_OPT(patches/lxip_icmp.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_ip_config.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_tcp.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_netlink.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 : # 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