diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-05-28 09:17:29 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-05-28 09:17:29 +0000 |
commit | 76ed58d705e7f3892a1259abcd92882a527e7b53 (patch) | |
tree | 80dfa6ecb493ee8cb9ca1436f1b37ee89f320a55 /target/linux/package | |
parent | e285af3e184318b0fefeab597ae5ee4a2628422d (diff) |
move package/linux into target/linux, use wbx' new kernel code. support building images with more than one kernel, split kernel module parts off of packages that use their own kernel modules (fuse, shfs, openswan). some cleanup in the image building process in target/. image builder is disabled for now, needs some fixing.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@1085 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/package')
-rw-r--r-- | target/linux/package/Config.in | 4 | ||||
-rw-r--r-- | target/linux/package/Makefile | 36 | ||||
-rw-r--r-- | target/linux/package/fuse/Config.in | 23 | ||||
-rw-r--r-- | target/linux/package/fuse/Makefile | 79 | ||||
-rw-r--r-- | target/linux/package/fuse/ipkg/kmod-fuse.control | 8 | ||||
-rw-r--r-- | target/linux/package/fuse/patches/101-kmod_build.patch | 59 | ||||
-rw-r--r-- | target/linux/package/fuse/patches/102-cflags_configure.patch | 22 | ||||
-rw-r--r-- | target/linux/package/openswan/Config.in | 9 | ||||
-rw-r--r-- | target/linux/package/openswan/Makefile | 36 | ||||
-rw-r--r-- | target/linux/package/openswan/ipkg/kmod-openswan.control | 6 | ||||
-rw-r--r-- | target/linux/package/shfs/Config.in | 24 | ||||
-rw-r--r-- | target/linux/package/shfs/Makefile | 47 | ||||
-rw-r--r-- | target/linux/package/shfs/ipkg/kmod-shfs.control | 8 | ||||
-rw-r--r-- | target/linux/package/shfs/patches/101-kmod_build.patch | 103 | ||||
-rw-r--r-- | target/linux/package/wlcompat/Config.in | 7 | ||||
-rw-r--r-- | target/linux/package/wlcompat/Makefile | 34 | ||||
-rw-r--r-- | target/linux/package/wlcompat/ipkg/kmod-wlcompat.control | 7 | ||||
-rw-r--r-- | target/linux/package/wlcompat/wlcompat.c | 824 |
18 files changed, 1336 insertions, 0 deletions
diff --git a/target/linux/package/Config.in b/target/linux/package/Config.in new file mode 100644 index 000000000..2b95c3c45 --- /dev/null +++ b/target/linux/package/Config.in @@ -0,0 +1,4 @@ +source "target/linux/package/wlcompat/Config.in" +source "target/linux/package/fuse/Config.in" +source "target/linux/package/shfs/Config.in" +source "target/linux/package/openswan/Config.in" diff --git a/target/linux/package/Makefile b/target/linux/package/Makefile new file mode 100644 index 000000000..868400d6a --- /dev/null +++ b/target/linux/package/Makefile @@ -0,0 +1,36 @@ +# Main makefile for the packages +include $(TOPDIR)/rules.mk + +package-$(BR2_PACKAGE_KMOD_FUSE) += fuse +package-$(BR2_PACKAGE_KMOD_SHFS) += shfs +package-$(BR2_PACKAGE_KMOD_OPENSWAN) += openswan + +all: compile install +clean: $(patsubst %,%-clean,$(package-) $(package-y) $(package-m)) +compile: $(patsubst %,%-compile,$(package-y) $(package-m)) +install: $(patsubst %,%-install,$(package-y)) + +%-prepare: + $(MAKE) -C $(patsubst %-prepare,%,$@) \ + BUILD_DIR="$(BUILD_DIR)" \ + KERNEL_DIR="$(KERNEL_DIR)" \ + LINUX_VERSION="$(LINUX_VERSION)" \ + prepare + +%-compile: %-prepare + $(MAKE) -C $(patsubst %-compile,%,$@) \ + BUILD_DIR="$(BUILD_DIR)" \ + KERNEL_DIR="$(KERNEL_DIR)" \ + LINUX_VERSION="$(LINUX_VERSION)" \ + compile + +%-install: %-compile + $(MAKE) -C $(patsubst %-install,%,$@) \ + BUILD_DIR="$(BUILD_DIR)" \ + KERNEL_DIR="$(KERNEL_DIR)" \ + LINUX_VERSION="$(LINUX_VERSION)" \ + install + +%-clean: + @$(MAKE) -C $(patsubst %-clean,%,$@) clean + diff --git a/target/linux/package/fuse/Config.in b/target/linux/package/fuse/Config.in new file mode 100644 index 000000000..7e575074f --- /dev/null +++ b/target/linux/package/fuse/Config.in @@ -0,0 +1,23 @@ +config BR2_PACKAGE_KMOD_FUSE + prompt "kmod-fuse - FUSE kernel module" + tristate + default m if CONFIG_DEVEL + select BR2_PACKAGE_FUSE + help + With FUSE it is possible to implement a fully functional + filesystem in a userspace program. + + Features include: + + * Simple library API + * Simple installation (no need to patch or recompile the kernel) + * Secure implementation + * Userspace - kernel interface is very efficient + * Usable by non privileged users + * Runs on Linux kernels 2.4.X and 2.6.X + * Has proven very stable over time + + + http://fuse.sourceforge.net/ + + This package contains the fuse.o kernel module. diff --git a/target/linux/package/fuse/Makefile b/target/linux/package/fuse/Makefile new file mode 100644 index 000000000..9db629598 --- /dev/null +++ b/target/linux/package/fuse/Makefile @@ -0,0 +1,79 @@ +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=fuse +PKG_VERSION:=2.2.1 +PKG_RELEASE:=1 +PKG_MD5SUM:=250d89b9c7b6ecf531df60c67f75737d + +PKG_SOURCE_URL:=@SF/$(PKG_NAME) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_CAT:=zcat + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install + +ifeq ($(KERNEL_DIR),) +KERNEL_DIR:=$(LINUX_DIR) +endif + +include $(TOPDIR)/package/rules.mk + +$(eval $(call PKG_template,KMOD_FUSE,kmod-fuse,$(LINUX_VERSION)+$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH))) + +$(PKG_BUILD_DIR)/.configured: + (cd $(PKG_BUILD_DIR); \ + rm -rf config.{cache,status} ; \ + touch configure.in ; \ + touch aclocal.m4 ; \ + touch Makefile.in ; \ + touch include/config.h.in ; \ + touch configure ; \ + $(TARGET_CONFIGURE_OPTS) \ + CFLAGS="$(TARGET_CFLAGS)" \ + ./configure \ + --target=$(GNU_TARGET_NAME) \ + --host=$(GNU_TARGET_NAME) \ + --build=$(GNU_HOST_NAME) \ + --program-prefix="" \ + --program-suffix="" \ + --prefix=/usr \ + --exec-prefix=/usr \ + --bindir=/usr/bin \ + --datadir=/usr/share \ + --includedir=/usr/include \ + --infodir=/usr/share/info \ + --libdir=/usr/lib \ + --libexecdir=/usr/lib \ + --localstatedir=/var \ + --mandir=/usr/share/man \ + --sbindir=/usr/sbin \ + --sysconfdir=/etc \ + $(DISABLE_LARGEFILE) \ + $(DISABLE_NLS) \ + --enable-shared \ + --enable-static \ + --enable-kernel-module \ + --enable-lib \ + --enable-util \ + --disable-example \ + --disable-auto-modprobe \ + --with-kernel=$(KERNEL_DIR) \ + ); + touch $@ + +$(PKG_BUILD_DIR)/.built: + mkdir -p $(PKG_INSTALL_DIR) + $(MAKE) -C $(PKG_BUILD_DIR) \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + SUBDIRS="kernel" \ + all install + touch $@ + +$(IPKG_KMOD_FUSE): + mkdir -p $(IDIR_KMOD_FUSE)/lib/modules/$(LINUX_VERSION) + cp -fpR $(PKG_INSTALL_DIR)/lib/modules/$(LINUX_VERSION)/kernel/fs/fuse/fuse.* \ + $(IDIR_KMOD_FUSE)/lib/modules/$(LINUX_VERSION)/ + $(IPKG_BUILD) $(IDIR_KMOD_FUSE) $(PACKAGE_DIR) + diff --git a/target/linux/package/fuse/ipkg/kmod-fuse.control b/target/linux/package/fuse/ipkg/kmod-fuse.control new file mode 100644 index 000000000..9d2e919c7 --- /dev/null +++ b/target/linux/package/fuse/ipkg/kmod-fuse.control @@ -0,0 +1,8 @@ +Package: kmod-fuse +Priority: optional +Section: kernel +Version: [TBDL] +Architecture: [TBDL] +Maintainer: Nico <nthill@free.fr> +Source: http://nthill.free.fr/openwrt/sources/fuse2/ +Description: Filesystem in Userspace (kernel module) diff --git a/target/linux/package/fuse/patches/101-kmod_build.patch b/target/linux/package/fuse/patches/101-kmod_build.patch new file mode 100644 index 000000000..5f4bee745 --- /dev/null +++ b/target/linux/package/fuse/patches/101-kmod_build.patch @@ -0,0 +1,59 @@ +--- fuse-2.2.1-orig/kernel/Makefile.in 2005-01-09 13:07:00.000000000 +0100 ++++ fuse-2.2.1-1/kernel/Makefile.in 2005-04-06 14:48:59.000000000 +0200 +@@ -31,11 +31,11 @@ + install-y: all + $(mkdir_p) $(DESTDIR)$(fusemoduledir) + $(INSTALL) -m 644 $(fusemodule) $(DESTDIR)$(fusemoduledir)/$(fusemodule) +- -/sbin/depmod -a ++# -/sbin/depmod -a + + uninstall-y: + rm -f $(DESTDIR)$(fusemoduledir)/$(fusemodule) +- -/sbin/depmod -a ++# -/sbin/depmod -a + + clean: + -rm -f $(fusemodule) *.o .*.cmd *.mod.c *.ko *.s */*.o +@@ -54,23 +54,8 @@ + + ifeq ($(majver), 2.4) + +-CC = gcc +-LD = ld +-CFLAGS = -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -pipe +-CPPFLAGS = -I@kernelsrc@/include -I. -D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -DFUSE_VERSION=\"$(VERSION)\" @KERNELCPPFLAGS@ +- + fuse_objs = dev.o dir.o file.o inode.o compat/parser.o + +-SUFFIXES = .c .o .s +- +-all-spec: fuse.o +- +-.c.o: +- $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ +- +-fuse.o: $(fuse_objs) +- $(LD) -r -o fuse.o $(fuse_objs) +- + fuse_headers = fuse_i.h fuse_kernel.h + + dev.o: $(fuse_headers) +@@ -78,6 +63,18 @@ + file.o: $(fuse_headers) + inode.o: $(fuse_headers) + ++EXTRA_CFLAGS += -DFUSE_VERSION=\"$(VERSION)\" ++ ++O_TARGET := fuse.o ++ ++obj-y := $(fuse_objs) ++obj-m := $(O_TARGET) ++ ++-include $(TOPDIR)/Rules.make ++ ++all-spec: ++ $(MAKE) -C @kernelsrc@ TOPDIR=@kernelsrc@ SUBDIRS=$(PWD) modules ++ + else + + EXTRA_CFLAGS += -DFUSE_VERSION=\"$(VERSION)\" diff --git a/target/linux/package/fuse/patches/102-cflags_configure.patch b/target/linux/package/fuse/patches/102-cflags_configure.patch new file mode 100644 index 000000000..b358ab4ec --- /dev/null +++ b/target/linux/package/fuse/patches/102-cflags_configure.patch @@ -0,0 +1,22 @@ +--- fuse-2.2.1-orig/configure 2005-03-08 15:48:57.000000000 +0100 ++++ fuse-2.2.1-1/configure 2005-04-06 14:39:18.000000000 +0200 +@@ -9354,7 +9354,7 @@ + + fi + +-CFLAGS="-Wall -W -g -O2" ++[ -z "$CFLAGS" ] && CFLAGS="-Wall -W -g -O2" + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=22" + + # Check whether --enable-kernel-module or --disable-kernel-module was given. +--- fuse-2.2.1-orig/configure.in 2005-03-08 15:39:23.000000000 +0100 ++++ fuse-2.2.1-1/configure.in 2005-04-06 14:39:20.000000000 +0200 +@@ -13,7 +13,7 @@ + AC_SUBST(mkdir_p) + fi + +-CFLAGS="-Wall -W -g -O2" ++[ -z "$CFLAGS" ] && CFLAGS="-Wall -W -g -O2" + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=22" + + AC_ARG_ENABLE(kernel-module, diff --git a/target/linux/package/openswan/Config.in b/target/linux/package/openswan/Config.in new file mode 100644 index 000000000..0746197e1 --- /dev/null +++ b/target/linux/package/openswan/Config.in @@ -0,0 +1,9 @@ +config BR2_PACKAGE_KMOD_OPENSWAN + tristate "kmod-openswan Openswan kernel module" + default m if CONFIG_DEVEL + help + Openswan is an implementation of IPsec for Linux. + + http://www.openswan.org/ + + This package contains the Openswan IPSec module for the kernel diff --git a/target/linux/package/openswan/Makefile b/target/linux/package/openswan/Makefile new file mode 100644 index 000000000..5ebb8702d --- /dev/null +++ b/target/linux/package/openswan/Makefile @@ -0,0 +1,36 @@ +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=openswan +PKG_VERSION:=2.3.1 +PKG_RELEASE:=1 +PKG_MD5SUM:=3dcf1cd7efcbe8db3148fc288d429db1 + +PKG_SOURCE_URL:=http://www.openswan.org/download +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_CAT:=zcat + +include $(TOPDIR)/package/rules.mk + +ifeq ($(KERNEL_DIR),) +KERNEL_DIR:=$(LINUX_DIR) +endif + +$(eval $(call PKG_template,KMOD_OPENSWAN,kmod-openswan,$(LINUX_VERSION)+$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH))) + +FLAGS := $(TARGET_CFLAGS) -I$(PKG_BUILD_DIR)/linux/include -L$(STAGING_DIR)/usr/lib -I$(STAGING_DIR)/usr/include + +$(PKG_BUILD_DIR)/.built: + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + KERNELSRC="$(KERNEL_DIR)" \ + ARCH="mips" \ + USERCOMPILE="$(FLAGS)" \ + module + +$(IPKG_KMOD_OPENSWAN): + mkdir -p $(IDIR_KMOD_OPENSWAN)/lib/modules/$(LINUX_VERSION) + cp $(PKG_BUILD_DIR)/modobj/ipsec.*o $(IDIR_KMOD_OPENSWAN)/lib/modules/$(LINUX_VERSION)/ + $(IPKG_BUILD) $(IDIR_KMOD_OPENSWAN) $(PACKAGE_DIR) diff --git a/target/linux/package/openswan/ipkg/kmod-openswan.control b/target/linux/package/openswan/ipkg/kmod-openswan.control new file mode 100644 index 000000000..45406e27e --- /dev/null +++ b/target/linux/package/openswan/ipkg/kmod-openswan.control @@ -0,0 +1,6 @@ +Package: kmod-openswan +Section: base +Priority: optional +Maintainer: Felix Fietkau <nbd@vd-s.ath.cx> +Source: buildroot internal +Description: Openswan IPSec kernel module diff --git a/target/linux/package/shfs/Config.in b/target/linux/package/shfs/Config.in new file mode 100644 index 000000000..8d30c8c03 --- /dev/null +++ b/target/linux/package/shfs/Config.in @@ -0,0 +1,24 @@ +config BR2_PACKAGE_KMOD_SHFS + prompt "kmod-shfs - Shell FileSystem kernel module (ShFS) kernel module" + tristate + default m if CONFIG_DEVEL + help + ShFS is a simple and easy to use Linux kernel module which + allows you to mount remote filesystems using a plain shell + (SSH) connection. When using ShFS, you can access all remote + files just like the local ones, only the access is governed + through the transport security of SSH. + + ShFS supports some nice features: + + * file cache for access speedup + * perl and shell code for the remote (server) side + * could preserve uid/gid (root connection) + * number of remote host platforms (Linux, Solaris, Cygwin, ...) + * Linux kernel 2.4.10+ and 2.6 + * arbitrary command used for connection (instead of SSH) + * persistent connection (reconnect after SSH dies) + + http://shfs.sourceforge.net/ + + This package contains the shfs.o kernel module. diff --git a/target/linux/package/shfs/Makefile b/target/linux/package/shfs/Makefile new file mode 100644 index 000000000..a329bbffc --- /dev/null +++ b/target/linux/package/shfs/Makefile @@ -0,0 +1,47 @@ +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME := shfs +PKG_VERSION := 0.35 +PKG_RELEASE := 2 +PKG_MD5SUM := 016f49d71bc32eee2b5d11fc1600cfbe + +PKG_SOURCE_URL := @SF/shfs +PKG_SOURCE := $(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_CAT := zcat + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install + +ifeq ($(KERNEL_DIR),) +KERNEL_DIR:=$(LINUX_DIR) +endif + +include $(TOPDIR)/package/rules.mk + +$(eval $(call PKG_template,KMOD_SHFS,kmod-shfs,$(LINUX_VERSION)+$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH))) + +$(PKG_BUILD_DIR)/.configured: + touch $@ + +$(PKG_BUILD_DIR)/.built: + rm -rf $(PKG_INSTALL_DIR) + mkdir -p $(PKG_INSTALL_DIR) + $(MAKE) -C $(PKG_BUILD_DIR) \ + OFLAGS="$(TARGET_CFLAGS)" \ + CC="$(TARGET_CC)" \ + LINKER="$(TARGET_CC)" \ + KERNEL="$(LINUX_VERSION)" \ + KERNEL_SOURCES="$(KERNEL_DIR)" \ + ROOT="$(PKG_INSTALL_DIR)" \ + module module-install + touch $@ + +$(IPKG_KMOD_SHFS): + install -m0755 -d $(IDIR_KMOD_SHFS)/lib/modules/$(LINUX_VERSION) + cp -fpR $(PKG_INSTALL_DIR)/lib/modules/$(LINUX_VERSION)/kernel/fs/shfs/shfs.o \ + $(IDIR_KMOD_SHFS)/lib/modules/$(LINUX_VERSION)/ + $(RSTRIP_KMOD) $(IDIR_KMOD_SHFS) + $(IPKG_BUILD) $(IDIR_KMOD_SHFS) $(PACKAGE_DIR) + diff --git a/target/linux/package/shfs/ipkg/kmod-shfs.control b/target/linux/package/shfs/ipkg/kmod-shfs.control new file mode 100644 index 000000000..b7ce61293 --- /dev/null +++ b/target/linux/package/shfs/ipkg/kmod-shfs.control @@ -0,0 +1,8 @@ +Package: kmod-shfs +Priority: optional +Section: net +Version: [TBDL] +Architecture: [TBDL] +Maintainer: Nico <nthill@free.fr> +Source: http://nthill.free.fr/openwrt/sources/shfs/ +Description: SHell FileSystem Linux kernel module diff --git a/target/linux/package/shfs/patches/101-kmod_build.patch b/target/linux/package/shfs/patches/101-kmod_build.patch new file mode 100644 index 000000000..635900472 --- /dev/null +++ b/target/linux/package/shfs/patches/101-kmod_build.patch @@ -0,0 +1,103 @@ +--- shfs-0.35-orig/shfs/Linux-2.4/Makefile 2004-06-01 15:16:19.000000000 +0200 ++++ shfs-0.35-2/shfs/Linux-2.4/Makefile 2005-04-09 02:34:35.000000000 +0200 +@@ -1,3 +1,17 @@ ++# ++# the original Makefile was trashed and replaced by this one ++# The main reason is that loadable modules should be built with ++# the same compile flags the kernel was built with, so we'd better ++# let the kernel tree build the module for us, like that : ++# ++# make -C $(KERNEL_DIR) SUBDIRS="$(shell pwd)" modules ++# make -C $(KERNEL_DIR) SUBDIRS="$(shell pwd)" modules_install ++# ++# ++# $(TOPDIR)/lib/string.o is needed at link time because the memchr function ++# is not exported on mips (insmod: unresolved symbol memchr) ++# ++ + ifndef KERNEL + KERNEL=$(shell uname -r) + endif +@@ -10,67 +24,30 @@ + KERNEL_SOURCES=${MODULESDIR}/build + endif + +-ifeq (${MODVERSIONS},detect) +- ifeq ($(shell test -e ${KERNEL_SOURCES}/include/linux/modversions.h; echo $$?),0) +- MODVERSIONS=yes +- endif +-endif +- +-ifeq (${MODVERSIONS},yes) +-MVER=-DMODVERSIONS -DEXPORT_SYMTAB +-endif +- +-LINVER=linux-${KERNEL} +- +-ALL_TARGETS := shfs.o +- +-SEARCHDIRS := -I- -I. -I${KERNEL_SOURCES}/include #-I/usr/src/linux/include/ ++all: all-y + +-CC := gcc +-CFLAGS = -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -Wall ${SEARCHDIRS} -DMODULE ${MVER} -D__KERNEL__ -DLINUX +-LINKER := ld +-LDFLAGS = -r +-LOADLIBES := ++O_TARGET := shfs.o + +-all: ${ALL_TARGETS} ++shfs-objs := dcache.o dir.o fcache.o file.o inode.o ioctl.o proc.o shell.o symlink.o + +-%.o: %.c $(wildcard *.h) +- ${CC} ${CFLAGS} -c $< -o $@ ++obj-y := $(shfs-objs) ++obj-m := $(O_TARGET) + +-shfs.o: dcache.o dir.o fcache.o file.o inode.o ioctl.o proc.o shell.o symlink.o +- ${LINKER} ${LDFLAGS} -o $@ ${filter-out %.a %.so, $^} ${LOADLIBES} +- +-tidy: +- ${RM} core dcache.o dir.o fcache.o file.o inode.o ioctl.o proc.o shell.o symlink.o +- +-clean: tidy patch-clean +- ${RM} shfs.o ++-include $(TOPDIR)/Rules.make + ++all-y: ++ make -C ${KERNEL_SOURCES} TOPDIR="${KERNEL_SOURCES}" SUBDIRS="$(shell pwd)" modules ++ + install: shfs.o + rm -f ${MODULESDIR}/kernel/fs/shfs/shfs.o + install -m644 -b -D shfs.o ${MODULESDIR}/kernel/fs/shfs/shfs.o +- if [ -x /sbin/depmod -a "${ROOT}" = "/" ]; then /sbin/depmod -aq; fi + + uninstall: + rm -rf ${MODULESDIR}/kernel/fs/shfs +- if [ -x /sbin/depmod -a "${ROOT}" = "/" ]; then /sbin/depmod -aq; fi + +-patch: +- rm -rf ${LINVER} ${LINVER}.orig; mkdir ${LINVER}; +- for i in Documentation fs/shfs include/linux; do \ +- mkdir -p ${LINVER}/$$i; \ +- done +- cp ${KERNEL_SOURCES}/Documentation/Configure.help ${LINVER}/Documentation +- cp ${KERNEL_SOURCES}/fs/{Makefile,Config.in} ${LINVER}/fs +- cp -r ${LINVER} ${LINVER}.orig +- cp ../../Changelog *.c shfs_debug.h proc.h ${LINVER}/fs/shfs/ +- cp shfs.h shfs_fs* ${LINVER}/include/linux/ +- (cd ${LINVER}; patch -p1 <../kernel-config.diff) +- find . -type f -name "*.orig" -print | xargs rm -f +- diff -urN ${LINVER}.orig ${LINVER} >${LINVER}.diff; true +- +-patch-clean: +- rm -rf ${LINVER} ${LINVER}.orig; +- rm -f ${LINVER}.diff +- +-.PHONY : all tidy clean install uninstall patch patch-clean ++clean: ++ rm -f core *.o *.a *.s ++ ++shfs.o: $(shfs-objs) ++ $(LD) -r -o $@ $(shfs-objs) $(TOPDIR)/lib/string.o ++ diff --git a/target/linux/package/wlcompat/Config.in b/target/linux/package/wlcompat/Config.in new file mode 100644 index 000000000..926cf4b3c --- /dev/null +++ b/target/linux/package/wlcompat/Config.in @@ -0,0 +1,7 @@ +config BR2_PACKAGE_KMOD_WLCOMPAT + tristate "kmod-wlcompat" + default y + depends BR2_PACKAGE_KMOD_BRCM_WL + help + A wrapper module, that provides Wireless Extension support for the + proprietary Broadcom wl module. diff --git a/target/linux/package/wlcompat/Makefile b/target/linux/package/wlcompat/Makefile new file mode 100644 index 000000000..30cb9f471 --- /dev/null +++ b/target/linux/package/wlcompat/Makefile @@ -0,0 +1,34 @@ +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME := kmod-wlcompat +PKG_RELEASE := 1 +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(TOPDIR)/package/rules.mk + +ifeq ($(patsubst 2.4%,2.4,$(LINUX_VERSION)),2.4) +$(eval $(call PKG_template,KMOD_WLCOMPAT,$(PKG_NAME),$(KERNEL_VERSION)-$(PKG_RELEASE),$(ARCH))) +endif + +WLCOMPAT_FLAGS:=$(TARGET_CLFAGS) -D__KERNEL__ -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 \ + -mno-abicalls -fno-pic -finline-limit=100000 -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 \ + -Wa,-mips32 -Wa,--trap -DMODULE -mlong-calls -fno-common -I. -I linux-2.4 -funsigned-char -nostdinc \ + -iwithprefix include -I$(LINUX_DIR)/include -I$(LINUX_DIR)/include/asm/gcc -I./include -c + +$(PKG_BUILD_DIR)/.built: $(PKG_BUILD_DIR)/wlcompat.o $(PKG_BUILD_DIR)/wlcompat-debug.o + touch $@ + +$(PKG_BUILD_DIR)/wlcompat.o: + $(TARGET_CC) $(WLCOMPAT_FLAGS) -o $@ wlcompat.c + +$(PKG_BUILD_DIR)/wlcompat-debug.o: + $(TARGET_CC) -DDEBUG $(WLCOMPAT_FLAGS) -o $@ wlcompat.c + +$(IPKG_KMOD_WLCOMPAT): $(PKG_BUILD_DIR)/wlcompat.o $(PKG_BUILD_DIR)/wlcompat-debug.o + mkdir -p $(IDIR_WLCOMPAT)/etc/modules.d + echo "wlcompat" > $(IDIR_WLCOMPAT)/etc/modules.d/10-wlcompat + mkdir -p $(IDIR_WLCOMPAT)/lib/modules/$(LINUX_VERSION) + cp $^ $(IDIR_WLCOMPAT)/lib/modules/$(LINUX_VERSION)/ + $(IPKG_BUILD) $(IDIR_WLCOMPAT) $(PACKAGE_DIR) diff --git a/target/linux/package/wlcompat/ipkg/kmod-wlcompat.control b/target/linux/package/wlcompat/ipkg/kmod-wlcompat.control new file mode 100644 index 000000000..8891fb4a1 --- /dev/null +++ b/target/linux/package/wlcompat/ipkg/kmod-wlcompat.control @@ -0,0 +1,7 @@ +Package: kmod-wlcompat +Priority: optional +Section: sys +Maintainer: Felix Fietkau <nbd@vd-s.ath.cx> +Source: buildroot internal +Depends: kmod-brcm-wl +Description: Compatibility module for using the Wireless Extension with broadcom's wl diff --git a/target/linux/package/wlcompat/wlcompat.c b/target/linux/package/wlcompat/wlcompat.c new file mode 100644 index 000000000..d010e2bc8 --- /dev/null +++ b/target/linux/package/wlcompat/wlcompat.c @@ -0,0 +1,824 @@ +/* + * wlcompat.c + * + * Copyright (C) 2005 Mike Baker, + * Felix Fietkau <nbd@vd-s.ath.cx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/if_arp.h> +#include <asm/uaccess.h> +#include <linux/wireless.h> + +#include <net/iw_handler.h> +#include <wlioctl.h> +#include <wlcompat.h> + +static struct net_device *dev; +char buf[WLC_IOCTL_MAXLEN]; + +/* The frequency of each channel in MHz */ +const long channel_frequency[] = { + 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 +}; +#define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) ) + + + +static int wlcompat_private_ioctl(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra); + +static int wl_ioctl(struct net_device *dev, int cmd, void *buf, int len) +{ + mm_segment_t old_fs = get_fs(); + struct ifreq ifr; + int ret; + wl_ioctl_t ioc; + ioc.cmd = cmd; + ioc.buf = buf; + ioc.len = len; + strncpy(ifr.ifr_name, dev->name, IFNAMSIZ); + ifr.ifr_data = (caddr_t) &ioc; + set_fs(KERNEL_DS); + ret = dev->do_ioctl(dev,&ifr,SIOCDEVPRIVATE); + set_fs (old_fs); + return ret; +} + +static int wl_set_val(struct net_device *dev, char *var, void *val, int len) +{ + char buf[128]; + int buf_len; + + /* check for overflow */ + if ((buf_len = strlen(var)) + 1 + len > sizeof(buf)) + return -1; + + strcpy(buf, var); + buf_len += 1; + + /* append int value onto the end of the name string */ + memcpy(&buf[buf_len], val, len); + buf_len += len; + + return wl_ioctl(dev, WLC_SET_VAR, buf, buf_len); +} + +static int wl_get_val(struct net_device *dev, char *var, void *val, int len) +{ + char buf[128]; + int ret; + + /* check for overflow */ + if (strlen(var) + 1 > sizeof(buf) || len > sizeof(buf)) + return -1; + + strcpy(buf, var); + if ((ret = wl_ioctl(dev, WLC_GET_VAR, buf, sizeof(buf)))) + return ret; + + memcpy(val, buf, len); + return 0; +} + +int read_shmem(struct net_device *dev, int offset) +{ + if (wl_ioctl(dev, WLC_GET_SHMEM, &offset, sizeof(offset)) < 0) + return -EINVAL; + + return offset; +} + +static int wlcompat_ioctl_getiwrange(struct net_device *dev, + char *extra) +{ + int i, k; + struct iw_range *range; + + range = (struct iw_range *) extra; + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = WIRELESS_EXT; + + range->min_nwid = range->max_nwid = 0; + + range->num_channels = NUM_CHANNELS; + k = 0; + for (i = 0; i < NUM_CHANNELS; i++) { + range->freq[k].i = i + 1; + range->freq[k].m = channel_frequency[i] * 100000; + range->freq[k].e = 1; + k++; + if (k >= IW_MAX_FREQUENCIES) + break; + } + range->num_frequency = k; + range->sensitivity = 3; + + /* nbd: don't know what this means, but other drivers set it this way */ + range->pmp_flags = IW_POWER_PERIOD; + range->pmt_flags = IW_POWER_TIMEOUT; + range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R; + + range->min_pmp = 0; + range->max_pmp = 65535000; + range->min_pmt = 0; + range->max_pmt = 65535 * 1000; + + range->min_rts = 0; + if (wl_ioctl(dev, WLC_GET_RTS, &range->max_rts, sizeof(int)) < 0) + range->max_rts = 2347; + + range->min_frag = 256; + + if (wl_ioctl(dev, WLC_GET_FRAG, &range->max_frag, sizeof(int)) < 0) + range->max_frag = 2346; + + range->txpower_capa = IW_TXPOW_MWATT; + + return 0; +} + + +static int wlcompat_set_scan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ap = 0, oldap = 0; + wl_scan_params_t params; + + memset(¶ms, 0, sizeof(params)); + + /* use defaults (same parameters as wl scan) */ + memset(¶ms.bssid, 0xff, sizeof(params.bssid)); + params.bss_type = DOT11_BSSTYPE_ANY; + params.scan_type = -1; + params.nprobes = -1; + params.active_time = -1; + params.passive_time = -1; + params.home_time = -1; + + /* can only scan in STA mode */ + wl_ioctl(dev, WLC_GET_AP, &oldap, sizeof(oldap)); + if (oldap > 0) + wl_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)); + + if (wl_ioctl(dev, WLC_SCAN, ¶ms, 64) < 0) + return -EINVAL; + + if (oldap > 0) + wl_ioctl(dev, WLC_SET_AP, &oldap, sizeof(oldap)); + + return 0; +} + + +static int wlcompat_get_scan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + wl_scan_results_t *results = (wl_scan_results_t *) buf; + wl_bss_info_t *bss_info; + char *info_ptr; + char *current_ev = extra; + char *current_val; + char *end_buf = extra + IW_SCAN_MAX_DATA; + struct iw_event iwe; + int i, j; + + if (wl_ioctl(dev, WLC_SCAN_RESULTS, buf, WLC_IOCTL_MAXLEN) < 0) + return -EAGAIN; + + bss_info = &(results->bss_info[0]); + info_ptr = (char *) bss_info; + for (i = 0; i < results->count; i++) { + + /* send the cell address (must be sent first) */ + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(&iwe.u.ap_addr.sa_data, &bss_info->BSSID, sizeof(bss_info->BSSID)); + current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* send the ESSID */ + iwe.cmd = SIOCGIWESSID; + iwe.u.data.length = bss_info->SSID_len; + if (iwe.u.data.length > IW_ESSID_MAX_SIZE) + iwe.u.data.length = IW_ESSID_MAX_SIZE; + iwe.u.data.flags = 1; + current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss_info->SSID); + + /* send frequency/channel info */ + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.e = 0; + iwe.u.freq.m = bss_info->channel; + current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); + + /* add quality statistics */ + iwe.cmd = IWEVQUAL; + iwe.u.qual.level = bss_info->RSSI; + iwe.u.qual.noise = bss_info->phy_noise; + iwe.u.qual.qual = 0; + current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + + /* send rate information */ + iwe.cmd = SIOCGIWRATE; + current_val = current_ev + IW_EV_LCP_LEN; + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + + for(j = 0 ; j < bss_info->rateset.count ; j++) { + iwe.u.bitrate.value = ((bss_info->rateset.rates[j] & 0x7f) * 500000); + current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); + } + if((current_val - current_ev) > IW_EV_LCP_LEN) + current_ev = current_val; + + info_ptr += sizeof(wl_bss_info_t); + if (bss_info->ie_length % 4) + info_ptr += bss_info->ie_length + 4 - (bss_info->ie_length % 4); + else + info_ptr += bss_info->ie_length; + bss_info = (wl_bss_info_t *) info_ptr; + } + + wrqu->data.length = (current_ev - extra); + wrqu->data.flags = 0; + + return 0; +} + +static int wlcompat_ioctl(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + switch (info->cmd) { + case SIOCGIWNAME: + strcpy(wrqu->name, "IEEE 802.11-DS"); + break; + case SIOCGIWFREQ: + { + channel_info_t ci; + + if (wl_ioctl(dev,WLC_GET_CHANNEL, &ci, sizeof(ci)) < 0) + return -EINVAL; + + wrqu->freq.m = ci.target_channel; + wrqu->freq.e = 0; + break; + } + case SIOCSIWFREQ: + { + if (wrqu->freq.e == 1) { + int channel = 0; + int f = wrqu->freq.m / 100000; + while ((channel < NUM_CHANNELS + 1) && (f != channel_frequency[channel])) + channel++; + + if (channel == NUM_CHANNELS) // channel not found + return -EINVAL; + + wrqu->freq.e = 0; + wrqu->freq.m = channel + 1; + } + if ((wrqu->freq.e == 0) && (wrqu->freq.m < 1000)) { + if (wl_ioctl(dev, WLC_SET_CHANNEL, &wrqu->freq.m, sizeof(int)) < 0) + return -EINVAL; + } else { + return -EINVAL; + } + break; + } + case SIOCSIWAP: + { + int ap = 0; + + if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) + return -EINVAL; + + if (wl_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)) < 0) + return -EINVAL; + + if (wl_ioctl(dev, (ap ? WLC_SET_BSSID : WLC_REASSOC), wrqu->ap_addr.sa_data, 6) < 0) + return -EINVAL; + + break; + } + case SIOCGIWAP: + { + wrqu->ap_addr.sa_family = ARPHRD_ETHER; + if (wl_ioctl(dev,WLC_GET_BSSID,wrqu->ap_addr.sa_data,6) < 0) + return -EINVAL; + break; + } + case SIOCGIWESSID: + { + wlc_ssid_t ssid; + + if (wl_ioctl(dev,WLC_GET_SSID, &ssid, sizeof(wlc_ssid_t)) < 0) + return -EINVAL; + + wrqu->essid.flags = wrqu->data.flags = 1; + wrqu->essid.length = wrqu->data.length = ssid.SSID_len + 1; + memcpy(extra,ssid.SSID,ssid.SSID_len + 1); + break; + } + case SIOCSIWESSID: + { + wlc_ssid_t ssid; + memset(&ssid, 0, sizeof(ssid)); + ssid.SSID_len = strlen(extra); + if (ssid.SSID_len > WLC_ESSID_MAX_SIZE) + ssid.SSID_len = WLC_ESSID_MAX_SIZE; + memcpy(ssid.SSID, extra, ssid.SSID_len); + if (wl_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid)) < 0) + return -EINVAL; + break; + } + case SIOCGIWRTS: + { + if (wl_ioctl(dev,WLC_GET_RTS,&(wrqu->rts.value),sizeof(int)) < 0) + return -EINVAL; + break; + } + case SIOCSIWRTS: + { + if (wl_ioctl(dev,WLC_SET_RTS,&(wrqu->rts.value),sizeof(int)) < 0) + return -EINVAL; + break; + } + case SIOCGIWFRAG: + { + if (wl_ioctl(dev,WLC_GET_FRAG,&(wrqu->frag.value),sizeof(int)) < 0) + return -EINVAL; + break; + } + case SIOCSIWFRAG: + { + if (wl_ioctl(dev,WLC_SET_FRAG,&(wrqu->frag.value),sizeof(int)) < 0) + return -EINVAL; + break; + } + case SIOCGIWTXPOW: + { + if (wl_get_val(dev, "qtxpower", &(wrqu->txpower.value), sizeof(int)) < 0) + return -EINVAL; + + wrqu->txpower.value &= ~WL_TXPWR_OVERRIDE; + + wrqu->txpower.fixed = 0; + wrqu->txpower.disabled = 0; + wrqu->txpower.flags = IW_TXPOW_MWATT; + break; + } + case SIOCSIWTXPOW: + { + int override; + + if (wl_get_val(dev, "qtxpower", &override, sizeof(int)) < 0) + return -EINVAL; + + wrqu->txpower.value |= override & WL_TXPWR_OVERRIDE; + + if (wrqu->txpower.flags != IW_TXPOW_MWATT) + return -EINVAL; + + if (wl_set_val(dev, "qtxpower", &wrqu->txpower.value, sizeof(int)) < 0) + return -EINVAL; + } + case SIOCGIWENCODE: + { + int val; + + if (wl_ioctl(dev, WLC_GET_WEP, &val, sizeof(val)) < 0) + return -EINVAL; + + + if (val > 0) { + int key; + + for (key = val = 0; (key < 4) && (val == 0); key++) { + val = key; + if (wl_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)) < 0) + return -EINVAL; + } + + wrqu->data.flags = IW_ENCODE_ENABLED; + if (key-- > 0) { + int magic_offset; + int16 buffer[8]; + + magic_offset = read_shmem(dev, 0x56) * 2; + + wrqu->data.flags |= key + 1; + wrqu->data.length = 16; + + for (val = 0; val < 8; val++) { + buffer[val] = read_shmem(dev, magic_offset + (key * 16) + val * 2); + } + + memset(extra, 0, 16); + memcpy(extra, buffer, 16); + } else { + wrqu->data.flags |= IW_ENCODE_NOKEY; + } + } else { + wrqu->data.flags = IW_ENCODE_DISABLED; + } + + break; + } + case SIOCGIWRANGE: + { + return wlcompat_ioctl_getiwrange(dev, extra); + break; + } + case SIOCSIWMODE: + { + int ap = -1, infra = -1, passive = 0, wet = 0; + + switch (wrqu->mode) { + case IW_MODE_MONITOR: + passive = 1; + break; + case IW_MODE_ADHOC: + infra = 0; + ap = 0; + break; + case IW_MODE_MASTER: + infra = 1; + ap = 1; + break; + case IW_MODE_INFRA: + infra = 1; + ap = 0; + break; + case IW_MODE_REPEAT: + infra = 1; + ap = 0; + wet = 1; + break; + default: + return -EINVAL; + } + + if (wl_ioctl(dev, WLC_SET_PASSIVE, &passive, sizeof(passive)) < 0) + return -EINVAL; + if (wl_ioctl(dev, WLC_SET_MONITOR, &passive, sizeof(passive)) < 0) + return -EINVAL; + if (wl_ioctl(dev, WLC_SET_WET, &wet, sizeof(wet)) < 0) + return -EINVAL; + if (ap >= 0) + if (wl_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)) < 0) + return -EINVAL; + if (infra >= 0) + if (wl_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra)) < 0) + return -EINVAL; + + break; + + } + case SIOCGIWMODE: + { + int ap, infra, wet, passive; + + if (wl_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)) < 0) + return -EINVAL; + if (wl_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra)) < 0) + return -EINVAL; + if (wl_ioctl(dev, WLC_GET_PASSIVE, &passive, sizeof(passive)) < 0) + return -EINVAL; + if (wl_ioctl(dev, WLC_GET_WET, &wet, sizeof(wet)) < 0) + return -EINVAL; + + if (passive) { + wrqu->mode = IW_MODE_MONITOR; + } else if (!infra) { + wrqu->mode = IW_MODE_ADHOC; + } else { + if (ap) { + wrqu->mode = IW_MODE_MASTER; + } else { + if (wet) { + wrqu->mode = IW_MODE_REPEAT; + } else { + wrqu->mode = IW_MODE_INFRA; + } + } + } + break; + } + default: + { + if (info->cmd >= SIOCIWFIRSTPRIV) + return wlcompat_private_ioctl(dev, info, wrqu, extra); + + return -EINVAL; + } + } + + return 0; +} + +static const iw_handler wlcompat_handler[] = { + NULL, /* SIOCSIWCOMMIT */ + wlcompat_ioctl, /* SIOCGIWNAME */ + NULL, /* SIOCSIWNWID */ + NULL, /* SIOCGIWNWID */ + wlcompat_ioctl, /* SIOCSIWFREQ */ + wlcompat_ioctl, /* SIOCGIWFREQ */ + wlcompat_ioctl, /* SIOCSIWMODE */ + wlcompat_ioctl, /* SIOCGIWMODE */ + NULL, /* SIOCSIWSENS */ + NULL, /* SIOCGIWSENS */ + NULL, /* SIOCSIWRANGE, unused */ + wlcompat_ioctl, /* SIOCGIWRANGE */ + NULL, /* SIOCSIWPRIV */ + NULL, /* SIOCGIWPRIV */ + NULL, /* SIOCSIWSTATS */ + NULL, /* SIOCGIWSTATS */ + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ + wlcompat_ioctl, /* SIOCSIWAP */ + wlcompat_ioctl, /* SIOCGIWAP */ + NULL, /* -- hole -- */ + NULL, /* SIOCGIWAPLIST */ + wlcompat_set_scan, /* SIOCSIWSCAN */ + wlcompat_get_scan, /* SIOCGIWSCAN */ + wlcompat_ioctl, /* SIOCSIWESSID */ + wlcompat_ioctl, /* SIOCGIWESSID */ + NULL, /* SIOCSIWNICKN */ + NULL, /* SIOCGIWNICKN */ + NULL, /* -- hole -- */ + NULL, /* -- hole -- */ + NULL, /* SIOCSIWRATE */ + NULL, /* SIOCGIWRATE */ + wlcompat_ioctl, /* SIOCSIWRTS */ + wlcompat_ioctl, /* SIOCGIWRTS */ + wlcompat_ioctl, /* SIOCSIWFRAG */ + wlcompat_ioctl, /* SIOCGIWFRAG */ + wlcompat_ioctl, /* SIOCSIWTXPOW */ + wlcompat_ioctl, /* SIOCGIWTXPOW */ + NULL, /* SIOCSIWRETRY */ + NULL, /* SIOCGIWRETRY */ + NULL, /* SIOCSIWENCODE */ + wlcompat_ioctl, /* SIOCGIWENCODE */ +}; + +static int wlcompat_private_ioctl(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int *value = (int *) wrqu->name; + + switch (info->cmd) { + case WLCOMPAT_SET_MONITOR: + { + if (wl_ioctl(dev, WLC_SET_MONITOR, value, sizeof(int)) < 0) + return -EINVAL; + + break; + } + case WLCOMPAT_GET_MONITOR: + { + if (wl_ioctl(dev, WLC_GET_MONITOR, extra, sizeof(int)) < 0) + return -EINVAL; + + break; + } + case WLCOMPAT_SET_TXPWR_LIMIT: + { + int val; + + + if (wl_get_val(dev, "qtxpower", &val, sizeof(int)) < 0) + return -EINVAL; + + if (*extra > 0) + val |= WL_TXPWR_OVERRIDE; + else + val &= ~WL_TXPWR_OVERRIDE; + + if (wl_set_val(dev, "qtxpower", &val, sizeof(int)) < 0) + return -EINVAL; + + break; + } + case WLCOMPAT_GET_TXPWR_LIMIT: + { + if (wl_get_val(dev, "qtxpower", value, sizeof(int)) < 0) + return -EINVAL; + + *value = ((*value & WL_TXPWR_OVERRIDE) == WL_TXPWR_OVERRIDE ? 1 : 0); + + break; + } + case WLCOMPAT_SET_ANTDIV: + { + if (wl_ioctl(dev, WLC_SET_ANTDIV, value, sizeof(int)) < 0) + return -EINVAL; + + break; + } + case WLCOMPAT_GET_ANTDIV: + { + if (wl_ioctl(dev, WLC_GET_ANTDIV, extra, sizeof(int)) < 0) + return -EINVAL; + + break; + } + case WLCOMPAT_SET_TXANT: + { + if (wl_ioctl(dev, WLC_SET_TXANT, value, sizeof(int)) < 0) + return -EINVAL; + + break; + } + case WLCOMPAT_GET_TXANT: + { + if (wl_ioctl(dev, WLC_GET_TXANT, extra, sizeof(int)) < 0) + return -EINVAL; + + break; + } + default: + { + return -EINVAL; + } + + } + return 0; +} + +static const struct iw_priv_args wlcompat_private_args[] = +{ + { WLCOMPAT_SET_MONITOR, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_monitor" + }, + { WLCOMPAT_GET_MONITOR, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_monitor" + }, + { WLCOMPAT_SET_TXPWR_LIMIT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_txpwr_force" + }, + { WLCOMPAT_GET_TXPWR_LIMIT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_txpwr_force" + }, + { WLCOMPAT_SET_ANTDIV, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_antdiv" + }, + { WLCOMPAT_GET_ANTDIV, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_antdiv" + }, + { WLCOMPAT_SET_TXANT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_txant" + }, + { WLCOMPAT_GET_TXANT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_txant" + }, +}; + +static const iw_handler wlcompat_private[] = +{ + wlcompat_private_ioctl, + NULL +}; + + +static const struct iw_handler_def wlcompat_handler_def = +{ + .standard = (iw_handler *) wlcompat_handler, + .num_standard = sizeof(wlcompat_handler)/sizeof(iw_handler), + .private = wlcompat_private, + .num_private = 1, + .private_args = wlcompat_private_args, + .num_private_args = sizeof(wlcompat_private_args) / sizeof(wlcompat_private_args[0]) +}; + + +#ifdef DEBUG +void print_buffer(int len, unsigned char *buf) { + int x; + if (buf != NULL) { + for (x=0;x<len && x<180 ;x++) { + if ((x % 4) == 0) + printk(" "); + printk("%02X",buf[x]); + } + } else { + printk(" NULL"); + } + printk("\n"); + +} +#endif +static int (*old_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); +static int new_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { + int ret = 0; + struct iwreq *iwr = (struct iwreq *) ifr; + struct iw_request_info info; + +#ifdef DEBUG + printk("dev: %s ioctl: 0x%04x\n",dev->name,cmd); +#endif + + if (cmd >= SIOCIWFIRSTPRIV) { + info.cmd = cmd; + info.flags = 0; + ret = wlcompat_private_ioctl(dev, &info, &(iwr->u), (char *) &(iwr->u)); +#ifdef DEBUG + } else if (cmd==SIOCDEVPRIVATE) { + wl_ioctl_t *ioc = (wl_ioctl_t *)ifr->ifr_data; + unsigned char *buf = ioc->buf; + printk(" cmd: %d buf: 0x%08x len: %d\n",ioc->cmd,&(ioc->buf),ioc->len); + printk(" send: ->"); + print_buffer(ioc->len, buf); + ret = old_ioctl(dev,ifr,cmd); + printk(" recv: ->"); + print_buffer(ioc->len, buf); + printk(" ret: %d\n", ret); +#endif + } else { + ret = old_ioctl(dev,ifr,cmd); + } + return ret; +} + +static int __init wlcompat_init() +{ + int found = 0, i; + char *devname = "eth0"; + + while (!found && (dev = dev_get_by_name(devname))) { + if ((dev->wireless_handlers == NULL) && ((wl_ioctl(dev, WLC_GET_MAGIC, &i, sizeof(i)) == 0) && i == WLC_IOCTL_MAGIC)) + found = 1; + devname[3]++; + } + + if (!found) { + printk("No Broadcom devices found.\n"); + return -ENODEV; + } + + + old_ioctl = dev->do_ioctl; + dev->do_ioctl = new_ioctl; + dev->wireless_handlers = (struct iw_handler_def *)&wlcompat_handler_def; + return 0; +} + +static void __exit wlcompat_exit() +{ + dev->wireless_handlers = NULL; + dev->do_ioctl = old_ioctl; + return; +} + +EXPORT_NO_SYMBOLS; +MODULE_AUTHOR("openwrt.org"); +MODULE_LICENSE("GPL"); + +module_init(wlcompat_init); +module_exit(wlcompat_exit); |