fix up hostapd for mac80211
authorFelix Fietkau <nbd@openwrt.org>
Fri, 16 Nov 2007 03:10:56 +0000 (03:10 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Fri, 16 Nov 2007 03:10:56 +0000 (03:10 +0000)
SVN-Revision: 9554

138 files changed:
package/hostapd/Makefile
package/hostapd/files/default.config
package/hostapd/files/mini.config
package/hostapd/patches/001-cross_compile_fix.patch [deleted file]
package/hostapd/patches/001-remove-michael-mic.patch [new file with mode: 0644]
package/hostapd/patches/002-use-nl80211-for-keys.patch [new file with mode: 0644]
package/hostapd/patches/003-use-nl80211-for-beacons.patch [new file with mode: 0644]
package/hostapd/patches/004-use-nl80211-for-get-key.patch [new file with mode: 0644]
package/hostapd/patches/005-pass-full-flags-to-sta-function.patch [new file with mode: 0644]
package/hostapd/patches/006-use-nl80211-for-sta.patch [new file with mode: 0644]
package/hostapd/patches/100-madwifi_fixes.patch [deleted file]
package/libnl/Makefile
package/mac80211/Makefile
package/mac80211/patches/000-mac80211_update.patch [new file with mode: 0644]
package/mac80211/patches/008-add-hostapd-ioctl-header.patch [new file with mode: 0644]
package/mac80211/patches/009-add-old-ioctl-skeleton.patch [new file with mode: 0644]
package/mac80211/patches/010-add-mgmt-iface.patch [new file with mode: 0644]
package/mac80211/patches/011-allow-ap-vlan-modes.patch [new file with mode: 0644]
package/mac80211/patches/012-mac80211-allow-wds.patch [new file with mode: 0644]
package/mac80211/patches/013-prism2-ioctl-bridge-packets.patch [new file with mode: 0644]
package/mac80211/patches/014-prism2-ioctl-8021x.patch [new file with mode: 0644]
package/mac80211/patches/015-hostapd-ioctl-hw-features.patch [new file with mode: 0644]
package/mac80211/patches/016-prism2-ioctl-eapol.patch [new file with mode: 0644]
package/mac80211/patches/017-nl80211-add-key-mgmt.patch [new file with mode: 0644]
package/mac80211/patches/018-mac80211-cfg80211-keys.patch [new file with mode: 0644]
package/mac80211/patches/019-mac80211-key-seq-nl80211.patch [new file with mode: 0644]
package/mac80211/patches/020-nl80211-beacon-parameters.patch [new file with mode: 0644]
package/mac80211/patches/021-mac80211-beacon-via-nl80211.patch [new file with mode: 0644]
package/mac80211/patches/022-nl80211-sta.patch [new file with mode: 0644]
package/mac80211/patches/023-mac80211-implement-sta.patch [new file with mode: 0644]
package/mac80211/patches/024-nl80211-get-sta.patch [new file with mode: 0644]
package/mac80211/patches/025-mac80211-get-sta.patch [new file with mode: 0644]
package/mac80211/src/mac80211/Kconfig [deleted file]
package/mac80211/src/mac80211/Makefile [deleted file]
package/mac80211/src/mac80211/aes_ccm.c [deleted file]
package/mac80211/src/mac80211/aes_ccm.h [deleted file]
package/mac80211/src/mac80211/cfg.c [deleted file]
package/mac80211/src/mac80211/cfg.h [deleted file]
package/mac80211/src/mac80211/debugfs.c [deleted file]
package/mac80211/src/mac80211/debugfs.h [deleted file]
package/mac80211/src/mac80211/debugfs_key.c [deleted file]
package/mac80211/src/mac80211/debugfs_key.h [deleted file]
package/mac80211/src/mac80211/debugfs_netdev.c [deleted file]
package/mac80211/src/mac80211/debugfs_netdev.h [deleted file]
package/mac80211/src/mac80211/debugfs_sta.c [deleted file]
package/mac80211/src/mac80211/debugfs_sta.h [deleted file]
package/mac80211/src/mac80211/event.c [deleted file]
package/mac80211/src/mac80211/ieee80211.c [deleted file]
package/mac80211/src/mac80211/ieee80211_common.h [deleted file]
package/mac80211/src/mac80211/ieee80211_i.h [deleted file]
package/mac80211/src/mac80211/ieee80211_iface.c [deleted file]
package/mac80211/src/mac80211/ieee80211_ioctl.c [deleted file]
package/mac80211/src/mac80211/ieee80211_key.h [deleted file]
package/mac80211/src/mac80211/ieee80211_led.c [deleted file]
package/mac80211/src/mac80211/ieee80211_led.h [deleted file]
package/mac80211/src/mac80211/ieee80211_rate.c [deleted file]
package/mac80211/src/mac80211/ieee80211_rate.h [deleted file]
package/mac80211/src/mac80211/ieee80211_sta.c [deleted file]
package/mac80211/src/mac80211/key.c [deleted file]
package/mac80211/src/mac80211/michael.c [deleted file]
package/mac80211/src/mac80211/michael.h [deleted file]
package/mac80211/src/mac80211/rc80211_simple.c [deleted file]
package/mac80211/src/mac80211/regdomain.c [deleted file]
package/mac80211/src/mac80211/rx.c [deleted file]
package/mac80211/src/mac80211/sta_info.c [deleted file]
package/mac80211/src/mac80211/sta_info.h [deleted file]
package/mac80211/src/mac80211/tkip.c [deleted file]
package/mac80211/src/mac80211/tkip.h [deleted file]
package/mac80211/src/mac80211/tx.c [deleted file]
package/mac80211/src/mac80211/util.c [deleted file]
package/mac80211/src/mac80211/wep.c [deleted file]
package/mac80211/src/mac80211/wep.h [deleted file]
package/mac80211/src/mac80211/wme.c [deleted file]
package/mac80211/src/mac80211/wme.h [deleted file]
package/mac80211/src/mac80211/wpa.c [deleted file]
package/mac80211/src/mac80211/wpa.h [deleted file]
package/mac80211/src/net/mac80211/Kconfig [new file with mode: 0644]
package/mac80211/src/net/mac80211/Makefile [new file with mode: 0644]
package/mac80211/src/net/mac80211/aes_ccm.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/aes_ccm.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/cfg.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/cfg.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/debugfs.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/debugfs.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/debugfs_key.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/debugfs_key.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/debugfs_netdev.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/debugfs_netdev.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/debugfs_sta.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/debugfs_sta.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/event.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_common.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_i.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_iface.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_ioctl.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_key.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_led.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_led.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_rate.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_rate.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/ieee80211_sta.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/key.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/michael.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/michael.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/rc80211_simple.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/regdomain.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/rx.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/sta_info.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/sta_info.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/tkip.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/tkip.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/tx.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/util.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/wep.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/wep.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/wme.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/wme.h [new file with mode: 0644]
package/mac80211/src/net/mac80211/wpa.c [new file with mode: 0644]
package/mac80211/src/net/mac80211/wpa.h [new file with mode: 0644]
package/mac80211/src/net/wireless/Kconfig [new file with mode: 0644]
package/mac80211/src/net/wireless/Makefile [new file with mode: 0644]
package/mac80211/src/net/wireless/core.c [new file with mode: 0644]
package/mac80211/src/net/wireless/core.h [new file with mode: 0644]
package/mac80211/src/net/wireless/nl80211.c [new file with mode: 0644]
package/mac80211/src/net/wireless/nl80211.h [new file with mode: 0644]
package/mac80211/src/net/wireless/radiotap.c [new file with mode: 0644]
package/mac80211/src/net/wireless/sysfs.c [new file with mode: 0644]
package/mac80211/src/net/wireless/sysfs.h [new file with mode: 0644]
package/mac80211/src/wireless/Kconfig [deleted file]
package/mac80211/src/wireless/Makefile [deleted file]
package/mac80211/src/wireless/core.c [deleted file]
package/mac80211/src/wireless/core.h [deleted file]
package/mac80211/src/wireless/nl80211.c [deleted file]
package/mac80211/src/wireless/nl80211.h [deleted file]
package/mac80211/src/wireless/radiotap.c [deleted file]
package/mac80211/src/wireless/sysfs.c [deleted file]
package/mac80211/src/wireless/sysfs.h [deleted file]

index 85f42dc..d791073 100644 (file)
@@ -9,14 +9,15 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=hostapd
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=hostapd
-PKG_VERSION:=0.5.8
+PKG_REV:=03ec0ec5cdb974d51a4a2a566bea4c4568138576
+PKG_VERSION:=20071107_$(PKG_REV)
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://hostap.epitest.fi/releases/
-PKG_MD5SUM:=40416b48cae9c78e5a2452caf214aff3
-
-PKG_BUILD_DEPENDS:=madwifi
+PKG_SOURCE_URL:=git://w1.fi/srv/git/hostap.git
+PKG_SOURCE_SUBDIR:=hostapd-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_BUILD_DEPENDS:=madwifi mac80211
 
 include $(INCLUDE_DIR)/package.mk
 
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -25,7 +26,7 @@ define Package/hostapd/Default
   CATEGORY:=Network
   TITLE:=IEEE 802.1x Authenticator
   URL:=http://hostap.epitest.fi/
   CATEGORY:=Network
   TITLE:=IEEE 802.1x Authenticator
   URL:=http://hostap.epitest.fi/
-  DEPENDS:=@!TARGET_avr32 @!TARGET_etrax
+  DEPENDS:=@!TARGET_avr32 @!TARGET_etrax $(if $(DUMP)$(CONFIG_LINUX_2_6_23),+libnl)
 endef
 
 define Package/hostapd
 endef
 
 define Package/hostapd
@@ -34,9 +35,9 @@ $(call Package/hostapd/Default)
   DEPENDS+= +libopenssl
 endef
 
   DEPENDS+= +libopenssl
 endef
 
-define Package/hostapd/conffiles
-/etc/hostapd.conf
-endef
+#define Package/hostapd/conffiles
+#/etc/hostapd.conf
+#endef
 
 define Package/hostapd/description
  This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS 
 
 define Package/hostapd/description
  This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS 
@@ -48,9 +49,9 @@ $(call Package/hostapd/Default)
   TITLE+= (WPA-PSK only)
 endef
 
   TITLE+= (WPA-PSK only)
 endef
 
-define Package/hostapd-mini/conffiles
-/etc/hostapd.conf
-endef
+#define Package/hostapd-mini/conffiles
+#/etc/hostapd.conf
+#endef
 
 define Package/hostapd-mini/description
  This package contains a minimal IEEE 802.1x/WPA/EAP/RADIUS Authenticator 
 
 define Package/hostapd-mini/description
  This package contains a minimal IEEE 802.1x/WPA/EAP/RADIUS Authenticator 
@@ -69,38 +70,31 @@ define Package/hostapd-utils/description
 endef
 
 define Build/ConfigureTarget
 endef
 
 define Build/ConfigureTarget
-       $(CP) $(PKG_BUILD_DIR) $(PKG_BUILD_DIR)_$(1)
-       $(CP) ./files/$(1).config $(PKG_BUILD_DIR)_$(1)/.config
-ifneq ($(CONFIG_PACKAGE_kmod-madwifi),)
-       echo "CONFIG_DRIVER_MADWIFI=y" >> $(PKG_BUILD_DIR)_$(1)/.config
-endif
+       rm -rf $(PKG_BUILD_DIR)/hostapd.$(1)
+       $(CP) $(PKG_BUILD_DIR)/hostapd $(PKG_BUILD_DIR)/hostapd.$(1)
+       $(CP) ./files/$(1).config $(PKG_BUILD_DIR)/hostapd.$(1)/.config
+       [ -d $(STAGING_DIR)/usr/include/mac80211 ] || $(SED) 's,^CONFIG_DRIVER_DEVICESCAPE,#CONFIG_DRIVER_DEVICESCAPE,g' $(PKG_BUILD_DIR)/hostapd.$(1)/.config
+       [ -d $(STAGING_DIR)/usr/include/madwifi ] || $(SED) 's,^CONFIG_DRIVER_MADWIFI,#CONFIG_DRIVER_MADWIFI,g' $(PKG_BUILD_DIR)/hostapd.$(1)/.config
 endef
 
 define Build/CompileTarget
 endef
 
 define Build/CompileTarget
-       $(MAKE) -C $(PKG_BUILD_DIR)_$(1) \
+       CFLAGS="$(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/include/madwifi -I$(STAGING_DIR)/usr/include/mac80211 -I$(STAGING_DIR)/usr/include" \
+       $(MAKE) -C $(PKG_BUILD_DIR)/hostapd.$(1) \
                $(TARGET_CONFIGURE_OPTS) \
                $(TARGET_CONFIGURE_OPTS) \
-               OPTFLAGS="$(TARGET_CFLAGS)" \
-               CPPFLAGS="$(TARGET_CPPFLAGS) -I$(STAGING_DIR)/usr/include/madwifi" \
-               LDFLAGS="$(TARGET_LDFLAGS)" \
+               LIBS="$(TARGET_LDFLAGS) -L$(STAGING_DIR)/usr/lib \
+                       $(if $(wildcard $(STAGING_DIR)/usr/include/mac80211/*),-lnl)" \
                hostapd hostapd_cli
                hostapd hostapd_cli
-       $(CP) $(PKG_BUILD_DIR)_$(1)/hostapd_cli $(PKG_BUILD_DIR)/
+       $(CP) $(PKG_BUILD_DIR)/hostapd.$(1)/hostapd_cli $(PKG_BUILD_DIR)/
 endef
 
 define Package/InstallTemplate
 endef
 
 define Package/InstallTemplate
-       if [ \! -f "$(PKG_BUILD_DIR)_$(2)/hostapd" ]; then \
-               rm -f $(PKG_BUILD_DIR)/.built; \
-               $(MAKE) $(PKG_BUILD_DIR)/.built; \
-       fi
        $(INSTALL_DIR) $$(1)/lib/wifi
        $(INSTALL_DATA) ./files/hostapd.sh $$(1)/lib/wifi/hostapd.sh
        $(INSTALL_DIR) $$(1)/lib/wifi
        $(INSTALL_DATA) ./files/hostapd.sh $$(1)/lib/wifi/hostapd.sh
-       $(INSTALL_DIR) $$(1)/etc
-ifneq ($(CONFIG_PACKAGE_kmod-madwifi),)
-       $(INSTALL_CONF) $(PKG_BUILD_DIR)_$(2)/madwifi.conf $$(1)/etc/hostapd.conf
-else
-       $(INSTALL_CONF) $(PKG_BUILD_DIR)_$(2)/hostapd.conf $$(1)/etc/hostapd.conf
-endif
+# config is managed through uci
+#      $(INSTALL_DIR) $$(1)/etc
+#      $(INSTALL_CONF) $(PKG_BUILD_DIR)/hostapd.$(2)/hostapd.conf $$(1)/etc/hostapd.conf 
        $(INSTALL_DIR) $$(1)/usr/sbin
        $(INSTALL_DIR) $$(1)/usr/sbin
-       $(INSTALL_BIN) $(PKG_BUILD_DIR)_$(2)/hostapd $$(1)/usr/sbin/
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd.$(2)/hostapd $$(1)/usr/sbin/
 endef
 
 define Package/Template
 endef
 
 define Package/Template
index de27420..700217d 100644 (file)
 CONFIG_DRIVER_HOSTAP=y
 
 # Driver interface for wired authenticator
 CONFIG_DRIVER_HOSTAP=y
 
 # Driver interface for wired authenticator
-#CONFIG_DRIVER_WIRED=y
+CONFIG_DRIVER_WIRED=y
 
 # Driver interface for madwifi driver
 
 # Driver interface for madwifi driver
-#CONFIG_DRIVER_MADWIFI=y
+CONFIG_DRIVER_MADWIFI=y
 #CFLAGS += -I../head # change to reflect local setup; directory for madwifi src
 
 # Driver interface for Prism54 driver
 #CONFIG_DRIVER_PRISM54=y
 
 #CFLAGS += -I../head # change to reflect local setup; directory for madwifi src
 
 # Driver interface for Prism54 driver
 #CONFIG_DRIVER_PRISM54=y
 
+# Driver interface for drivers using Devicescape IEEE 802.11 stack
+CONFIG_DRIVER_DEVICESCAPE=y
+# Currently, driver_devicescape.c build requires some additional parameters
+# to be able to include some of the kernel header files. Following lines can
+# be used to set these (WIRELESS_DEV must point to the root directory of the
+# wireless-dev.git tree).
+#WIRELESS_DEV=/usr/src/wireless-dev
+#CFLAGS += -I$(WIRELESS_DEV)/net/mac80211
+# driver_devicescape.c requires a rather new libnl, probably not
+# shipped with your distribution yet
+#LIBNL=/usr/src/libnl
+#CFLAGS += -I$(LIBNL)/include
+#LIBS += -L$(LIBNL)/lib
+
 # Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
 #CONFIG_DRIVER_BSD=y
 #CFLAGS += -I/usr/local/include
 # Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
 #CONFIG_DRIVER_BSD=y
 #CFLAGS += -I/usr/local/include
@@ -33,37 +47,76 @@ CONFIG_IAPP=y
 # WPA2/IEEE 802.11i RSN pre-authentication
 CONFIG_RSN_PREAUTH=y
 
 # WPA2/IEEE 802.11i RSN pre-authentication
 CONFIG_RSN_PREAUTH=y
 
-# Integrated EAP authenticator
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Integrated EAP server
 CONFIG_EAP=y
 
 CONFIG_EAP=y
 
-# EAP-MD5 for the integrated EAP authenticator
+# EAP-MD5 for the integrated EAP server
 CONFIG_EAP_MD5=y
 
 CONFIG_EAP_MD5=y
 
-# EAP-TLS for the integrated EAP authenticator
+# EAP-TLS for the integrated EAP server
 CONFIG_EAP_TLS=y
 
 CONFIG_EAP_TLS=y
 
-# EAP-MSCHAPv2 for the integrated EAP authenticator
+# EAP-MSCHAPv2 for the integrated EAP server
 CONFIG_EAP_MSCHAPV2=y
 
 CONFIG_EAP_MSCHAPV2=y
 
-# EAP-PEAP for the integrated EAP authenticator
+# EAP-PEAP for the integrated EAP server
 CONFIG_EAP_PEAP=y
 
 CONFIG_EAP_PEAP=y
 
-# EAP-PSK for the integrated EAP authenticator
-CONFIG_EAP_PSK=y
-
-# EAP-GTC for the integrated EAP authenticator
+# EAP-GTC for the integrated EAP server
 CONFIG_EAP_GTC=y
 
 CONFIG_EAP_GTC=y
 
-# EAP-TTLS for the integrated EAP authenticator
+# EAP-TTLS for the integrated EAP server
 CONFIG_EAP_TTLS=y
 
 CONFIG_EAP_TTLS=y
 
-# EAP-SIM for the integrated EAP authenticator
+# EAP-SIM for the integrated EAP server
 #CONFIG_EAP_SIM=y
 
 #CONFIG_EAP_SIM=y
 
+# EAP-AKA for the integrated EAP server
+#CONFIG_EAP_AKA=y
+
+# EAP-PAX for the integrated EAP server
+#CONFIG_EAP_PAX=y
+
+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-SAKE for the integrated EAP server
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK for the integrated EAP server
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-FAST for the integrated EAP server
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
 # PKCS#12 (PFX) support (used to read private key and certificate file from
 # a file that usually has extension .p12 or .pfx)
 CONFIG_PKCS12=y
 
 # RADIUS authentication server. This provides access to the integrated EAP
 # PKCS#12 (PFX) support (used to read private key and certificate file from
 # a file that usually has extension .p12 or .pfx)
 CONFIG_PKCS12=y
 
 # RADIUS authentication server. This provides access to the integrated EAP
-# authenticator from external hosts using RADIUS.
+# server from external hosts using RADIUS.
 #CONFIG_RADIUS_SERVER=y
 #CONFIG_RADIUS_SERVER=y
+
+# Build IPv6 support for RADIUS operations
+CONFIG_IPV6=y
+
+# IEEE 802.11r/D4.1 (Fast BSS Transition)
+# This enables an experimental implementation of a draft version of
+# IEEE 802.11r. This draft is still subject to change, so it should be noted
+# that this version may not comply with the final standard.
+#CONFIG_IEEE80211R=y
index cfdc485..a2f3f62 100644 (file)
 CONFIG_DRIVER_HOSTAP=y
 
 # Driver interface for wired authenticator
 CONFIG_DRIVER_HOSTAP=y
 
 # Driver interface for wired authenticator
-#CONFIG_DRIVER_WIRED=y
+CONFIG_DRIVER_WIRED=y
 
 # Driver interface for madwifi driver
 
 # Driver interface for madwifi driver
-#CONFIG_DRIVER_MADWIFI=y
+CONFIG_DRIVER_MADWIFI=y
 #CFLAGS += -I../head # change to reflect local setup; directory for madwifi src
 
 # Driver interface for Prism54 driver
 #CONFIG_DRIVER_PRISM54=y
 
 #CFLAGS += -I../head # change to reflect local setup; directory for madwifi src
 
 # Driver interface for Prism54 driver
 #CONFIG_DRIVER_PRISM54=y
 
+# Driver interface for drivers using Devicescape IEEE 802.11 stack
+CONFIG_DRIVER_DEVICESCAPE=y
+# Currently, driver_devicescape.c build requires some additional parameters
+# to be able to include some of the kernel header files. Following lines can
+# be used to set these (WIRELESS_DEV must point to the root directory of the
+# wireless-dev.git tree).
+#WIRELESS_DEV=/usr/src/wireless-dev
+#CFLAGS += -I$(WIRELESS_DEV)/net/mac80211
+# driver_devicescape.c requires a rather new libnl, probably not
+# shipped with your distribution yet
+#LIBNL=/usr/src/libnl
+#CFLAGS += -I$(LIBNL)/include
+#LIBS += -L$(LIBNL)/lib
+
 # Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
 #CONFIG_DRIVER_BSD=y
 #CFLAGS += -I/usr/local/include
 # Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
 #CONFIG_DRIVER_BSD=y
 #CFLAGS += -I/usr/local/include
@@ -33,37 +47,76 @@ CONFIG_IAPP=y
 # WPA2/IEEE 802.11i RSN pre-authentication
 CONFIG_RSN_PREAUTH=y
 
 # WPA2/IEEE 802.11i RSN pre-authentication
 CONFIG_RSN_PREAUTH=y
 
-# Integrated EAP authenticator
-CONFIG_EAP=y
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Integrated EAP server
+#CONFIG_EAP=y
 
 
-# EAP-MD5 for the integrated EAP authenticator
+# EAP-MD5 for the integrated EAP server
 #CONFIG_EAP_MD5=y
 
 #CONFIG_EAP_MD5=y
 
-# EAP-TLS for the integrated EAP authenticator
+# EAP-TLS for the integrated EAP server
 #CONFIG_EAP_TLS=y
 
 #CONFIG_EAP_TLS=y
 
-# EAP-MSCHAPv2 for the integrated EAP authenticator
+# EAP-MSCHAPv2 for the integrated EAP server
 #CONFIG_EAP_MSCHAPV2=y
 
 #CONFIG_EAP_MSCHAPV2=y
 
-# EAP-PEAP for the integrated EAP authenticator
+# EAP-PEAP for the integrated EAP server
 #CONFIG_EAP_PEAP=y
 
 #CONFIG_EAP_PEAP=y
 
-# EAP-PSK for the integrated EAP authenticator
-CONFIG_EAP_PSK=y
-
-# EAP-GTC for the integrated EAP authenticator
+# EAP-GTC for the integrated EAP server
 #CONFIG_EAP_GTC=y
 
 #CONFIG_EAP_GTC=y
 
-# EAP-TTLS for the integrated EAP authenticator
+# EAP-TTLS for the integrated EAP server
 #CONFIG_EAP_TTLS=y
 
 #CONFIG_EAP_TTLS=y
 
-# EAP-SIM for the integrated EAP authenticator
+# EAP-SIM for the integrated EAP server
 #CONFIG_EAP_SIM=y
 
 #CONFIG_EAP_SIM=y
 
+# EAP-AKA for the integrated EAP server
+#CONFIG_EAP_AKA=y
+
+# EAP-PAX for the integrated EAP server
+#CONFIG_EAP_PAX=y
+
+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-SAKE for the integrated EAP server
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK for the integrated EAP server
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-FAST for the integrated EAP server
+# Note: Default OpenSSL package does not include support for all the
+# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
+# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
+# to add the needed functions.
+#CONFIG_EAP_FAST=y
+
 # PKCS#12 (PFX) support (used to read private key and certificate file from
 # a file that usually has extension .p12 or .pfx)
 #CONFIG_PKCS12=y
 
 # RADIUS authentication server. This provides access to the integrated EAP
 # PKCS#12 (PFX) support (used to read private key and certificate file from
 # a file that usually has extension .p12 or .pfx)
 #CONFIG_PKCS12=y
 
 # RADIUS authentication server. This provides access to the integrated EAP
-# authenticator from external hosts using RADIUS.
+# server from external hosts using RADIUS.
 #CONFIG_RADIUS_SERVER=y
 #CONFIG_RADIUS_SERVER=y
+
+# Build IPv6 support for RADIUS operations
+#CONFIG_IPV6=y
+
+# IEEE 802.11r/D4.1 (Fast BSS Transition)
+# This enables an experimental implementation of a draft version of
+# IEEE 802.11r. This draft is still subject to change, so it should be noted
+# that this version may not comply with the final standard.
+#CONFIG_IEEE80211R=y
diff --git a/package/hostapd/patches/001-cross_compile_fix.patch b/package/hostapd/patches/001-cross_compile_fix.patch
deleted file mode 100644 (file)
index 669264c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-Common subdirectories: hostapd-0.5.2/logwatch and hostapd-0.5.2.new/logwatch
-Index: hostapd-0.5.7/Makefile
-===================================================================
---- hostapd-0.5.7.orig/Makefile        2007-06-04 13:22:31.790022464 +0200
-+++ hostapd-0.5.7/Makefile     2007-06-04 13:22:31.856012432 +0200
-@@ -2,7 +2,7 @@
- DIR_WPA_SUPPLICANT=.
- ifndef CFLAGS
--CFLAGS = -MMD -O2 -Wall -g
-+CFLAGS = -MMD $(OPTFLAGS) $(CPPFLAGS)
- endif
- # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to
-@@ -336,7 +336,7 @@
-       for i in $(ALL); do cp $$i /usr/local/bin/$$i; done
- hostapd: $(OBJS)
--      $(CC) -o hostapd $(OBJS) $(LIBS)
-+      $(CC) -o hostapd $(OBJS) $(LDFLAGS) $(LIBS)
- driver_conf.c: Makefile .config
-       rm -f driver_conf.c
-@@ -400,10 +400,10 @@
- endif
- nt_password_hash: $(NOBJS)
--      $(CC) -o nt_password_hash $(NOBJS) $(LIBS_n)
-+      $(CC) -o nt_password_hash $(NOBJS) $(LDFLAGS) $(LIBS_n)
- hlr_auc_gw: $(HOBJS)
--      $(CC) -o hlr_auc_gw $(HOBJS) $(LIBS_h)
-+      $(CC) -o hlr_auc_gw $(HOBJS) $(LDFLAGS) $(LIBS_h)
- clean:
-       rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw
diff --git a/package/hostapd/patches/001-remove-michael-mic.patch b/package/hostapd/patches/001-remove-michael-mic.patch
new file mode 100644 (file)
index 0000000..de76c06
--- /dev/null
@@ -0,0 +1,18 @@
+---
+ hostapd/driver_devicescape.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c   2007-11-09 13:41:08.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c        2007-11-09 13:41:12.000000000 +0100
+@@ -1386,10 +1386,10 @@ static void handle_frame(struct hostapd_
+       case ieee80211_msg_wep_frame_unknown_key:
+               ieee802_11_rx_unknown_key(hapd, buf, data_len);
+               return;
+- */
+       case ieee80211_msg_michael_mic_failure:
+               hostapd_michael_mic_failure(hapd, buf, data_len);
+               return;
++ */
+ /*
+  * TODO
+  * We should be telling them to go away. But we don't support that now.
diff --git a/package/hostapd/patches/002-use-nl80211-for-keys.patch b/package/hostapd/patches/002-use-nl80211-for-keys.patch
new file mode 100644 (file)
index 0000000..6b7fe80
--- /dev/null
@@ -0,0 +1,112 @@
+---
+ hostapd/driver_devicescape.c |   93 ++++++++++++++++++++++++++++++-------------
+ 1 file changed, 67 insertions(+), 26 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c   2007-11-09 13:41:12.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c        2007-11-09 13:41:13.000000000 +0100
+@@ -150,38 +150,79 @@ static int i802_set_encryption(const cha
+                              size_t key_len, int txkey)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param *param;
+-      u8 *buf;
+-      size_t blen;
+-      int ret = 0;
++      struct nl_msg *msg;
++      int ret = -1;
++      int err = 0;
+-      blen = sizeof(*param) + key_len;
+-      buf = os_zalloc(blen);
+-      if (buf == NULL)
+-              return -1;
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
+-      param = (struct prism2_hostapd_param *) buf;
+-      param->cmd = PRISM2_SET_ENCRYPTION;
+-      if (addr == NULL)
+-              memset(param->sta_addr, 0xff, ETH_ALEN);
+-      else
+-              memcpy(param->sta_addr, addr, ETH_ALEN);
+-      os_strlcpy((char *) param->u.crypt.alg, alg,
+-                 HOSTAP_CRYPT_ALG_NAME_LEN);
+-      param->u.crypt.flags = txkey ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0;
+-      param->u.crypt.idx = idx;
+-      param->u.crypt.key_len = key_len;
+-      memcpy(param->u.crypt.key, key, key_len);
++      if (strcmp(alg, "none") == 0) {
++              genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                          0, NL80211_CMD_DEL_KEY, 0);
++      } else {
++              genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                          0, NL80211_CMD_NEW_KEY, 0);
++              NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
++              if (strcmp(alg, "WEP") == 0) {
++                      if (key_len == 5)
++                              NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
++                                          0x000FAC01);
++                      else
++                              NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
++                                          0x000FAC05);
++              } else if (strcmp(alg, "TKIP") == 0)
++                      NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC02);
++              else if (strcmp(alg, "CCMP") == 0)
++                      NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04);
++              else
++                      goto out;
++      }
+-      if (hostapd_ioctl_iface(iface, drv, param, blen) && errno != ENOENT) {
+-              printf("%s: Failed to set encryption to alg '%s' addr " MACSTR
+-                     " errno=%d\n",
+-                     iface, alg, MAC2STR(param->sta_addr), errno);
+-              ret = -1;
++      if (addr)
++              NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++      NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          (err = nl_wait_for_ack(drv->nl_handle)) < 0) {
++              if (err != -ENOENT) {
++                      err = 0;
++                      goto out;
++              }
+       }
+-      free(buf);
++      if (!txkey) {
++              ret = 0;
++              goto out;
++      }
++
++      nlmsg_free(msg);
++
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_SET_KEY, 0);
++      NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++      NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          (err = nl_wait_for_ack(drv->nl_handle)) < 0) {
++              if (err != -ENOENT) {
++                      err = 0;
++                      goto out;
++              }
++      }
++
++      ret = 0;
++
++ out:
++ nla_put_failure:
++      nlmsg_free(msg);
+       return ret;
+ }
diff --git a/package/hostapd/patches/003-use-nl80211-for-beacons.patch b/package/hostapd/patches/003-use-nl80211-for-beacons.patch
new file mode 100644 (file)
index 0000000..34fa841
--- /dev/null
@@ -0,0 +1,149 @@
+---
+ hostapd/driver_devicescape.c |  111 +++++++++++++++++++++++++++++++------------
+ 1 file changed, 82 insertions(+), 29 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c   2007-11-09 13:41:13.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c        2007-11-09 13:41:13.000000000 +0100
+@@ -68,6 +68,8 @@ struct i802_driver_data {
+       struct nl_handle *nl_handle;
+       struct nl_cache *nl_cache;
+       struct genl_family *nl80211;
++      int dtim_period;
++      unsigned int beacon_set:1;
+ };
+@@ -908,37 +910,44 @@ static int i802_bss_remove(void *priv, c
+ }
+-static int i802_set_beacon(const char *ifname, void *priv,
++static int i802_set_beacon(const char *iface, void *priv,
+                          u8 *head, size_t head_len,
+                          u8 *tail, size_t tail_len)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param *param;
+-      int len, ret = 0;
++      struct nl_msg *msg;
++      u8 cmd = NL80211_CMD_NEW_BEACON;
++      int ret = -1;
+-      param = os_zalloc(sizeof(*param) + head_len + tail_len);
+-      if (param == NULL) {
+-              printf("Failed to alloc memory for beacon ioctl\n");
+-              return -1;
+-      }
+-      len = (&param->u.beacon.data[0] - (u8 *) param) + head_len + tail_len;
+-      param->cmd = PRISM2_HOSTAPD_SET_BEACON;
+-      param->u.beacon.head_len = head_len;
+-      param->u.beacon.tail_len = tail_len;
+-      memcpy(&param->u.beacon.data[0], head, head_len);
+-      memcpy(&param->u.beacon.data[0] + head_len, tail, tail_len);
+-
+-      if (len < (int) sizeof(*param))
+-              len = sizeof(*param);
+-      if (hostapd_ioctl_iface(ifname, drv, param, len)) {
+-              printf("Could not set beacon data to kernel driver.\n");
+-              printf("ifname='%s' head=%p head_len=%d tail=%p tail_len=%d "
+-                     "cmd=%d\n",
+-                     ifname, head, head_len, tail, tail_len, param->cmd);
+-              ret = -1;
+-      }
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
+-      free(param);
++      if (drv->beacon_set)
++              cmd = NL80211_CMD_SET_BEACON;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, cmd, 0);
++      NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, head_len, head);
++      NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, tail_len, tail);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++      NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, 1000);
++
++      if (!drv->dtim_period)
++              drv->dtim_period = 2;
++      NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, drv->dtim_period);
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0)
++              goto out;
++
++      ret = 0;
++
++      drv->beacon_set = 1;
++
++ out:
++ nla_put_failure:
++      nlmsg_free(msg);
+       return ret;
+ }
+@@ -985,15 +994,59 @@ static int i802_set_internal_bridge(void
+ static int i802_set_beacon_int(void *priv, int value)
+ {
+       struct i802_driver_data *drv = priv;
+-      return hostap_ioctl_prism2param(drv, PRISM2_PARAM_BEACON_INT, value);
++      struct nl_msg *msg;
++      int ret = -1;
++
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_SET_BEACON, 0);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));
++
++      NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, value);
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0)
++              goto out;
++
++      ret = 0;
++
++ out:
++ nla_put_failure:
++      nlmsg_free(msg);
++      return ret;
+ }
+-static int i802_set_dtim_period(const char *ifname, void *priv, int value)
++static int i802_set_dtim_period(const char *iface, void *priv, int value)
+ {
+       struct i802_driver_data *drv = priv;
+-      return hostap_ioctl_prism2param_iface(ifname, drv,
+-                                            PRISM2_PARAM_DTIM_PERIOD, value);
++      struct nl_msg *msg;
++      int ret = -1;
++
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_SET_BEACON, 0);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++
++      drv->dtim_period = value;
++      NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, drv->dtim_period);
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0)
++              goto out;
++
++      ret = 0;
++
++ out:
++ nla_put_failure:
++      nlmsg_free(msg);
++      return ret;
+ }
diff --git a/package/hostapd/patches/004-use-nl80211-for-get-key.patch b/package/hostapd/patches/004-use-nl80211-for-get-key.patch
new file mode 100644 (file)
index 0000000..142c193
--- /dev/null
@@ -0,0 +1,116 @@
+---
+ hostapd/driver_devicescape.c |   96 ++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 76 insertions(+), 20 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c   2007-11-09 13:41:13.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c        2007-11-09 13:41:14.000000000 +0100
+@@ -228,33 +228,89 @@ static int i802_set_encryption(const cha
+       return ret;
+ }
++static inline int min_int(int a, int b)
++{
++      if (a<b)
++              return a;
++      return b;
++}
++
++static int get_key_handler(struct nl_msg *msg, void *arg)
++{
++      struct nlattr *tb[NL80211_ATTR_MAX];
++      struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
++
++      nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
++                genlmsg_attrlen(gnlh, 0), NULL);
++
++      /*
++       * TODO: validate the key index and mac address!
++       * Otherwise, there's a race condition as soon as
++       * the kernel starts sending key notifications.
++       */
++
++      if (tb[NL80211_ATTR_KEY_SEQ])
++              memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
++                     min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
++      return NL_SKIP;
++}
++
++static int ack_wait_handler(struct nl_msg *msg, void *arg)
++{
++      int *finished = arg;
++
++      *finished = 1;
++      return NL_STOP;
++}
+ static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
+                          int idx, u8 *seq)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param *param;
+-      size_t param_len;
+-      int ret;
++      struct nl_msg *msg;
++      struct nl_cb *cb = NULL;
++      int ret = -1;
++      int err = 0;
++      int finished = 0;
+-      param_len = sizeof(struct prism2_hostapd_param) + 32;
+-      param = os_zalloc(param_len);
+-      if (param == NULL)
+-              return -1;
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
+-      param->cmd = PRISM2_GET_ENCRYPTION;
+-      if (addr == NULL)
+-              memset(param->sta_addr, 0xff, ETH_ALEN);
+-      else
+-              memcpy(param->sta_addr, addr, ETH_ALEN);
+-      param->u.crypt.idx = idx;
+-
+-      ret = hostapd_ioctl_iface(iface, drv, param, param_len);
+-      if (ret == 0) {
+-              memcpy(seq, param->u.crypt.seq_counter,
+-                     HOSTAP_SEQ_COUNTER_SIZE);
+-      }
+-      free(param);
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_GET_KEY, 0);
++
++      if (addr)
++              NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++      NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
++
++      cb = nl_cb_alloc(NL_CB_CUSTOM);
++      if (!cb)
++              goto out;
++
++      memset(seq, 0, 6);
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0)
++              goto out;
++
++      nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_key_handler, seq);
++      nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
++
++      err = nl_recvmsgs(drv->nl_handle, cb);
++
++      if (!finished)
++              err = nl_wait_for_ack(drv->nl_handle);
++
++      if (err < 0)
++              goto out;
++
++      ret = 0;
++
++ out:
++      nl_cb_put(cb);
++ nla_put_failure:
++      nlmsg_free(msg);
+       return ret;
+ }
diff --git a/package/hostapd/patches/005-pass-full-flags-to-sta-function.patch b/package/hostapd/patches/005-pass-full-flags-to-sta-function.patch
new file mode 100644 (file)
index 0000000..11c8c5f
--- /dev/null
@@ -0,0 +1,173 @@
+---
+ hostapd/driver.h             |    8 ++++----
+ hostapd/driver_bsd.c         |    3 ++-
+ hostapd/driver_devicescape.c |    6 +++---
+ hostapd/driver_hostap.c      |    4 ++--
+ hostapd/driver_madwifi.c     |    3 ++-
+ hostapd/driver_prism54.c     |    3 ++-
+ hostapd/ieee802_11.c         |    4 ++--
+ hostapd/ieee802_1x.c         |    4 ++--
+ hostapd/wme.c                |    6 ++++--
+ 9 files changed, 23 insertions(+), 18 deletions(-)
+
+--- hostap.orig/hostapd/driver.h       2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver.h    2007-11-09 13:41:15.000000000 +0100
+@@ -92,7 +92,7 @@ struct wpa_driver_ops {
+       int (*get_retry)(void *priv, int *short_retry, int *long_retry);
+       int (*sta_set_flags)(void *priv, const u8 *addr,
+-                           int flags_or, int flags_and);
++                           int total_flags, int flags_or, int flags_and);
+       int (*set_rate_sets)(void *priv, int *supp_rates, int *basic_rates,
+                            int mode);
+       int (*set_channel_flag)(void *priv, int mode, int chan, int flag,
+@@ -427,12 +427,12 @@ hostapd_get_retry(struct hostapd_data *h
+ static inline int
+ hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
+-                    int flags_or, int flags_and)
++                    int total_flags, int flags_or, int flags_and)
+ {
+       if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
+               return 0;
+-      return hapd->driver->sta_set_flags(hapd->drv_priv, addr, flags_or,
+-                                         flags_and);
++      return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
++                                         flags_or, flags_and);
+ }
+ static inline int
+--- hostap.orig/hostapd/driver_bsd.c   2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver_bsd.c        2007-11-09 13:41:15.000000000 +0100
+@@ -322,7 +322,8 @@ bsd_set_sta_authorized(void *priv, const
+ }
+ static int
+-bsd_sta_set_flags(void *priv, const u8 *addr, int flags_or, int flags_and)
++bsd_sta_set_flags(void *priv, const u8 *addr, int total_flags, int flags_or,
++                int flags_and)
+ {
+       /* For now, only support setting Authorized flag */
+       if (flags_or & WLAN_STA_AUTHORIZED)
+--- hostap.orig/hostapd/driver_devicescape.c   2007-11-09 13:41:14.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c        2007-11-09 13:41:15.000000000 +0100
+@@ -76,7 +76,7 @@ struct i802_driver_data {
+ #define HAPD_DECL     struct hostapd_data *hapd = iface->bss[0]
+ static int i802_sta_set_flags(void *priv, const u8 *addr,
+-                            int flags_or, int flags_and);
++                            int total_flags, int flags_or, int flags_and);
+ static int hostapd_set_iface_flags(struct i802_driver_data *drv, int dev_up)
+@@ -765,7 +765,7 @@ static int i802_sta_remove(void *priv, c
+       struct i802_driver_data *drv = priv;
+       struct prism2_hostapd_param param;
+-      i802_sta_set_flags(drv, addr, 0, ~WLAN_STA_AUTHORIZED);
++      i802_sta_set_flags(drv, addr, 0, 0, ~WLAN_STA_AUTHORIZED);
+       memset(&param, 0, sizeof(param));
+       param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
+@@ -777,7 +777,7 @@ static int i802_sta_remove(void *priv, c
+ static int i802_sta_set_flags(void *priv, const u8 *addr,
+-                            int flags_or, int flags_and)
++                            int total_flags, int flags_or, int flags_and)
+ {
+       struct i802_driver_data *drv = priv;
+       struct prism2_hostapd_param param;
+--- hostap.orig/hostapd/driver_hostap.c        2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver_hostap.c     2007-11-09 13:41:15.000000000 +0100
+@@ -374,7 +374,7 @@ static int hostap_send_eapol(void *priv,
+ static int hostap_sta_set_flags(void *priv, const u8 *addr,
+-                              int flags_or, int flags_and)
++                              int total_flags, int flags_or, int flags_and)
+ {
+       struct hostap_driver_data *drv = priv;
+       struct prism2_hostapd_param param;
+@@ -694,7 +694,7 @@ static int hostap_sta_remove(void *priv,
+       struct hostap_driver_data *drv = priv;
+       struct prism2_hostapd_param param;
+-      hostap_sta_set_flags(drv, addr, 0, ~WLAN_STA_AUTHORIZED);
++      hostap_sta_set_flags(drv, addr, 0, 0, ~WLAN_STA_AUTHORIZED);
+       memset(&param, 0, sizeof(param));
+       param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
+--- hostap.orig/hostapd/driver_madwifi.c       2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver_madwifi.c    2007-11-09 13:41:15.000000000 +0100
+@@ -410,7 +410,8 @@ madwifi_set_sta_authorized(void *priv, c
+ }
+ static int
+-madwifi_sta_set_flags(void *priv, const u8 *addr, int flags_or, int flags_and)
++madwifi_sta_set_flags(void *priv, const u8 *addr, int total_flags,
++                    int flags_or, int flags_and)
+ {
+       /* For now, only support setting Authorized flag */
+       if (flags_or & WLAN_STA_AUTHORIZED)
+--- hostap.orig/hostapd/driver_prism54.c       2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/driver_prism54.c    2007-11-09 13:41:15.000000000 +0100
+@@ -187,7 +187,8 @@ static int prism54_set_sta_authorized(vo
+ static int
+-prism54_sta_set_flags(void *priv, const u8 *addr, int flags_or, int flags_and)
++prism54_sta_set_flags(void *priv, const u8 *addr, int total_flags,
++                    int flags_or, int flags_and)
+ {
+       /* For now, only support setting Authorized flag */
+       if (flags_or & WLAN_STA_AUTHORIZED)
+--- hostap.orig/hostapd/ieee802_11.c   2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/ieee802_11.c        2007-11-09 13:41:15.000000000 +0100
+@@ -1625,10 +1625,10 @@ static void handle_assoc_cb(struct hosta
+               ap_sta_bind_vlan(hapd, sta, 0);
+       }
+       if (sta->flags & WLAN_STA_SHORT_PREAMBLE) {
+-              hostapd_sta_set_flags(hapd, sta->addr,
++              hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+                                     WLAN_STA_SHORT_PREAMBLE, ~0);
+       } else {
+-              hostapd_sta_set_flags(hapd, sta->addr,
++              hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+                                     0, ~WLAN_STA_SHORT_PREAMBLE);
+       }
+--- hostap.orig/hostapd/ieee802_1x.c   2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/ieee802_1x.c        2007-11-09 13:41:15.000000000 +0100
+@@ -94,13 +94,13 @@ void ieee802_1x_set_sta_authorized(struc
+       if (authorized) {
+               sta->flags |= WLAN_STA_AUTHORIZED;
+-              res = hostapd_sta_set_flags(hapd, sta->addr,
++              res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+                                           WLAN_STA_AUTHORIZED, ~0);
+               hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+                              HOSTAPD_LEVEL_DEBUG, "authorizing port");
+       } else {
+               sta->flags &= ~WLAN_STA_AUTHORIZED;
+-              res = hostapd_sta_set_flags(hapd, sta->addr,
++              res = hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
+                                           0, ~WLAN_STA_AUTHORIZED);
+               hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+                              HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
+--- hostap.orig/hostapd/wme.c  2007-11-09 13:41:07.000000000 +0100
++++ hostap/hostapd/wme.c       2007-11-09 13:41:15.000000000 +0100
+@@ -110,9 +110,11 @@ int hostapd_wme_sta_config(struct hostap
+ {
+       /* update kernel STA data for WME related items (WLAN_STA_WPA flag) */
+       if (sta->flags & WLAN_STA_WME)
+-              hostapd_sta_set_flags(hapd, sta->addr, WLAN_STA_WME, ~0);
++              hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
++                                    WLAN_STA_WME, ~0);
+       else
+-              hostapd_sta_set_flags(hapd, sta->addr, 0, ~WLAN_STA_WME);
++              hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
++                                    0, ~WLAN_STA_WME);
+       return 0;
+ }
diff --git a/package/hostapd/patches/006-use-nl80211-for-sta.patch b/package/hostapd/patches/006-use-nl80211-for-sta.patch
new file mode 100644 (file)
index 0000000..f94ba42
--- /dev/null
@@ -0,0 +1,411 @@
+---
+ hostapd/driver_devicescape.c |  330 ++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 249 insertions(+), 81 deletions(-)
+
+--- hostap.orig/hostapd/driver_devicescape.c   2007-11-09 13:41:15.000000000 +0100
++++ hostap/hostapd/driver_devicescape.c        2007-11-09 13:41:16.000000000 +0100
+@@ -75,8 +75,14 @@ struct i802_driver_data {
+ #define HAPD_DECL     struct hostapd_data *hapd = iface->bss[0]
+-static int i802_sta_set_flags(void *priv, const u8 *addr,
+-                            int total_flags, int flags_or, int flags_and);
++/* helper for netlink get routines */
++static int ack_wait_handler(struct nl_msg *msg, void *arg)
++{
++      int *finished = arg;
++
++      *finished = 1;
++      return NL_STOP;
++}
+ static int hostapd_set_iface_flags(struct i802_driver_data *drv, int dev_up)
+@@ -255,14 +261,6 @@ static int get_key_handler(struct nl_msg
+       return NL_SKIP;
+ }
+-static int ack_wait_handler(struct nl_msg *msg, void *arg)
+-{
+-      int *finished = arg;
+-
+-      *finished = 1;
+-      return NL_STOP;
+-}
+-
+ static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
+                          int idx, u8 *seq)
+ {
+@@ -629,43 +627,126 @@ static int i802_get_retry(void *priv, in
+ static int i802_flush(void *priv)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param param;
++      struct nl_msg *msg;
++      int ret = -1;
+-      memset(&param, 0, sizeof(param));
+-      param.cmd = PRISM2_HOSTAPD_FLUSH;
+-      return hostapd_ioctl(drv, &param, sizeof(param));
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_NEW_STATION, 0);
++
++      /*
++       * XXX: FIX! this needs to flush all VLANs too
++       */
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++                  if_nametoindex(drv->iface));
++
++      ret = 0;
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0) {
++              ret = -1;
++      }
++
++ nla_put_failure:
++      nlmsg_free(msg);
++
++ out:
++      return ret;
+ }
++static int get_sta_handler(struct nl_msg *msg, void *arg)
++{
++      struct nlattr *tb[NL80211_ATTR_MAX + 1];
++      struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
++      struct hostap_sta_driver_data *data = arg;
++      struct nlattr *stats[NL80211_STA_STAT_MAX + 1];
++      static struct nla_policy stats_policy[NL80211_STA_STAT_MAX + 1] = {
++              [NL80211_STA_STAT_INACTIVE_TIME] = { .type = NLA_U32 },
++              [NL80211_STA_STAT_RX_BYTES] = { .type = NLA_U32 },
++              [NL80211_STA_STAT_TX_BYTES] = { .type = NLA_U32 },
++      };
++
++      nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
++                genlmsg_attrlen(gnlh, 0), NULL);
++
++      /*
++       * TODO: validate the interface and mac address!
++       * Otherwise, there's a race condition as soon as
++       * the kernel starts sending station notifications.
++       */
++
++      if (!tb[NL80211_ATTR_STA_STATS]) {
++              printf("sta stats missing!\n");
++              return NL_SKIP;
++      }
++      if (nla_parse_nested(stats, NL80211_STA_STAT_MAX,
++                           tb[NL80211_ATTR_STA_STATS],
++                           stats_policy)) {
++              printf("failed to parse nested attributes!\n");
++              return NL_SKIP;
++      }
++
++      if (stats[NL80211_STA_STAT_INACTIVE_TIME])
++              data->inactive_msec =
++                      nla_get_u32(stats[NL80211_STA_STAT_INACTIVE_TIME]);
++      if (stats[NL80211_STA_STAT_RX_BYTES])
++              data->rx_bytes = nla_get_u32(stats[NL80211_STA_STAT_RX_BYTES]);
++      if (stats[NL80211_STA_STAT_TX_BYTES])
++              data->rx_bytes = nla_get_u32(stats[NL80211_STA_STAT_TX_BYTES]);
++
++      return NL_SKIP;
++}
++
+ static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,
+                             const u8 *addr)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param param;
++      struct nl_msg *msg;
++      struct nl_cb *cb = NULL;
++      int ret = -1;
++      int err = 0;
++      int finished = 0;
+-      memset(data, 0, sizeof(*data));
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
+-      memset(&param, 0, sizeof(param));
+-      param.cmd = PRISM2_HOSTAPD_GET_INFO_STA;
+-      memcpy(param.sta_addr, addr, ETH_ALEN);
+-      if (hostapd_ioctl(drv, &param, sizeof(param))) {
+-              printf("  Could not get station info from kernel driver.\n");
+-              return -1;
+-      }
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_GET_STATION, 0);
++
++      NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->iface));
++
++      cb = nl_cb_alloc(NL_CB_CUSTOM);
++      if (!cb)
++              goto out;
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0)
++              goto out;
++
++      nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, get_sta_handler, data);
++      nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
++
++      err = nl_recvmsgs(drv->nl_handle, cb);
++
++      if (!finished)
++              err = nl_wait_for_ack(drv->nl_handle);
++
++      if (err < 0)
++              goto out;
++
++      ret = 0;
++
++ out:
++      nl_cb_put(cb);
++ nla_put_failure:
++      nlmsg_free(msg);
++      return ret;
+-      data->inactive_msec = param.u.get_info_sta.inactive_msec;
+-      data->rx_packets = param.u.get_info_sta.rx_packets;
+-      data->tx_packets = param.u.get_info_sta.tx_packets;
+-      data->rx_bytes = param.u.get_info_sta.rx_bytes;
+-      data->tx_bytes = param.u.get_info_sta.tx_bytes;
+-      data->current_tx_rate = param.u.get_info_sta.current_tx_rate;
+-      data->flags = param.u.get_info_sta.flags;
+-      data->num_ps_buf_frames = param.u.get_info_sta.num_ps_buf_frames;
+-      data->tx_retry_failed = param.u.get_info_sta.tx_retry_failed;
+-      data->tx_retry_count = param.u.get_info_sta.tx_retry_count;
+-      data->last_rssi = param.u.get_info_sta.last_rssi;
+-      data->last_ack_rssi = param.u.get_info_sta.last_ack_rssi;
+-      return 0;
+ }
+@@ -744,35 +825,68 @@ static int i802_sta_add(const char *ifna
+                       size_t supp_rates_len, int flags)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param param;
+-      size_t len;
++      struct nl_msg *msg;
++      int ret = -1;
+-      memset(&param, 0, sizeof(param));
+-      param.cmd = PRISM2_HOSTAPD_ADD_STA;
+-      memcpy(param.sta_addr, addr, ETH_ALEN);
+-      param.u.add_sta.aid = aid;
+-      param.u.add_sta.capability = capability;
+-      len = supp_rates_len;
+-      if (len > sizeof(param.u.add_sta.supp_rates))
+-              len = sizeof(param.u.add_sta.supp_rates);
+-      memcpy(param.u.add_sta.supp_rates, supp_rates, len);
+-      return hostapd_ioctl_iface(ifname, drv, &param, sizeof(param));
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_NEW_STATION, 0);
++
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++                  if_nametoindex(drv->iface));
++      NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++      NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, aid);
++      NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, supp_rates_len,
++              supp_rates);
++      NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL, 0);
++
++      ret = 0;
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0) {
++              ret = -1;
++      }
++
++ nla_put_failure:
++      nlmsg_free(msg);
++
++ out:
++      return ret;
+ }
+ static int i802_sta_remove(void *priv, const u8 *addr)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param param;
++      struct nl_msg *msg;
++      int ret = -1;
+-      i802_sta_set_flags(drv, addr, 0, 0, ~WLAN_STA_AUTHORIZED);
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
+-      memset(&param, 0, sizeof(param));
+-      param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
+-      memcpy(param.sta_addr, addr, ETH_ALEN);
+-      if (hostapd_ioctl(drv, &param, sizeof(param)))
+-              return -1;
+-      return 0;
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_DEL_STATION, 0);
++
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++                  if_nametoindex(drv->iface));
++      NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++
++      ret = 0;
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0) {
++              ret = -1;
++      }
++
++ nla_put_failure:
++      nlmsg_free(msg);
++
++ out:
++      return ret;
+ }
+@@ -780,14 +894,51 @@ static int i802_sta_set_flags(void *priv
+                             int total_flags, int flags_or, int flags_and)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param param;
++      struct nl_msg *msg, *flags = NULL;
++      int ret = -1;
+-      memset(&param, 0, sizeof(param));
+-      param.cmd = PRISM2_HOSTAPD_SET_FLAGS_STA;
+-      memcpy(param.sta_addr, addr, ETH_ALEN);
+-      param.u.set_flags_sta.flags_or = flags_or;
+-      param.u.set_flags_sta.flags_and = flags_and;
+-      return hostapd_ioctl(drv, &param, sizeof(param));
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++
++      flags = nlmsg_alloc();
++      if (!flags)
++              goto free_msg;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_SET_STATION, 0);
++
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++                  if_nametoindex(drv->iface));
++      NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++
++      if (total_flags & WLAN_STA_AUTHORIZED)
++              NLA_PUT_FLAG(flags, NL80211_STA_FLAG_AUTHORIZED);
++
++      if (total_flags & WLAN_STA_WME)
++              NLA_PUT_FLAG(flags, NL80211_STA_FLAG_WME);
++
++      if (total_flags & WLAN_STA_SHORT_PREAMBLE)
++              NLA_PUT_FLAG(flags, NL80211_STA_FLAG_SHORT_PREAMBLE);
++
++      if (nla_put_nested(msg, NL80211_ATTR_STA_FLAGS, flags))
++              goto nla_put_failure;
++
++      ret = 0;
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0) {
++              ret = -1;
++      }
++
++ nla_put_failure:
++      nlmsg_free(flags);
++
++ free_msg:
++      nlmsg_free(msg);
++
++ out:
++      return ret;
+ }
+@@ -1257,18 +1408,38 @@ static struct hostapd_hw_modes * i802_ge
+ }
+-static int i802_set_sta_vlan(void *priv, const u8 *addr, const char *ifname,
+-                           int vlan_id)
++static int i802_set_sta_vlan(void *priv, const u8 *addr,
++                           const char *ifname, int vlan_id)
+ {
+       struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param param;
++      struct nl_msg *msg;
++      int ret = -1;
+-      memset(&param, 0, sizeof(param));
+-      param.cmd = PRISM2_HOSTAPD_SET_STA_VLAN;
+-      memcpy(param.sta_addr, addr, ETH_ALEN);
+-      os_strlcpy(param.u.set_sta_vlan.vlan_name, ifname, IFNAMSIZ);
+-      param.u.set_sta_vlan.vlan_id = vlan_id;
+-      return hostapd_ioctl(drv, &param, sizeof(param));
++      msg = nlmsg_alloc();
++      if (!msg)
++              goto out;
++
++      genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
++                  0, NL80211_CMD_SET_STATION, 0);
++
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++                  if_nametoindex(drv->iface));
++      NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
++                  if_nametoindex(ifname));
++
++      ret = 0;
++
++      if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
++          nl_wait_for_ack(drv->nl_handle) < 0) {
++              ret = -1;
++      }
++
++ nla_put_failure:
++      nlmsg_free(msg);
++
++ out:
++      return ret;
+ }
+@@ -1750,17 +1921,14 @@ static int i802_init_sockets(struct i802
+ static int i802_get_inact_sec(void *priv, const u8 *addr)
+ {
+-      struct i802_driver_data *drv = priv;
+-      struct prism2_hostapd_param param;
++      struct hostap_sta_driver_data data;
++      int ret;
+-      memset(&param, 0, sizeof(param));
+-      param.cmd = PRISM2_HOSTAPD_GET_INFO_STA;
+-      memcpy(param.sta_addr, addr, ETH_ALEN);
+-      if (hostapd_ioctl(drv, &param, sizeof(param))) {
++      data.inactive_msec = -1;
++      ret = i802_read_sta_data(priv, &data, addr);
++      if (ret || data.inactive_msec == -1)
+               return -1;
+-      }
+-
+-      return param.u.get_info_sta.inactive_msec / 1000;
++      return data.inactive_msec / 1000;
+ }
diff --git a/package/hostapd/patches/100-madwifi_fixes.patch b/package/hostapd/patches/100-madwifi_fixes.patch
deleted file mode 100644 (file)
index 74d0c44..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-Index: hostapd-0.5.7/driver_madwifi.c
-===================================================================
---- hostapd-0.5.7.orig/driver_madwifi.c        2007-06-04 13:22:31.768025808 +0200
-+++ hostapd-0.5.7/driver_madwifi.c     2007-06-04 13:22:32.051982640 +0200
-@@ -21,12 +21,9 @@
- #include <include/compat.h>
- #include <net80211/ieee80211.h>
- #ifdef WME_NUM_AC
--/* Assume this is built against BSD branch of madwifi driver. */
--#define MADWIFI_BSD
--#include <net80211/_ieee80211.h>
--#endif /* WME_NUM_AC */
- #include <net80211/ieee80211_crypto.h>
- #include <net80211/ieee80211_ioctl.h>
-+#endif /* WME_NUM_AC */
- #ifdef IEEE80211_IOCTL_SETWMMPARAMS
- /* Assume this is built against madwifi-ng */
-@@ -169,6 +166,11 @@
-       return 0;
- }
-+static int madwifi_get_inact_sec(void *priv, const u8 *addr)
-+{
-+      return 0;
-+}
-+
- static int
- set80211param(struct madwifi_driver_data *drv, int op, int arg)
- {
-@@ -1258,7 +1260,6 @@
-               goto bad;
-       }
--      madwifi_set_iface_flags(drv, 0);        /* mark down during setup */
-       madwifi_set_privacy(drv->iface, drv, 0); /* default to no privacy */
-       hapd->driver = &drv->ops;
-@@ -1281,7 +1282,6 @@
-       drv->hapd->driver = NULL;
--      (void) madwifi_set_iface_flags(drv, 0);
-       if (drv->ioctl_sock >= 0)
-               close(drv->ioctl_sock);
-       if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
-@@ -1367,6 +1367,7 @@
-       .get_ssid               = madwifi_get_ssid,
-       .set_countermeasures    = madwifi_set_countermeasures,
-       .sta_clear_stats        = madwifi_sta_clear_stats,
-+      .get_inact_sec          = madwifi_get_inact_sec,
-       .commit                 = madwifi_commit,
- };
index 9f33410..28958f4 100644 (file)
@@ -36,16 +36,19 @@ define Build/Compile
                install
 endef
 
                install
 endef
 
-define Build/InstallDev
+ifneq ($(CONFIG_LINUX_2_6_23),)
+  define Build/InstallDev
        $(CP) $(PKG_INSTALL_DIR)/* $(1)/
        $(CP) $(PKG_INSTALL_DIR)/* $(1)/
-endef
+       $(CP) $(PKG_BUILD_DIR)/include/linux $(1)/usr/include/
+  endef
 
 
-define Build/UninstallDev
-endef
+  define Build/UninstallDev
+  endef
 
 
-define Package/libnl/install
+  define Package/libnl/install
        $(INSTALL_DIR) $(1)/usr/lib
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libnl.so.1 $(1)/usr/lib/
        $(INSTALL_DIR) $(1)/usr/lib
        $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libnl.so.1 $(1)/usr/lib/
-endef
+  endef
+endif
 
 $(eval $(call BuildPackage,libnl))
 
 $(eval $(call BuildPackage,libnl))
index 476160d..65f2005 100644 (file)
@@ -19,10 +19,9 @@ define KernelPackage/mac80211
   TITLE:=Linux 802.11 Wireless Networking Stack
   DEPENDS:=@LINUX_2_6_23 +kmod-crypto-arc4 +kmod-crypto-aes +wireless-tools
   FILES:= \
   TITLE:=Linux 802.11 Wireless Networking Stack
   DEPENDS:=@LINUX_2_6_23 +kmod-crypto-arc4 +kmod-crypto-aes +wireless-tools
   FILES:= \
-       $(PKG_BUILD_DIR)/mac80211/mac80211.$(LINUX_KMOD_SUFFIX) \
-       $(PKG_BUILD_DIR)/mac80211/rc80211_simple.$(LINUX_KMOD_SUFFIX) \
-       $(PKG_BUILD_DIR)/wireless/cfg80211.$(LINUX_KMOD_SUFFIX)
-  AUTOLOAD:=$(call AutoLoad,20,cfg80211 mac80211 rc80211_simple)
+       $(PKG_BUILD_DIR)/net/mac80211/mac80211.$(LINUX_KMOD_SUFFIX) \
+       $(PKG_BUILD_DIR)/net/wireless/cfg80211.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoLoad,20,cfg80211 mac80211)
 endef
 
 define KernelPackage/mac80211/description
 endef
 
 define KernelPackage/mac80211/description
@@ -32,7 +31,7 @@ endef
 CONFOPTS:=MAC80211 CFG80211 NL80211
 
 BUILDFLAGS:= \
 CONFOPTS:=MAC80211 CFG80211 NL80211
 
 BUILDFLAGS:= \
-       $(foreach opt,$(CONFOPTS),-DCONFIG_$(opt) ) \
+       $(foreach opt,$(CONFOPTS),-DCONFIG_$(opt) -DCONFIG_MAC80211_RCSIMPLE=1) \
        $(if $(CONFIG_LEDS_TRIGGERS), -DCONFIG_MAC80211_LEDS -DCONFIG_LEDS_TRIGGERS)
 
 MAKE_OPTS:= \
        $(if $(CONFIG_LEDS_TRIGGERS), -DCONFIG_MAC80211_LEDS -DCONFIG_LEDS_TRIGGERS)
 
 MAKE_OPTS:= \
@@ -41,24 +40,26 @@ MAKE_OPTS:= \
        EXTRA_CFLAGS="$(BUILDFLAGS)" \
        $(foreach opt,$(CONFOPTS),CONFIG_$(opt)=m) \
        CONFIG_NL80211=y \
        EXTRA_CFLAGS="$(BUILDFLAGS)" \
        $(foreach opt,$(CONFOPTS),CONFIG_$(opt)=m) \
        CONFIG_NL80211=y \
+       CONFIG_MAC80211_RCSIMPLE=y \
        CONFIG_MAC80211_LEDS=$(CONFIG_LEDS_TRIGGERS) \
        CONFIG_MAC80211_LEDS=$(CONFIG_LEDS_TRIGGERS) \
-       LINUXINCLUDE="-I${CURDIR}/src/include -I$(LINUX_DIR)/include -include linux/autoconf.h" \
+       LINUXINCLUDE="-I$(PKG_BUILD_DIR)/include -I$(LINUX_DIR)/include -include linux/autoconf.h" \
 
 define Build/Prepare
 
 define Build/Prepare
-       mkdir -p $(PKG_BUILD_DIR)/mac80211
-       $(CP) ./src/mac80211/* $(PKG_BUILD_DIR)/mac80211/
-       mkdir -p $(PKG_BUILD_DIR)/wireless
-       $(CP) ./src/wireless/* $(PKG_BUILD_DIR)/wireless/
+       rm -rf $(PKG_BUILD_DIR)
+       mkdir -p $(PKG_BUILD_DIR)
+       $(CP) ./src/* $(PKG_BUILD_DIR)/
+       $(Build/Patch)
+       $(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used)
 endef
 
 define Build/Compile
 endef
 
 define Build/Compile
-       $(MAKE) -C "$(LINUX_DIR)" $(MAKE_OPTS) SUBDIRS="$(PKG_BUILD_DIR)/wireless" modules
-       $(MAKE) -C "$(LINUX_DIR)" $(MAKE_OPTS) SUBDIRS="$(PKG_BUILD_DIR)/mac80211" modules
+       $(MAKE) -C "$(LINUX_DIR)" $(MAKE_OPTS) SUBDIRS="$(PKG_BUILD_DIR)/net/wireless" modules
+       $(MAKE) -C "$(LINUX_DIR)" $(MAKE_OPTS) SUBDIRS="$(PKG_BUILD_DIR)/net/mac80211" modules
 endef
 
 define Build/InstallDev
        mkdir -p $(1)/usr/include/mac80211
 endef
 
 define Build/InstallDev
        mkdir -p $(1)/usr/include/mac80211
-       $(CP) ./src/include/* $(1)/usr/include/mac80211/
+       $(CP) $(PKG_BUILD_DIR)/net/mac80211/*.h $(PKG_BUILD_DIR)/include/* $(1)/usr/include/mac80211/
 endef
 
 define Build/UninstallDev
 endef
 
 define Build/UninstallDev
diff --git a/package/mac80211/patches/000-mac80211_update.patch b/package/mac80211/patches/000-mac80211_update.patch
new file mode 100644 (file)
index 0000000..7a1a1e2
--- /dev/null
@@ -0,0 +1,933 @@
+Index: mac80211/include/linux/ieee80211.h
+===================================================================
+--- mac80211.orig/include/linux/ieee80211.h    2007-11-11 15:45:23.153490050 +0100
++++ mac80211/include/linux/ieee80211.h 2007-11-11 15:45:30.417904025 +0100
+@@ -81,18 +81,18 @@
+ /* miscellaneous IEEE 802.11 constants */
+-#define IEEE80211_MAX_FRAG_THRESHOLD  2346
+-#define IEEE80211_MAX_RTS_THRESHOLD   2347
++#define IEEE80211_MAX_FRAG_THRESHOLD  2352
++#define IEEE80211_MAX_RTS_THRESHOLD   2353
+ #define IEEE80211_MAX_AID             2007
+ #define IEEE80211_MAX_TIM_LEN         251
+-#define IEEE80211_MAX_DATA_LEN                2304
+ /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+    6.2.1.1.2.
+-   The figure in section 7.1.2 suggests a body size of up to 2312
+-   bytes is allowed, which is a bit confusing, I suspect this
+-   represents the 2304 bytes of real data, plus a possible 8 bytes of
+-   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
++   802.11e clarifies the figure in section 7.1.2. The frame body is
++   up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */
++#define IEEE80211_MAX_DATA_LEN                2304
++/* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */
++#define IEEE80211_MAX_FRAME_LEN               2352
+ #define IEEE80211_MAX_SSID_LEN                32
+Index: mac80211/include/linux/nl80211.h
+===================================================================
+--- mac80211.orig/include/linux/nl80211.h      2007-11-11 15:45:23.161490506 +0100
++++ mac80211/include/linux/nl80211.h   2007-11-11 15:45:30.421904255 +0100
+@@ -25,7 +25,7 @@
+  *    either a dump request on a %NL80211_ATTR_WIPHY or a specific get
+  *    on an %NL80211_ATTR_IFINDEX is supported.
+  * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires
+-      %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE.
++ *    %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE.
+  * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response
+  *    to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX,
+  *    %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also
+Index: mac80211/include/net/mac80211.h
+===================================================================
+--- mac80211.orig/include/net/mac80211.h       2007-11-11 15:45:23.169490961 +0100
++++ mac80211/include/net/mac80211.h    2007-11-11 15:45:30.429904707 +0100
+@@ -706,11 +706,16 @@
+  *
+  * @queues: number of available hardware transmit queues for
+  *    data packets. WMM/QoS requires at least four.
++ *
++ * @rate_control_algorithm: rate control algorithm for this hardware.
++ *    If unset (NULL), the default algorithm will be used. Must be
++ *    set before calling ieee80211_register_hw().
+  */
+ struct ieee80211_hw {
+       struct ieee80211_conf conf;
+       struct wiphy *wiphy;
+       struct workqueue_struct *workqueue;
++      const char *rate_control_algorithm;
+       void *priv;
+       u32 flags;
+       unsigned int extra_tx_headroom;
+@@ -936,27 +941,11 @@
+  *    and remove_interface calls, i.e. while the interface with the
+  *    given local_address is enabled.
+  *
+- * @set_ieee8021x: Enable/disable IEEE 802.1X. This item requests wlan card
+- *    to pass unencrypted EAPOL-Key frames even when encryption is
+- *    configured. If the wlan card does not require such a configuration,
+- *    this function pointer can be set to NULL.
+- *
+- * @set_port_auth: Set port authorization state (IEEE 802.1X PAE) to be
+- *    authorized (@authorized=1) or unauthorized (=0). This function can be
+- *    used if the wlan hardware or low-level driver implements PAE.
+- *    mac80211 will filter frames based on authorization state in any case,
+- *    so this function pointer can be NULL if low-level driver does not
+- *    require event notification about port state changes.
+- *
+  * @hw_scan: Ask the hardware to service the scan request, no need to start
+  *    the scan state machine in stack.
+  *
+  * @get_stats: return low-level statistics
+  *
+- * @set_privacy_invoked: For devices that generate their own beacons and probe
+- *    response or association responses this updates the state of privacy_invoked
+- *    returns 0 for success or an error number.
+- *
+  * @get_sequence_counter: For devices that have internal sequence counters this
+  *    callback allows mac80211 to access the current value of a counter.
+  *    This callback seems not well-defined, tell us if you need it.
+@@ -1029,14 +1018,9 @@
+       int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+                      const u8 *local_address, const u8 *address,
+                      struct ieee80211_key_conf *key);
+-      int (*set_ieee8021x)(struct ieee80211_hw *hw, int use_ieee8021x);
+-      int (*set_port_auth)(struct ieee80211_hw *hw, u8 *addr,
+-                           int authorized);
+       int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
+       int (*get_stats)(struct ieee80211_hw *hw,
+                        struct ieee80211_low_level_stats *stats);
+-      int (*set_privacy_invoked)(struct ieee80211_hw *hw,
+-                                 int privacy_invoked);
+       int (*get_sequence_counter)(struct ieee80211_hw *hw,
+                                   u8* addr, u8 keyidx, u8 txrx,
+                                   u32* iv32, u16* iv16);
+Index: mac80211/net/mac80211/aes_ccm.c
+===================================================================
+--- mac80211.orig/net/mac80211/aes_ccm.c       2007-11-11 15:45:23.177491419 +0100
++++ mac80211/net/mac80211/aes_ccm.c    2007-11-11 15:45:30.433904936 +0100
+@@ -7,10 +7,10 @@
+  * published by the Free Software Foundation.
+  */
++#include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/crypto.h>
+ #include <linux/err.h>
+-#include <asm/scatterlist.h>
+ #include <net/mac80211.h>
+ #include "ieee80211_key.h"
+@@ -63,7 +63,7 @@
+       s_0 = scratch + AES_BLOCK_LEN;
+       e = scratch + 2 * AES_BLOCK_LEN;
+-      num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
++      num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
+       last_len = data_len % AES_BLOCK_LEN;
+       aes_ccm_prepare(tfm, b_0, aad, b, s_0, b);
+@@ -102,7 +102,7 @@
+       s_0 = scratch + AES_BLOCK_LEN;
+       a = scratch + 2 * AES_BLOCK_LEN;
+-      num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
++      num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
+       last_len = data_len % AES_BLOCK_LEN;
+       aes_ccm_prepare(tfm, b_0, aad, b, s_0, a);
+Index: mac80211/net/mac80211/ieee80211.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211.c     2007-11-11 15:45:23.185491871 +0100
++++ mac80211/net/mac80211/ieee80211.c  2007-11-11 15:45:30.437905164 +0100
+@@ -1061,7 +1061,8 @@
+       ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
+       ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
+-      result = ieee80211_init_rate_ctrl_alg(local, NULL);
++      result = ieee80211_init_rate_ctrl_alg(local,
++                                            hw->rate_control_algorithm);
+       if (result < 0) {
+               printk(KERN_DEBUG "%s: Failed to initialize rate control "
+                      "algorithm\n", wiphy_name(local->hw.wiphy));
+@@ -1222,8 +1223,17 @@
+       BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
++#ifdef CONFIG_MAC80211_RCSIMPLE
++      ret = ieee80211_rate_control_register(&mac80211_rcsimple);
++      if (ret)
++              return ret;
++#endif
++
+       ret = ieee80211_wme_register();
+       if (ret) {
++#ifdef CONFIG_MAC80211_RCSIMPLE
++              ieee80211_rate_control_unregister(&mac80211_rcsimple);
++#endif
+               printk(KERN_DEBUG "ieee80211_init: failed to "
+                      "initialize WME (err=%d)\n", ret);
+               return ret;
+@@ -1237,6 +1247,10 @@
+ static void __exit ieee80211_exit(void)
+ {
++#ifdef CONFIG_MAC80211_RCSIMPLE
++      ieee80211_rate_control_unregister(&mac80211_rcsimple);
++#endif
++
+       ieee80211_wme_unregister();
+       ieee80211_debugfs_netdev_exit();
+ }
+Index: mac80211/net/mac80211/ieee80211_i.h
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_i.h   2007-11-11 15:45:23.189492100 +0100
++++ mac80211/net/mac80211/ieee80211_i.h        2007-11-11 15:45:30.441905395 +0100
+@@ -232,6 +232,7 @@
+ #define IEEE80211_STA_AUTO_SSID_SEL   BIT(10)
+ #define IEEE80211_STA_AUTO_BSSID_SEL  BIT(11)
+ #define IEEE80211_STA_AUTO_CHANNEL_SEL        BIT(12)
++#define IEEE80211_STA_PRIVACY_INVOKED BIT(13)
+ struct ieee80211_if_sta {
+       enum {
+               IEEE80211_DISABLED, IEEE80211_AUTHENTICATE,
+@@ -261,7 +262,6 @@
+       unsigned long request;
+       struct sk_buff_head skb_queue;
+-      int key_management_enabled;
+       unsigned long last_probe;
+ #define IEEE80211_AUTH_ALG_OPEN BIT(0)
+Index: mac80211/net/mac80211/ieee80211_ioctl.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_ioctl.c       2007-11-11 15:45:23.197492559 +0100
++++ mac80211/net/mac80211/ieee80211_ioctl.c    2007-11-11 15:45:30.441905395 +0100
+@@ -305,9 +305,12 @@
+                           ((chan->chan == channel) || (chan->freq == freq))) {
+                               local->oper_channel = chan;
+                               local->oper_hw_mode = mode;
+-                              set++;
++                              set = 1;
++                              break;
+                       }
+               }
++              if (set)
++                      break;
+       }
+       if (set) {
+@@ -507,10 +510,11 @@
+ static int ieee80211_ioctl_siwscan(struct net_device *dev,
+                                  struct iw_request_info *info,
+-                                 struct iw_point *data, char *extra)
++                                 union iwreq_data *wrqu, char *extra)
+ {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      struct iw_scan_req *req = NULL;
+       u8 *ssid = NULL;
+       size_t ssid_len = 0;
+@@ -535,6 +539,14 @@
+               return -EOPNOTSUPP;
+       }
++      /* if SSID was specified explicitly then use that */
++      if (wrqu->data.length == sizeof(struct iw_scan_req) &&
++          wrqu->data.flags & IW_SCAN_THIS_ESSID) {
++              req = (struct iw_scan_req *)extra;
++              ssid = req->essid;
++              ssid_len = req->essid_len;
++      }
++
+       return ieee80211_sta_req_scan(dev, ssid, ssid_len);
+ }
+@@ -621,22 +633,35 @@
+ {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       bool need_reconfig = 0;
++      u8 new_power_level;
+       if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
+               return -EINVAL;
+       if (data->txpower.flags & IW_TXPOW_RANGE)
+               return -EINVAL;
+-      if (!data->txpower.fixed)
+-              return -EINVAL;
+-      if (local->hw.conf.power_level != data->txpower.value) {
+-              local->hw.conf.power_level = data->txpower.value;
++      if (data->txpower.fixed) {
++              new_power_level = data->txpower.value;
++      } else {
++              /* Automatic power level. Get the px power from the current
++               * channel. */
++              struct ieee80211_channel* chan = local->oper_channel;
++              if (!chan)
++                      return -EINVAL;
++
++              new_power_level = chan->power_level;
++      }
++
++      if (local->hw.conf.power_level != new_power_level) {
++              local->hw.conf.power_level = new_power_level;
+               need_reconfig = 1;
+       }
++
+       if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
+               local->hw.conf.radio_enabled = !(data->txpower.disabled);
+               need_reconfig = 1;
+       }
++
+       if (need_reconfig) {
+               ieee80211_hw_config(local);
+               /* The return value of hw_config is not of big interest here,
+@@ -904,7 +929,6 @@
+                                  struct iw_request_info *info,
+                                  struct iw_param *data, char *extra)
+ {
+-      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       int ret = 0;
+@@ -914,18 +938,21 @@
+       case IW_AUTH_CIPHER_GROUP:
+       case IW_AUTH_WPA_ENABLED:
+       case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+-              break;
+       case IW_AUTH_KEY_MGMT:
++              break;
++      case IW_AUTH_PRIVACY_INVOKED:
+               if (sdata->type != IEEE80211_IF_TYPE_STA)
+                       ret = -EINVAL;
+               else {
++                      sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
+                       /*
+-                       * Key management was set by wpa_supplicant,
+-                       * we only need this to associate to a network
+-                       * that has privacy enabled regardless of not
+-                       * having a key.
++                       * Privacy invoked by wpa_supplicant, store the
++                       * value and allow associating to a protected
++                       * network without having a key up front.
+                        */
+-                      sdata->u.sta.key_management_enabled = !!data->value;
++                      if (data->value)
++                              sdata->u.sta.flags |=
++                                      IEEE80211_STA_PRIVACY_INVOKED;
+               }
+               break;
+       case IW_AUTH_80211_AUTH_ALG:
+@@ -935,11 +962,6 @@
+               else
+                       ret = -EOPNOTSUPP;
+               break;
+-      case IW_AUTH_PRIVACY_INVOKED:
+-              if (local->ops->set_privacy_invoked)
+-                      ret = local->ops->set_privacy_invoked(
+-                                      local_to_hw(local), data->value);
+-              break;
+       default:
+               ret = -EOPNOTSUPP;
+               break;
+Index: mac80211/net/mac80211/ieee80211_rate.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_rate.c        2007-11-11 15:45:23.205493011 +0100
++++ mac80211/net/mac80211/ieee80211_rate.c     2007-11-11 15:45:30.441905395 +0100
+@@ -25,13 +25,25 @@
+ {
+       struct rate_control_alg *alg;
++      if (!ops->name)
++              return -EINVAL;
++
++      mutex_lock(&rate_ctrl_mutex);
++      list_for_each_entry(alg, &rate_ctrl_algs, list) {
++              if (!strcmp(alg->ops->name, ops->name)) {
++                      /* don't register an algorithm twice */
++                      WARN_ON(1);
++                      return -EALREADY;
++              }
++      }
++
+       alg = kzalloc(sizeof(*alg), GFP_KERNEL);
+       if (alg == NULL) {
++              mutex_unlock(&rate_ctrl_mutex);
+               return -ENOMEM;
+       }
+       alg->ops = ops;
+-      mutex_lock(&rate_ctrl_mutex);
+       list_add_tail(&alg->list, &rate_ctrl_algs);
+       mutex_unlock(&rate_ctrl_mutex);
+@@ -61,9 +73,12 @@
+       struct rate_control_alg *alg;
+       struct rate_control_ops *ops = NULL;
++      if (!name)
++              return NULL;
++
+       mutex_lock(&rate_ctrl_mutex);
+       list_for_each_entry(alg, &rate_ctrl_algs, list) {
+-              if (!name || !strcmp(alg->ops->name, name))
++              if (!strcmp(alg->ops->name, name))
+                       if (try_module_get(alg->ops->module)) {
+                               ops = alg->ops;
+                               break;
+@@ -80,9 +95,12 @@
+ {
+       struct rate_control_ops *ops;
++      if (!name)
++              name = "simple";
++
+       ops = ieee80211_try_rate_control_ops_get(name);
+       if (!ops) {
+-              request_module("rc80211_%s", name ? name : "default");
++              request_module("rc80211_%s", name);
+               ops = ieee80211_try_rate_control_ops_get(name);
+       }
+       return ops;
+Index: mac80211/net/mac80211/ieee80211_rate.h
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_rate.h        2007-11-11 15:45:23.213493469 +0100
++++ mac80211/net/mac80211/ieee80211_rate.h     2007-11-11 15:45:30.445905621 +0100
+@@ -65,6 +65,9 @@
+       struct kref kref;
+ };
++/* default 'simple' algorithm */
++extern struct rate_control_ops mac80211_rcsimple;
++
+ int ieee80211_rate_control_register(struct rate_control_ops *ops);
+ void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
+Index: mac80211/net/mac80211/ieee80211_sta.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_sta.c 2007-11-11 15:45:23.217493699 +0100
++++ mac80211/net/mac80211/ieee80211_sta.c      2007-11-11 15:46:32.885463850 +0100
+@@ -12,7 +12,6 @@
+  */
+ /* TODO:
+- * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
+  * order BSS list by RSSI(?) ("quality of AP")
+  * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
+  *    SSID)
+@@ -61,7 +60,8 @@
+ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
+                                    u8 *ssid, size_t ssid_len);
+ static struct ieee80211_sta_bss *
+-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid);
++ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
++                   u8 *ssid, u8 ssid_len);
+ static void ieee80211_rx_bss_put(struct net_device *dev,
+                                struct ieee80211_sta_bss *bss);
+ static int ieee80211_sta_find_ibss(struct net_device *dev,
+@@ -108,14 +108,11 @@
+       u8 wmm_param_len;
+ };
+-enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 };
+-
+-static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
+-                                          struct ieee802_11_elems *elems)
++static void ieee802_11_parse_elems(u8 *start, size_t len,
++                                 struct ieee802_11_elems *elems)
+ {
+       size_t left = len;
+       u8 *pos = start;
+-      int unknown = 0;
+       memset(elems, 0, sizeof(*elems));
+@@ -126,15 +123,8 @@
+               elen = *pos++;
+               left -= 2;
+-              if (elen > left) {
+-#if 0
+-                      if (net_ratelimit())
+-                              printk(KERN_DEBUG "IEEE 802.11 element parse "
+-                                     "failed (id=%d elen=%d left=%d)\n",
+-                                     id, elen, left);
+-#endif
+-                      return ParseFailed;
+-              }
++              if (elen > left)
++                      return;
+               switch (id) {
+               case WLAN_EID_SSID:
+@@ -201,28 +191,15 @@
+                       elems->ext_supp_rates_len = elen;
+                       break;
+               default:
+-#if 0
+-                      printk(KERN_DEBUG "IEEE 802.11 element parse ignored "
+-                                    "unknown element (id=%d elen=%d)\n",
+-                                    id, elen);
+-#endif
+-                      unknown++;
+                       break;
+               }
+               left -= elen;
+               pos += elen;
+       }
+-
+-      /* Do not trigger error if left == 1 as Apple Airport base stations
+-       * send AssocResps that are one spurious byte too long. */
+-
+-      return unknown ? ParseUnknown : ParseOK;
+ }
+-
+-
+ static int ecw2cw(int ecw)
+ {
+       int cw = 1;
+@@ -426,7 +403,9 @@
+               if (sdata->type != IEEE80211_IF_TYPE_STA)
+                       return;
+-              bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
++              bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
++                                         local->hw.conf.channel,
++                                         ifsta->ssid, ifsta->ssid_len);
+               if (bss) {
+                       if (bss->has_erp_value)
+                               ieee80211_handle_erp_ie(dev, bss->erp_value);
+@@ -571,7 +550,8 @@
+               capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
+                       WLAN_CAPABILITY_SHORT_PREAMBLE;
+       }
+-      bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
++      bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
++                                 ifsta->ssid, ifsta->ssid_len);
+       if (bss) {
+               if (bss->capability & WLAN_CAPABILITY_PRIVACY)
+                       capab |= WLAN_CAPABILITY_PRIVACY;
+@@ -719,24 +699,30 @@
+ static int ieee80211_privacy_mismatch(struct net_device *dev,
+                                     struct ieee80211_if_sta *ifsta)
+ {
++      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sta_bss *bss;
+-      int res = 0;
++      int bss_privacy;
++      int wep_privacy;
++      int privacy_invoked;
+-      if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL) ||
+-          ifsta->key_management_enabled)
++      if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
+               return 0;
+-      bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
++      bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
++                                 ifsta->ssid, ifsta->ssid_len);
+       if (!bss)
+               return 0;
+-      if (ieee80211_sta_wep_configured(dev) !=
+-          !!(bss->capability & WLAN_CAPABILITY_PRIVACY))
+-              res = 1;
++      bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
++      wep_privacy = !!ieee80211_sta_wep_configured(dev);
++      privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
+       ieee80211_rx_bss_put(dev, bss);
+-      return res;
++      if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
++              return 0;
++
++      return 1;
+ }
+@@ -920,12 +906,7 @@
+       printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name);
+       pos = mgmt->u.auth.variable;
+-      if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
+-          == ParseFailed) {
+-              printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n",
+-                     dev->name);
+-              return;
+-      }
++      ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
+       if (!elems.challenge) {
+               printk(KERN_DEBUG "%s: no challenge IE in shared key auth "
+                      "frame\n", dev->name);
+@@ -1214,12 +1195,7 @@
+       }
+       pos = mgmt->u.assoc_resp.variable;
+-      if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
+-          == ParseFailed) {
+-              printk(KERN_DEBUG "%s: failed to parse AssocResp\n",
+-                     dev->name);
+-              return;
+-      }
++      ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
+       if (!elems.supp_rates) {
+               printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
+@@ -1231,7 +1207,9 @@
+        * update our stored copy */
+       if (elems.erp_info && elems.erp_info_len >= 1) {
+               struct ieee80211_sta_bss *bss
+-                      = ieee80211_rx_bss_get(dev, ifsta->bssid);
++                      = ieee80211_rx_bss_get(dev, ifsta->bssid,
++                                             local->hw.conf.channel,
++                                             ifsta->ssid, ifsta->ssid_len);
+               if (bss) {
+                       bss->erp_value = elems.erp_info[0];
+                       bss->has_erp_value = 1;
+@@ -1261,7 +1239,9 @@
+                              " AP\n", dev->name);
+                       return;
+               }
+-              bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
++              bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
++                                         local->hw.conf.channel,
++                                         ifsta->ssid, ifsta->ssid_len);
+               if (bss) {
+                       sta->last_rssi = bss->rssi;
+                       sta->last_signal = bss->signal;
+@@ -1337,7 +1317,8 @@
+ static struct ieee80211_sta_bss *
+-ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
++ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
++                   u8 *ssid, u8 ssid_len)
+ {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sta_bss *bss;
+@@ -1348,6 +1329,11 @@
+       atomic_inc(&bss->users);
+       atomic_inc(&bss->users);
+       memcpy(bss->bssid, bssid, ETH_ALEN);
++      bss->channel = channel;
++      if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
++              memcpy(bss->ssid, ssid, ssid_len);
++              bss->ssid_len = ssid_len;
++      }
+       spin_lock_bh(&local->sta_bss_lock);
+       /* TODO: order by RSSI? */
+@@ -1359,7 +1345,8 @@
+ static struct ieee80211_sta_bss *
+-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
++ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
++                   u8 *ssid, u8 ssid_len)
+ {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sta_bss *bss;
+@@ -1367,7 +1354,10 @@
+       spin_lock_bh(&local->sta_bss_lock);
+       bss = local->sta_bss_hash[STA_HASH(bssid)];
+       while (bss) {
+-              if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
++              if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
++                  bss->channel == channel &&
++                  bss->ssid_len == ssid_len &&
++                  (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
+                       atomic_inc(&bss->users);
+                       break;
+               }
+@@ -1429,7 +1419,7 @@
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee802_11_elems elems;
+       size_t baselen;
+-      int channel, invalid = 0, clen;
++      int channel, clen;
+       struct ieee80211_sta_bss *bss;
+       struct sta_info *sta;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+@@ -1473,9 +1463,7 @@
+ #endif /* CONFIG_MAC80211_IBSS_DEBUG */
+       }
+-      if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
+-                                 &elems) == ParseFailed)
+-              invalid = 1;
++      ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
+       if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
+           memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
+@@ -1533,9 +1521,11 @@
+       else
+               channel = rx_status->channel;
+-      bss = ieee80211_rx_bss_get(dev, mgmt->bssid);
++      bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
++                                 elems.ssid, elems.ssid_len);
+       if (!bss) {
+-              bss = ieee80211_rx_bss_add(dev, mgmt->bssid);
++              bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
++                                         elems.ssid, elems.ssid_len);
+               if (!bss)
+                       return;
+       } else {
+@@ -1561,10 +1551,6 @@
+       bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
+       bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
+-      if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
+-              memcpy(bss->ssid, elems.ssid, elems.ssid_len);
+-              bss->ssid_len = elems.ssid_len;
+-      }
+       bss->supp_rates_len = 0;
+       if (elems.supp_rates) {
+@@ -1635,7 +1621,6 @@
+       bss->hw_mode = rx_status->phymode;
+-      bss->channel = channel;
+       bss->freq = rx_status->freq;
+       if (channel != rx_status->channel &&
+           (bss->hw_mode == MODE_IEEE80211G ||
+@@ -1695,9 +1680,7 @@
+       if (baselen > len)
+               return;
+-      if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
+-                                 &elems) == ParseFailed)
+-              return;
++      ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
+       if (elems.erp_info && elems.erp_info_len >= 1)
+               ieee80211_handle_erp_ie(dev, elems.erp_info[0]);
+@@ -2098,7 +2081,8 @@
+ {
+       int tmp, hidden_ssid;
+-      if (!memcmp(ifsta->ssid, ssid, ssid_len))
++      if (ssid_len == ifsta->ssid_len &&
++          !memcmp(ifsta->ssid, ssid, ssid_len))
+               return 1;
+       if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
+@@ -2357,7 +2341,7 @@
+ {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sta_bss *bss;
+-      struct ieee80211_sub_if_data *sdata;
++      struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_hw_mode *mode;
+       u8 bssid[ETH_ALEN], *pos;
+       int i;
+@@ -2379,18 +2363,17 @@
+       printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n",
+              dev->name, MAC_ARG(bssid));
+-      bss = ieee80211_rx_bss_add(dev, bssid);
++      bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
++                                 sdata->u.sta.ssid, sdata->u.sta.ssid_len);
+       if (!bss)
+               return -ENOMEM;
+-      sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       mode = local->oper_hw_mode;
+       if (local->hw.conf.beacon_int == 0)
+               local->hw.conf.beacon_int = 100;
+       bss->beacon_int = local->hw.conf.beacon_int;
+       bss->hw_mode = local->hw.conf.phymode;
+-      bss->channel = local->hw.conf.channel;
+       bss->freq = local->hw.conf.freq;
+       bss->last_update = jiffies;
+       bss->capability = WLAN_CAPABILITY_IBSS;
+@@ -2448,7 +2431,8 @@
+              MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid));
+ #endif /* CONFIG_MAC80211_IBSS_DEBUG */
+       if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
+-          (bss = ieee80211_rx_bss_get(dev, bssid))) {
++          (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
++                                      ifsta->ssid, ifsta->ssid_len))) {
+               printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT
+                      " based on configured SSID\n",
+                      dev->name, MAC_ARG(bssid));
+Index: mac80211/net/mac80211/Kconfig
+===================================================================
+--- mac80211.orig/net/mac80211/Kconfig 2007-11-11 15:45:23.225494151 +0100
++++ mac80211/net/mac80211/Kconfig      2007-11-11 15:45:30.449905846 +0100
+@@ -13,6 +13,18 @@
+       This option enables the hardware independent IEEE 802.11
+       networking stack.
++config MAC80211_RCSIMPLE
++      bool "'simple' rate control algorithm" if EMBEDDED
++      default y
++      depends on MAC80211
++      help
++        This option allows you to turn off the 'simple' rate
++        control algorithm in mac80211. If you do turn it off,
++        you absolutely need another rate control algorithm.
++
++        Say Y unless you know you will have another algorithm
++        available.
++
+ config MAC80211_LEDS
+       bool "Enable LED triggers"
+       depends on MAC80211 && LEDS_TRIGGERS
+Index: mac80211/net/mac80211/Makefile
+===================================================================
+--- mac80211.orig/net/mac80211/Makefile        2007-11-11 15:45:23.233494609 +0100
++++ mac80211/net/mac80211/Makefile     2007-11-11 15:45:30.449905846 +0100
+@@ -1,8 +1,9 @@
+-obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o
++obj-$(CONFIG_MAC80211) += mac80211.o
+ mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o
+ mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o
+ mac80211-objs-$(CONFIG_NET_SCHED) += wme.o
++mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o
+ mac80211-objs := \
+       ieee80211.o \
+Index: mac80211/net/mac80211/rc80211_simple.c
+===================================================================
+--- mac80211.orig/net/mac80211/rc80211_simple.c        2007-11-11 15:45:23.237494839 +0100
++++ mac80211/net/mac80211/rc80211_simple.c     2007-11-11 15:45:30.449905846 +0100
+@@ -7,7 +7,6 @@
+  * published by the Free Software Foundation.
+  */
+-#include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/netdevice.h>
+ #include <linux/types.h>
+@@ -29,8 +28,6 @@
+ #define RATE_CONTROL_INTERVAL (HZ / 20)
+ #define RATE_CONTROL_MIN_TX 10
+-MODULE_ALIAS("rc80211_default");
+-
+ static void rate_control_rate_inc(struct ieee80211_local *local,
+                                 struct sta_info *sta)
+ {
+@@ -393,8 +390,7 @@
+ }
+ #endif
+-static struct rate_control_ops rate_control_simple = {
+-      .module = THIS_MODULE,
++struct rate_control_ops mac80211_rcsimple = {
+       .name = "simple",
+       .tx_status = rate_control_simple_tx_status,
+       .get_rate = rate_control_simple_get_rate,
+@@ -409,22 +405,3 @@
+       .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs,
+ #endif
+ };
+-
+-
+-static int __init rate_control_simple_init(void)
+-{
+-      return ieee80211_rate_control_register(&rate_control_simple);
+-}
+-
+-
+-static void __exit rate_control_simple_exit(void)
+-{
+-      ieee80211_rate_control_unregister(&rate_control_simple);
+-}
+-
+-
+-subsys_initcall(rate_control_simple_init);
+-module_exit(rate_control_simple_exit);
+-
+-MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211");
+-MODULE_LICENSE("GPL");
+Index: mac80211/net/mac80211/rx.c
+===================================================================
+--- mac80211.orig/net/mac80211/rx.c    2007-11-11 15:45:23.245495291 +0100
++++ mac80211/net/mac80211/rx.c 2007-11-11 15:45:30.449905846 +0100
+@@ -509,9 +509,11 @@
+               rx->key->tx_rx_count++;
+               /* TODO: add threshold stuff again */
+       } else {
++#ifdef CONFIG_MAC80211_DEBUG
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "%s: RX protected frame,"
+                              " but have no key\n", rx->dev->name);
++#endif /* CONFIG_MAC80211_DEBUG */
+               return TXRX_DROP;
+       }
+Index: mac80211/net/mac80211/wep.c
+===================================================================
+--- mac80211.orig/net/mac80211/wep.c   2007-11-11 15:45:23.253495749 +0100
++++ mac80211/net/mac80211/wep.c        2007-11-11 15:45:30.449905846 +0100
+@@ -16,7 +16,7 @@
+ #include <linux/crypto.h>
+ #include <linux/err.h>
+ #include <linux/mm.h>
+-#include <asm/scatterlist.h>
++#include <linux/scatterlist.h>
+ #include <net/mac80211.h>
+ #include "ieee80211_i.h"
+@@ -138,9 +138,7 @@
+       *icv = cpu_to_le32(~crc32_le(~0, data, data_len));
+       crypto_blkcipher_setkey(tfm, rc4key, klen);
+-      sg.page = virt_to_page(data);
+-      sg.offset = offset_in_page(data);
+-      sg.length = data_len + WEP_ICV_LEN;
++      sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
+       crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
+ }
+@@ -204,9 +202,7 @@
+       __le32 crc;
+       crypto_blkcipher_setkey(tfm, rc4key, klen);
+-      sg.page = virt_to_page(data);
+-      sg.offset = offset_in_page(data);
+-      sg.length = data_len + WEP_ICV_LEN;
++      sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
+       crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
+       crc = cpu_to_le32(~crc32_le(~0, data, data_len));
+@@ -318,9 +314,11 @@
+       if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
+               if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
++#ifdef CONFIG_MAC80211_DEBUG
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
+                                      "failed\n", rx->dev->name);
++#endif /* CONFIG_MAC80211_DEBUG */
+                       return TXRX_DROP;
+               }
+       } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
+Index: mac80211/net/wireless/Kconfig
+===================================================================
+--- mac80211.orig/net/wireless/Kconfig 2007-11-11 15:45:23.261496205 +0100
++++ mac80211/net/wireless/Kconfig      2007-11-11 15:45:30.453906075 +0100
+@@ -3,7 +3,7 @@
+ config NL80211
+       bool "nl80211 new netlink interface support"
+-      depends CFG80211
++      depends on CFG80211
+       default y
+       ---help---
+          This option turns on the new netlink interface
diff --git a/package/mac80211/patches/008-add-hostapd-ioctl-header.patch b/package/mac80211/patches/008-add-hostapd-ioctl-header.patch
new file mode 100644 (file)
index 0000000..acea0ce
--- /dev/null
@@ -0,0 +1,110 @@
+---
+ net/mac80211/hostapd_ioctl.h |  103 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 103 insertions(+)
+
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ everything/net/mac80211/hostapd_ioctl.h    2007-11-07 13:19:23.031516330 +0100
+@@ -0,0 +1,103 @@
++/*
++ * Host AP (software wireless LAN access point) user space daemon for
++ * Host AP kernel driver
++ * Copyright 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
++ * Copyright 2002-2004, Instant802 Networks, Inc.
++ * Copyright 2005, Devicescape Software, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef HOSTAPD_IOCTL_H
++#define HOSTAPD_IOCTL_H
++
++#ifdef __KERNEL__
++#include <linux/types.h>
++#endif /* __KERNEL__ */
++
++#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0)
++#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1)
++#define PRISM2_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 3)
++
++/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes:
++ * This table is no longer added to, the whole sub-ioctl
++ * mess shall be deleted completely. */
++enum {
++      PRISM2_PARAM_AP_BRIDGE_PACKETS = 10,
++      PRISM2_PARAM_IEEE_802_1X = 23,
++
++      /* Instant802 additions */
++      PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES = 1001,
++      PRISM2_PARAM_PREAMBLE = 1003,
++      PRISM2_PARAM_SHORT_SLOT_TIME = 1006,
++      PRISM2_PARAM_NEXT_MODE = 1008,
++      PRISM2_PARAM_PRIVACY_INVOKED = 1014,
++      PRISM2_PARAM_EAPOL = 1023,
++      PRISM2_PARAM_MGMT_IF = 1046,
++};
++
++/* PRISM2_IOCTL_HOSTAPD ioctl() cmd:
++ * This table is no longer added to, the hostapd ioctl
++ * shall be deleted completely. */
++enum {
++      PRISM2_HOSTAPD_FLUSH = 1,
++
++      /* Instant802 additions */
++      PRISM2_HOSTAPD_GET_HW_FEATURES = 1002,
++      PRISM2_HOSTAPD_SET_RATE_SETS = 1005,
++      PRISM2_HOSTAPD_SET_CHANNEL_FLAG = 1012,
++      PRISM2_HOSTAPD_SET_REGULATORY_DOMAIN = 1013,
++      PRISM2_HOSTAPD_SET_TX_QUEUE_PARAMS = 1014,
++};
++
++#define PRISM2_HOSTAPD_MAX_BUF_SIZE 2048
++#define ALIGNED __attribute__ ((aligned))
++
++struct prism2_hostapd_param {
++      u32 cmd;
++      u8 sta_addr[ETH_ALEN];
++      u8 pad[2];
++      union {
++              struct {
++                      u16 num_modes;
++                      u16 flags;
++                      u8 data[0] ALIGNED; /* num_modes * feature data */
++              } hw_features;
++              struct {
++                      u16 mode; /* MODE_* */
++                      u16 num_supported_rates;
++                      u16 num_basic_rates;
++                      u8 data[0] ALIGNED; /* num_supported_rates * u16 +
++                                           * num_basic_rates * u16 */
++              } set_rate_sets;
++              struct {
++                      u16 mode; /* MODE_* */
++                      u16 chan;
++                      u32 flag;
++                      u8 power_level; /* regulatory limit in dBm */
++                      u8 antenna_max;
++              } set_channel_flag;
++              struct {
++                      u32 rd;
++              } set_regulatory_domain;
++              struct {
++                      u32 queue;
++                      s32 aifs;
++                      u32 cw_min;
++                      u32 cw_max;
++                      u32 burst_time; /* maximum burst time in 0.1 ms, i.e.,
++                                       * 10 = 1 ms */
++              } tx_queue_params;
++      } u;
++};
++
++/* Data structures used for get_hw_features ioctl */
++struct hostapd_ioctl_hw_modes_hdr {
++      int mode;
++      int num_channels;
++      int num_rates;
++};
++
++#endif /* HOSTAPD_IOCTL_H */
diff --git a/package/mac80211/patches/009-add-old-ioctl-skeleton.patch b/package/mac80211/patches/009-add-old-ioctl-skeleton.patch
new file mode 100644 (file)
index 0000000..fb9f25f
--- /dev/null
@@ -0,0 +1,187 @@
+---
+ net/mac80211/ieee80211.c       |    5 +
+ net/mac80211/ieee80211_ioctl.c |  121 +++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 126 insertions(+)
+
+--- everything.orig/net/mac80211/ieee80211_ioctl.c     2007-11-07 13:06:34.902124618 +0100
++++ everything/net/mac80211/ieee80211_ioctl.c  2007-11-07 13:19:24.311521482 +0100
+@@ -21,6 +21,7 @@
+ #include <net/mac80211.h>
+ #include "ieee80211_i.h"
++#include "hostapd_ioctl.h"
+ #include "ieee80211_rate.h"
+ #include "wpa.h"
+ #include "aes_ccm.h"
+@@ -124,6 +125,47 @@ static int ieee80211_ioctl_siwgenie(stru
+       return -EOPNOTSUPP;
+ }
++
++static int ieee80211_ioctl_priv_hostapd(struct net_device *dev,
++                                      struct iw_point *p)
++{
++      struct prism2_hostapd_param *param;
++      int ret = 0;
++
++      if (p->length < sizeof(struct prism2_hostapd_param) ||
++          p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer) {
++              printk(KERN_DEBUG "%s: hostapd ioctl: ptr=%p len=%d min=%d "
++                     "max=%d\n", dev->name, p->pointer, p->length,
++                     (int)sizeof(struct prism2_hostapd_param),
++                     PRISM2_HOSTAPD_MAX_BUF_SIZE);
++              return -EINVAL;
++      }
++
++      param = kmalloc(p->length, GFP_KERNEL);
++      if (!param)
++              return -ENOMEM;
++
++      if (copy_from_user(param, p->pointer, p->length)) {
++              ret = -EFAULT;
++              goto out;
++      }
++
++      switch (param->cmd) {
++      default:
++              ret = -EOPNOTSUPP;
++              break;
++      }
++
++      if (copy_to_user(p->pointer, param, p->length))
++              ret = -EFAULT;
++
++ out:
++      kfree(param);
++
++      return ret;
++}
++
++
+ static int ieee80211_ioctl_giwname(struct net_device *dev,
+                                  struct iw_request_info *info,
+                                  char *name, char *extra)
+@@ -819,6 +861,49 @@ static int ieee80211_ioctl_giwretry(stru
+       return 0;
+ }
++static int ieee80211_ioctl_prism2_param(struct net_device *dev,
++                                      struct iw_request_info *info,
++                                      void *wrqu, char *extra)
++{
++      struct ieee80211_sub_if_data *sdata;
++      int *i = (int *) extra;
++      int param = *i;
++      int ret = 0;
++
++      if (!capable(CAP_NET_ADMIN))
++              return -EPERM;
++
++      sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++
++      switch (param) {
++      default:
++              ret = -EOPNOTSUPP;
++              break;
++      }
++
++      return ret;
++}
++
++
++static int ieee80211_ioctl_get_prism2_param(struct net_device *dev,
++                                          struct iw_request_info *info,
++                                          void *wrqu, char *extra)
++{
++      struct ieee80211_sub_if_data *sdata;
++      int *param = (int *) extra;
++      int ret = 0;
++
++      sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++
++      switch (*param) {
++      default:
++              ret = -EOPNOTSUPP;
++              break;
++      }
++
++      return ret;
++}
++
+ static int ieee80211_ioctl_siwmlme(struct net_device *dev,
+                                  struct iw_request_info *info,
+                                  struct iw_point *data, char *extra)
+@@ -1073,6 +1158,32 @@ static int ieee80211_ioctl_siwencodeext(
+ }
++static const struct iw_priv_args ieee80211_ioctl_priv[] = {
++      { PRISM2_IOCTL_PRISM2_PARAM,
++        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "param" },
++      { PRISM2_IOCTL_GET_PRISM2_PARAM,
++        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
++        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param" },
++};
++
++
++int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
++{
++      struct iwreq *wrq = (struct iwreq *) rq;
++
++      switch (cmd) {
++              /* Private ioctls (iwpriv) that have not yet been converted
++               * into new wireless extensions API */
++      case PRISM2_IOCTL_HOSTAPD:
++              if (!capable(CAP_NET_ADMIN))
++                      return -EPERM;
++              return ieee80211_ioctl_priv_hostapd(dev, &wrq->u.data);
++      default:
++              return -EOPNOTSUPP;
++      }
++}
++
++
+ /* Structures to export the Wireless Handlers */
+ static const iw_handler ieee80211_handler[] =
+@@ -1135,9 +1246,19 @@ static const iw_handler ieee80211_handle
+       (iw_handler) NULL,                              /* -- hole -- */
+ };
++static const iw_handler ieee80211_private_handler[] =
++{                                                     /* SIOCIWFIRSTPRIV + */
++      (iw_handler) ieee80211_ioctl_prism2_param,      /* 0 */
++      (iw_handler) ieee80211_ioctl_get_prism2_param,  /* 1 */
++};
++
+ const struct iw_handler_def ieee80211_iw_handler_def =
+ {
+       .num_standard   = ARRAY_SIZE(ieee80211_handler),
++      .num_private    = ARRAY_SIZE(ieee80211_private_handler),
++      .num_private_args = ARRAY_SIZE(ieee80211_ioctl_priv),
+       .standard       = (iw_handler *) ieee80211_handler,
++      .private        = (iw_handler *) ieee80211_private_handler,
++      .private_args   = (struct iw_priv_args *) ieee80211_ioctl_priv,
+       .get_wireless_stats = ieee80211_get_wireless_stats,
+ };
+--- everything.orig/net/mac80211/ieee80211.c   2007-11-07 13:18:36.001511500 +0100
++++ everything/net/mac80211/ieee80211.c        2007-11-07 13:19:24.311521482 +0100
+@@ -413,6 +413,9 @@ static const struct header_ops ieee80211
+       .cache_update   = eth_header_cache_update,
+ };
++/* HACK */
++extern int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
++
+ /* Must not be called for mdev */
+ void ieee80211_if_setup(struct net_device *dev)
+ {
+@@ -425,6 +428,8 @@ void ieee80211_if_setup(struct net_devic
+       dev->open = ieee80211_open;
+       dev->stop = ieee80211_stop;
+       dev->destructor = ieee80211_if_free;
++
++      dev->do_ioctl = ieee80211_ioctl;
+ }
+ /* WDS specialties */
diff --git a/package/mac80211/patches/010-add-mgmt-iface.patch b/package/mac80211/patches/010-add-mgmt-iface.patch
new file mode 100644 (file)
index 0000000..eae5ff6
--- /dev/null
@@ -0,0 +1,688 @@
+---
+ include/net/mac80211.h          |    1 
+ net/mac80211/ieee80211.c        |  198 ++++++++++++++++++++++++++++++++++++++--
+ net/mac80211/ieee80211_common.h |   64 ++++++++++++
+ net/mac80211/ieee80211_i.h      |    9 +
+ net/mac80211/ieee80211_iface.c  |   66 +++++++++++++
+ net/mac80211/ieee80211_ioctl.c  |   21 ++++
+ net/mac80211/ieee80211_rate.c   |    3 
+ net/mac80211/ieee80211_rate.h   |    2 
+ net/mac80211/ieee80211_sta.c    |    2 
+ net/mac80211/rx.c               |   29 ++++-
+ net/mac80211/tx.c               |   14 ++
+ net/mac80211/wme.c              |   10 +-
+ 12 files changed, 399 insertions(+), 20 deletions(-)
+
+Index: mac80211/include/net/mac80211.h
+===================================================================
+--- mac80211.orig/include/net/mac80211.h       2007-11-11 15:15:42.824034853 +0100
++++ mac80211/include/net/mac80211.h    2007-11-11 15:15:53.784659457 +0100
+@@ -472,6 +472,7 @@
+ enum ieee80211_if_types {
+       IEEE80211_IF_TYPE_INVALID,
+       IEEE80211_IF_TYPE_AP,
++      IEEE80211_IF_TYPE_MGMT,
+       IEEE80211_IF_TYPE_STA,
+       IEEE80211_IF_TYPE_IBSS,
+       IEEE80211_IF_TYPE_MNTR,
+Index: mac80211/net/mac80211/ieee80211.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211.c     2007-11-11 15:15:51.536531354 +0100
++++ mac80211/net/mac80211/ieee80211.c  2007-11-11 15:16:22.214279577 +0100
+@@ -23,6 +23,7 @@
+ #include <linux/bitmap.h>
+ #include <net/cfg80211.h>
++#include "ieee80211_common.h"
+ #include "ieee80211_i.h"
+ #include "ieee80211_rate.h"
+ #include "wep.h"
+@@ -121,6 +122,152 @@
+       ieee80211_configure_filter(local);
+ }
++/* management interface */
++
++static void
++ieee80211_fill_frame_info(struct ieee80211_local *local,
++                        struct ieee80211_frame_info *fi,
++                        struct ieee80211_rx_status *status)
++{
++      if (status) {
++              struct timespec ts;
++              struct ieee80211_rate *rate;
++
++              jiffies_to_timespec(jiffies, &ts);
++              fi->hosttime = cpu_to_be64((u64) ts.tv_sec * 1000000 +
++                                         ts.tv_nsec / 1000);
++              fi->mactime = cpu_to_be64(status->mactime);
++              switch (status->phymode) {
++              case MODE_IEEE80211A:
++                      fi->phytype = htonl(ieee80211_phytype_ofdm_dot11_a);
++                      break;
++              case MODE_IEEE80211B:
++                      fi->phytype = htonl(ieee80211_phytype_dsss_dot11_b);
++                      break;
++              case MODE_IEEE80211G:
++                      fi->phytype = htonl(ieee80211_phytype_pbcc_dot11_g);
++                      break;
++              default:
++                      fi->phytype = htonl(0xAAAAAAAA);
++                      break;
++              }
++              fi->channel = htonl(status->channel);
++              rate = ieee80211_get_rate(local, status->phymode,
++                                        status->rate);
++              if (rate) {
++                      fi->datarate = htonl(rate->rate);
++                      if (rate->flags & IEEE80211_RATE_PREAMBLE2) {
++                              if (status->rate == rate->val)
++                                      fi->preamble = htonl(2); /* long */
++                              else if (status->rate == rate->val2)
++                                      fi->preamble = htonl(1); /* short */
++                      } else
++                              fi->preamble = htonl(0);
++              } else {
++                      fi->datarate = htonl(0);
++                      fi->preamble = htonl(0);
++              }
++
++              fi->antenna = htonl(status->antenna);
++              fi->priority = htonl(0xffffffff); /* no clue */
++              fi->ssi_type = htonl(ieee80211_ssi_raw);
++              fi->ssi_signal = htonl(status->ssi);
++              fi->ssi_noise = 0x00000000;
++              fi->encoding = 0;
++      } else {
++              /* clear everything because we really don't know.
++               * the msg_type field isn't present on monitor frames
++               * so we don't know whether it will be present or not,
++               * but it's ok to not clear it since it'll be assigned
++               * anyway */
++              memset(fi, 0, sizeof(*fi) - sizeof(fi->msg_type));
++
++              fi->ssi_type = htonl(ieee80211_ssi_none);
++      }
++      fi->version = htonl(IEEE80211_FI_VERSION);
++      fi->length = cpu_to_be32(sizeof(*fi) - sizeof(fi->msg_type));
++}
++
++/* this routine is actually not just for this, but also
++ * for pushing fake 'management' frames into userspace.
++ * it shall be replaced by a netlink-based system. */
++void
++ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb,
++                struct ieee80211_rx_status *status, u32 msg_type)
++{
++      struct ieee80211_frame_info *fi;
++      const size_t hlen = sizeof(struct ieee80211_frame_info);
++      struct net_device *dev = local->apdev;
++
++      skb->dev = dev;
++
++      if (skb_headroom(skb) < hlen) {
++              I802_DEBUG_INC(local->rx_expand_skb_head);
++              if (pskb_expand_head(skb, hlen, 0, GFP_ATOMIC)) {
++                      dev_kfree_skb(skb);
++                      return;
++              }
++      }
++
++      fi = (struct ieee80211_frame_info *) skb_push(skb, hlen);
++
++      ieee80211_fill_frame_info(local, fi, status);
++      fi->msg_type = htonl(msg_type);
++
++      dev->stats.rx_packets++;
++      dev->stats.rx_bytes += skb->len;
++
++      skb_set_mac_header(skb, 0);
++      skb->ip_summed = CHECKSUM_UNNECESSARY;
++      skb->pkt_type = PACKET_OTHERHOST;
++      skb->protocol = htons(ETH_P_802_2);
++      memset(skb->cb, 0, sizeof(skb->cb));
++      netif_rx(skb);
++}
++
++static int ieee80211_mgmt_open(struct net_device *dev)
++{
++      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
++
++      if (!netif_running(local->mdev))
++              return -EOPNOTSUPP;
++      return 0;
++}
++
++static int ieee80211_mgmt_stop(struct net_device *dev)
++{
++      return 0;
++}
++
++static int ieee80211_change_mtu_apdev(struct net_device *dev, int new_mtu)
++{
++      /* FIX: what would be proper limits for MTU?
++       * This interface uses 802.11 frames. */
++      if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN) {
++              printk(KERN_WARNING "%s: invalid MTU %d\n",
++                     dev->name, new_mtu);
++              return -EINVAL;
++      }
++
++#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
++      printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu);
++#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
++      dev->mtu = new_mtu;
++      return 0;
++}
++
++void ieee80211_if_mgmt_setup(struct net_device *dev)
++{
++      ether_setup(dev);
++      dev->hard_start_xmit = ieee80211_mgmt_start_xmit;
++      dev->change_mtu = ieee80211_change_mtu_apdev;
++      dev->open = ieee80211_mgmt_open;
++      dev->stop = ieee80211_mgmt_stop;
++      dev->type = ARPHRD_IEEE80211_PRISM;
++      dev->hard_header_parse = &header_parse_80211;
++      dev->destructor = ieee80211_if_free;
++}
++
+ /* regular interfaces */
+ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
+@@ -198,6 +345,7 @@
+                       return -ENOLINK;
+               break;
+       case IEEE80211_IF_TYPE_AP:
++      case IEEE80211_IF_TYPE_MGMT:
+       case IEEE80211_IF_TYPE_STA:
+       case IEEE80211_IF_TYPE_MNTR:
+       case IEEE80211_IF_TYPE_IBSS:
+@@ -262,6 +410,10 @@
+       if (local->open_count == 0) {
+               res = dev_open(local->mdev);
+               WARN_ON(res);
++              if (local->apdev) {
++                      res = dev_open(local->apdev);
++                      WARN_ON(res);
++              }
+               tasklet_enable(&local->tx_pending_tasklet);
+               tasklet_enable(&local->tasklet);
+       }
+@@ -347,6 +499,9 @@
+               if (netif_running(local->mdev))
+                       dev_close(local->mdev);
++              if (local->apdev)
++                      dev_close(local->apdev);
++
+               if (local->ops->stop)
+                       local->ops->stop(local_to_hw(local));
+@@ -646,6 +801,8 @@
+               pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
+       if (control->flags & IEEE80211_TXCTL_REQUEUE)
+               pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
++      if (control->type == IEEE80211_IF_TYPE_MGMT)
++              pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
+       pkt_data->queue = control->queue;
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+@@ -698,6 +855,7 @@
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_local *local = hw_to_local(hw);
+       u16 frag, type;
++      u32 msg_type;
+       struct ieee80211_tx_status_rtap_hdr *rthdr;
+       struct ieee80211_sub_if_data *sdata;
+       int monitors;
+@@ -812,9 +970,29 @@
+                       local->dot11FailedCount++;
+       }
++      msg_type = (status->flags & IEEE80211_TX_STATUS_ACK) ?
++              ieee80211_msg_tx_callback_ack : ieee80211_msg_tx_callback_fail;
++
+       /* this was a transmitted frame, but now we want to reuse it */
+       skb_orphan(skb);
++      if ((status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) &&
++          local->apdev) {
++              if (local->monitors) {
++                      skb2 = skb_clone(skb, GFP_ATOMIC);
++              } else {
++                      skb2 = skb;
++                      skb = NULL;
++              }
++
++              if (skb2)
++                      /* Send frame to hostapd */
++                      ieee80211_rx_mgmt(local, skb2, NULL, msg_type);
++
++              if (!skb)
++                      return;
++      }
++
+       if (!local->monitors) {
+               dev_kfree_skb(skb);
+               return;
+@@ -1161,6 +1339,8 @@
+       BUG_ON(local->reg_state != IEEE80211_DEV_REGISTERED);
+       local->reg_state = IEEE80211_DEV_UNREGISTERED;
++      if (local->apdev)
++              ieee80211_if_del_mgmt(local);
+       /*
+        * At this point, interface list manipulations are fine
+Index: mac80211/net/mac80211/ieee80211_i.h
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_i.h   2007-11-11 15:15:42.840035769 +0100
++++ mac80211/net/mac80211/ieee80211_i.h        2007-11-11 15:15:53.792659922 +0100
+@@ -142,6 +142,7 @@
+                        * when using CTS protection with IEEE 802.11g. */
+                       struct ieee80211_rate *last_frag_rate;
+                       int last_frag_hwrate;
++                      int mgmt_interface;
+                       /* Extra fragments (in addition to the first fragment
+                        * in skb) */
+@@ -163,6 +164,7 @@
+ #define IEEE80211_TXPD_REQ_TX_STATUS  BIT(0)
+ #define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1)
+ #define IEEE80211_TXPD_REQUEUE                BIT(2)
++#define IEEE80211_TXPD_MGMT_IFACE     BIT(3)
+ /* Stored in sk_buff->cb */
+ struct ieee80211_tx_packet_data {
+       int ifindex;
+@@ -408,6 +410,7 @@
+       struct list_head modes_list;
+       struct net_device *mdev; /* wmaster# - "master" 802.11 device */
++      struct net_device *apdev; /* wlan#ap - management frames (hostapd) */
+       int open_count;
+       int monitors;
+       unsigned int filter_flags; /* FIF_* */
+@@ -701,11 +704,14 @@
+ int ieee80211_hw_config(struct ieee80211_local *local);
+ int ieee80211_if_config(struct net_device *dev);
+ int ieee80211_if_config_beacon(struct net_device *dev);
++void ieee80211_rx_mgmt(struct ieee80211_local *local, struct sk_buff *skb,
++                     struct ieee80211_rx_status *status, u32 msg_type);
+ void ieee80211_prepare_rates(struct ieee80211_local *local,
+                            struct ieee80211_hw_mode *mode);
+ void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx);
+ int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
+ void ieee80211_if_setup(struct net_device *dev);
++void ieee80211_if_mgmt_setup(struct net_device *dev);
+ struct ieee80211_rate *ieee80211_get_rate(struct ieee80211_local *local,
+                                         int phymode, int hwrate);
+@@ -772,6 +778,8 @@
+ int ieee80211_if_remove(struct net_device *dev, const char *name, int id);
+ void ieee80211_if_free(struct net_device *dev);
+ void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata);
++int ieee80211_if_add_mgmt(struct ieee80211_local *local);
++void ieee80211_if_del_mgmt(struct ieee80211_local *local);
+ /* regdomain.c */
+ void ieee80211_regdomain_init(void);
+@@ -788,6 +796,7 @@
+ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
++int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ /* utility functions/constants */
+ extern void *mac80211_wiphy_privid; /* for wiphy privid */
+Index: mac80211/net/mac80211/ieee80211_iface.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_iface.c       2007-11-11 15:15:42.848036222 +0100
++++ mac80211/net/mac80211/ieee80211_iface.c    2007-11-11 15:15:53.796660158 +0100
+@@ -96,6 +96,66 @@
+       return ret;
+ }
++int ieee80211_if_add_mgmt(struct ieee80211_local *local)
++{
++      struct net_device *ndev;
++      struct ieee80211_sub_if_data *nsdata;
++      int ret;
++
++      ASSERT_RTNL();
++
++      ndev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), "wmgmt%d",
++                          ieee80211_if_mgmt_setup);
++      if (!ndev)
++              return -ENOMEM;
++      ret = dev_alloc_name(ndev, ndev->name);
++      if (ret < 0)
++              goto fail;
++
++      memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
++      SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
++
++      nsdata = IEEE80211_DEV_TO_SUB_IF(ndev);
++      ndev->ieee80211_ptr = &nsdata->wdev;
++      nsdata->wdev.wiphy = local->hw.wiphy;
++      nsdata->type = IEEE80211_IF_TYPE_MGMT;
++      nsdata->dev = ndev;
++      nsdata->local = local;
++      ieee80211_if_sdata_init(nsdata);
++
++      ret = register_netdevice(ndev);
++      if (ret)
++              goto fail;
++
++      /*
++       * Called even when register_netdevice fails, it would
++       * oops if assigned before initialising the rest.
++       */
++      ndev->uninit = ieee80211_if_reinit;
++
++      ieee80211_debugfs_add_netdev(nsdata);
++
++      if (local->open_count > 0)
++              dev_open(ndev);
++      local->apdev = ndev;
++      return 0;
++
++fail:
++      free_netdev(ndev);
++      return ret;
++}
++
++void ieee80211_if_del_mgmt(struct ieee80211_local *local)
++{
++      struct net_device *apdev;
++
++      ASSERT_RTNL();
++      apdev = local->apdev;
++      ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(apdev));
++      local->apdev = NULL;
++      unregister_netdevice(apdev);
++}
++
+ void ieee80211_if_set_type(struct net_device *dev, int type)
+ {
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+@@ -183,6 +243,9 @@
+       ieee80211_if_sdata_deinit(sdata);
+       switch (sdata->type) {
++      case IEEE80211_IF_TYPE_MGMT:
++              /* nothing to do */
++              break;
+       case IEEE80211_IF_TYPE_INVALID:
+               /* cannot happen */
+               WARN_ON(1);
+@@ -294,8 +357,11 @@
+ void ieee80211_if_free(struct net_device *dev)
+ {
++      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      /* local->apdev must be NULL when freeing management interface */
++      BUG_ON(dev == local->apdev);
+       ieee80211_if_sdata_deinit(sdata);
+       free_netdev(dev);
+ }
+Index: mac80211/net/mac80211/ieee80211_rate.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_rate.c        2007-11-11 15:15:42.852036451 +0100
++++ mac80211/net/mac80211/ieee80211_rate.c     2007-11-11 15:15:53.800660386 +0100
+@@ -145,7 +145,8 @@
+       struct rate_control_ref *ref, *old;
+       ASSERT_RTNL();
+-      if (local->open_count || netif_running(local->mdev))
++      if (local->open_count || netif_running(local->mdev) ||
++          (local->apdev && netif_running(local->apdev)))
+               return -EBUSY;
+       ref = rate_control_alloc(name, local);
+Index: mac80211/net/mac80211/ieee80211_rate.h
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_rate.h        2007-11-11 15:15:42.860036908 +0100
++++ mac80211/net/mac80211/ieee80211_rate.h     2007-11-11 15:15:53.800660386 +0100
+@@ -30,6 +30,8 @@
+       /* parameters from the caller to rate_control_get_rate(): */
+       struct ieee80211_hw_mode *mode;
++      int mgmt_data; /* this is data frame that is used for management
++                      * (e.g., IEEE 802.1X EAPOL) */
+       u16 ethertype;
+ };
+Index: mac80211/net/mac80211/ieee80211_sta.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_sta.c 2007-11-11 15:15:42.868037362 +0100
++++ mac80211/net/mac80211/ieee80211_sta.c      2007-11-11 15:15:53.800660386 +0100
+@@ -475,6 +475,8 @@
+       pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
+       memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
+       pkt_data->ifindex = sdata->dev->ifindex;
++      if (sdata->type == IEEE80211_IF_TYPE_MGMT)
++              pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
+       if (!encrypt)
+               pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
+Index: mac80211/net/mac80211/rx.c
+===================================================================
+--- mac80211.orig/net/mac80211/rx.c    2007-11-11 15:15:42.872037591 +0100
++++ mac80211/net/mac80211/rx.c 2007-11-11 15:15:53.804660611 +0100
+@@ -19,6 +19,7 @@
+ #include "ieee80211_i.h"
+ #include "ieee80211_led.h"
++#include "ieee80211_common.h"
+ #include "wep.h"
+ #include "wpa.h"
+ #include "tkip.h"
+@@ -411,7 +412,12 @@
+                       return TXRX_DROP;
+               }
+-              return TXRX_DROP;
++              if (!rx->local->apdev)
++                      return TXRX_DROP;
++
++              ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
++                                ieee80211_msg_sta_not_assoc);
++              return TXRX_QUEUED;
+       }
+       return TXRX_CONTINUE;
+@@ -953,8 +959,15 @@
+ {
+       if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) &&
+           rx->sdata->type != IEEE80211_IF_TYPE_STA &&
+-          (rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
+-              return TXRX_CONTINUE;
++          (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
++              /* Pass both encrypted and unencrypted EAPOL frames to user
++               * space for processing. */
++              if (!rx->local->apdev)
++                      return TXRX_DROP;
++              ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
++                                ieee80211_msg_normal);
++              return TXRX_QUEUED;
++      }
+       if (unlikely(rx->sdata->ieee802_1x &&
+                    (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
+@@ -1196,8 +1209,13 @@
+            sdata->type == IEEE80211_IF_TYPE_IBSS) &&
+           !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
+               ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
+-      else
+-              return TXRX_DROP;
++      else {
++              /* Management frames are sent to hostapd for processing */
++              if (!rx->local->apdev)
++                      return TXRX_DROP;
++              ieee80211_rx_mgmt(rx->local, rx->skb, rx->u.rx.status,
++                                ieee80211_msg_normal);
++      }
+       return TXRX_QUEUED;
+ }
+@@ -1407,6 +1425,7 @@
+               /* take everything */
+               break;
+       case IEEE80211_IF_TYPE_INVALID:
++      case IEEE80211_IF_TYPE_MGMT:
+               /* should never get here */
+               WARN_ON(1);
+               break;
+Index: mac80211/net/mac80211/tx.c
+===================================================================
+--- mac80211.orig/net/mac80211/tx.c    2007-11-11 15:15:42.880038048 +0100
++++ mac80211/net/mac80211/tx.c 2007-11-11 15:15:53.804660611 +0100
+@@ -258,7 +258,7 @@
+               return TXRX_CONTINUE;
+       }
+-      if (unlikely(/* !injected && */ tx->sdata->ieee802_1x &&
++      if (unlikely(!tx->u.tx.mgmt_interface && tx->sdata->ieee802_1x &&
+                    !(sta_flags & WLAN_STA_AUTHORIZED))) {
+ #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+               printk(KERN_DEBUG "%s: dropped frame to " MAC_FMT
+@@ -568,6 +568,8 @@
+               memset(&extra, 0, sizeof(extra));
+               extra.mode = tx->u.tx.mode;
+               extra.ethertype = tx->ethertype;
++              extra.mgmt_data = tx->sdata &&
++                                tx->sdata->type == IEEE80211_IF_TYPE_MGMT;
+               tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev,
+                                                     tx->skb, &extra);
+@@ -1076,7 +1078,7 @@
+ }
+ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
+-                      struct ieee80211_tx_control *control)
++                      struct ieee80211_tx_control *control, int mgmt)
+ {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct sta_info *sta;
+@@ -1107,6 +1109,7 @@
+       rcu_read_lock();
+       sta = tx.sta;
++      tx.u.tx.mgmt_interface = mgmt;
+       tx.u.tx.mode = local->hw.conf.mode;
+       for (handler = local->tx_handlers; *handler != NULL;
+@@ -1253,7 +1256,8 @@
+               control.flags |= IEEE80211_TXCTL_REQUEUE;
+       control.queue = pkt_data->queue;
+-      ret = ieee80211_tx(odev, skb, &control);
++      ret = ieee80211_tx(odev, skb, &control,
++                         control.type == IEEE80211_IF_TYPE_MGMT);
+       dev_put(odev);
+       return ret;
+@@ -1498,6 +1502,8 @@
+       pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
+       memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
+       pkt_data->ifindex = dev->ifindex;
++      if (sdata->type == IEEE80211_IF_TYPE_MGMT)
++              pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
+       skb->dev = local->mdev;
+       dev->stats.tx_packets++;
+@@ -1555,6 +1561,8 @@
+       pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
+       memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
+       pkt_data->ifindex = sdata->dev->ifindex;
++      if (sdata->type == IEEE80211_IF_TYPE_MGMT)
++              pkt_data->flags |= IEEE80211_TXPD_MGMT_IFACE;
+       skb->priority = 20; /* use hardcoded priority for mgmt TX queue */
+       skb->dev = sdata->local->mdev;
+Index: mac80211/net/mac80211/wme.c
+===================================================================
+--- mac80211.orig/net/mac80211/wme.c   2007-11-11 15:15:42.888038502 +0100
++++ mac80211/net/mac80211/wme.c        2007-11-11 15:15:53.804660611 +0100
+@@ -94,6 +94,8 @@
+ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd)
+ {
+       struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
++      struct ieee80211_tx_packet_data *pkt_data =
++              (struct ieee80211_tx_packet_data *) skb->cb;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       unsigned short fc = le16_to_cpu(hdr->frame_control);
+       int qos;
+@@ -106,8 +108,12 @@
+               return IEEE80211_TX_QUEUE_DATA0;
+       }
+-      if (0 /* injected */) {
+-              /* use AC from radiotap */
++      if (unlikely(pkt_data->flags & IEEE80211_TXPD_MGMT_IFACE)) {
++              /* Data frames from hostapd (mainly, EAPOL) use AC_VO
++              * and they will include QoS control fields if
++              * the target STA is using WME. */
++              skb->priority = 7;
++              return ieee802_1d_to_ac[skb->priority];
+       }
+       /* is this a QoS frame? */
+Index: mac80211/net/mac80211/ieee80211_ioctl.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_ioctl.c       2007-11-11 15:15:51.532531127 +0100
++++ mac80211/net/mac80211/ieee80211_ioctl.c    2007-11-11 15:15:53.808660833 +0100
+@@ -840,16 +840,29 @@
+                                       void *wrqu, char *extra)
+ {
+       struct ieee80211_sub_if_data *sdata;
++      struct ieee80211_local *local;
+       int *i = (int *) extra;
+       int param = *i;
++      int value = *(i + 1);
+       int ret = 0;
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      local = sdata->local;
+       switch (param) {
++      case PRISM2_PARAM_MGMT_IF:
++              if (value == 1) {
++                      if (!local->apdev)
++                              ret = ieee80211_if_add_mgmt(local);
++              } else if (value == 0) {
++                      if (local->apdev)
++                              ieee80211_if_del_mgmt(local);
++              } else
++                      ret = -EINVAL;
++              break;
+       default:
+               ret = -EOPNOTSUPP;
+               break;
+@@ -864,12 +877,20 @@
+                                           void *wrqu, char *extra)
+ {
+       struct ieee80211_sub_if_data *sdata;
++      struct ieee80211_local *local;
+       int *param = (int *) extra;
+       int ret = 0;
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      local = sdata->local;
+       switch (*param) {
++      case PRISM2_PARAM_MGMT_IF:
++              if (local->apdev)
++                      *param = local->apdev->ifindex;
++              else
++                      ret = -ENOENT;
++              break;
+       default:
+               ret = -EOPNOTSUPP;
+               break;
diff --git a/package/mac80211/patches/011-allow-ap-vlan-modes.patch b/package/mac80211/patches/011-allow-ap-vlan-modes.patch
new file mode 100644 (file)
index 0000000..d0edfe8
--- /dev/null
@@ -0,0 +1,37 @@
+Subject: mac80211: allow AP and VLAN modes
+
+This adds AP/VLAN modes to the list of modes that a mac80211
+interface can be created in/switched into.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ net/mac80211/cfg.c             |    4 ++++
+ net/mac80211/ieee80211_ioctl.c |    3 +++
+ 2 files changed, 7 insertions(+)
+
+--- everything.orig/net/mac80211/cfg.c 2007-10-30 15:33:43.227379286 +0100
++++ everything/net/mac80211/cfg.c      2007-11-07 13:19:27.981515569 +0100
+@@ -25,6 +25,10 @@ nl80211_type_to_mac80211_type(enum nl802
+               return IEEE80211_IF_TYPE_STA;
+       case NL80211_IFTYPE_MONITOR:
+               return IEEE80211_IF_TYPE_MNTR;
++      case NL80211_IFTYPE_AP:
++              return IEEE80211_IF_TYPE_AP;
++      case NL80211_IFTYPE_AP_VLAN:
++              return IEEE80211_IF_TYPE_VLAN;
+       default:
+               return IEEE80211_IF_TYPE_INVALID;
+       }
+--- everything.orig/net/mac80211/ieee80211_ioctl.c     2007-11-07 13:19:25.851524684 +0100
++++ everything/net/mac80211/ieee80211_ioctl.c  2007-11-07 13:19:27.981515569 +0100
+@@ -284,6 +284,9 @@ static int ieee80211_ioctl_siwmode(struc
+       case IW_MODE_MONITOR:
+               type = IEEE80211_IF_TYPE_MNTR;
+               break;
++      case IW_MODE_MASTER:
++              type = IEEE80211_IF_TYPE_AP;
++              break;
+       default:
+               return -EINVAL;
+       }
diff --git a/package/mac80211/patches/012-mac80211-allow-wds.patch b/package/mac80211/patches/012-mac80211-allow-wds.patch
new file mode 100644 (file)
index 0000000..d5c57cd
--- /dev/null
@@ -0,0 +1,22 @@
+Subject: mac80211: allow WDS mode
+
+This allows creating interfaces in WDS mode or switching
+existing ones into WDS mode (both via cfg80211.)
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ net/mac80211/cfg.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- everything.orig/net/mac80211/cfg.c 2007-11-07 13:19:27.981515569 +0100
++++ everything/net/mac80211/cfg.c      2007-11-07 13:19:29.441515732 +0100
+@@ -29,6 +29,8 @@ nl80211_type_to_mac80211_type(enum nl802
+               return IEEE80211_IF_TYPE_AP;
+       case NL80211_IFTYPE_AP_VLAN:
+               return IEEE80211_IF_TYPE_VLAN;
++      case NL80211_IFTYPE_WDS:
++              return IEEE80211_IF_TYPE_WDS;
+       default:
+               return IEEE80211_IF_TYPE_INVALID;
+       }
diff --git a/package/mac80211/patches/013-prism2-ioctl-bridge-packets.patch b/package/mac80211/patches/013-prism2-ioctl-bridge-packets.patch
new file mode 100644 (file)
index 0000000..d418ad3
--- /dev/null
@@ -0,0 +1,26 @@
+---
+ net/mac80211/ieee80211_ioctl.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- everything.orig/net/mac80211/ieee80211_ioctl.c     2007-11-07 13:19:27.981515569 +0100
++++ everything/net/mac80211/ieee80211_ioctl.c  2007-11-07 13:19:30.781513182 +0100
+@@ -882,6 +882,9 @@ static int ieee80211_ioctl_prism2_param(
+       local = sdata->local;
+       switch (param) {
++      case PRISM2_PARAM_AP_BRIDGE_PACKETS:
++              local->bridge_packets = value;
++              break;
+       case PRISM2_PARAM_MGMT_IF:
+               if (value == 1) {
+                       if (!local->apdev)
+@@ -914,6 +917,9 @@ static int ieee80211_ioctl_get_prism2_pa
+       local = sdata->local;
+       switch (*param) {
++      case PRISM2_PARAM_AP_BRIDGE_PACKETS:
++              *param = local->bridge_packets;
++              break;
+       case PRISM2_PARAM_MGMT_IF:
+               if (local->apdev)
+                       *param = local->apdev->ifindex;
diff --git a/package/mac80211/patches/014-prism2-ioctl-8021x.patch b/package/mac80211/patches/014-prism2-ioctl-8021x.patch
new file mode 100644 (file)
index 0000000..5feb01e
--- /dev/null
@@ -0,0 +1,26 @@
+---
+ net/mac80211/ieee80211_ioctl.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- everything.orig/net/mac80211/ieee80211_ioctl.c     2007-11-07 13:19:30.781513182 +0100
++++ everything/net/mac80211/ieee80211_ioctl.c  2007-11-07 13:19:32.281514919 +0100
+@@ -882,6 +882,9 @@ static int ieee80211_ioctl_prism2_param(
+       local = sdata->local;
+       switch (param) {
++      case PRISM2_PARAM_IEEE_802_1X:
++              sdata->ieee802_1x = value;
++              break;
+       case PRISM2_PARAM_AP_BRIDGE_PACKETS:
+               local->bridge_packets = value;
+               break;
+@@ -917,6 +920,9 @@ static int ieee80211_ioctl_get_prism2_pa
+       local = sdata->local;
+       switch (*param) {
++      case PRISM2_PARAM_IEEE_802_1X:
++              *param = sdata->ieee802_1x;
++              break;
+       case PRISM2_PARAM_AP_BRIDGE_PACKETS:
+               *param = local->bridge_packets;
+               break;
diff --git a/package/mac80211/patches/015-hostapd-ioctl-hw-features.patch b/package/mac80211/patches/015-hostapd-ioctl-hw-features.patch
new file mode 100644 (file)
index 0000000..d6e5dfd
--- /dev/null
@@ -0,0 +1,122 @@
+---
+ net/mac80211/ieee80211_ioctl.c |  102 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 102 insertions(+)
+
+--- everything.orig/net/mac80211/ieee80211_ioctl.c     2007-11-07 13:19:32.281514919 +0100
++++ everything/net/mac80211/ieee80211_ioctl.c  2007-11-07 13:19:33.681513453 +0100
+@@ -125,6 +125,105 @@ static int ieee80211_ioctl_siwgenie(stru
+       return -EOPNOTSUPP;
+ }
++/*
++ * Wow. This ioctl interface is such crap, it's tied
++ * to internal definitions. I hope it dies soon.
++ */
++static int mode_to_hostapd_mode(enum ieee80211_phymode mode)
++{
++      switch (mode) {
++      case MODE_IEEE80211A:
++              return 0;
++      case MODE_IEEE80211B:
++              return 1;
++      case MODE_IEEE80211G:
++              return 3;
++      case NUM_IEEE80211_MODES:
++              WARN_ON(1);
++              break;
++      }
++      WARN_ON(1);
++      return -1;
++}
++
++static int channel_flags_to_hostapd_flags(int flags)
++{
++      int res = 0;
++
++      if (flags & IEEE80211_CHAN_W_SCAN)
++              res |= 1;
++      if (flags & IEEE80211_CHAN_W_ACTIVE_SCAN)
++              res |= 2;
++      if (flags & IEEE80211_CHAN_W_IBSS)
++              res |= 4;
++
++      return res;
++}
++
++struct ieee80211_channel_data {
++      short chan; /* channel number (IEEE 802.11) */
++      short freq; /* frequency in MHz */
++      int flag; /* flag for hostapd use (IEEE80211_CHAN_*) */
++};
++
++struct ieee80211_rate_data {
++      int rate; /* rate in 100 kbps */
++      int flags; /* IEEE80211_RATE_ flags */
++};
++
++static int ieee80211_ioctl_get_hw_features(struct net_device *dev,
++                                         struct prism2_hostapd_param *param,
++                                         int param_len)
++{
++      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
++      u8 *pos = param->u.hw_features.data;
++      int left = param_len - (pos - (u8 *) param);
++      int i;
++      struct hostapd_ioctl_hw_modes_hdr *hdr;
++      struct ieee80211_rate_data *rate;
++      struct ieee80211_channel_data *chan;
++      struct ieee80211_hw_mode *mode;
++
++      param->u.hw_features.flags = 0;
++
++      param->u.hw_features.num_modes = 0;
++      list_for_each_entry(mode, &local->modes_list, list) {
++              int clen, rlen;
++
++              param->u.hw_features.num_modes++;
++              clen =
++                  mode->num_channels * sizeof(struct ieee80211_channel_data);
++              rlen = mode->num_rates * sizeof(struct ieee80211_rate_data);
++              if (left < sizeof(*hdr) + clen + rlen)
++                      return -E2BIG;
++              left -= sizeof(*hdr) + clen + rlen;
++
++              hdr = (struct hostapd_ioctl_hw_modes_hdr *)pos;
++              hdr->mode = mode_to_hostapd_mode(mode->mode);
++              hdr->num_channels = mode->num_channels;
++              hdr->num_rates = mode->num_rates;
++
++              pos = (u8 *) (hdr + 1);
++              chan = (struct ieee80211_channel_data *)pos;
++              for (i = 0; i < mode->num_channels; i++) {
++                      chan[i].chan = mode->channels[i].chan;
++                      chan[i].freq = mode->channels[i].freq;
++                      chan[i].flag = channel_flags_to_hostapd_flags(
++                                              mode->channels[i].flag);
++              }
++              pos += clen;
++
++              rate = (struct ieee80211_rate_data *)pos;
++              for (i = 0; i < mode->num_rates; i++) {
++                      rate[i].rate = mode->rates[i].rate;
++                      rate[i].flags = mode->rates[i].flags;
++              }
++              pos += rlen;
++      }
++
++      return 0;
++}
++
+ static int ieee80211_ioctl_priv_hostapd(struct net_device *dev,
+                                       struct iw_point *p)
+@@ -151,6 +250,9 @@ static int ieee80211_ioctl_priv_hostapd(
+       }
+       switch (param->cmd) {
++      case PRISM2_HOSTAPD_GET_HW_FEATURES:
++              ret = ieee80211_ioctl_get_hw_features(dev, param, p->length);
++              break;
+       default:
+               ret = -EOPNOTSUPP;
+               break;
diff --git a/package/mac80211/patches/016-prism2-ioctl-eapol.patch b/package/mac80211/patches/016-prism2-ioctl-eapol.patch
new file mode 100644 (file)
index 0000000..5ce5758
--- /dev/null
@@ -0,0 +1,26 @@
+---
+ net/mac80211/ieee80211_ioctl.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- everything.orig/net/mac80211/ieee80211_ioctl.c     2007-11-07 13:19:33.681513453 +0100
++++ everything/net/mac80211/ieee80211_ioctl.c  2007-11-07 13:19:35.171517576 +0100
+@@ -984,6 +984,9 @@ static int ieee80211_ioctl_prism2_param(
+       local = sdata->local;
+       switch (param) {
++      case PRISM2_PARAM_EAPOL:
++              sdata->eapol = value;
++              break;
+       case PRISM2_PARAM_IEEE_802_1X:
+               sdata->ieee802_1x = value;
+               break;
+@@ -1022,6 +1025,9 @@ static int ieee80211_ioctl_get_prism2_pa
+       local = sdata->local;
+       switch (*param) {
++      case PRISM2_PARAM_EAPOL:
++              *param = sdata->eapol;
++              break;
+       case PRISM2_PARAM_IEEE_802_1X:
+               *param = sdata->ieee802_1x;
+               break;
diff --git a/package/mac80211/patches/017-nl80211-add-key-mgmt.patch b/package/mac80211/patches/017-nl80211-add-key-mgmt.patch
new file mode 100644 (file)
index 0000000..f5b1d45
--- /dev/null
@@ -0,0 +1,470 @@
+Subject: cfg80211/nl80211: introduce key handling
+
+This introduces key handling to cfg80211/nl80211. Default
+and group keys can be added, changed and removed; sequence
+counters for each key can be retrieved.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ include/linux/nl80211.h |   34 +++++
+ include/net/cfg80211.h  |   44 +++++++
+ net/wireless/core.c     |    3 
+ net/wireless/nl80211.c  |  289 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 370 insertions(+)
+
+--- everything.orig/include/linux/nl80211.h    2007-10-30 15:33:43.587381346 +0100
++++ everything/include/linux/nl80211.h 2007-11-07 13:19:37.861516599 +0100
+@@ -37,6 +37,16 @@
+  *    userspace to request deletion of a virtual interface, then requires
+  *    attribute %NL80211_ATTR_IFINDEX.
+  *
++ * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
++ *    by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
++ * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT or
++ *    %NL80211_ATTR_KEY_THRESHOLD.
++ * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
++ *    %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER
++ *    attributes.
++ * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
++ *    or %NL80211_ATTR_MAC.
++ *
+  * @NL80211_CMD_MAX: highest used command number
+  * @__NL80211_CMD_AFTER_LAST: internal use
+  */
+@@ -54,6 +64,11 @@ enum nl80211_commands {
+       NL80211_CMD_NEW_INTERFACE,
+       NL80211_CMD_DEL_INTERFACE,
++      NL80211_CMD_GET_KEY,
++      NL80211_CMD_SET_KEY,
++      NL80211_CMD_NEW_KEY,
++      NL80211_CMD_DEL_KEY,
++
+       /* add commands here */
+       /* used to define NL80211_CMD_MAX below */
+@@ -75,6 +90,17 @@ enum nl80211_commands {
+  * @NL80211_ATTR_IFNAME: network interface name
+  * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype
+  *
++ * @NL80211_ATTR_MAC: MAC address (various uses)
++ *
++ * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of
++ *    16 bytes encryption key followed by 8 bytes each for TX and RX MIC
++ *    keys
++ * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3)
++ * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
++ *    section 7.3.2.25.1, e.g. 0x000FAC04)
++ * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
++ *    CCMP keys, each six bytes in little endian
++ *
+  * @NL80211_ATTR_MAX: highest attribute number currently defined
+  * @__NL80211_ATTR_AFTER_LAST: internal use
+  */
+@@ -89,6 +115,14 @@ enum nl80211_attrs {
+       NL80211_ATTR_IFNAME,
+       NL80211_ATTR_IFTYPE,
++      NL80211_ATTR_MAC,
++
++      NL80211_ATTR_KEY_DATA,
++      NL80211_ATTR_KEY_IDX,
++      NL80211_ATTR_KEY_CIPHER,
++      NL80211_ATTR_KEY_SEQ,
++      NL80211_ATTR_KEY_DEFAULT,
++
+       /* add attributes here, update the policy in nl80211.c */
+       __NL80211_ATTR_AFTER_LAST,
+--- everything.orig/net/wireless/nl80211.c     2007-10-30 15:33:43.637380153 +0100
++++ everything/net/wireless/nl80211.c  2007-11-07 13:19:38.201511066 +0100
+@@ -61,6 +61,14 @@ static struct nla_policy nl80211_policy[
+       [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
+       [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
+       [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
++
++      [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
++
++      [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
++                                  .len = WLAN_MAX_KEY_LEN },
++      [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
++      [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
++      [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
+ };
+ /* message building helper */
+@@ -335,6 +343,263 @@ static int nl80211_del_interface(struct 
+       return err;
+ }
++struct get_key_cookie {
++      struct sk_buff *msg;
++      int error;
++};
++
++static void get_key_callback(void *c, struct key_params *params)
++{
++      struct get_key_cookie *cookie = c;
++
++      if (params->key)
++              NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
++                      params->key_len, params->key);
++
++      if (params->seq)
++              NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
++                      params->seq_len, params->seq);
++
++      if (params->cipher)
++              NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
++                          params->cipher);
++
++      return;
++ nla_put_failure:
++      cookie->error = 1;
++}
++
++static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
++{
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      u8 key_idx = 0;
++      u8 *mac_addr = NULL;
++      struct get_key_cookie cookie = {
++              .error = 0,
++      };
++      void *hdr;
++      struct sk_buff *msg;
++
++      if (info->attrs[NL80211_ATTR_KEY_IDX])
++              key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
++
++      if (key_idx > 3)
++              return -EINVAL;
++
++      if (info->attrs[NL80211_ATTR_MAC])
++              mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      if (!drv->ops->get_key) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
++      if (!msg) {
++              err = -ENOMEM;
++              goto out;
++      }
++
++      hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
++                           NL80211_CMD_NEW_KEY);
++
++      if (IS_ERR(hdr)) {
++              err = PTR_ERR(hdr);
++              goto out;
++      }
++
++      cookie.msg = msg;
++
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
++      NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
++      if (mac_addr)
++              NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
++
++      rtnl_lock();
++      err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
++                              &cookie, get_key_callback);
++      rtnl_unlock();
++
++      if (err)
++              goto out;
++
++      if (cookie.error)
++              goto nla_put_failure;
++
++      genlmsg_end(msg, hdr);
++      err = genlmsg_unicast(msg, info->snd_pid);
++      goto out;
++
++ nla_put_failure:
++      err = -ENOBUFS;
++      nlmsg_free(msg);
++ out:
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
++static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
++{
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      u8 key_idx;
++
++      if (!info->attrs[NL80211_ATTR_KEY_IDX])
++              return -EINVAL;
++
++      key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
++
++      if (key_idx > 3)
++              return -EINVAL;
++
++      /* currently only support setting default key */
++      if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
++              return -EINVAL;
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      if (!drv->ops->set_default_key) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
++      rtnl_unlock();
++
++ out:
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
++static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
++{
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      struct key_params params;
++      u8 key_idx = 0;
++      u8 *mac_addr = NULL;
++
++      memset(&params, 0, sizeof(params));
++
++      if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
++              return -EINVAL;
++
++      if (info->attrs[NL80211_ATTR_KEY_DATA]) {
++              params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
++              params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
++      }
++
++      if (info->attrs[NL80211_ATTR_KEY_IDX])
++              key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
++
++      params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
++
++      if (info->attrs[NL80211_ATTR_MAC])
++              mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
++
++      if (key_idx > 3)
++              return -EINVAL;
++
++      /*
++       * Disallow pairwise keys with non-zero index unless it's WEP
++       * (because current deployments use pairwise WEP keys with
++       * non-zero indizes but 802.11i clearly specifies to use zero)
++       */
++      if (mac_addr && key_idx &&
++          params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
++          params.cipher != WLAN_CIPHER_SUITE_WEP104)
++              return -EINVAL;
++
++      /* TODO: add definitions for the lengths to linux/ieee80211.h */
++      switch (params.cipher) {
++      case WLAN_CIPHER_SUITE_WEP40:
++              if (params.key_len != 5)
++                      return -EINVAL;
++              break;
++      case WLAN_CIPHER_SUITE_TKIP:
++              if (params.key_len != 32)
++                      return -EINVAL;
++              break;
++      case WLAN_CIPHER_SUITE_CCMP:
++              if (params.key_len != 16)
++                      return -EINVAL;
++              break;
++      case WLAN_CIPHER_SUITE_WEP104:
++              if (params.key_len != 13)
++                      return -EINVAL;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      if (!drv->ops->add_key) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
++      rtnl_unlock();
++
++ out:
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
++static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
++{
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      u8 key_idx = 0;
++      u8 *mac_addr = NULL;
++
++      if (info->attrs[NL80211_ATTR_KEY_IDX])
++              key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
++
++      if (key_idx > 3)
++              return -EINVAL;
++
++      if (info->attrs[NL80211_ATTR_MAC])
++              mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      if (!drv->ops->del_key) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
++      rtnl_unlock();
++
++ out:
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
+ static struct genl_ops nl80211_ops[] = {
+       {
+               .cmd = NL80211_CMD_GET_WIPHY,
+@@ -374,6 +639,30 @@ static struct genl_ops nl80211_ops[] = {
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
++      {
++              .cmd = NL80211_CMD_GET_KEY,
++              .doit = nl80211_get_key,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++      },
++      {
++              .cmd = NL80211_CMD_SET_KEY,
++              .doit = nl80211_set_key,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++      },
++      {
++              .cmd = NL80211_CMD_NEW_KEY,
++              .doit = nl80211_new_key,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++      },
++      {
++              .cmd = NL80211_CMD_DEL_KEY,
++              .doit = nl80211_del_key,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++      },
+ };
+ /* multicast groups */
+--- everything.orig/net/wireless/core.c        2007-10-30 15:33:43.677380478 +0100
++++ everything/net/wireless/core.c     2007-11-07 13:19:38.221513833 +0100
+@@ -184,6 +184,9 @@ struct wiphy *wiphy_new(struct cfg80211_
+       struct cfg80211_registered_device *drv;
+       int alloc_size;
++      WARN_ON(!ops->add_key && ops->del_key);
++      WARN_ON(ops->add_key && !ops->del_key);
++
+       alloc_size = sizeof(*drv) + sizeof_priv;
+       drv = kzalloc(alloc_size, GFP_KERNEL);
+--- everything.orig/include/net/cfg80211.h     2007-10-30 15:33:43.617381780 +0100
++++ everything/include/net/cfg80211.h  2007-11-07 13:19:38.231512748 +0100
+@@ -49,6 +49,26 @@ extern int ieee80211_radiotap_iterator_n
+    struct ieee80211_radiotap_iterator *iterator);
++ /**
++ * struct key_params - key information
++ *
++ * Information about a key
++ *
++ * @key: key material
++ * @key_len: length of key material
++ * @cipher: cipher suite selector
++ * @seq: sequence counter (IV/PN) for TKIP and CCMP keys, only used
++ *    with the get_key() callback, must be in little endian,
++ *    length given by @seq_len.
++ */
++struct key_params {
++      u8 *key;
++      u8 *seq;
++      int key_len;
++      int seq_len;
++      u32 cipher;
++};
++
+ /* from net/wireless.h */
+ struct wiphy;
+@@ -71,6 +91,18 @@ struct wiphy;
+  *
+  * @change_virtual_intf: change type of virtual interface
+  *
++ * @add_key: add a key with the given parameters. @mac_addr will be %NULL
++ *    when adding a group key.
++ *
++ * @get_key: get information about the key with the given parameters.
++ *    @mac_addr will be %NULL when requesting information for a group
++ *    key. All pointers given to the @callback function need not be valid
++ *    after it returns.
++ *
++ * @del_key: remove a key given the @mac_addr (%NULL for a group key)
++ *    and @key_index
++ *
++ * @set_default_key: set the default key on an interface
+  */
+ struct cfg80211_ops {
+       int     (*add_virtual_intf)(struct wiphy *wiphy, char *name,
+@@ -78,6 +110,18 @@ struct cfg80211_ops {
+       int     (*del_virtual_intf)(struct wiphy *wiphy, int ifindex);
+       int     (*change_virtual_intf)(struct wiphy *wiphy, int ifindex,
+                                      enum nl80211_iftype type);
++
++      int     (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
++                         u8 key_index, u8 *mac_addr,
++                         struct key_params *params);
++      int     (*get_key)(struct wiphy *wiphy, struct net_device *netdev,
++                         u8 key_index, u8 *mac_addr, void *cookie,
++                         void (*callback)(void *cookie, struct key_params*));
++      int     (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
++                         u8 key_index, u8 *mac_addr);
++      int     (*set_default_key)(struct wiphy *wiphy,
++                                 struct net_device *netdev,
++                                 u8 key_index);
+ };
+ #endif /* __NET_CFG80211_H */
diff --git a/package/mac80211/patches/018-mac80211-cfg80211-keys.patch b/package/mac80211/patches/018-mac80211-cfg80211-keys.patch
new file mode 100644 (file)
index 0000000..0c98623
--- /dev/null
@@ -0,0 +1,120 @@
+Subject: mac80211: support adding/removing keys via cfg80211
+
+This adds the necessary hooks to mac80211 to allow userspace
+to edit keys with cfg80211 (through nl80211.)
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ net/mac80211/cfg.c |   91 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 91 insertions(+)
+
+--- everything.orig/net/mac80211/cfg.c 2007-11-07 13:19:29.441515732 +0100
++++ everything/net/mac80211/cfg.c      2007-11-07 13:19:39.531517685 +0100
+@@ -6,6 +6,7 @@
+  * This file is GPLv2 as found in COPYING.
+  */
++#include <linux/ieee80211.h>
+ #include <linux/nl80211.h>
+ #include <linux/rtnetlink.h>
+ #include <net/net_namespace.h>
+@@ -105,8 +106,98 @@ static int ieee80211_change_iface(struct
+       return 0;
+ }
++static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
++                           u8 key_idx, u8 *mac_addr,
++                           struct key_params *params)
++{
++      struct ieee80211_sub_if_data *sdata;
++      struct sta_info *sta = NULL;
++      enum ieee80211_key_alg alg;
++      int ret;
++
++      sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++
++      switch (params->cipher) {
++      case WLAN_CIPHER_SUITE_WEP40:
++      case WLAN_CIPHER_SUITE_WEP104:
++              alg = ALG_WEP;
++              break;
++      case WLAN_CIPHER_SUITE_TKIP:
++              alg = ALG_TKIP;
++              break;
++      case WLAN_CIPHER_SUITE_CCMP:
++              alg = ALG_CCMP;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      if (mac_addr) {
++              sta = sta_info_get(sdata->local, mac_addr);
++              if (!sta)
++                      return -ENOENT;
++      }
++
++      ret = 0;
++      if (!ieee80211_key_alloc(sdata, sta, alg, key_idx,
++                               params->key_len, params->key))
++              ret = -ENOMEM;
++
++      if (sta)
++              sta_info_put(sta);
++
++      return ret;
++}
++
++static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
++                           u8 key_idx, u8 *mac_addr)
++{
++      struct ieee80211_sub_if_data *sdata;
++      struct sta_info *sta;
++      int ret;
++
++      sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++
++      if (mac_addr) {
++              sta = sta_info_get(sdata->local, mac_addr);
++              if (!sta)
++                      return -ENOENT;
++
++              ret = 0;
++              if (sta->key)
++                      ieee80211_key_free(sta->key);
++              else
++                      ret = -ENOENT;
++
++              sta_info_put(sta);
++              return ret;
++      }
++
++      if (!sdata->keys[key_idx])
++              return -ENOENT;
++
++      ieee80211_key_free(sdata->keys[key_idx]);
++
++      return 0;
++}
++
++static int ieee80211_config_default_key(struct wiphy *wiphy,
++                                      struct net_device *dev,
++                                      u8 key_idx)
++{
++      struct ieee80211_sub_if_data *sdata;
++
++      sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      ieee80211_set_default_key(sdata, key_idx);
++
++      return 0;
++}
++
+ struct cfg80211_ops mac80211_config_ops = {
+       .add_virtual_intf = ieee80211_add_iface,
+       .del_virtual_intf = ieee80211_del_iface,
+       .change_virtual_intf = ieee80211_change_iface,
++      .add_key = ieee80211_add_key,
++      .del_key = ieee80211_del_key,
++      .set_default_key = ieee80211_config_default_key,
+ };
diff --git a/package/mac80211/patches/019-mac80211-key-seq-nl80211.patch b/package/mac80211/patches/019-mac80211-key-seq-nl80211.patch
new file mode 100644 (file)
index 0000000..5d0020b
--- /dev/null
@@ -0,0 +1,161 @@
+Subject: mac80211: support getting key sequence counters via cfg80211
+
+This implements cfg80211's get_key() to allow retrieving the sequence
+counter for a TKIP or CCMP key from userspace. It also cleans up and
+documents the associated low-level driver interface.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ include/net/mac80211.h |   14 ++------
+ net/mac80211/cfg.c     |   85 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 89 insertions(+), 10 deletions(-)
+
+Index: mac80211/net/mac80211/cfg.c
+===================================================================
+--- mac80211.orig/net/mac80211/cfg.c   2007-11-11 15:46:41.497954646 +0100
++++ mac80211/net/mac80211/cfg.c        2007-11-11 15:46:51.346515884 +0100
+@@ -1,7 +1,7 @@
+ /*
+  * mac80211 configuration hooks for cfg80211
+  *
+- * Copyright 2006     Johannes Berg <johannes@sipsolutions.net>
++ * Copyright 2006, 2007       Johannes Berg <johannes@sipsolutions.net>
+  *
+  * This file is GPLv2 as found in COPYING.
+  */
+@@ -180,6 +180,88 @@
+       return 0;
+ }
++static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
++                           u8 key_idx, u8 *mac_addr, void *cookie,
++                           void (*callback)(void *cookie,
++                                            struct key_params *params))
++{
++      struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      struct sta_info *sta = NULL;
++      u8 seq[6] = {0};
++      struct key_params params;
++      struct ieee80211_key *key;
++      u32 iv32;
++      u16 iv16;
++      int err = -ENOENT;
++
++      if (mac_addr) {
++              sta = sta_info_get(sdata->local, mac_addr);
++              if (!sta)
++                      goto out;
++
++              key = sta->key;
++      } else
++              key = sdata->keys[key_idx];
++
++      if (!key)
++              goto out;
++
++      memset(&params, 0, sizeof(params));
++
++      switch (key->conf.alg) {
++      case ALG_TKIP:
++              params.cipher = WLAN_CIPHER_SUITE_TKIP;
++
++              iv32 = key->u.tkip.iv32;
++              iv16 = key->u.tkip.iv16;
++
++              if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
++                  sdata->local->ops->get_tkip_seq)
++                      sdata->local->ops->get_tkip_seq(
++                              local_to_hw(sdata->local),
++                              key->conf.hw_key_idx,
++                              &iv32, &iv16);
++
++              seq[0] = iv16 & 0xff;
++              seq[1] = (iv16 >> 8) & 0xff;
++              seq[2] = iv32 & 0xff;
++              seq[3] = (iv32 >> 8) & 0xff;
++              seq[4] = (iv32 >> 16) & 0xff;
++              seq[5] = (iv32 >> 24) & 0xff;
++              params.seq = seq;
++              params.seq_len = 6;
++              break;
++      case ALG_CCMP:
++              params.cipher = WLAN_CIPHER_SUITE_CCMP;
++              seq[0] = key->u.ccmp.tx_pn[5];
++              seq[1] = key->u.ccmp.tx_pn[4];
++              seq[2] = key->u.ccmp.tx_pn[3];
++              seq[3] = key->u.ccmp.tx_pn[2];
++              seq[4] = key->u.ccmp.tx_pn[1];
++              seq[5] = key->u.ccmp.tx_pn[0];
++              params.seq = seq;
++              params.seq_len = 6;
++              break;
++      case ALG_WEP:
++              if (key->conf.keylen == 5)
++                      params.cipher = WLAN_CIPHER_SUITE_WEP40;
++              else
++                      params.cipher = WLAN_CIPHER_SUITE_WEP104;
++              break;
++      }
++
++      params.key = key->conf.key;
++      params.key_len = key->conf.keylen;
++
++      callback(cookie, &params);
++      err = 0;
++
++ out:
++      if (sta)
++              sta_info_put(sta);
++      return err;
++}
++
+ static int ieee80211_config_default_key(struct wiphy *wiphy,
+                                       struct net_device *dev,
+                                       u8 key_idx)
+@@ -198,5 +280,6 @@
+       .change_virtual_intf = ieee80211_change_iface,
+       .add_key = ieee80211_add_key,
+       .del_key = ieee80211_del_key,
++      .get_key = ieee80211_get_key,
+       .set_default_key = ieee80211_config_default_key,
+ };
+Index: mac80211/include/net/mac80211.h
+===================================================================
+--- mac80211.orig/include/net/mac80211.h       2007-11-11 15:46:41.377947807 +0100
++++ mac80211/include/net/mac80211.h    2007-11-11 15:47:08.183475366 +0100
+@@ -598,9 +598,6 @@
+       u8 key[0];
+ };
+-#define IEEE80211_SEQ_COUNTER_RX      0
+-#define IEEE80211_SEQ_COUNTER_TX      1
+-
+ /**
+  * enum set_key_cmd - key command
+  *
+@@ -947,9 +944,9 @@
+  *
+  * @get_stats: return low-level statistics
+  *
+- * @get_sequence_counter: For devices that have internal sequence counters this
+- *    callback allows mac80211 to access the current value of a counter.
+- *    This callback seems not well-defined, tell us if you need it.
++ * @get_tkip_seq: If your device implements TKIP encryption in hardware this
++ *    callback should be provided to read the TKIP transmit IVs (both IV32
++ *    and IV16) for the given key from hardware.
+  *
+  * @set_rts_threshold: Configuration of RTS threshold (if device needs it)
+  *
+@@ -1022,9 +1019,8 @@
+       int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
+       int (*get_stats)(struct ieee80211_hw *hw,
+                        struct ieee80211_low_level_stats *stats);
+-      int (*get_sequence_counter)(struct ieee80211_hw *hw,
+-                                  u8* addr, u8 keyidx, u8 txrx,
+-                                  u32* iv32, u16* iv16);
++      void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
++                           u32 *iv32, u16 *iv16);
+       int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
+       int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
+       int (*set_retry_limit)(struct ieee80211_hw *hw,
diff --git a/package/mac80211/patches/020-nl80211-beacon-parameters.patch b/package/mac80211/patches/020-nl80211-beacon-parameters.patch
new file mode 100644 (file)
index 0000000..51836f3
--- /dev/null
@@ -0,0 +1,279 @@
+Subject: cfg80211/nl80211: add beacon settings
+
+This adds the necessary API to cfg80211/nl80211 to allow
+changing beaconing settings.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ include/linux/nl80211.h |   24 ++++++++
+ include/net/cfg80211.h  |   33 +++++++++++
+ net/wireless/nl80211.c  |  133 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 190 insertions(+)
+
+--- everything.orig/include/net/cfg80211.h     2007-11-08 11:50:57.412840007 +0100
++++ everything/include/net/cfg80211.h  2007-11-08 16:50:38.421522842 +0100
+@@ -69,6 +69,26 @@ struct key_params {
+       u32 cipher;
+ };
++/**
++ * struct beacon_parameters - beacon parameters
++ *
++ * Used to configure the beacon for an interface.
++ *
++ * @head: head portion of beacon (before TIM IE)
++ *     or %NULL if not changed
++ * @tail: tail portion of beacon (after TIM IE)
++ *     or %NULL if not changed
++ * @interval: beacon interval or zero if not changed
++ * @dtim_period: DTIM period or zero if not changed
++ * @head_len: length of @head
++ * @tail_len: length of @tail
++ */
++struct beacon_parameters {
++      u8 *head, *tail;
++      int interval, dtim_period;
++      int head_len, tail_len;
++};
++
+ /* from net/wireless.h */
+ struct wiphy;
+@@ -103,6 +123,13 @@ struct wiphy;
+  *    and @key_index
+  *
+  * @set_default_key: set the default key on an interface
++ *
++ * @add_beacon: Add a beacon with given parameters, @head, @interval
++ *    and @dtim_period will be valid, @tail is optional.
++ * @set_beacon: Change the beacon parameters for an access point mode
++ *    interface. This should reject the call when no beacon has been
++ *    configured.
++ * @del_beacon: Remove beacon configuration and stop sending the beacon.
+  */
+ struct cfg80211_ops {
+       int     (*add_virtual_intf)(struct wiphy *wiphy, char *name,
+@@ -122,6 +149,12 @@ struct cfg80211_ops {
+       int     (*set_default_key)(struct wiphy *wiphy,
+                                  struct net_device *netdev,
+                                  u8 key_index);
++
++      int     (*add_beacon)(struct wiphy *wiphy, struct net_device *dev,
++                            struct beacon_parameters *info);
++      int     (*set_beacon)(struct wiphy *wiphy, struct net_device *dev,
++                            struct beacon_parameters *info);
++      int     (*del_beacon)(struct wiphy *wiphy, struct net_device *dev);
+ };
+ #endif /* __NET_CFG80211_H */
+--- everything.orig/include/linux/nl80211.h    2007-11-08 11:50:57.362839952 +0100
++++ everything/include/linux/nl80211.h 2007-11-08 16:56:32.431522732 +0100
+@@ -47,6 +47,15 @@
+  * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
+  *    or %NL80211_ATTR_MAC.
+  *
++ * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a
++ *    %NL80222_CMD_NEW_BEACON message)
++ * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface
++ *    using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD,
++ *    %NL80211_BEACON_HEAD and %NL80211_BEACON_TAIL attributes.
++ * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface,
++ *    parameters are like for %NL80211_CMD_SET_BEACON.
++ * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
++ *
+  * @NL80211_CMD_MAX: highest used command number
+  * @__NL80211_CMD_AFTER_LAST: internal use
+  */
+@@ -69,6 +78,11 @@ enum nl80211_commands {
+       NL80211_CMD_NEW_KEY,
+       NL80211_CMD_DEL_KEY,
++      NL80211_CMD_GET_BEACON,
++      NL80211_CMD_SET_BEACON,
++      NL80211_CMD_NEW_BEACON,
++      NL80211_CMD_DEL_BEACON,
++
+       /* add commands here */
+       /* used to define NL80211_CMD_MAX below */
+@@ -101,6 +115,11 @@ enum nl80211_commands {
+  * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+  *    CCMP keys, each six bytes in little endian
+  *
++ * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU
++ * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing
++ * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE
++ * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE
++ *
+  * @NL80211_ATTR_MAX: highest attribute number currently defined
+  * @__NL80211_ATTR_AFTER_LAST: internal use
+  */
+@@ -123,6 +142,11 @@ enum nl80211_attrs {
+       NL80211_ATTR_KEY_SEQ,
+       NL80211_ATTR_KEY_DEFAULT,
++      NL80211_ATTR_BEACON_INTERVAL,
++      NL80211_ATTR_DTIM_PERIOD,
++      NL80211_ATTR_BEACON_HEAD,
++      NL80211_ATTR_BEACON_TAIL,
++
+       /* add attributes here, update the policy in nl80211.c */
+       __NL80211_ATTR_AFTER_LAST,
+--- everything.orig/net/wireless/nl80211.c     2007-11-08 11:50:57.382836589 +0100
++++ everything/net/wireless/nl80211.c  2007-11-08 16:58:36.711524524 +0100
+@@ -69,6 +69,13 @@ static struct nla_policy nl80211_policy[
+       [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
+       [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
+       [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
++
++      [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
++      [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
++      [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
++                                     .len = IEEE80211_MAX_DATA_LEN },
++      [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
++                                     .len = IEEE80211_MAX_DATA_LEN },
+ };
+ /* message building helper */
+@@ -600,6 +607,114 @@ static int nl80211_del_key(struct sk_buf
+       return err;
+ }
++static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
++{
++        int (*call)(struct wiphy *wiphy, struct net_device *dev,
++                  struct beacon_parameters *info);
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      struct beacon_parameters params;
++      int haveinfo = 0;
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      switch (info->genlhdr->cmd) {
++      case NL80211_CMD_NEW_BEACON:
++              /* these are required for NEW_BEACON */
++              if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
++                  !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
++                  !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
++                      err = -EINVAL;
++                      goto out;
++              }
++
++              call = drv->ops->add_beacon;
++              break;
++      case NL80211_CMD_SET_BEACON:
++              call = drv->ops->set_beacon;
++              break;
++      default:
++              WARN_ON(1);
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      if (!call) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      memset(&params, 0, sizeof(params));
++
++      if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
++              params.interval =
++                  nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
++              haveinfo = 1;
++      }
++
++      if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
++              params.dtim_period =
++                  nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
++              haveinfo = 1;
++      }
++
++      if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
++              params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
++              params.head_len =
++                  nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
++              haveinfo = 1;
++      }
++
++      if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
++              params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
++              params.tail_len =
++                  nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
++              haveinfo = 1;
++      }
++
++      if (!haveinfo) {
++              err = -EINVAL;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = call(&drv->wiphy, dev, &params);
++      rtnl_unlock();
++
++ out:
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
++static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
++{
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      if (!drv->ops->del_beacon) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = drv->ops->del_beacon(&drv->wiphy, dev);
++      rtnl_unlock();
++
++ out:
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
+ static struct genl_ops nl80211_ops[] = {
+       {
+               .cmd = NL80211_CMD_GET_WIPHY,
+@@ -663,6 +778,24 @@ static struct genl_ops nl80211_ops[] = {
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
++      {
++              .cmd = NL80211_CMD_SET_BEACON,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++              .doit = nl80211_addset_beacon,
++      },
++      {
++              .cmd = NL80211_CMD_NEW_BEACON,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++              .doit = nl80211_addset_beacon,
++      },
++      {
++              .cmd = NL80211_CMD_DEL_BEACON,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++              .doit = nl80211_del_beacon,
++      },
+ };
+ /* multicast groups */
diff --git a/package/mac80211/patches/021-mac80211-beacon-via-nl80211.patch b/package/mac80211/patches/021-mac80211-beacon-via-nl80211.patch
new file mode 100644 (file)
index 0000000..702c68f
--- /dev/null
@@ -0,0 +1,484 @@
+Subject: mac80211: add beacon configuration via cfg80211
+
+This patch implements the cfg80211 hooks for configuring beaconing
+on an access point interface in mac80211. While doing so, it fixes
+a number of races that could badly crash the machine when the
+beacon is changed while being requested by the driver.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+The dtim_count field should possibly also be part of the beacon
+structure, but the possible race there doesn't really matter,
+worst thing is that one beacon will be sent with a wrong dtim
+count if (and only if) userspace changes the dtim period during
+operation.
+
+ net/mac80211/cfg.c             |  156 +++++++++++++++++++++++++++++++++++++++++
+ net/mac80211/debugfs_netdev.c  |   27 -------
+ net/mac80211/ieee80211_i.h     |   14 ++-
+ net/mac80211/ieee80211_iface.c |    4 -
+ net/mac80211/tx.c              |   63 ++++++++++------
+ 5 files changed, 204 insertions(+), 60 deletions(-)
+
+Index: mac80211/net/mac80211/cfg.c
+===================================================================
+--- mac80211.orig/net/mac80211/cfg.c   2007-11-11 15:17:12.837164411 +0100
++++ mac80211/net/mac80211/cfg.c        2007-11-11 15:18:36.853952256 +0100
+@@ -9,6 +9,7 @@
+ #include <linux/ieee80211.h>
+ #include <linux/nl80211.h>
+ #include <linux/rtnetlink.h>
++#include <linux/rcupdate.h>
+ #include <net/cfg80211.h>
+ #include "ieee80211_i.h"
+ #include "cfg.h"
+@@ -274,6 +275,158 @@
+       return 0;
+ }
++/*
++ * This handles both adding a beacon and setting new beacon info
++ */
++static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
++                                 struct beacon_parameters *params)
++{
++      struct beacon_data *new, *old;
++      int new_head_len, new_tail_len;
++      int size;
++      int err = -EINVAL;
++
++      old = sdata->u.ap.beacon;
++
++      /* head must not be zero-length */
++      if (params->head && !params->head_len)
++              return -EINVAL;
++
++      /*
++       * This is a kludge. beacon interval should really be part
++       * of the beacon information.
++       */
++      if (params->interval) {
++              sdata->local->hw.conf.beacon_int = params->interval;
++              if (ieee80211_hw_config(sdata->local))
++                      return -EINVAL;
++              /*
++               * We updated some parameter so if below bails out
++               * it's not an error.
++               */
++              err = 0;
++      }
++
++      /* Need to have a beacon head if we don't have one yet */
++      if (!params->head && !old)
++              return err;
++
++      /* sorry, no way to start beaconing without dtim period */
++      if (!params->dtim_period && !old)
++              return err;
++
++      /* new or old head? */
++      if (params->head)
++              new_head_len = params->head_len;
++      else
++              new_head_len = old->head_len;
++
++      /* new or old tail? */
++      if (params->tail || !old)
++              /* params->tail_len will be zero for !params->tail */
++              new_tail_len = params->tail_len;
++      else
++              new_tail_len = old->tail_len;
++
++      size = sizeof(*new) + new_head_len + new_tail_len;
++
++      new = kzalloc(size, GFP_KERNEL);
++      if (!new)
++              return -ENOMEM;
++
++      /* start filling the new info now */
++
++      /* new or old dtim period? */
++      if (params->dtim_period)
++              new->dtim_period = params->dtim_period;
++      else
++              new->dtim_period = old->dtim_period;
++
++      /*
++       * pointers go into the block we allocated,
++       * memory is | beacon_data | head | tail |
++       */
++      new->head = ((u8 *) new) + sizeof(*new);
++      new->tail = new->head + new_head_len;
++      new->head_len = new_head_len;
++      new->tail_len = new_tail_len;
++
++      /* copy in head */
++      if (params->head)
++              memcpy(new->head, params->head, new_head_len);
++      else
++              memcpy(new->head, old->head, new_head_len);
++
++      /* copy in optional tail */
++      if (params->tail)
++              memcpy(new->tail, params->tail, new_tail_len);
++      else
++              if (old)
++                      memcpy(new->tail, old->tail, new_tail_len);
++
++      rcu_assign_pointer(sdata->u.ap.beacon, new);
++
++      synchronize_rcu();
++
++      kfree(old);
++
++      return ieee80211_if_config_beacon(sdata->dev);
++}
++
++static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
++                              struct beacon_parameters *params)
++{
++      struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      struct beacon_data *old;
++
++      if (sdata->type != IEEE80211_IF_TYPE_AP)
++              return -EINVAL;
++
++      old = sdata->u.ap.beacon;
++
++      if (old)
++              return -EALREADY;
++
++      return ieee80211_config_beacon(sdata, params);
++}
++
++static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
++                              struct beacon_parameters *params)
++{
++      struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      struct beacon_data *old;
++
++      if (sdata->type != IEEE80211_IF_TYPE_AP)
++              return -EINVAL;
++
++      old = sdata->u.ap.beacon;
++
++      if (!old)
++              return -ENOENT;
++
++      return ieee80211_config_beacon(sdata, params);
++}
++
++static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
++{
++      struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++      struct beacon_data *old;
++
++      if (sdata->type != IEEE80211_IF_TYPE_AP)
++              return -EINVAL;
++
++      old = sdata->u.ap.beacon;
++
++      if (!old)
++              return -ENOENT;
++
++      rcu_assign_pointer(sdata->u.ap.beacon, NULL);
++      synchronize_rcu();
++      kfree(old);
++
++      return ieee80211_if_config_beacon(dev);
++}
++
+ struct cfg80211_ops mac80211_config_ops = {
+       .add_virtual_intf = ieee80211_add_iface,
+       .del_virtual_intf = ieee80211_del_iface,
+@@ -282,4 +435,7 @@
+       .del_key = ieee80211_del_key,
+       .get_key = ieee80211_get_key,
+       .set_default_key = ieee80211_config_default_key,
++      .add_beacon = ieee80211_add_beacon,
++      .set_beacon = ieee80211_set_beacon,
++      .del_beacon = ieee80211_del_beacon,
+ };
+Index: mac80211/net/mac80211/debugfs_netdev.c
+===================================================================
+--- mac80211.orig/net/mac80211/debugfs_netdev.c        2007-10-14 00:42:30.054156000 +0200
++++ mac80211/net/mac80211/debugfs_netdev.c     2007-11-11 15:18:11.852527505 +0100
+@@ -124,7 +124,6 @@
+ /* AP attributes */
+ IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
+-IEEE80211_IF_FILE(dtim_period, u.ap.dtim_period, DEC);
+ IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
+ IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC);
+ IEEE80211_IF_FILE(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC);
+@@ -138,26 +137,6 @@
+ }
+ __IEEE80211_IF_FILE(num_buffered_multicast);
+-static ssize_t ieee80211_if_fmt_beacon_head_len(
+-      const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
+-{
+-      if (sdata->u.ap.beacon_head)
+-              return scnprintf(buf, buflen, "%d\n",
+-                               sdata->u.ap.beacon_head_len);
+-      return scnprintf(buf, buflen, "\n");
+-}
+-__IEEE80211_IF_FILE(beacon_head_len);
+-
+-static ssize_t ieee80211_if_fmt_beacon_tail_len(
+-      const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
+-{
+-      if (sdata->u.ap.beacon_tail)
+-              return scnprintf(buf, buflen, "%d\n",
+-                               sdata->u.ap.beacon_tail_len);
+-      return scnprintf(buf, buflen, "\n");
+-}
+-__IEEE80211_IF_FILE(beacon_tail_len);
+-
+ /* WDS attributes */
+ IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
+@@ -194,14 +173,11 @@
+       DEBUGFS_ADD(eapol, ap);
+       DEBUGFS_ADD(ieee8021_x, ap);
+       DEBUGFS_ADD(num_sta_ps, ap);
+-      DEBUGFS_ADD(dtim_period, ap);
+       DEBUGFS_ADD(dtim_count, ap);
+       DEBUGFS_ADD(num_beacons, ap);
+       DEBUGFS_ADD(force_unicast_rateidx, ap);
+       DEBUGFS_ADD(max_ratectrl_rateidx, ap);
+       DEBUGFS_ADD(num_buffered_multicast, ap);
+-      DEBUGFS_ADD(beacon_head_len, ap);
+-      DEBUGFS_ADD(beacon_tail_len, ap);
+ }
+ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
+@@ -287,14 +263,11 @@
+       DEBUGFS_DEL(eapol, ap);
+       DEBUGFS_DEL(ieee8021_x, ap);
+       DEBUGFS_DEL(num_sta_ps, ap);
+-      DEBUGFS_DEL(dtim_period, ap);
+       DEBUGFS_DEL(dtim_count, ap);
+       DEBUGFS_DEL(num_beacons, ap);
+       DEBUGFS_DEL(force_unicast_rateidx, ap);
+       DEBUGFS_DEL(max_ratectrl_rateidx, ap);
+       DEBUGFS_DEL(num_buffered_multicast, ap);
+-      DEBUGFS_DEL(beacon_head_len, ap);
+-      DEBUGFS_DEL(beacon_tail_len, ap);
+ }
+ static void del_wds_files(struct ieee80211_sub_if_data *sdata)
+Index: mac80211/net/mac80211/ieee80211_i.h
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_i.h   2007-11-11 15:15:53.792659922 +0100
++++ mac80211/net/mac80211/ieee80211_i.h        2007-11-11 15:18:11.864528190 +0100
+@@ -190,9 +190,14 @@
+ typedef ieee80211_txrx_result (*ieee80211_rx_handler)
+ (struct ieee80211_txrx_data *rx);
++struct beacon_data {
++      u8 *head, *tail;
++      int head_len, tail_len;
++      int dtim_period;
++};
++
+ struct ieee80211_if_ap {
+-      u8 *beacon_head, *beacon_tail;
+-      int beacon_head_len, beacon_tail_len;
++      struct beacon_data *beacon;
+       struct list_head vlans;
+@@ -205,7 +210,7 @@
+       u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)];
+       atomic_t num_sta_ps; /* number of stations in PS mode */
+       struct sk_buff_head ps_bc_buf;
+-      int dtim_period, dtim_count;
++      int dtim_count;
+       int force_unicast_rateidx; /* forced TX rateidx for unicast frames */
+       int max_ratectrl_rateidx; /* max TX rateidx for rate control */
+       int num_beacons; /* number of TXed beacon frames for this BSS */
+@@ -361,14 +366,11 @@
+                       struct dentry *eapol;
+                       struct dentry *ieee8021_x;
+                       struct dentry *num_sta_ps;
+-                      struct dentry *dtim_period;
+                       struct dentry *dtim_count;
+                       struct dentry *num_beacons;
+                       struct dentry *force_unicast_rateidx;
+                       struct dentry *max_ratectrl_rateidx;
+                       struct dentry *num_buffered_multicast;
+-                      struct dentry *beacon_head_len;
+-                      struct dentry *beacon_tail_len;
+               } ap;
+               struct {
+                       struct dentry *channel_use;
+Index: mac80211/net/mac80211/ieee80211_iface.c
+===================================================================
+--- mac80211.orig/net/mac80211/ieee80211_iface.c       2007-11-11 15:15:53.796660158 +0100
++++ mac80211/net/mac80211/ieee80211_iface.c    2007-11-11 15:18:11.868528415 +0100
+@@ -187,7 +187,6 @@
+               sdata->u.vlan.ap = NULL;
+               break;
+       case IEEE80211_IF_TYPE_AP:
+-              sdata->u.ap.dtim_period = 2;
+               sdata->u.ap.force_unicast_rateidx = -1;
+               sdata->u.ap.max_ratectrl_rateidx = -1;
+               skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
+@@ -271,8 +270,7 @@
+                       }
+               }
+-              kfree(sdata->u.ap.beacon_head);
+-              kfree(sdata->u.ap.beacon_tail);
++              kfree(sdata->u.ap.beacon);
+               while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
+                       local->total_ps_buffered--;
+Index: mac80211/net/mac80211/tx.c
+===================================================================
+--- mac80211.orig/net/mac80211/tx.c    2007-11-11 15:15:53.804660611 +0100
++++ mac80211/net/mac80211/tx.c 2007-11-11 15:18:11.868528415 +0100
+@@ -1656,7 +1656,8 @@
+ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
+                                    struct ieee80211_if_ap *bss,
+-                                   struct sk_buff *skb)
++                                   struct sk_buff *skb,
++                                   struct beacon_data *beacon)
+ {
+       u8 *pos, *tim;
+       int aid0 = 0;
+@@ -1672,7 +1673,7 @@
+                                         IEEE80211_MAX_AID+1);
+       if (bss->dtim_count == 0)
+-              bss->dtim_count = bss->dtim_period - 1;
++              bss->dtim_count = beacon->dtim_period - 1;
+       else
+               bss->dtim_count--;
+@@ -1680,7 +1681,7 @@
+       *pos++ = WLAN_EID_TIM;
+       *pos++ = 4;
+       *pos++ = bss->dtim_count;
+-      *pos++ = bss->dtim_period;
++      *pos++ = beacon->dtim_period;
+       if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf))
+               aid0 = 1;
+@@ -1728,8 +1729,9 @@
+       struct ieee80211_if_ap *ap = NULL;
+       struct ieee80211_rate *rate;
+       struct rate_control_extra extra;
+-      u8 *b_head, *b_tail;
+-      int bh_len, bt_len;
++      struct beacon_data *beacon;
++
++      rcu_read_lock();
+       bdev = dev_get_by_index(if_id);
+       if (bdev) {
+@@ -1738,37 +1740,35 @@
+               dev_put(bdev);
+       }
+-      if (!ap || sdata->type != IEEE80211_IF_TYPE_AP ||
+-          !ap->beacon_head) {
++      beacon = rcu_dereference(ap->beacon);
++
++      if (!ap || sdata->type != IEEE80211_IF_TYPE_AP || !beacon) {
+ #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "no beacon data avail for idx=%d "
+                              "(%s)\n", if_id, bdev ? bdev->name : "N/A");
+ #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
+-              return NULL;
++              skb = NULL;
++              goto out;
+       }
+-      /* Assume we are generating the normal beacon locally */
+-      b_head = ap->beacon_head;
+-      b_tail = ap->beacon_tail;
+-      bh_len = ap->beacon_head_len;
+-      bt_len = ap->beacon_tail_len;
+-
+-      skb = dev_alloc_skb(local->tx_headroom +
+-              bh_len + bt_len + 256 /* maximum TIM len */);
++      /* headroom, head length, tail length and maximum TIM length */
++      skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
++                          beacon->tail_len + 256);
+       if (!skb)
+-              return NULL;
++              goto out;
+       skb_reserve(skb, local->tx_headroom);
+-      memcpy(skb_put(skb, bh_len), b_head, bh_len);
++      memcpy(skb_put(skb, beacon->head_len), beacon->head,
++             beacon->head_len);
+       ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data);
+-      ieee80211_beacon_add_tim(local, ap, skb);
++      ieee80211_beacon_add_tim(local, ap, skb, beacon);
+-      if (b_tail) {
+-              memcpy(skb_put(skb, bt_len), b_tail, bt_len);
+-      }
++      if (beacon->tail)
++              memcpy(skb_put(skb, beacon->tail_len), beacon->tail,
++                     beacon->tail_len);
+       if (control) {
+               memset(&extra, 0, sizeof(extra));
+@@ -1781,7 +1781,8 @@
+                                      "found\n", wiphy_name(local->hw.wiphy));
+                       }
+                       dev_kfree_skb(skb);
+-                      return NULL;
++                      skb = NULL;
++                      goto out;
+               }
+               control->tx_rate =
+@@ -1796,6 +1797,9 @@
+       }
+       ap->num_beacons++;
++
++ out:
++      rcu_read_unlock();
+       return skb;
+ }
+ EXPORT_SYMBOL(ieee80211_beacon_get);
+@@ -1844,6 +1848,7 @@
+       struct net_device *bdev;
+       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_if_ap *bss = NULL;
++      struct beacon_data *beacon;
+       bdev = dev_get_by_index(if_id);
+       if (bdev) {
+@@ -1851,9 +1856,19 @@
+               bss = &sdata->u.ap;
+               dev_put(bdev);
+       }
+-      if (!bss || sdata->type != IEEE80211_IF_TYPE_AP || !bss->beacon_head)
++
++      if (!bss)
+               return NULL;
++      rcu_read_lock();
++      beacon = rcu_dereference(bss->beacon);
++
++      if (sdata->type != IEEE80211_IF_TYPE_AP || !beacon || !beacon->head) {
++              rcu_read_unlock();
++              return NULL;
++      }
++      rcu_read_unlock();
++
+       if (bss->dtim_count != 0)
+               return NULL; /* send buffered bc/mc only after DTIM beacon */
+       memset(control, 0, sizeof(*control));
diff --git a/package/mac80211/patches/022-nl80211-sta.patch b/package/mac80211/patches/022-nl80211-sta.patch
new file mode 100644 (file)
index 0000000..4d08721
--- /dev/null
@@ -0,0 +1,464 @@
+Subject: cfg80211/nl80211: station handling
+
+This patch adds station handling to cfg80211/nl80211.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ include/linux/nl80211.h |   68 +++++++++++++
+ include/net/cfg80211.h  |   54 ++++++++++
+ net/wireless/nl80211.c  |  236 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 358 insertions(+)
+
+--- everything.orig/include/linux/nl80211.h    2007-11-08 16:56:32.431522732 +0100
++++ everything/include/linux/nl80211.h 2007-11-08 17:15:15.961529840 +0100
+@@ -7,6 +7,18 @@
+  */
+ /**
++ * DOC: Station handling
++ *
++ * Stations are added per interface, but a special case exists with VLAN
++ * interfaces. When a station is bound to an AP interface, it may be moved
++ * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN).
++ * The station is still assumed to belong to the AP interface it was added
++ * to.
++ *
++ * TODO: need more info?
++ */
++
++/**
+  * enum nl80211_commands - supported nl80211 commands
+  *
+  * @NL80211_CMD_UNSPEC: unspecified command to catch errors
+@@ -56,6 +68,16 @@
+  *    parameters are like for %NL80211_CMD_SET_BEACON.
+  * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
+  *
++ * @NL80211_CMD_GET_STATION: Get station attributes for station identified by
++ *    %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
++ * @NL80211_CMD_SET_STATION: Set station attributes for station identified by
++ *    %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
++ * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the
++ *    the interface identified by %NL80211_ATTR_IFINDEX.
++ * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC
++ *    or, if no MAC address given, all stations, on the interface identified
++ *    by %NL80211_ATTR_IFINDEX.
++ *
+  * @NL80211_CMD_MAX: highest used command number
+  * @__NL80211_CMD_AFTER_LAST: internal use
+  */
+@@ -83,6 +105,11 @@ enum nl80211_commands {
+       NL80211_CMD_NEW_BEACON,
+       NL80211_CMD_DEL_BEACON,
++      NL80211_CMD_GET_STATION,
++      NL80211_CMD_SET_STATION,
++      NL80211_CMD_NEW_STATION,
++      NL80211_CMD_DEL_STATION,
++
+       /* add commands here */
+       /* used to define NL80211_CMD_MAX below */
+@@ -120,6 +147,17 @@ enum nl80211_commands {
+  * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE
+  * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE
+  *
++ * @NL80211_ATTR_STA_AID: Association ID for the station (u16)
++ * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
++ *    &enum nl80211_sta_flags.
++ * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
++ *    IEEE 802.11 7.3.1.6 (u16).
++ * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
++ *    rates as defined by IEEE 802.11 7.3.2.2 but without the length
++ *    restriction (at most %NL80211_MAX_SUPP_RATES).
++ * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
++ *    to, or the AP interface the station was originally added to to.
++ *
+  * @NL80211_ATTR_MAX: highest attribute number currently defined
+  * @__NL80211_ATTR_AFTER_LAST: internal use
+  */
+@@ -147,12 +185,20 @@ enum nl80211_attrs {
+       NL80211_ATTR_BEACON_HEAD,
+       NL80211_ATTR_BEACON_TAIL,
++      NL80211_ATTR_STA_AID,
++      NL80211_ATTR_STA_FLAGS,
++      NL80211_ATTR_STA_LISTEN_INTERVAL,
++      NL80211_ATTR_STA_SUPPORTED_RATES,
++      NL80211_ATTR_STA_VLAN,
++
+       /* add attributes here, update the policy in nl80211.c */
+       __NL80211_ATTR_AFTER_LAST,
+       NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
+ };
++#define NL80211_MAX_SUPP_RATES        32
++
+ /**
+  * enum nl80211_iftype - (virtual) interface types
+  *
+@@ -184,4 +230,26 @@ enum nl80211_iftype {
+       NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1
+ };
++/**
++ * enum nl80211_sta_flags - station flags
++ *
++ * Station flags. When a station is added to an AP interface, it is
++ * assumed to be already associated (and hence authenticated.)
++ *
++ * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X)
++ * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
++ *    with short barker preamble
++ * @NL80211_STA_FLAG_WME: station is WME/QoS capable
++ */
++enum nl80211_sta_flags {
++      __NL80211_STA_FLAG_INVALID,
++      NL80211_STA_FLAG_AUTHORIZED,
++      NL80211_STA_FLAG_SHORT_PREAMBLE,
++      NL80211_STA_FLAG_WME,
++
++      /* keep last */
++      __NL80211_STA_FLAG_AFTER_LAST,
++      NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
++};
++
+ #endif /* __LINUX_NL80211_H */
+--- everything.orig/include/net/cfg80211.h     2007-11-08 16:50:38.421522842 +0100
++++ everything/include/net/cfg80211.h  2007-11-08 17:15:15.971532444 +0100
+@@ -89,6 +89,47 @@ struct beacon_parameters {
+       int head_len, tail_len;
+ };
++/**
++ * enum station_flags - station flags
++ *
++ * Station capability flags. Note that these must be the bits
++ * according to the nl80211 flags.
++ *
++ * @STATION_FLAG_CHANGED: station flags were changed
++ * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X)
++ * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
++ *    with short preambles
++ * @STATION_FLAG_WME: station is WME/QoS capable
++ */
++enum station_flags {
++      STATION_FLAG_CHANGED            = 1<<0,
++      STATION_FLAG_AUTHORIZED         = 1<<NL80211_STA_FLAG_AUTHORIZED,
++      STATION_FLAG_SHORT_PREAMBLE     = 1<<NL80211_STA_FLAG_SHORT_PREAMBLE,
++      STATION_FLAG_WME                = 1<<NL80211_STA_FLAG_WME,
++};
++
++/**
++ * struct station_parameters - station parameters
++ *
++ * Used to change and create a new station.
++ *
++ * @vlan: vlan interface station should belong to
++ * @supported_rates: supported rates in IEEE 802.11 format
++ *    (or NULL for no change)
++ * @supported_rates_len: number of supported rates
++ * @station_flags: station flags (see &enum station_flags)
++ * @listen_interval: listen interval or -1 for no change
++ * @aid: AID or zero for no change
++ */
++struct station_parameters {
++      u8 *supported_rates;
++      struct net_device *vlan;
++      u32 station_flags;
++      int listen_interval;
++      u16 aid;
++      u8 supported_rates_len;
++};
++
+ /* from net/wireless.h */
+ struct wiphy;
+@@ -130,6 +171,12 @@ struct wiphy;
+  *    interface. This should reject the call when no beacon has been
+  *    configured.
+  * @del_beacon: Remove beacon configuration and stop sending the beacon.
++ *
++ * @add_station: Add a new station.
++ *
++ * @del_station: Remove a station; @mac may be NULL to remove all stations.
++ *
++ * @change_station: Modify a given station.
+  */
+ struct cfg80211_ops {
+       int     (*add_virtual_intf)(struct wiphy *wiphy, char *name,
+@@ -155,6 +202,13 @@ struct cfg80211_ops {
+       int     (*set_beacon)(struct wiphy *wiphy, struct net_device *dev,
+                             struct beacon_parameters *info);
+       int     (*del_beacon)(struct wiphy *wiphy, struct net_device *dev);
++
++      int     (*add_station)(struct wiphy *wiphy, struct net_device *dev,
++                             u8 *mac, struct station_parameters *params);
++      int     (*del_station)(struct wiphy *wiphy, struct net_device *dev,
++                             u8 *mac);
++      int     (*change_station)(struct wiphy *wiphy, struct net_device *dev,
++                                u8 *mac, struct station_parameters *params);
+ };
+ #endif /* __NET_CFG80211_H */
+--- everything.orig/net/wireless/nl80211.c     2007-11-08 16:58:36.711524524 +0100
++++ everything/net/wireless/nl80211.c  2007-11-08 17:15:15.981533909 +0100
+@@ -76,6 +76,12 @@ static struct nla_policy nl80211_policy[
+                                      .len = IEEE80211_MAX_DATA_LEN },
+       [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
+                                      .len = IEEE80211_MAX_DATA_LEN },
++      [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
++      [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
++      [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
++      [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
++                                             .len = NL80211_MAX_SUPP_RATES },
++      [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
+ };
+ /* message building helper */
+@@ -715,6 +721,211 @@ static int nl80211_del_beacon(struct sk_
+       return err;
+ }
++static
++struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] __read_mostly = {
++      [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
++      [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
++      [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
++};
++
++static int parse_station_flags(struct nlattr *nla, u32 *staflags)
++{
++      struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
++      int flag;
++
++      *staflags = 0;
++
++      if (!nla)
++              return 0;
++
++      if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
++                           nla, sta_flags_policy))
++              return -EINVAL;
++
++      *staflags = STATION_FLAG_CHANGED;
++
++      for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
++              if (flags[flag])
++                      *staflags |= (1<<flag);
++
++      return 0;
++}
++
++static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
++{
++      return -EOPNOTSUPP;
++}
++
++/*
++ * Get vlan interface making sure it is on the right wiphy.
++ */
++static int get_vlan(struct nlattr *vlanattr,
++                  struct cfg80211_registered_device *rdev,
++                  struct net_device **vlan)
++{
++      *vlan = NULL;
++
++      if (vlanattr) {
++              *vlan = dev_get_by_index(nla_get_u32(vlanattr));
++              if (!*vlan)
++                      return -ENODEV;
++              if (!(*vlan)->ieee80211_ptr)
++                      return -EINVAL;
++              if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
++                      return -EINVAL;
++      }
++      return 0;
++}
++
++static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
++{
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      struct station_parameters params;
++      u8 *mac_addr = NULL;
++
++      memset(&params, 0, sizeof(params));
++
++      params.listen_interval = -1;
++
++      if (info->attrs[NL80211_ATTR_STA_AID])
++              return -EINVAL;
++
++      if (!info->attrs[NL80211_ATTR_MAC])
++              return -EINVAL;
++
++      mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
++
++      if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
++              params.supported_rates =
++                      nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
++              params.supported_rates_len =
++                      nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
++      }
++
++      if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
++              params.listen_interval =
++                  nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
++
++      if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
++                              &params.station_flags))
++              return -EINVAL;
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
++      if (err)
++              goto out;
++
++      if (!drv->ops->change_station) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
++      rtnl_unlock();
++
++ out:
++      if (params.vlan)
++              dev_put(params.vlan);
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
++static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
++{
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      struct station_parameters params;
++      u8 *mac_addr = NULL;
++
++      memset(&params, 0, sizeof(params));
++
++      if (!info->attrs[NL80211_ATTR_MAC])
++              return -EINVAL;
++
++      if (!info->attrs[NL80211_ATTR_STA_AID])
++              return -EINVAL;
++
++      if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
++              return -EINVAL;
++
++      if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
++              return -EINVAL;
++
++      mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
++      params.supported_rates =
++              nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
++      params.supported_rates_len =
++              nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
++      params.listen_interval =
++              nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
++      params.listen_interval = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
++
++      if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
++                              &params.station_flags))
++              return -EINVAL;
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
++      if (err)
++              goto out;
++
++      if (!drv->ops->add_station) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
++      rtnl_unlock();
++
++ out:
++      if (params.vlan)
++              dev_put(params.vlan);
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
++static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
++{
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      u8 *mac_addr = NULL;
++
++      if (info->attrs[NL80211_ATTR_MAC])
++              mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      if (!drv->ops->del_station) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
++      rtnl_unlock();
++
++ out:
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
++}
++
+ static struct genl_ops nl80211_ops[] = {
+       {
+               .cmd = NL80211_CMD_GET_WIPHY,
+@@ -796,6 +1007,31 @@ static struct genl_ops nl80211_ops[] = {
+               .flags = GENL_ADMIN_PERM,
+               .doit = nl80211_del_beacon,
+       },
++      {
++              .cmd = NL80211_CMD_GET_STATION,
++              .doit = nl80211_get_station,
++              /* TODO: implement dumpit */
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++      },
++      {
++              .cmd = NL80211_CMD_SET_STATION,
++              .doit = nl80211_set_station,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++      },
++      {
++              .cmd = NL80211_CMD_NEW_STATION,
++              .doit = nl80211_new_station,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++      },
++      {
++              .cmd = NL80211_CMD_DEL_STATION,
++              .doit = nl80211_del_station,
++              .policy = nl80211_policy,
++              .flags = GENL_ADMIN_PERM,
++      },
+ };
+ /* multicast groups */
diff --git a/package/mac80211/patches/023-mac80211-implement-sta.patch b/package/mac80211/patches/023-mac80211-implement-sta.patch
new file mode 100644 (file)
index 0000000..0950676
--- /dev/null
@@ -0,0 +1,224 @@
+Subject: mac80211: implement cfg80211's station handling
+
+This implements station handling from userspace via cfg80211
+in mac80211.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ net/mac80211/cfg.c |  192 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 192 insertions(+)
+
+--- everything.orig/net/mac80211/cfg.c 2007-11-08 17:11:52.351521702 +0100
++++ everything/net/mac80211/cfg.c      2007-11-08 17:15:51.801523493 +0100
+@@ -14,6 +14,7 @@
+ #include <net/cfg80211.h>
+ #include "ieee80211_i.h"
+ #include "cfg.h"
++#include "ieee80211_rate.h"
+ static enum ieee80211_if_types
+ nl80211_type_to_mac80211_type(enum nl80211_iftype type)
+@@ -428,6 +429,194 @@ static int ieee80211_del_beacon(struct w
+       return ieee80211_if_config_beacon(dev);
+ }
++/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
++struct iapp_layer2_update {
++      u8 da[ETH_ALEN];        /* broadcast */
++      u8 sa[ETH_ALEN];        /* STA addr */
++      __be16 len;             /* 6 */
++      u8 dsap;                /* 0 */
++      u8 ssap;                /* 0 */
++      u8 control;
++      u8 xid_info[3];
++} __attribute__ ((packed));
++
++static void ieee80211_send_layer2_update(struct sta_info *sta)
++{
++      struct iapp_layer2_update *msg;
++      struct sk_buff *skb;
++
++      /* Send Level 2 Update Frame to update forwarding tables in layer 2
++       * bridge devices */
++
++      skb = dev_alloc_skb(sizeof(*msg));
++      if (!skb)
++              return;
++      msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
++
++      /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
++       * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
++
++      memset(msg->da, 0xff, ETH_ALEN);
++      memcpy(msg->sa, sta->addr, ETH_ALEN);
++      msg->len = htons(6);
++      msg->dsap = 0;
++      msg->ssap = 0x01;       /* NULL LSAP, CR Bit: Response */
++      msg->control = 0xaf;    /* XID response lsb.1111F101.
++                               * F=0 (no poll command; unsolicited frame) */
++      msg->xid_info[0] = 0x81;        /* XID format identifier */
++      msg->xid_info[1] = 1;   /* LLC types/classes: Type 1 LLC */
++      msg->xid_info[2] = 0;   /* XID sender's receive window size (RW) */
++
++      skb->dev = sta->dev;
++      skb->protocol = eth_type_trans(skb, sta->dev);
++      memset(skb->cb, 0, sizeof(skb->cb));
++      netif_rx(skb);
++}
++
++static void sta_apply_parameters(struct ieee80211_local *local,
++                               struct sta_info *sta,
++                               struct station_parameters *params)
++{
++      u32 rates;
++      int i, j;
++      struct ieee80211_hw_mode *mode;
++
++      if (params->station_flags & STATION_FLAG_CHANGED) {
++              sta->flags &= ~WLAN_STA_AUTHORIZED;
++              if (params->station_flags & STATION_FLAG_AUTHORIZED)
++                      sta->flags |= WLAN_STA_AUTHORIZED;
++
++              sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
++              if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
++                      sta->flags |= WLAN_STA_SHORT_PREAMBLE;
++
++              sta->flags &= ~WLAN_STA_WME;
++              if (params->station_flags & STATION_FLAG_WME)
++                      sta->flags |= WLAN_STA_WME;
++      }
++
++      if (params->aid) {
++              sta->aid = params->aid;
++              if (sta->aid > IEEE80211_MAX_AID)
++                      sta->aid = 0; /* XXX: should this be an error? */
++      }
++
++      if (params->listen_interval >= 0)
++              sta->listen_interval = params->listen_interval;
++
++      if (params->supported_rates) {
++              rates = 0;
++              mode = local->oper_hw_mode;
++              for (i = 0; i < params->supported_rates_len; i++) {
++                      int rate = (params->supported_rates[i] & 0x7f) * 5;
++                      for (j = 0; j < mode->num_rates; j++) {
++                              if (mode->rates[j].rate == rate)
++                                      rates |= BIT(j);
++                      }
++              }
++              sta->supp_rates = rates;
++      }
++}
++
++static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
++                               u8 *mac, struct station_parameters *params)
++{
++      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
++      struct sta_info *sta;
++      struct ieee80211_sub_if_data *sdata;
++
++      /* Prevent a race with changing the rate control algorithm */
++      if (!netif_running(dev))
++              return -ENETDOWN;
++
++      /* XXX: get sta belonging to dev */
++      sta = sta_info_get(local, mac);
++      if (sta) {
++              sta_info_put(sta);
++              return -EEXIST;
++      }
++
++      if (params->vlan) {
++              sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
++
++              if (sdata->type != IEEE80211_IF_TYPE_VLAN ||
++                  sdata->type != IEEE80211_IF_TYPE_AP)
++                      return -EINVAL;
++      } else
++              sdata = IEEE80211_DEV_TO_SUB_IF(dev);
++
++      sta = sta_info_add(local, dev, mac, GFP_KERNEL);
++      if (!sta)
++              return -ENOMEM;
++
++      sta->dev = sdata->dev;
++      if (sdata->type == IEEE80211_IF_TYPE_VLAN ||
++          sdata->type == IEEE80211_IF_TYPE_AP)
++              ieee80211_send_layer2_update(sta);
++
++      sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
++
++      sta_apply_parameters(local, sta, params);
++
++      rate_control_rate_init(sta, local);
++
++      sta_info_put(sta);
++
++      return 0;
++}
++
++static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
++                               u8 *mac)
++{
++      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
++      struct sta_info *sta;
++
++      if (mac) {
++              /* XXX: get sta belonging to dev */
++              sta = sta_info_get(local, mac);
++              if (!sta)
++                      return -ENOENT;
++
++              sta_info_free(sta);
++              sta_info_put(sta);
++      } else
++              sta_info_flush(local, dev);
++
++      return 0;
++}
++
++static int ieee80211_change_station(struct wiphy *wiphy,
++                                  struct net_device *dev,
++                                  u8 *mac,
++                                  struct station_parameters *params)
++{
++      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
++      struct sta_info *sta;
++      struct ieee80211_sub_if_data *vlansdata;
++
++      /* XXX: get sta belonging to dev */
++      sta = sta_info_get(local, mac);
++      if (!sta)
++              return -ENOENT;
++
++      if (params->vlan && params->vlan != sta->dev) {
++              vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
++
++              if (vlansdata->type != IEEE80211_IF_TYPE_VLAN ||
++                  vlansdata->type != IEEE80211_IF_TYPE_AP)
++                      return -EINVAL;
++
++              sta->dev = params->vlan;
++              ieee80211_send_layer2_update(sta);
++      }
++
++      sta_apply_parameters(local, sta, params);
++
++      sta_info_put(sta);
++
++      return 0;
++}
++
+ struct cfg80211_ops mac80211_config_ops = {
+       .add_virtual_intf = ieee80211_add_iface,
+       .del_virtual_intf = ieee80211_del_iface,
+@@ -439,4 +628,7 @@ struct cfg80211_ops mac80211_config_ops 
+       .add_beacon = ieee80211_add_beacon,
+       .set_beacon = ieee80211_set_beacon,
+       .del_beacon = ieee80211_del_beacon,
++      .add_station = ieee80211_add_station,
++      .del_station = ieee80211_del_station,
++      .change_station = ieee80211_change_station,
+ };
diff --git a/package/mac80211/patches/024-nl80211-get-sta.patch b/package/mac80211/patches/024-nl80211-get-sta.patch
new file mode 100644 (file)
index 0000000..198ad18
--- /dev/null
@@ -0,0 +1,208 @@
+Subject: cfg80211/nl80211: implement station attribute retrieval
+
+After a station is added to the kernel's structures, userspace
+has to be able to retrieve statistics about that station, especially
+whether the station was idle and how much bytes were transferred
+to and from it. This adds the necessary code to nl80211.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ include/linux/nl80211.h |   28 ++++++++++++++++
+ include/net/cfg80211.h  |   35 ++++++++++++++++++++
+ net/wireless/nl80211.c  |   82 +++++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 144 insertions(+), 1 deletion(-)
+
+--- everything.orig/include/linux/nl80211.h    2007-11-08 17:15:15.961529840 +0100
++++ everything/include/linux/nl80211.h 2007-11-08 17:17:00.891547364 +0100
+@@ -157,6 +157,9 @@ enum nl80211_commands {
+  *    restriction (at most %NL80211_MAX_SUPP_RATES).
+  * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
+  *    to, or the AP interface the station was originally added to to.
++ * @NL80211_ATTR_STA_STATS: statistics for a station, part of station info
++ *    given for %NL80211_CMD_GET_STATION, nested attribute containing
++ *    info as possible, see &enum nl80211_sta_stats.
+  *
+  * @NL80211_ATTR_MAX: highest attribute number currently defined
+  * @__NL80211_ATTR_AFTER_LAST: internal use
+@@ -190,6 +193,7 @@ enum nl80211_attrs {
+       NL80211_ATTR_STA_LISTEN_INTERVAL,
+       NL80211_ATTR_STA_SUPPORTED_RATES,
+       NL80211_ATTR_STA_VLAN,
++      NL80211_ATTR_STA_STATS,
+       /* add attributes here, update the policy in nl80211.c */
+@@ -252,4 +256,28 @@ enum nl80211_sta_flags {
+       NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
+ };
++/**
++ * enum nl80211_sta_stats - station statistics
++ *
++ * These attribute types are used with %NL80211_ATTR_STA_STATS
++ * when getting information about a station.
++ *
++ * @__NL80211_STA_STAT_INVALID: attribute number 0 is reserved
++ * @NL80211_STA_STAT_INACTIVE_TIME: time since last activity (u32, msecs)
++ * @NL80211_STA_STAT_RX_BYTES: total received bytes (u32, from this station)
++ * @NL80211_STA_STAT_TX_BYTES: total transmitted bytes (u32, to this station)
++ * @__NL80211_STA_STAT_AFTER_LAST: internal
++ * @NL80211_STA_STAT_MAX: highest possible station stats attribute
++ */
++enum nl80211_sta_stats {
++      __NL80211_STA_STAT_INVALID,
++      NL80211_STA_STAT_INACTIVE_TIME,
++      NL80211_STA_STAT_RX_BYTES,
++      NL80211_STA_STAT_TX_BYTES,
++
++      /* keep last */
++      __NL80211_STA_STAT_AFTER_LAST,
++      NL80211_STA_STAT_MAX = __NL80211_STA_STAT_AFTER_LAST - 1
++};
++
+ #endif /* __LINUX_NL80211_H */
+--- everything.orig/include/net/cfg80211.h     2007-11-08 17:15:15.971532444 +0100
++++ everything/include/net/cfg80211.h  2007-11-08 17:17:00.891547364 +0100
+@@ -130,6 +130,39 @@ struct station_parameters {
+       u8 supported_rates_len;
+ };
++/**
++ * enum station_stats_flags - station statistics flags
++ *
++ * Used by the driver to indicate which info in &struct station_stats
++ * it has filled in during get_station().
++ *
++ * @STATION_STAT_INACTIVE_TIME: @inactive_time filled
++ * @STATION_STAT_RX_BYTES: @rx_bytes filled
++ * @STATION_STAT_TX_BYTES: @tx_bytes filled
++ */
++enum station_stats_flags {
++      STATION_STAT_INACTIVE_TIME      = 1<<0,
++      STATION_STAT_RX_BYTES           = 1<<1,
++      STATION_STAT_TX_BYTES           = 1<<2,
++};
++
++/**
++ * struct station_stats - station statistics
++ *
++ * Station information filled by driver for get_station().
++ *
++ * @filled: bitflag of flags from &enum station_stats_flags
++ * @inactive_time: time since last station activity (tx/rx) in milliseconds
++ * @rx_bytes: bytes received from this station
++ * @tx_bytes: bytes transmitted to this station
++ */
++struct station_stats {
++      u32 filled;
++      u32 inactive_time;
++      u32 rx_bytes;
++      u32 tx_bytes;
++};
++
+ /* from net/wireless.h */
+ struct wiphy;
+@@ -209,6 +242,8 @@ struct cfg80211_ops {
+                              u8 *mac);
+       int     (*change_station)(struct wiphy *wiphy, struct net_device *dev,
+                                 u8 *mac, struct station_parameters *params);
++      int     (*get_station)(struct wiphy *wiphy, struct net_device *dev,
++                             u8 *mac, struct station_stats *stats);
+ };
+ #endif /* __NET_CFG80211_H */
+--- everything.orig/net/wireless/nl80211.c     2007-11-08 17:15:15.981533909 +0100
++++ everything/net/wireless/nl80211.c  2007-11-08 17:17:00.901534235 +0100
+@@ -751,9 +751,89 @@ static int parse_station_flags(struct nl
+       return 0;
+ }
++static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
++                              int flags, struct net_device *dev,
++                              u8 *mac_addr, struct station_stats *stats)
++{
++      void *hdr;
++      struct nlattr *statsattr;
++
++      hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
++      if (!hdr)
++              return -1;
++
++      NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
++      NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
++
++      statsattr = nla_nest_start(msg, NL80211_ATTR_STA_STATS);
++      if (!statsattr)
++              goto nla_put_failure;
++      if (stats->filled & STATION_STAT_INACTIVE_TIME)
++              NLA_PUT_U32(msg, NL80211_STA_STAT_INACTIVE_TIME,
++                          stats->inactive_time);
++      if (stats->filled & STATION_STAT_RX_BYTES)
++              NLA_PUT_U32(msg, NL80211_STA_STAT_RX_BYTES,
++                          stats->rx_bytes);
++      if (stats->filled & STATION_STAT_TX_BYTES)
++              NLA_PUT_U32(msg, NL80211_STA_STAT_TX_BYTES,
++                          stats->tx_bytes);
++
++      nla_nest_end(msg, statsattr);
++
++      return genlmsg_end(msg, hdr);
++
++ nla_put_failure:
++      return genlmsg_cancel(msg, hdr);
++}
++
++
+ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
+ {
+-      return -EOPNOTSUPP;
++      struct cfg80211_registered_device *drv;
++      int err;
++      struct net_device *dev;
++      struct station_stats stats;
++      struct sk_buff *msg;
++      u8 *mac_addr = NULL;
++
++      memset(&stats, 0, sizeof(stats));
++
++      if (!info->attrs[NL80211_ATTR_MAC])
++              return -EINVAL;
++
++      mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
++
++      err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
++      if (err)
++              return err;
++
++      if (!drv->ops->get_station) {
++              err = -EOPNOTSUPP;
++              goto out;
++      }
++
++      rtnl_lock();
++      err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &stats);
++      rtnl_unlock();
++
++      msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
++      if (!msg)
++              goto out;
++
++      if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
++                               dev, mac_addr, &stats) < 0)
++              goto out_free;
++
++      err = genlmsg_unicast(msg, info->snd_pid);
++      goto out;
++
++ out_free:
++      nlmsg_free(msg);
++
++ out:
++      cfg80211_put_dev(drv);
++      dev_put(dev);
++      return err;
+ }
+ /*
diff --git a/package/mac80211/patches/025-mac80211-get-sta.patch b/package/mac80211/patches/025-mac80211-get-sta.patch
new file mode 100644 (file)
index 0000000..868ca86
--- /dev/null
@@ -0,0 +1,51 @@
+Subject: mac80211: implement station stats retrieval
+
+This implements the required cfg80211 callback in mac80211
+to allow userspace to get station statistics.
+
+Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
+
+---
+ net/mac80211/cfg.c |   26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- everything.orig/net/mac80211/cfg.c 2007-11-08 17:15:51.801523493 +0100
++++ everything/net/mac80211/cfg.c      2007-11-08 17:17:01.921529351 +0100
+@@ -617,6 +617,31 @@ static int ieee80211_change_station(stru
+       return 0;
+ }
++static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
++                               u8 *mac, struct station_stats *stats)
++{
++      struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
++      struct sta_info *sta;
++
++      sta = sta_info_get(local, mac);
++      if (!sta)
++              return -ENOENT;
++
++      /* XXX: verify sta->dev == dev */
++
++      stats->filled = STATION_STAT_INACTIVE_TIME |
++                      STATION_STAT_RX_BYTES |
++                      STATION_STAT_TX_BYTES;
++
++      stats->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
++      stats->rx_bytes = sta->rx_bytes;
++      stats->tx_bytes = sta->tx_bytes;
++
++      sta_info_put(sta);
++
++      return 0;
++}
++
+ struct cfg80211_ops mac80211_config_ops = {
+       .add_virtual_intf = ieee80211_add_iface,
+       .del_virtual_intf = ieee80211_del_iface,
+@@ -631,4 +656,5 @@ struct cfg80211_ops mac80211_config_ops 
+       .add_station = ieee80211_add_station,
+       .del_station = ieee80211_del_station,
+       .change_station = ieee80211_change_station,
++      .get_station = ieee80211_get_station,
+ };
diff --git a/package/mac80211/src/mac80211/Kconfig b/package/mac80211/src/mac80211/Kconfig
deleted file mode 100644 (file)
index 6fffb38..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-config MAC80211
-       tristate "Generic IEEE 802.11 Networking Stack (mac80211)"
-       depends on EXPERIMENTAL
-       select CRYPTO
-       select CRYPTO_ECB
-       select CRYPTO_ARC4
-       select CRYPTO_AES
-       select CRC32
-       select WIRELESS_EXT
-       select CFG80211
-       select NET_SCH_FIFO
-       ---help---
-       This option enables the hardware independent IEEE 802.11
-       networking stack.
-
-config MAC80211_LEDS
-       bool "Enable LED triggers"
-       depends on MAC80211 && LEDS_TRIGGERS
-       ---help---
-       This option enables a few LED triggers for different
-       packet receive/transmit events.
-
-config MAC80211_DEBUGFS
-       bool "Export mac80211 internals in DebugFS"
-       depends on MAC80211 && DEBUG_FS
-       ---help---
-         Select this to see extensive information about
-         the internal state of mac80211 in debugfs.
-
-         Say N unless you know you need this.
-
-config MAC80211_DEBUG
-       bool "Enable debugging output"
-       depends on MAC80211
-       ---help---
-         This option will enable debug tracing output for the
-         ieee80211 network stack.
-
-         If you are not trying to debug or develop the ieee80211
-         subsystem, you most likely want to say N here.
-
-config MAC80211_VERBOSE_DEBUG
-       bool "Verbose debugging output"
-       depends on MAC80211_DEBUG
-
-config MAC80211_LOWTX_FRAME_DUMP
-       bool "Debug frame dumping"
-       depends on MAC80211_DEBUG
-       ---help---
-         Selecting this option will cause the stack to
-         print a message for each frame that is handed
-         to the lowlevel driver for transmission. This
-         message includes all MAC addresses and the
-         frame control field.
-
-         If unsure, say N and insert the debugging code
-         you require into the driver you are debugging.
-
-config TKIP_DEBUG
-       bool "TKIP debugging"
-       depends on MAC80211_DEBUG
-
-config MAC80211_DEBUG_COUNTERS
-       bool "Extra statistics for TX/RX debugging"
-       depends on MAC80211_DEBUG
-
-config MAC80211_IBSS_DEBUG
-       bool "Support for IBSS testing"
-       depends on MAC80211_DEBUG
-       ---help---
-         Say Y here if you intend to debug the IBSS code.
-
-config MAC80211_VERBOSE_PS_DEBUG
-       bool "Verbose powersave mode debugging"
-       depends on MAC80211_DEBUG
-       ---help---
-         Say Y here to print out verbose powersave
-         mode debug messages.
diff --git a/package/mac80211/src/mac80211/Makefile b/package/mac80211/src/mac80211/Makefile
deleted file mode 100644 (file)
index 219cd9f..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o
-
-mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o
-mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o
-mac80211-objs-$(CONFIG_NET_SCHED) += wme.o
-
-mac80211-objs := \
-       ieee80211.o \
-       ieee80211_ioctl.o \
-       sta_info.o \
-       wep.o \
-       wpa.o \
-       ieee80211_sta.o \
-       ieee80211_iface.o \
-       ieee80211_rate.o \
-       michael.o \
-       regdomain.o \
-       tkip.o \
-       aes_ccm.o \
-       cfg.o \
-       rx.o \
-       tx.o \
-       key.o \
-       util.o \
-       event.o \
-       $(mac80211-objs-y)
diff --git a/package/mac80211/src/mac80211/aes_ccm.c b/package/mac80211/src/mac80211/aes_ccm.c
deleted file mode 100644 (file)
index e55569b..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2003-2004, Instant802 Networks, Inc.
- * Copyright 2005-2006, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/types.h>
-#include <linux/crypto.h>
-#include <linux/err.h>
-#include <asm/scatterlist.h>
-
-#include <net/mac80211.h>
-#include "ieee80211_key.h"
-#include "aes_ccm.h"
-
-
-static void ieee80211_aes_encrypt(struct crypto_cipher *tfm,
-                                 const u8 pt[16], u8 ct[16])
-{
-       crypto_cipher_encrypt_one(tfm, ct, pt);
-}
-
-
-static inline void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-                                  u8 *b, u8 *s_0, u8 *a)
-{
-       int i;
-
-       ieee80211_aes_encrypt(tfm, b_0, b);
-
-       /* Extra Authenticate-only data (always two AES blocks) */
-       for (i = 0; i < AES_BLOCK_LEN; i++)
-               aad[i] ^= b[i];
-       ieee80211_aes_encrypt(tfm, aad, b);
-
-       aad += AES_BLOCK_LEN;
-
-       for (i = 0; i < AES_BLOCK_LEN; i++)
-               aad[i] ^= b[i];
-       ieee80211_aes_encrypt(tfm, aad, a);
-
-       /* Mask out bits from auth-only-b_0 */
-       b_0[0] &= 0x07;
-
-       /* S_0 is used to encrypt T (= MIC) */
-       b_0[14] = 0;
-       b_0[15] = 0;
-       ieee80211_aes_encrypt(tfm, b_0, s_0);
-}
-
-
-void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
-                              u8 *b_0, u8 *aad, u8 *data, size_t data_len,
-                              u8 *cdata, u8 *mic)
-{
-       int i, j, last_len, num_blocks;
-       u8 *pos, *cpos, *b, *s_0, *e;
-
-       b = scratch;
-       s_0 = scratch + AES_BLOCK_LEN;
-       e = scratch + 2 * AES_BLOCK_LEN;
-
-       num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
-       last_len = data_len % AES_BLOCK_LEN;
-       aes_ccm_prepare(tfm, b_0, aad, b, s_0, b);
-
-       /* Process payload blocks */
-       pos = data;
-       cpos = cdata;
-       for (j = 1; j <= num_blocks; j++) {
-               int blen = (j == num_blocks && last_len) ?
-                       last_len : AES_BLOCK_LEN;
-
-               /* Authentication followed by encryption */
-               for (i = 0; i < blen; i++)
-                       b[i] ^= pos[i];
-               ieee80211_aes_encrypt(tfm, b, b);
-
-               b_0[14] = (j >> 8) & 0xff;
-               b_0[15] = j & 0xff;
-               ieee80211_aes_encrypt(tfm, b_0, e);
-               for (i = 0; i < blen; i++)
-                       *cpos++ = *pos++ ^ e[i];
-       }
-
-       for (i = 0; i < CCMP_MIC_LEN; i++)
-               mic[i] = b[i] ^ s_0[i];
-}
-
-
-int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
-                             u8 *b_0, u8 *aad, u8 *cdata, size_t data_len,
-                             u8 *mic, u8 *data)
-{
-       int i, j, last_len, num_blocks;
-       u8 *pos, *cpos, *b, *s_0, *a;
-
-       b = scratch;
-       s_0 = scratch + AES_BLOCK_LEN;
-       a = scratch + 2 * AES_BLOCK_LEN;
-
-       num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
-       last_len = data_len % AES_BLOCK_LEN;
-       aes_ccm_prepare(tfm, b_0, aad, b, s_0, a);
-
-       /* Process payload blocks */
-       cpos = cdata;
-       pos = data;
-       for (j = 1; j <= num_blocks; j++) {
-               int blen = (j == num_blocks && last_len) ?
-                       last_len : AES_BLOCK_LEN;
-
-               /* Decryption followed by authentication */
-               b_0[14] = (j >> 8) & 0xff;
-               b_0[15] = j & 0xff;
-               ieee80211_aes_encrypt(tfm, b_0, b);
-               for (i = 0; i < blen; i++) {
-                       *pos = *cpos++ ^ b[i];
-                       a[i] ^= *pos++;
-               }
-
-               ieee80211_aes_encrypt(tfm, a, a);
-       }
-
-       for (i = 0; i < CCMP_MIC_LEN; i++) {
-               if ((mic[i] ^ s_0[i]) != a[i])
-                       return -1;
-       }
-
-       return 0;
-}
-
-
-struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[])
-{
-       struct crypto_cipher *tfm;
-
-       tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
-       if (IS_ERR(tfm))
-               return NULL;
-
-       crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN);
-
-       return tfm;
-}
-
-
-void ieee80211_aes_key_free(struct crypto_cipher *tfm)
-{
-       if (tfm)
-               crypto_free_cipher(tfm);
-}
diff --git a/package/mac80211/src/mac80211/aes_ccm.h b/package/mac80211/src/mac80211/aes_ccm.h
deleted file mode 100644 (file)
index 885f190..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2003-2004, Instant802 Networks, Inc.
- * Copyright 2006, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef AES_CCM_H
-#define AES_CCM_H
-
-#include <linux/crypto.h>
-
-#define AES_BLOCK_LEN 16
-
-struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[]);
-void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
-                              u8 *b_0, u8 *aad, u8 *data, size_t data_len,
-                              u8 *cdata, u8 *mic);
-int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
-                             u8 *b_0, u8 *aad, u8 *cdata, size_t data_len,
-                             u8 *mic, u8 *data);
-void ieee80211_aes_key_free(struct crypto_cipher *tfm);
-
-#endif /* AES_CCM_H */
diff --git a/package/mac80211/src/mac80211/cfg.c b/package/mac80211/src/mac80211/cfg.c
deleted file mode 100644 (file)
index cd78b3f..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * mac80211 configuration hooks for cfg80211
- *
- * Copyright 2006      Johannes Berg <johannes@sipsolutions.net>
- *
- * This file is GPLv2 as found in COPYING.
- */
-
-#include <linux/nl80211.h>
-#include <linux/rtnetlink.h>
-#include <net/cfg80211.h>
-#include "ieee80211_i.h"
-#include "cfg.h"
-
-static enum ieee80211_if_types
-nl80211_type_to_mac80211_type(enum nl80211_iftype type)
-{
-       switch (type) {
-       case NL80211_IFTYPE_UNSPECIFIED:
-               return IEEE80211_IF_TYPE_STA;
-       case NL80211_IFTYPE_ADHOC:
-               return IEEE80211_IF_TYPE_IBSS;
-       case NL80211_IFTYPE_STATION:
-               return IEEE80211_IF_TYPE_STA;
-       case NL80211_IFTYPE_MONITOR:
-               return IEEE80211_IF_TYPE_MNTR;
-       default:
-               return IEEE80211_IF_TYPE_INVALID;
-       }
-}
-
-static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
-                              enum nl80211_iftype type)
-{
-       struct ieee80211_local *local = wiphy_priv(wiphy);
-       enum ieee80211_if_types itype;
-
-       if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
-               return -ENODEV;
-
-       itype = nl80211_type_to_mac80211_type(type);
-       if (itype == IEEE80211_IF_TYPE_INVALID)
-               return -EINVAL;
-
-       return ieee80211_if_add(local->mdev, name, NULL, itype);
-}
-
-static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
-{
-       struct ieee80211_local *local = wiphy_priv(wiphy);
-       struct net_device *dev;
-       char *name;
-
-       if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
-               return -ENODEV;
-
-       /* we're under RTNL */
-       dev = __dev_get_by_index(ifindex);
-       if (!dev)
-               return 0;
-
-       name = dev->name;
-
-       return ieee80211_if_remove(local->mdev, name, -1);
-}
-
-static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
-                                 enum nl80211_iftype type)
-{
-       struct ieee80211_local *local = wiphy_priv(wiphy);
-       struct net_device *dev;
-       enum ieee80211_if_types itype;
-       struct ieee80211_sub_if_data *sdata;
-
-       if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED))
-               return -ENODEV;
-
-       /* we're under RTNL */
-       dev = __dev_get_by_index(ifindex);
-       if (!dev)
-               return -ENODEV;
-
-       if (netif_running(dev))
-               return -EBUSY;
-
-       itype = nl80211_type_to_mac80211_type(type);
-       if (itype == IEEE80211_IF_TYPE_INVALID)
-               return -EINVAL;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-        if (sdata->type == IEEE80211_IF_TYPE_VLAN)
-               return -EOPNOTSUPP;
-
-       ieee80211_if_reinit(dev);
-       ieee80211_if_set_type(dev, itype);
-
-       return 0;
-}
-
-struct cfg80211_ops mac80211_config_ops = {
-       .add_virtual_intf = ieee80211_add_iface,
-       .del_virtual_intf = ieee80211_del_iface,
-       .change_virtual_intf = ieee80211_change_iface,
-};
diff --git a/package/mac80211/src/mac80211/cfg.h b/package/mac80211/src/mac80211/cfg.h
deleted file mode 100644 (file)
index 7d7879f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * mac80211 configuration hooks for cfg80211
- */
-#ifndef __CFG_H
-#define __CFG_H
-
-extern struct cfg80211_ops mac80211_config_ops;
-
-#endif /* __CFG_H */
diff --git a/package/mac80211/src/mac80211/debugfs.c b/package/mac80211/src/mac80211/debugfs.c
deleted file mode 100644 (file)
index 60514b2..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * mac80211 debugfs for wireless PHYs
- *
- * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
- *
- * GPLv2
- *
- */
-
-#include <linux/debugfs.h>
-#include <linux/rtnetlink.h>
-#include "ieee80211_i.h"
-#include "ieee80211_rate.h"
-#include "debugfs.h"
-
-int mac80211_open_file_generic(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-static const char *ieee80211_mode_str(int mode)
-{
-       switch (mode) {
-       case MODE_IEEE80211A:
-               return "IEEE 802.11a";
-       case MODE_IEEE80211B:
-               return "IEEE 802.11b";
-       case MODE_IEEE80211G:
-               return "IEEE 802.11g";
-       default:
-               return "UNKNOWN";
-       }
-}
-
-static ssize_t modes_read(struct file *file, char __user *userbuf,
-                         size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-       struct ieee80211_hw_mode *mode;
-       char buf[150], *p = buf;
-
-       /* FIXME: locking! */
-       list_for_each_entry(mode, &local->modes_list, list) {
-               p += scnprintf(p, sizeof(buf)+buf-p,
-                              "%s\n", ieee80211_mode_str(mode->mode));
-       }
-
-       return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
-}
-
-static const struct file_operations modes_ops = {
-       .read = modes_read,
-       .open = mac80211_open_file_generic,
-};
-
-#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)             \
-static ssize_t name## _read(struct file *file, char __user *userbuf,   \
-                           size_t count, loff_t *ppos)                 \
-{                                                                      \
-       struct ieee80211_local *local = file->private_data;             \
-       char buf[buflen];                                               \
-       int res;                                                        \
-                                                                       \
-       res = scnprintf(buf, buflen, fmt "\n", ##value);                \
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-}                                                                      \
-                                                                       \
-static const struct file_operations name## _ops = {                    \
-       .read = name## _read,                                           \
-       .open = mac80211_open_file_generic,                             \
-};
-
-#define DEBUGFS_ADD(name)                                              \
-       local->debugfs.name = debugfs_create_file(#name, 0444, phyd,    \
-                                                 local, &name## _ops);
-
-#define DEBUGFS_DEL(name)                                              \
-       debugfs_remove(local->debugfs.name);                            \
-       local->debugfs.name = NULL;
-
-
-DEBUGFS_READONLY_FILE(channel, 20, "%d",
-                     local->hw.conf.channel);
-DEBUGFS_READONLY_FILE(frequency, 20, "%d",
-                     local->hw.conf.freq);
-DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d",
-                     local->hw.conf.antenna_sel_tx);
-DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d",
-                     local->hw.conf.antenna_sel_rx);
-DEBUGFS_READONLY_FILE(bridge_packets, 20, "%d",
-                     local->bridge_packets);
-DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
-                     local->rts_threshold);
-DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
-                     local->fragmentation_threshold);
-DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
-                     local->short_retry_limit);
-DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
-                     local->long_retry_limit);
-DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
-                     local->total_ps_buffered);
-DEBUGFS_READONLY_FILE(mode, 20, "%s",
-                     ieee80211_mode_str(local->hw.conf.phymode));
-DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x",
-                     local->wep_iv & 0xffffff);
-DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s",
-                     local->rate_ctrl ? local->rate_ctrl->ops->name : "<unset>");
-
-/* statistics stuff */
-
-static inline int rtnl_lock_local(struct ieee80211_local *local)
-{
-       rtnl_lock();
-       if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) {
-               rtnl_unlock();
-               return -ENODEV;
-       }
-       return 0;
-}
-
-#define DEBUGFS_STATS_FILE(name, buflen, fmt, value...)                        \
-       DEBUGFS_READONLY_FILE(stats_ ##name, buflen, fmt, ##value)
-
-static ssize_t format_devstat_counter(struct ieee80211_local *local,
-       char __user *userbuf,
-       size_t count, loff_t *ppos,
-       int (*printvalue)(struct ieee80211_low_level_stats *stats, char *buf,
-                         int buflen))
-{
-       struct ieee80211_low_level_stats stats;
-       char buf[20];
-       int res;
-
-       if (!local->ops->get_stats)
-               return -EOPNOTSUPP;
-
-       res = rtnl_lock_local(local);
-       if (res)
-               return res;
-
-       res = local->ops->get_stats(local_to_hw(local), &stats);
-       rtnl_unlock();
-       if (!res)
-               res = printvalue(&stats, buf, sizeof(buf));
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res);
-}
-
-#define DEBUGFS_DEVSTATS_FILE(name)                                    \
-static int print_devstats_##name(struct ieee80211_low_level_stats *stats,\
-                                char *buf, int buflen)                 \
-{                                                                      \
-       return scnprintf(buf, buflen, "%u\n", stats->name);             \
-}                                                                      \
-static ssize_t stats_ ##name## _read(struct file *file,                        \
-                                    char __user *userbuf,              \
-                                    size_t count, loff_t *ppos)        \
-{                                                                      \
-       return format_devstat_counter(file->private_data,               \
-                                     userbuf,                          \
-                                     count,                            \
-                                     ppos,                             \
-                                     print_devstats_##name);           \
-}                                                                      \
-                                                                       \
-static const struct file_operations stats_ ##name## _ops = {           \
-       .read = stats_ ##name## _read,                                  \
-       .open = mac80211_open_file_generic,                             \
-};
-
-#define DEBUGFS_STATS_ADD(name)                                                \
-       local->debugfs.stats.name = debugfs_create_file(#name, 0444, statsd,\
-               local, &stats_ ##name## _ops);
-
-#define DEBUGFS_STATS_DEL(name)                                                \
-       debugfs_remove(local->debugfs.stats.name);                      \
-       local->debugfs.stats.name = NULL;
-
-DEBUGFS_STATS_FILE(transmitted_fragment_count, 20, "%u",
-                  local->dot11TransmittedFragmentCount);
-DEBUGFS_STATS_FILE(multicast_transmitted_frame_count, 20, "%u",
-                  local->dot11MulticastTransmittedFrameCount);
-DEBUGFS_STATS_FILE(failed_count, 20, "%u",
-                  local->dot11FailedCount);
-DEBUGFS_STATS_FILE(retry_count, 20, "%u",
-                  local->dot11RetryCount);
-DEBUGFS_STATS_FILE(multiple_retry_count, 20, "%u",
-                  local->dot11MultipleRetryCount);
-DEBUGFS_STATS_FILE(frame_duplicate_count, 20, "%u",
-                  local->dot11FrameDuplicateCount);
-DEBUGFS_STATS_FILE(received_fragment_count, 20, "%u",
-                  local->dot11ReceivedFragmentCount);
-DEBUGFS_STATS_FILE(multicast_received_frame_count, 20, "%u",
-                  local->dot11MulticastReceivedFrameCount);
-DEBUGFS_STATS_FILE(transmitted_frame_count, 20, "%u",
-                  local->dot11TransmittedFrameCount);
-DEBUGFS_STATS_FILE(wep_undecryptable_count, 20, "%u",
-                  local->dot11WEPUndecryptableCount);
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-DEBUGFS_STATS_FILE(tx_handlers_drop, 20, "%u",
-                  local->tx_handlers_drop);
-DEBUGFS_STATS_FILE(tx_handlers_queued, 20, "%u",
-                  local->tx_handlers_queued);
-DEBUGFS_STATS_FILE(tx_handlers_drop_unencrypted, 20, "%u",
-                  local->tx_handlers_drop_unencrypted);
-DEBUGFS_STATS_FILE(tx_handlers_drop_fragment, 20, "%u",
-                  local->tx_handlers_drop_fragment);
-DEBUGFS_STATS_FILE(tx_handlers_drop_wep, 20, "%u",
-                  local->tx_handlers_drop_wep);
-DEBUGFS_STATS_FILE(tx_handlers_drop_not_assoc, 20, "%u",
-                  local->tx_handlers_drop_not_assoc);
-DEBUGFS_STATS_FILE(tx_handlers_drop_unauth_port, 20, "%u",
-                  local->tx_handlers_drop_unauth_port);
-DEBUGFS_STATS_FILE(rx_handlers_drop, 20, "%u",
-                  local->rx_handlers_drop);
-DEBUGFS_STATS_FILE(rx_handlers_queued, 20, "%u",
-                  local->rx_handlers_queued);
-DEBUGFS_STATS_FILE(rx_handlers_drop_nullfunc, 20, "%u",
-                  local->rx_handlers_drop_nullfunc);
-DEBUGFS_STATS_FILE(rx_handlers_drop_defrag, 20, "%u",
-                  local->rx_handlers_drop_defrag);
-DEBUGFS_STATS_FILE(rx_handlers_drop_short, 20, "%u",
-                  local->rx_handlers_drop_short);
-DEBUGFS_STATS_FILE(rx_handlers_drop_passive_scan, 20, "%u",
-                  local->rx_handlers_drop_passive_scan);
-DEBUGFS_STATS_FILE(tx_expand_skb_head, 20, "%u",
-                  local->tx_expand_skb_head);
-DEBUGFS_STATS_FILE(tx_expand_skb_head_cloned, 20, "%u",
-                  local->tx_expand_skb_head_cloned);
-DEBUGFS_STATS_FILE(rx_expand_skb_head, 20, "%u",
-                  local->rx_expand_skb_head);
-DEBUGFS_STATS_FILE(rx_expand_skb_head2, 20, "%u",
-                  local->rx_expand_skb_head2);
-DEBUGFS_STATS_FILE(rx_handlers_fragments, 20, "%u",
-                  local->rx_handlers_fragments);
-DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u",
-                  local->tx_status_drop);
-
-static ssize_t stats_wme_rx_queue_read(struct file *file,
-                                      char __user *userbuf,
-                                      size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-       char buf[NUM_RX_DATA_QUEUES*15], *p = buf;
-       int i;
-
-       for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
-               p += scnprintf(p, sizeof(buf)+buf-p,
-                              "%u\n", local->wme_rx_queue[i]);
-
-       return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
-}
-
-static const struct file_operations stats_wme_rx_queue_ops = {
-       .read = stats_wme_rx_queue_read,
-       .open = mac80211_open_file_generic,
-};
-
-static ssize_t stats_wme_tx_queue_read(struct file *file,
-                                      char __user *userbuf,
-                                      size_t count, loff_t *ppos)
-{
-       struct ieee80211_local *local = file->private_data;
-       char buf[NUM_TX_DATA_QUEUES*15], *p = buf;
-       int i;
-
-       for (i = 0; i < NUM_TX_DATA_QUEUES; i++)
-               p += scnprintf(p, sizeof(buf)+buf-p,
-                              "%u\n", local->wme_tx_queue[i]);
-
-       return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
-}
-
-static const struct file_operations stats_wme_tx_queue_ops = {
-       .read = stats_wme_tx_queue_read,
-       .open = mac80211_open_file_generic,
-};
-#endif
-
-DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount);
-DEBUGFS_DEVSTATS_FILE(dot11RTSFailureCount);
-DEBUGFS_DEVSTATS_FILE(dot11FCSErrorCount);
-DEBUGFS_DEVSTATS_FILE(dot11RTSSuccessCount);
-
-
-void debugfs_hw_add(struct ieee80211_local *local)
-{
-       struct dentry *phyd = local->hw.wiphy->debugfsdir;
-       struct dentry *statsd;
-
-       if (!phyd)
-               return;
-
-       local->debugfs.stations = debugfs_create_dir("stations", phyd);
-       local->debugfs.keys = debugfs_create_dir("keys", phyd);
-
-       DEBUGFS_ADD(channel);
-       DEBUGFS_ADD(frequency);
-       DEBUGFS_ADD(antenna_sel_tx);
-       DEBUGFS_ADD(antenna_sel_rx);
-       DEBUGFS_ADD(bridge_packets);
-       DEBUGFS_ADD(rts_threshold);
-       DEBUGFS_ADD(fragmentation_threshold);
-       DEBUGFS_ADD(short_retry_limit);
-       DEBUGFS_ADD(long_retry_limit);
-       DEBUGFS_ADD(total_ps_buffered);
-       DEBUGFS_ADD(mode);
-       DEBUGFS_ADD(wep_iv);
-       DEBUGFS_ADD(modes);
-
-       statsd = debugfs_create_dir("statistics", phyd);
-       local->debugfs.statistics = statsd;
-
-       /* if the dir failed, don't put all the other things into the root! */
-       if (!statsd)
-               return;
-
-       DEBUGFS_STATS_ADD(transmitted_fragment_count);
-       DEBUGFS_STATS_ADD(multicast_transmitted_frame_count);
-       DEBUGFS_STATS_ADD(failed_count);
-       DEBUGFS_STATS_ADD(retry_count);
-       DEBUGFS_STATS_ADD(multiple_retry_count);
-       DEBUGFS_STATS_ADD(frame_duplicate_count);
-       DEBUGFS_STATS_ADD(received_fragment_count);
-       DEBUGFS_STATS_ADD(multicast_received_frame_count);
-       DEBUGFS_STATS_ADD(transmitted_frame_count);
-       DEBUGFS_STATS_ADD(wep_undecryptable_count);
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-       DEBUGFS_STATS_ADD(tx_handlers_drop);
-       DEBUGFS_STATS_ADD(tx_handlers_queued);
-       DEBUGFS_STATS_ADD(tx_handlers_drop_unencrypted);
-       DEBUGFS_STATS_ADD(tx_handlers_drop_fragment);
-       DEBUGFS_STATS_ADD(tx_handlers_drop_wep);
-       DEBUGFS_STATS_ADD(tx_handlers_drop_not_assoc);
-       DEBUGFS_STATS_ADD(tx_handlers_drop_unauth_port);
-       DEBUGFS_STATS_ADD(rx_handlers_drop);
-       DEBUGFS_STATS_ADD(rx_handlers_queued);
-       DEBUGFS_STATS_ADD(rx_handlers_drop_nullfunc);
-       DEBUGFS_STATS_ADD(rx_handlers_drop_defrag);
-       DEBUGFS_STATS_ADD(rx_handlers_drop_short);
-       DEBUGFS_STATS_ADD(rx_handlers_drop_passive_scan);
-       DEBUGFS_STATS_ADD(tx_expand_skb_head);
-       DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned);
-       DEBUGFS_STATS_ADD(rx_expand_skb_head);
-       DEBUGFS_STATS_ADD(rx_expand_skb_head2);
-       DEBUGFS_STATS_ADD(rx_handlers_fragments);
-       DEBUGFS_STATS_ADD(tx_status_drop);
-       DEBUGFS_STATS_ADD(wme_tx_queue);
-       DEBUGFS_STATS_ADD(wme_rx_queue);
-#endif
-       DEBUGFS_STATS_ADD(dot11ACKFailureCount);
-       DEBUGFS_STATS_ADD(dot11RTSFailureCount);
-       DEBUGFS_STATS_ADD(dot11FCSErrorCount);
-       DEBUGFS_STATS_ADD(dot11RTSSuccessCount);
-}
-
-void debugfs_hw_del(struct ieee80211_local *local)
-{
-       DEBUGFS_DEL(channel);
-       DEBUGFS_DEL(frequency);
-       DEBUGFS_DEL(antenna_sel_tx);
-       DEBUGFS_DEL(antenna_sel_rx);
-       DEBUGFS_DEL(bridge_packets);
-       DEBUGFS_DEL(rts_threshold);
-       DEBUGFS_DEL(fragmentation_threshold);
-       DEBUGFS_DEL(short_retry_limit);
-       DEBUGFS_DEL(long_retry_limit);
-       DEBUGFS_DEL(total_ps_buffered);
-       DEBUGFS_DEL(mode);
-       DEBUGFS_DEL(wep_iv);
-       DEBUGFS_DEL(modes);
-
-       DEBUGFS_STATS_DEL(transmitted_fragment_count);
-       DEBUGFS_STATS_DEL(multicast_transmitted_frame_count);
-       DEBUGFS_STATS_DEL(failed_count);
-       DEBUGFS_STATS_DEL(retry_count);
-       DEBUGFS_STATS_DEL(multiple_retry_count);
-       DEBUGFS_STATS_DEL(frame_duplicate_count);
-       DEBUGFS_STATS_DEL(received_fragment_count);
-       DEBUGFS_STATS_DEL(multicast_received_frame_count);
-       DEBUGFS_STATS_DEL(transmitted_frame_count);
-       DEBUGFS_STATS_DEL(wep_undecryptable_count);
-       DEBUGFS_STATS_DEL(num_scans);
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-       DEBUGFS_STATS_DEL(tx_handlers_drop);
-       DEBUGFS_STATS_DEL(tx_handlers_queued);
-       DEBUGFS_STATS_DEL(tx_handlers_drop_unencrypted);
-       DEBUGFS_STATS_DEL(tx_handlers_drop_fragment);
-       DEBUGFS_STATS_DEL(tx_handlers_drop_wep);
-       DEBUGFS_STATS_DEL(tx_handlers_drop_not_assoc);
-       DEBUGFS_STATS_DEL(tx_handlers_drop_unauth_port);
-       DEBUGFS_STATS_DEL(rx_handlers_drop);
-       DEBUGFS_STATS_DEL(rx_handlers_queued);
-       DEBUGFS_STATS_DEL(rx_handlers_drop_nullfunc);
-       DEBUGFS_STATS_DEL(rx_handlers_drop_defrag);
-       DEBUGFS_STATS_DEL(rx_handlers_drop_short);
-       DEBUGFS_STATS_DEL(rx_handlers_drop_passive_scan);
-       DEBUGFS_STATS_DEL(tx_expand_skb_head);
-       DEBUGFS_STATS_DEL(tx_expand_skb_head_cloned);
-       DEBUGFS_STATS_DEL(rx_expand_skb_head);
-       DEBUGFS_STATS_DEL(rx_expand_skb_head2);
-       DEBUGFS_STATS_DEL(rx_handlers_fragments);
-       DEBUGFS_STATS_DEL(tx_status_drop);
-       DEBUGFS_STATS_DEL(wme_tx_queue);
-       DEBUGFS_STATS_DEL(wme_rx_queue);
-#endif
-       DEBUGFS_STATS_DEL(dot11ACKFailureCount);
-       DEBUGFS_STATS_DEL(dot11RTSFailureCount);
-       DEBUGFS_STATS_DEL(dot11FCSErrorCount);
-       DEBUGFS_STATS_DEL(dot11RTSSuccessCount);
-
-       debugfs_remove(local->debugfs.statistics);
-       local->debugfs.statistics = NULL;
-       debugfs_remove(local->debugfs.stations);
-       local->debugfs.stations = NULL;
-       debugfs_remove(local->debugfs.keys);
-       local->debugfs.keys = NULL;
-}
diff --git a/package/mac80211/src/mac80211/debugfs.h b/package/mac80211/src/mac80211/debugfs.h
deleted file mode 100644 (file)
index dd25419..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __MAC80211_DEBUGFS_H
-#define __MAC80211_DEBUGFS_H
-
-#ifdef CONFIG_MAC80211_DEBUGFS
-extern void debugfs_hw_add(struct ieee80211_local *local);
-extern void debugfs_hw_del(struct ieee80211_local *local);
-extern int mac80211_open_file_generic(struct inode *inode, struct file *file);
-#else
-static inline void debugfs_hw_add(struct ieee80211_local *local)
-{
-       return;
-}
-static inline void debugfs_hw_del(struct ieee80211_local *local) {}
-#endif
-
-#endif /* __MAC80211_DEBUGFS_H */
diff --git a/package/mac80211/src/mac80211/debugfs_key.c b/package/mac80211/src/mac80211/debugfs_key.c
deleted file mode 100644 (file)
index 8e4a1bc..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright 2003-2005 Devicescape Software, Inc.
- * Copyright (c) 2006  Jiri Benc <jbenc@suse.cz>
- * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kobject.h>
-#include "ieee80211_i.h"
-#include "ieee80211_key.h"
-#include "debugfs.h"
-#include "debugfs_key.h"
-
-#define KEY_READ(name, prop, buflen, format_string)                    \
-static ssize_t key_##name##_read(struct file *file,                    \
-                                char __user *userbuf,                  \
-                                size_t count, loff_t *ppos)            \
-{                                                                      \
-       char buf[buflen];                                               \
-       struct ieee80211_key *key = file->private_data;                 \
-       int res = scnprintf(buf, buflen, format_string, key->prop);     \
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-}
-#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n")
-#define KEY_READ_X(name) KEY_READ(name, name, 20, "0x%x\n")
-
-#define KEY_OPS(name)                                                  \
-static const struct file_operations key_ ##name## _ops = {             \
-       .read = key_##name##_read,                                      \
-       .open = mac80211_open_file_generic,                             \
-}
-
-#define KEY_FILE(name, format)                                         \
-                KEY_READ_##format(name)                                \
-                KEY_OPS(name)
-
-#define KEY_CONF_READ(name, buflen, format_string)                     \
-       KEY_READ(conf_##name, conf.name, buflen, format_string)
-#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n")
-
-#define KEY_CONF_OPS(name)                                             \
-static const struct file_operations key_ ##name## _ops = {             \
-       .read = key_conf_##name##_read,                                 \
-       .open = mac80211_open_file_generic,                             \
-}
-
-#define KEY_CONF_FILE(name, format)                                    \
-                KEY_CONF_READ_##format(name)                           \
-                KEY_CONF_OPS(name)
-
-KEY_CONF_FILE(keylen, D);
-KEY_CONF_FILE(keyidx, D);
-KEY_CONF_FILE(hw_key_idx, D);
-KEY_FILE(flags, X);
-KEY_FILE(tx_rx_count, D);
-KEY_READ(ifindex, sdata->dev->ifindex, 20, "%d\n");
-KEY_OPS(ifindex);
-
-static ssize_t key_algorithm_read(struct file *file,
-                                 char __user *userbuf,
-                                 size_t count, loff_t *ppos)
-{
-       char *alg;
-       struct ieee80211_key *key = file->private_data;
-
-       switch (key->conf.alg) {
-       case ALG_WEP:
-               alg = "WEP\n";
-               break;
-       case ALG_TKIP:
-               alg = "TKIP\n";
-               break;
-       case ALG_CCMP:
-               alg = "CCMP\n";
-               break;
-       default:
-               return 0;
-       }
-       return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg));
-}
-KEY_OPS(algorithm);
-
-static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
-                               size_t count, loff_t *ppos)
-{
-       const u8 *tpn;
-       char buf[20];
-       int len;
-       struct ieee80211_key *key = file->private_data;
-
-       switch (key->conf.alg) {
-       case ALG_WEP:
-               len = scnprintf(buf, sizeof(buf), "\n");
-               break;
-       case ALG_TKIP:
-               len = scnprintf(buf, sizeof(buf), "%08x %04x\n",
-                               key->u.tkip.iv32,
-                               key->u.tkip.iv16);
-               break;
-       case ALG_CCMP:
-               tpn = key->u.ccmp.tx_pn;
-               len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
-                               tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
-               break;
-       default:
-               return 0;
-       }
-       return simple_read_from_buffer(userbuf, count, ppos, buf, len);
-}
-KEY_OPS(tx_spec);
-
-static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
-                               size_t count, loff_t *ppos)
-{
-       struct ieee80211_key *key = file->private_data;
-       char buf[14*NUM_RX_DATA_QUEUES+1], *p = buf;
-       int i, len;
-       const u8 *rpn;
-
-       switch (key->conf.alg) {
-       case ALG_WEP:
-               len = scnprintf(buf, sizeof(buf), "\n");
-               break;
-       case ALG_TKIP:
-               for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
-                       p += scnprintf(p, sizeof(buf)+buf-p,
-                                      "%08x %04x\n",
-                                      key->u.tkip.iv32_rx[i],
-                                      key->u.tkip.iv16_rx[i]);
-               len = p - buf;
-               break;
-       case ALG_CCMP:
-               for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
-                       rpn = key->u.ccmp.rx_pn[i];
-                       p += scnprintf(p, sizeof(buf)+buf-p,
-                                      "%02x%02x%02x%02x%02x%02x\n",
-                                      rpn[0], rpn[1], rpn[2],
-                                      rpn[3], rpn[4], rpn[5]);
-               }
-               len = p - buf;
-               break;
-       default:
-               return 0;
-       }
-       return simple_read_from_buffer(userbuf, count, ppos, buf, len);
-}
-KEY_OPS(rx_spec);
-
-static ssize_t key_replays_read(struct file *file, char __user *userbuf,
-                               size_t count, loff_t *ppos)
-{
-       struct ieee80211_key *key = file->private_data;
-       char buf[20];
-       int len;
-
-       if (key->conf.alg != ALG_CCMP)
-               return 0;
-       len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
-       return simple_read_from_buffer(userbuf, count, ppos, buf, len);
-}
-KEY_OPS(replays);
-
-static ssize_t key_key_read(struct file *file, char __user *userbuf,
-                           size_t count, loff_t *ppos)
-{
-       struct ieee80211_key *key = file->private_data;
-       int i, res, bufsize = 2 * key->conf.keylen + 2;
-       char *buf = kmalloc(bufsize, GFP_KERNEL);
-       char *p = buf;
-
-       for (i = 0; i < key->conf.keylen; i++)
-               p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]);
-       p += scnprintf(p, bufsize+buf-p, "\n");
-       res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
-       kfree(buf);
-       return res;
-}
-KEY_OPS(key);
-
-#define DEBUGFS_ADD(name) \
-       key->debugfs.name = debugfs_create_file(#name, 0400,\
-                               key->debugfs.dir, key, &key_##name##_ops);
-
-void ieee80211_debugfs_key_add(struct ieee80211_local *local,
-                              struct ieee80211_key *key)
-{
-       static int keycount;
-       char buf[20];
-
-       if (!local->debugfs.keys)
-               return;
-
-       sprintf(buf, "%d", keycount);
-       keycount++;
-       key->debugfs.dir = debugfs_create_dir(buf,
-                                       local->debugfs.keys);
-
-       if (!key->debugfs.dir)
-               return;
-
-       DEBUGFS_ADD(keylen);
-       DEBUGFS_ADD(flags);
-       DEBUGFS_ADD(keyidx);
-       DEBUGFS_ADD(hw_key_idx);
-       DEBUGFS_ADD(tx_rx_count);
-       DEBUGFS_ADD(algorithm);
-       DEBUGFS_ADD(tx_spec);
-       DEBUGFS_ADD(rx_spec);
-       DEBUGFS_ADD(replays);
-       DEBUGFS_ADD(key);
-       DEBUGFS_ADD(ifindex);
-};
-
-#define DEBUGFS_DEL(name) \
-       debugfs_remove(key->debugfs.name); key->debugfs.name = NULL;
-
-void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
-{
-       if (!key)
-               return;
-
-       DEBUGFS_DEL(keylen);
-       DEBUGFS_DEL(flags);
-       DEBUGFS_DEL(keyidx);
-       DEBUGFS_DEL(hw_key_idx);
-       DEBUGFS_DEL(tx_rx_count);
-       DEBUGFS_DEL(algorithm);
-       DEBUGFS_DEL(tx_spec);
-       DEBUGFS_DEL(rx_spec);
-       DEBUGFS_DEL(replays);
-       DEBUGFS_DEL(key);
-       DEBUGFS_DEL(ifindex);
-
-       debugfs_remove(key->debugfs.stalink);
-       key->debugfs.stalink = NULL;
-       debugfs_remove(key->debugfs.dir);
-       key->debugfs.dir = NULL;
-}
-void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
-{
-       char buf[50];
-
-       if (!sdata->debugfsdir)
-               return;
-
-       sprintf(buf, "../keys/%d", sdata->default_key->conf.keyidx);
-       sdata->debugfs.default_key =
-               debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
-}
-void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
-{
-       if (!sdata)
-               return;
-
-       debugfs_remove(sdata->debugfs.default_key);
-       sdata->debugfs.default_key = NULL;
-}
-void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key,
-                                   struct sta_info *sta)
-{
-       char buf[50];
-
-       if (!key->debugfs.dir)
-               return;
-
-       sprintf(buf, "../../stations/" MAC_FMT, MAC_ARG(sta->addr));
-       key->debugfs.stalink =
-               debugfs_create_symlink("station", key->debugfs.dir, buf);
-}
-
-void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
-                                  struct sta_info *sta)
-{
-       debugfs_remove(key->debugfs.stalink);
-       key->debugfs.stalink = NULL;
-}
diff --git a/package/mac80211/src/mac80211/debugfs_key.h b/package/mac80211/src/mac80211/debugfs_key.h
deleted file mode 100644 (file)
index aecfce3..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __MAC80211_DEBUGFS_KEY_H
-#define __MAC80211_DEBUGFS_KEY_H
-
-#ifdef CONFIG_MAC80211_DEBUGFS
-void ieee80211_debugfs_key_add(struct ieee80211_local *local,
-                              struct ieee80211_key *key);
-void ieee80211_debugfs_key_remove(struct ieee80211_key *key);
-void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata);
-void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata);
-void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key,
-                                   struct sta_info *sta);
-void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
-                                  struct sta_info *sta);
-#else
-static inline void ieee80211_debugfs_key_add(struct ieee80211_local *local,
-                                            struct ieee80211_key *key)
-{}
-static inline void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
-{}
-static inline void ieee80211_debugfs_key_add_default(
-       struct ieee80211_sub_if_data *sdata)
-{}
-static inline void ieee80211_debugfs_key_remove_default(
-       struct ieee80211_sub_if_data *sdata)
-{}
-static inline void ieee80211_debugfs_key_sta_link(
-       struct ieee80211_key *key, struct sta_info *sta)
-{}
-static inline void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
-                                                struct sta_info *sta)
-{}
-#endif
-
-#endif /* __MAC80211_DEBUGFS_KEY_H */
diff --git a/package/mac80211/src/mac80211/debugfs_netdev.c b/package/mac80211/src/mac80211/debugfs_netdev.c
deleted file mode 100644 (file)
index 2b5e761..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (c) 2006  Jiri Benc <jbenc@suse.cz>
- * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/if.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/notifier.h>
-#include <net/mac80211.h>
-#include <net/cfg80211.h>
-#include "ieee80211_i.h"
-#include "ieee80211_rate.h"
-#include "debugfs.h"
-#include "debugfs_netdev.h"
-
-static ssize_t ieee80211_if_read(
-       struct ieee80211_sub_if_data *sdata,
-       char __user *userbuf,
-       size_t count, loff_t *ppos,
-       ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int))
-{
-       char buf[70];
-       ssize_t ret = -EINVAL;
-
-       read_lock(&dev_base_lock);
-       if (sdata->dev->reg_state == NETREG_REGISTERED) {
-               ret = (*format)(sdata, buf, sizeof(buf));
-               ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret);
-       }
-       read_unlock(&dev_base_lock);
-       return ret;
-}
-
-#define IEEE80211_IF_FMT(name, field, format_string)                   \
-static ssize_t ieee80211_if_fmt_##name(                                        \
-       const struct ieee80211_sub_if_data *sdata, char *buf,           \
-       int buflen)                                                     \
-{                                                                      \
-       return scnprintf(buf, buflen, format_string, sdata->field);     \
-}
-#define IEEE80211_IF_FMT_DEC(name, field)                              \
-               IEEE80211_IF_FMT(name, field, "%d\n")
-#define IEEE80211_IF_FMT_HEX(name, field)                              \
-               IEEE80211_IF_FMT(name, field, "%#x\n")
-#define IEEE80211_IF_FMT_SIZE(name, field)                             \
-               IEEE80211_IF_FMT(name, field, "%zd\n")
-
-#define IEEE80211_IF_FMT_ATOMIC(name, field)                           \
-static ssize_t ieee80211_if_fmt_##name(                                        \
-       const struct ieee80211_sub_if_data *sdata,                      \
-       char *buf, int buflen)                                          \
-{                                                                      \
-       return scnprintf(buf, buflen, "%d\n", atomic_read(&sdata->field));\
-}
-
-#define IEEE80211_IF_FMT_MAC(name, field)                              \
-static ssize_t ieee80211_if_fmt_##name(                                        \
-       const struct ieee80211_sub_if_data *sdata, char *buf,           \
-       int buflen)                                                     \
-{                                                                      \
-       return scnprintf(buf, buflen, MAC_FMT "\n", MAC_ARG(sdata->field));\
-}
-
-#define __IEEE80211_IF_FILE(name)                                      \
-static ssize_t ieee80211_if_read_##name(struct file *file,             \
-                                       char __user *userbuf,           \
-                                       size_t count, loff_t *ppos)     \
-{                                                                      \
-       return ieee80211_if_read(file->private_data,                    \
-                                userbuf, count, ppos,                  \
-                                ieee80211_if_fmt_##name);              \
-}                                                                      \
-static const struct file_operations name##_ops = {                     \
-       .read = ieee80211_if_read_##name,                               \
-       .open = mac80211_open_file_generic,                             \
-}
-
-#define IEEE80211_IF_FILE(name, field, format)                         \
-               IEEE80211_IF_FMT_##format(name, field)                  \
-               __IEEE80211_IF_FILE(name)
-
-/* common attributes */
-IEEE80211_IF_FILE(channel_use, channel_use, DEC);
-IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
-IEEE80211_IF_FILE(eapol, eapol, DEC);
-IEEE80211_IF_FILE(ieee8021_x, ieee802_1x, DEC);
-
-/* STA/IBSS attributes */
-IEEE80211_IF_FILE(state, u.sta.state, DEC);
-IEEE80211_IF_FILE(bssid, u.sta.bssid, MAC);
-IEEE80211_IF_FILE(prev_bssid, u.sta.prev_bssid, MAC);
-IEEE80211_IF_FILE(ssid_len, u.sta.ssid_len, SIZE);
-IEEE80211_IF_FILE(aid, u.sta.aid, DEC);
-IEEE80211_IF_FILE(ap_capab, u.sta.ap_capab, HEX);
-IEEE80211_IF_FILE(capab, u.sta.capab, HEX);
-IEEE80211_IF_FILE(extra_ie_len, u.sta.extra_ie_len, SIZE);
-IEEE80211_IF_FILE(auth_tries, u.sta.auth_tries, DEC);
-IEEE80211_IF_FILE(assoc_tries, u.sta.assoc_tries, DEC);
-IEEE80211_IF_FILE(auth_algs, u.sta.auth_algs, HEX);
-IEEE80211_IF_FILE(auth_alg, u.sta.auth_alg, DEC);
-IEEE80211_IF_FILE(auth_transaction, u.sta.auth_transaction, DEC);
-
-static ssize_t ieee80211_if_fmt_flags(
-       const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-{
-       return scnprintf(buf, buflen, "%s%s%s%s%s%s%s\n",
-                sdata->u.sta.flags & IEEE80211_STA_SSID_SET ? "SSID\n" : "",
-                sdata->u.sta.flags & IEEE80211_STA_BSSID_SET ? "BSSID\n" : "",
-                sdata->u.sta.flags & IEEE80211_STA_PREV_BSSID_SET ? "prev BSSID\n" : "",
-                sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "",
-                sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "",
-                sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "",
-                sdata->flags & IEEE80211_SDATA_USE_PROTECTION ? "CTS prot\n" : "");
-}
-__IEEE80211_IF_FILE(flags);
-
-/* AP attributes */
-IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
-IEEE80211_IF_FILE(dtim_period, u.ap.dtim_period, DEC);
-IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
-IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC);
-IEEE80211_IF_FILE(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC);
-IEEE80211_IF_FILE(max_ratectrl_rateidx, u.ap.max_ratectrl_rateidx, DEC);
-
-static ssize_t ieee80211_if_fmt_num_buffered_multicast(
-       const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-{
-       return scnprintf(buf, buflen, "%u\n",
-                        skb_queue_len(&sdata->u.ap.ps_bc_buf));
-}
-__IEEE80211_IF_FILE(num_buffered_multicast);
-
-static ssize_t ieee80211_if_fmt_beacon_head_len(
-       const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-{
-       if (sdata->u.ap.beacon_head)
-               return scnprintf(buf, buflen, "%d\n",
-                                sdata->u.ap.beacon_head_len);
-       return scnprintf(buf, buflen, "\n");
-}
-__IEEE80211_IF_FILE(beacon_head_len);
-
-static ssize_t ieee80211_if_fmt_beacon_tail_len(
-       const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-{
-       if (sdata->u.ap.beacon_tail)
-               return scnprintf(buf, buflen, "%d\n",
-                                sdata->u.ap.beacon_tail_len);
-       return scnprintf(buf, buflen, "\n");
-}
-__IEEE80211_IF_FILE(beacon_tail_len);
-
-/* WDS attributes */
-IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
-
-#define DEBUGFS_ADD(name, type)\
-       sdata->debugfs.type.name = debugfs_create_file(#name, 0444,\
-               sdata->debugfsdir, sdata, &name##_ops);
-
-static void add_sta_files(struct ieee80211_sub_if_data *sdata)
-{
-       DEBUGFS_ADD(channel_use, sta);
-       DEBUGFS_ADD(drop_unencrypted, sta);
-       DEBUGFS_ADD(eapol, sta);
-       DEBUGFS_ADD(ieee8021_x, sta);
-       DEBUGFS_ADD(state, sta);
-       DEBUGFS_ADD(bssid, sta);
-       DEBUGFS_ADD(prev_bssid, sta);
-       DEBUGFS_ADD(ssid_len, sta);
-       DEBUGFS_ADD(aid, sta);
-       DEBUGFS_ADD(ap_capab, sta);
-       DEBUGFS_ADD(capab, sta);
-       DEBUGFS_ADD(extra_ie_len, sta);
-       DEBUGFS_ADD(auth_tries, sta);
-       DEBUGFS_ADD(assoc_tries, sta);
-       DEBUGFS_ADD(auth_algs, sta);
-       DEBUGFS_ADD(auth_alg, sta);
-       DEBUGFS_ADD(auth_transaction, sta);
-       DEBUGFS_ADD(flags, sta);
-}
-
-static void add_ap_files(struct ieee80211_sub_if_data *sdata)
-{
-       DEBUGFS_ADD(channel_use, ap);
-       DEBUGFS_ADD(drop_unencrypted, ap);
-       DEBUGFS_ADD(eapol, ap);
-       DEBUGFS_ADD(ieee8021_x, ap);
-       DEBUGFS_ADD(num_sta_ps, ap);
-       DEBUGFS_ADD(dtim_period, ap);
-       DEBUGFS_ADD(dtim_count, ap);
-       DEBUGFS_ADD(num_beacons, ap);
-       DEBUGFS_ADD(force_unicast_rateidx, ap);
-       DEBUGFS_ADD(max_ratectrl_rateidx, ap);
-       DEBUGFS_ADD(num_buffered_multicast, ap);
-       DEBUGFS_ADD(beacon_head_len, ap);
-       DEBUGFS_ADD(beacon_tail_len, ap);
-}
-
-static void add_wds_files(struct ieee80211_sub_if_data *sdata)
-{
-       DEBUGFS_ADD(channel_use, wds);
-       DEBUGFS_ADD(drop_unencrypted, wds);
-       DEBUGFS_ADD(eapol, wds);
-       DEBUGFS_ADD(ieee8021_x, wds);
-       DEBUGFS_ADD(peer, wds);
-}
-
-static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
-{
-       DEBUGFS_ADD(channel_use, vlan);
-       DEBUGFS_ADD(drop_unencrypted, vlan);
-       DEBUGFS_ADD(eapol, vlan);
-       DEBUGFS_ADD(ieee8021_x, vlan);
-}
-
-static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
-{
-}
-
-static void add_files(struct ieee80211_sub_if_data *sdata)
-{
-       if (!sdata->debugfsdir)
-               return;
-
-       switch (sdata->type) {
-       case IEEE80211_IF_TYPE_STA:
-       case IEEE80211_IF_TYPE_IBSS:
-               add_sta_files(sdata);
-               break;
-       case IEEE80211_IF_TYPE_AP:
-               add_ap_files(sdata);
-               break;
-       case IEEE80211_IF_TYPE_WDS:
-               add_wds_files(sdata);
-               break;
-       case IEEE80211_IF_TYPE_MNTR:
-               add_monitor_files(sdata);
-               break;
-       case IEEE80211_IF_TYPE_VLAN:
-               add_vlan_files(sdata);
-               break;
-       default:
-               break;
-       }
-}
-
-#define DEBUGFS_DEL(name, type)                                        \
-       do {                                                    \
-               debugfs_remove(sdata->debugfs.type.name);       \
-               sdata->debugfs.type.name = NULL;                \
-       } while (0)
-
-static void del_sta_files(struct ieee80211_sub_if_data *sdata)
-{
-       DEBUGFS_DEL(channel_use, sta);
-       DEBUGFS_DEL(drop_unencrypted, sta);
-       DEBUGFS_DEL(eapol, sta);
-       DEBUGFS_DEL(ieee8021_x, sta);
-       DEBUGFS_DEL(state, sta);
-       DEBUGFS_DEL(bssid, sta);
-       DEBUGFS_DEL(prev_bssid, sta);
-       DEBUGFS_DEL(ssid_len, sta);
-       DEBUGFS_DEL(aid, sta);
-       DEBUGFS_DEL(ap_capab, sta);
-       DEBUGFS_DEL(capab, sta);
-       DEBUGFS_DEL(extra_ie_len, sta);
-       DEBUGFS_DEL(auth_tries, sta);
-       DEBUGFS_DEL(assoc_tries, sta);
-       DEBUGFS_DEL(auth_algs, sta);
-       DEBUGFS_DEL(auth_alg, sta);
-       DEBUGFS_DEL(auth_transaction, sta);
-       DEBUGFS_DEL(flags, sta);
-}
-
-static void del_ap_files(struct ieee80211_sub_if_data *sdata)
-{
-       DEBUGFS_DEL(channel_use, ap);
-       DEBUGFS_DEL(drop_unencrypted, ap);
-       DEBUGFS_DEL(eapol, ap);
-       DEBUGFS_DEL(ieee8021_x, ap);
-       DEBUGFS_DEL(num_sta_ps, ap);
-       DEBUGFS_DEL(dtim_period, ap);
-       DEBUGFS_DEL(dtim_count, ap);
-       DEBUGFS_DEL(num_beacons, ap);
-       DEBUGFS_DEL(force_unicast_rateidx, ap);
-       DEBUGFS_DEL(max_ratectrl_rateidx, ap);
-       DEBUGFS_DEL(num_buffered_multicast, ap);
-       DEBUGFS_DEL(beacon_head_len, ap);
-       DEBUGFS_DEL(beacon_tail_len, ap);
-}
-
-static void del_wds_files(struct ieee80211_sub_if_data *sdata)
-{
-       DEBUGFS_DEL(channel_use, wds);
-       DEBUGFS_DEL(drop_unencrypted, wds);
-       DEBUGFS_DEL(eapol, wds);
-       DEBUGFS_DEL(ieee8021_x, wds);
-       DEBUGFS_DEL(peer, wds);
-}
-
-static void del_vlan_files(struct ieee80211_sub_if_data *sdata)
-{
-       DEBUGFS_DEL(channel_use, vlan);
-       DEBUGFS_DEL(drop_unencrypted, vlan);
-       DEBUGFS_DEL(eapol, vlan);
-       DEBUGFS_DEL(ieee8021_x, vlan);
-}
-
-static void del_monitor_files(struct ieee80211_sub_if_data *sdata)
-{
-}
-
-static void del_files(struct ieee80211_sub_if_data *sdata, int type)
-{
-       if (!sdata->debugfsdir)
-               return;
-
-       switch (type) {
-       case IEEE80211_IF_TYPE_STA:
-       case IEEE80211_IF_TYPE_IBSS:
-               del_sta_files(sdata);
-               break;
-       case IEEE80211_IF_TYPE_AP:
-               del_ap_files(sdata);
-               break;
-       case IEEE80211_IF_TYPE_WDS:
-               del_wds_files(sdata);
-               break;
-       case IEEE80211_IF_TYPE_MNTR:
-               del_monitor_files(sdata);
-               break;
-       case IEEE80211_IF_TYPE_VLAN:
-               del_vlan_files(sdata);
-               break;
-       default:
-               break;
-       }
-}
-
-static int notif_registered;
-
-void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
-{
-       char buf[10+IFNAMSIZ];
-
-       if (!notif_registered)
-               return;
-
-       sprintf(buf, "netdev:%s", sdata->dev->name);
-       sdata->debugfsdir = debugfs_create_dir(buf,
-               sdata->local->hw.wiphy->debugfsdir);
-}
-
-void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
-{
-       del_files(sdata, sdata->type);
-       debugfs_remove(sdata->debugfsdir);
-       sdata->debugfsdir = NULL;
-}
-
-void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata,
-                                     int oldtype)
-{
-       del_files(sdata, oldtype);
-       add_files(sdata);
-}
-
-static int netdev_notify(struct notifier_block * nb,
-                        unsigned long state,
-                        void *ndev)
-{
-       struct net_device *dev = ndev;
-       struct dentry *dir;
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       char buf[10+IFNAMSIZ];
-
-       if (state != NETDEV_CHANGENAME)
-               return 0;
-
-       if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
-               return 0;
-
-       if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
-               return 0;
-
-       sprintf(buf, "netdev:%s", dev->name);
-       dir = sdata->debugfsdir;
-       if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
-               printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
-                      "dir to %s\n", buf);
-
-       return 0;
-}
-
-static struct notifier_block mac80211_debugfs_netdev_notifier = {
-       .notifier_call = netdev_notify,
-};
-
-void ieee80211_debugfs_netdev_init(void)
-{
-       int err;
-
-       err = register_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
-       if (err) {
-               printk(KERN_ERR
-                      "mac80211: failed to install netdev notifier,"
-                      " disabling per-netdev debugfs!\n");
-       } else
-               notif_registered = 1;
-}
-
-void ieee80211_debugfs_netdev_exit(void)
-{
-       unregister_netdevice_notifier(&mac80211_debugfs_netdev_notifier);
-       notif_registered = 0;
-}
diff --git a/package/mac80211/src/mac80211/debugfs_netdev.h b/package/mac80211/src/mac80211/debugfs_netdev.h
deleted file mode 100644 (file)
index a690071..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* routines exported for debugfs handling */
-
-#ifndef __IEEE80211_DEBUGFS_NETDEV_H
-#define __IEEE80211_DEBUGFS_NETDEV_H
-
-#ifdef CONFIG_MAC80211_DEBUGFS
-void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata);
-void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata);
-void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata,
-                                    int oldtype);
-void ieee80211_debugfs_netdev_init(void);
-void ieee80211_debugfs_netdev_exit(void);
-#else
-static inline void ieee80211_debugfs_add_netdev(
-       struct ieee80211_sub_if_data *sdata)
-{}
-static inline void ieee80211_debugfs_remove_netdev(
-       struct ieee80211_sub_if_data *sdata)
-{}
-static inline void ieee80211_debugfs_change_if_type(
-       struct ieee80211_sub_if_data *sdata, int oldtype)
-{}
-static inline void ieee80211_debugfs_netdev_init(void)
-{}
-
-static inline void ieee80211_debugfs_netdev_exit(void)
-{}
-#endif
-
-#endif /* __IEEE80211_DEBUGFS_NETDEV_H */
diff --git a/package/mac80211/src/mac80211/debugfs_sta.c b/package/mac80211/src/mac80211/debugfs_sta.c
deleted file mode 100644 (file)
index 4ea0ea7..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright 2003-2005 Devicescape Software, Inc.
- * Copyright (c) 2006  Jiri Benc <jbenc@suse.cz>
- * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/debugfs.h>
-#include <linux/ieee80211.h>
-#include "ieee80211_i.h"
-#include "debugfs.h"
-#include "debugfs_sta.h"
-#include "sta_info.h"
-
-/* sta attributtes */
-
-#define STA_READ(name, buflen, field, format_string)                   \
-static ssize_t sta_ ##name## _read(struct file *file,                  \
-                                  char __user *userbuf,                \
-                                  size_t count, loff_t *ppos)          \
-{                                                                      \
-       int res;                                                        \
-       struct sta_info *sta = file->private_data;                      \
-       char buf[buflen];                                               \
-       res = scnprintf(buf, buflen, format_string, sta->field);        \
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-}
-#define STA_READ_D(name, field) STA_READ(name, 20, field, "%d\n")
-#define STA_READ_U(name, field) STA_READ(name, 20, field, "%u\n")
-#define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n")
-#define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n")
-
-#define STA_READ_RATE(name, field)                                     \
-static ssize_t sta_##name##_read(struct file *file,                    \
-                                char __user *userbuf,                  \
-                                size_t count, loff_t *ppos)            \
-{                                                                      \
-       struct sta_info *sta = file->private_data;                      \
-       struct ieee80211_local *local = wdev_priv(sta->dev->ieee80211_ptr);\
-       struct ieee80211_hw_mode *mode = local->oper_hw_mode;           \
-       char buf[20];                                                   \
-       int res = scnprintf(buf, sizeof(buf), "%d\n",                   \
-                           (sta->field >= 0 &&                         \
-                           sta->field < mode->num_rates) ?             \
-                           mode->rates[sta->field].rate : -1);         \
-       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-}
-
-#define STA_OPS(name)                                                  \
-static const struct file_operations sta_ ##name## _ops = {             \
-       .read = sta_##name##_read,                                      \
-       .open = mac80211_open_file_generic,                             \
-}
-
-#define STA_FILE(name, field, format)                                  \
-               STA_READ_##format(name, field)                          \
-               STA_OPS(name)
-
-STA_FILE(aid, aid, D);
-STA_FILE(dev, dev->name, S);
-STA_FILE(rx_packets, rx_packets, LU);
-STA_FILE(tx_packets, tx_packets, LU);
-STA_FILE(rx_bytes, rx_bytes, LU);
-STA_FILE(tx_bytes, tx_bytes, LU);
-STA_FILE(rx_duplicates, num_duplicates, LU);
-STA_FILE(rx_fragments, rx_fragments, LU);
-STA_FILE(rx_dropped, rx_dropped, LU);
-STA_FILE(tx_fragments, tx_fragments, LU);
-STA_FILE(tx_filtered, tx_filtered_count, LU);
-STA_FILE(txrate, txrate, RATE);
-STA_FILE(last_txrate, last_txrate, RATE);
-STA_FILE(tx_retry_failed, tx_retry_failed, LU);
-STA_FILE(tx_retry_count, tx_retry_count, LU);
-STA_FILE(last_rssi, last_rssi, D);
-STA_FILE(last_signal, last_signal, D);
-STA_FILE(last_noise, last_noise, D);
-STA_FILE(channel_use, channel_use, D);
-STA_FILE(wep_weak_iv_count, wep_weak_iv_count, D);
-
-static ssize_t sta_flags_read(struct file