Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
David S. Miller [Sat, 22 Nov 2008 01:05:11 +0000 (17:05 -0800)]
119 files changed:
Documentation/networking/mac80211_hwsim/README
MAINTAINERS
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/ath5k/phy.c
drivers/net/wireless/ath5k/reset.c
drivers/net/wireless/ath9k/hw.c
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/ath9k/rc.c
drivers/net/wireless/ath9k/recv.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43legacy/b43legacy.h
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/hostap/Kconfig
drivers/net/wireless/hostap/hostap.h
drivers/net/wireless/hostap/hostap_80211.h
drivers/net/wireless/hostap/hostap_80211_rx.c
drivers/net/wireless/hostap/hostap_80211_tx.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_ap.h
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/hostap/hostap_proc.c
drivers/net/wireless/hostap/hostap_wlan.h
drivers/net/wireless/ipw2x00/Kconfig [new file with mode: 0644]
drivers/net/wireless/ipw2x00/Makefile [new file with mode: 0644]
drivers/net/wireless/ipw2x00/ipw2100.c [moved from drivers/net/wireless/ipw2100.c with 99% similarity]
drivers/net/wireless/ipw2x00/ipw2100.h [moved from drivers/net/wireless/ipw2100.h with 100% similarity]
drivers/net/wireless/ipw2x00/ipw2200.c [moved from drivers/net/wireless/ipw2200.c with 99% similarity]
drivers/net/wireless/ipw2x00/ipw2200.h [moved from drivers/net/wireless/ipw2200.h with 100% similarity]
drivers/net/wireless/ipw2x00/libipw_geo.c [moved from net/ieee80211/ieee80211_geo.c with 100% similarity]
drivers/net/wireless/ipw2x00/libipw_module.c [moved from net/ieee80211/ieee80211_module.c with 93% similarity]
drivers/net/wireless/ipw2x00/libipw_rx.c [moved from net/ieee80211/ieee80211_rx.c with 99% similarity]
drivers/net/wireless/ipw2x00/libipw_tx.c [moved from net/ieee80211/ieee80211_tx.c with 98% similarity]
drivers/net/wireless/ipw2x00/libipw_wx.c [moved from net/ieee80211/ieee80211_wx.c with 93% similarity]
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/iwl-4965-hw.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000-hw.h
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-fh.h
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-spectrum.c [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-spectrum.h
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/cmd.h
drivers/net/wireless/libertas/defs.h
drivers/net/wireless/libertas/ethtool.c
drivers/net/wireless/libertas/host.h
drivers/net/wireless/libertas/hostcmd.h
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/orinoco/orinoco.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00leds.c
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00pci.h
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt2x00usb.h
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtl818x/Makefile [new file with mode: 0644]
drivers/net/wireless/rtl818x/rtl8180.h [moved from drivers/net/wireless/rtl8180.h with 100% similarity]
drivers/net/wireless/rtl818x/rtl8180_dev.c [moved from drivers/net/wireless/rtl8180_dev.c with 98% similarity]
drivers/net/wireless/rtl818x/rtl8180_grf5101.c [moved from drivers/net/wireless/rtl8180_grf5101.c with 100% similarity]
drivers/net/wireless/rtl818x/rtl8180_grf5101.h [moved from drivers/net/wireless/rtl8180_grf5101.h with 100% similarity]
drivers/net/wireless/rtl818x/rtl8180_max2820.c [moved from drivers/net/wireless/rtl8180_max2820.c with 100% similarity]
drivers/net/wireless/rtl818x/rtl8180_max2820.h [moved from drivers/net/wireless/rtl8180_max2820.h with 100% similarity]
drivers/net/wireless/rtl818x/rtl8180_rtl8225.c [moved from drivers/net/wireless/rtl8180_rtl8225.c with 98% similarity]
drivers/net/wireless/rtl818x/rtl8180_rtl8225.h [moved from drivers/net/wireless/rtl8180_rtl8225.h with 100% similarity]
drivers/net/wireless/rtl818x/rtl8180_sa2400.c [moved from drivers/net/wireless/rtl8180_sa2400.c with 100% similarity]
drivers/net/wireless/rtl818x/rtl8180_sa2400.h [moved from drivers/net/wireless/rtl8180_sa2400.h with 100% similarity]
drivers/net/wireless/rtl818x/rtl8187.h [moved from drivers/net/wireless/rtl8187.h with 100% similarity]
drivers/net/wireless/rtl818x/rtl8187_dev.c [moved from drivers/net/wireless/rtl8187_dev.c with 99% similarity]
drivers/net/wireless/rtl818x/rtl8187_rtl8225.c [moved from drivers/net/wireless/rtl8187_rtl8225.c with 100% similarity]
drivers/net/wireless/rtl818x/rtl8187_rtl8225.h [moved from drivers/net/wireless/rtl8187_rtl8225.h with 100% similarity]
drivers/net/wireless/rtl818x/rtl818x.h [moved from drivers/net/wireless/rtl818x.h with 98% similarity]
drivers/net/wireless/zd1201.c
drivers/ssb/main.c
drivers/ssb/pcihost_wrapper.c
include/net/ieee80211.h
include/net/ieee80211_crypt.h [deleted file]
include/net/lib80211.h
include/net/mac80211.h
net/Kconfig
net/Makefile
net/ieee80211/Kconfig [deleted file]
net/ieee80211/Makefile [deleted file]
net/ieee80211/ieee80211_crypt.c [deleted file]
net/mac80211/iface.c
net/mac80211/mlme.c
net/mac80211/rc80211_pid_algo.c
net/mac80211/sta_info.h
net/wireless/Kconfig
net/wireless/Makefile
net/wireless/lib80211.c
net/wireless/lib80211_crypt_ccmp.c [moved from net/ieee80211/ieee80211_crypt_ccmp.c with 76% similarity]
net/wireless/lib80211_crypt_tkip.c [moved from net/ieee80211/ieee80211_crypt_tkip.c with 82% similarity]
net/wireless/lib80211_crypt_wep.c [moved from net/ieee80211/ieee80211_crypt_wep.c with 74% similarity]
net/wireless/sysfs.c

index 2ff8ccb..24ac91d 100644 (file)
@@ -50,10 +50,6 @@ associates with the AP. hostapd and wpa_supplicant are used to take
 care of WPA2-PSK authentication. In addition, hostapd is also
 processing access point side of association.
 
-Please note that the current Linux kernel does not enable AP mode, so a
-simple patch is needed to enable AP mode selection:
-http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch
-
 
 # Build mac80211_hwsim as part of kernel configuration
 
@@ -65,3 +61,8 @@ hostapd hostapd.conf
 
 # Run wpa_supplicant (station) for wlan1
 wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf
+
+
+More test cases are available in hostap.git:
+git://w1.fi/srv/git/hostap.git and mac80211_hwsim/tests subdirectory
+(http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=tree;f=mac80211_hwsim/tests)
index ecfcc24..7b98da9 100644 (file)
@@ -3608,15 +3608,25 @@ L:      linux-hams@vger.kernel.org
 W:     http://www.linux-ax25.org/
 S:     Maintained
 
-RTL818X WIRELESS DRIVER
-P:     Michael Wu
-M:     flamingice@sourmilk.net
-P:     Andrea Merello
-M:     andreamrl@tiscali.it
+RTL8180 WIRELESS DRIVER
+P:     John W. Linville
+M:     linville@tuxdriver.com
 L:     linux-wireless@vger.kernel.org
 W:     http://linuxwireless.org/
-T:     git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git
-S:     Maintained
+T:     git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git
+S:     Maintained
+
+RTL8187 WIRELESS DRIVER
+P:      Herton Ronaldo Krzesinski
+M:      herton@mandriva.com.br
+P:      Hin-Tak Leung
+M       htl10@users.sourceforge.net
+P:      Larry Finger
+M:      Larry.Finger@lwfinger.net
+L:      linux-wireless@vger.kernel.org
+W:      http://linuxwireless.org/
+T:      git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git
+S:      Maintained
 
 S3 SAVAGE FRAMEBUFFER DRIVER
 P:     Antonino Daplas
index 42afaed..84b49c8 100644 (file)
@@ -123,150 +123,6 @@ config PCMCIA_RAYCS
          To compile this driver as a module, choose M here: the module will be
          called ray_cs.  If unsure, say N.
 
-config IPW2100
-       tristate "Intel PRO/Wireless 2100 Network Connection"
-       depends on PCI && WLAN_80211
-       select WIRELESS_EXT
-       select FW_LOADER
-       select IEEE80211
-       ---help---
-          A driver for the Intel PRO/Wireless 2100 Network 
-         Connection 802.11b wireless network adapter.
-
-          See <file:Documentation/networking/README.ipw2100> for information on
-          the capabilities currently enabled in this driver and for tips
-          for debugging issues and problems.
-
-         In order to use this driver, you will need a firmware image for it.
-          You can obtain the firmware from
-         <http://ipw2100.sf.net/>.  Once you have the firmware image, you 
-         will need to place it in /lib/firmware.
-
-          You will also very likely need the Wireless Tools in order to
-          configure your card:
-
-          <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
-
-          It is recommended that you compile this driver as a module (M)
-          rather than built-in (Y). This driver requires firmware at device
-          initialization time, and when built-in this typically happens
-          before the filesystem is accessible (hence firmware will be
-          unavailable and initialization will fail). If you do choose to build
-          this driver into your kernel image, you can avoid this problem by
-          including the firmware and a firmware loader in an initramfs.
-config IPW2100_MONITOR
-        bool "Enable promiscuous mode"
-        depends on IPW2100
-        ---help---
-         Enables promiscuous/monitor mode support for the ipw2100 driver.
-         With this feature compiled into the driver, you can switch to 
-         promiscuous mode via the Wireless Tool's Monitor mode.  While in this
-         mode, no packets can be sent.
-
-config IPW2100_DEBUG
-       bool "Enable full debugging output in IPW2100 module."
-       depends on IPW2100
-       ---help---
-         This option will enable debug tracing output for the IPW2100.  
-
-         This will result in the kernel module being ~60k larger.  You can 
-         control which debug output is sent to the kernel log by setting the 
-         value in 
-
-         /sys/bus/pci/drivers/ipw2100/debug_level
-
-         This entry will only exist if this option is enabled.
-
-         If you are not trying to debug or develop the IPW2100 driver, you 
-         most likely want to say N here.
-
-config IPW2200
-       tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
-       depends on PCI && WLAN_80211
-       select WIRELESS_EXT
-       select FW_LOADER
-       select IEEE80211
-       ---help---
-          A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
-         Connection adapters. 
-
-          See <file:Documentation/networking/README.ipw2200> for 
-         information on the capabilities currently enabled in this 
-         driver and for tips for debugging issues and problems.
-
-         In order to use this driver, you will need a firmware image for it.
-          You can obtain the firmware from
-         <http://ipw2200.sf.net/>.  See the above referenced README.ipw2200 
-         for information on where to install the firmware images.
-
-          You will also very likely need the Wireless Tools in order to
-          configure your card:
-
-          <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
-
-          It is recommended that you compile this driver as a module (M)
-          rather than built-in (Y). This driver requires firmware at device
-          initialization time, and when built-in this typically happens
-          before the filesystem is accessible (hence firmware will be
-          unavailable and initialization will fail). If you do choose to build
-          this driver into your kernel image, you can avoid this problem by
-          including the firmware and a firmware loader in an initramfs.
-
-config IPW2200_MONITOR
-        bool "Enable promiscuous mode"
-        depends on IPW2200
-        ---help---
-         Enables promiscuous/monitor mode support for the ipw2200 driver.
-         With this feature compiled into the driver, you can switch to 
-         promiscuous mode via the Wireless Tool's Monitor mode.  While in this
-         mode, no packets can be sent.
-
-config IPW2200_RADIOTAP
-       bool "Enable radiotap format 802.11 raw packet support"
-       depends on IPW2200_MONITOR
-
-config IPW2200_PROMISCUOUS
-       bool "Enable creation of a RF radiotap promiscuous interface"
-       depends on IPW2200_MONITOR
-       select IPW2200_RADIOTAP
-       ---help---
-          Enables the creation of a second interface prefixed 'rtap'. 
-          This second interface will provide every received in radiotap
-         format.
-
-          This is useful for performing wireless network analysis while
-          maintaining an active association.
-
-          Example usage:
-
-            % modprobe ipw2200 rtap_iface=1
-            % ifconfig rtap0 up
-            % tethereal -i rtap0
-
-          If you do not specify 'rtap_iface=1' as a module parameter then 
-          the rtap interface will not be created and you will need to turn 
-          it on via sysfs:
-       
-            % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
-
-config IPW2200_QOS
-        bool "Enable QoS support"
-        depends on IPW2200 && EXPERIMENTAL
-
-config IPW2200_DEBUG
-       bool "Enable full debugging output in IPW2200 module."
-       depends on IPW2200
-       ---help---
-         This option will enable low level debug tracing output for IPW2200.
-
-         Note, normal debug code is already compiled in. This low level
-         debug option enables debug on hot paths (e.g Tx, Rx, ISR) and
-         will result in the kernel module being ~70 larger.  Most users
-         will typically not need this high verbosity debug information.
-
-         If you are not sure, say N here.
-
 config LIBERTAS
        tristate "Marvell 8xxx Libertas WLAN driver support"
        depends on WLAN_80211
@@ -712,6 +568,7 @@ config MAC80211_HWSIM
 source "drivers/net/wireless/p54/Kconfig"
 source "drivers/net/wireless/ath5k/Kconfig"
 source "drivers/net/wireless/ath9k/Kconfig"
+source "drivers/net/wireless/ipw2x00/Kconfig"
 source "drivers/net/wireless/iwlwifi/Kconfig"
 source "drivers/net/wireless/hostap/Kconfig"
 source "drivers/net/wireless/b43/Kconfig"
index 7882084..ac590e1 100644 (file)
@@ -2,9 +2,8 @@
 # Makefile for the Linux Wireless network device drivers.
 #
 
-obj-$(CONFIG_IPW2100) += ipw2100.o
-
-obj-$(CONFIG_IPW2200) += ipw2200.o
+obj-$(CONFIG_IPW2100) += ipw2x00/
+obj-$(CONFIG_IPW2200) += ipw2x00/
 
 obj-$(CONFIG_STRIP) += strip.o
 obj-$(CONFIG_ARLAN) += arlan.o 
@@ -31,6 +30,8 @@ obj-$(CONFIG_HOSTAP)          += hostap/
 obj-$(CONFIG_B43)              += b43/
 obj-$(CONFIG_B43LEGACY)                += b43legacy/
 obj-$(CONFIG_ZD1211RW)         += zd1211rw/
+obj-$(CONFIG_RTL8180)          += rtl818x/
+obj-$(CONFIG_RTL8187)          += rtl818x/
 
 # 16-bit wireless PCMCIA client drivers
 obj-$(CONFIG_PCMCIA_RAYCS)     += ray_cs.o
@@ -43,12 +44,6 @@ obj-$(CONFIG_LIBERTAS)               += libertas/
 
 obj-$(CONFIG_LIBERTAS_THINFIRM)        += libertas_tf/
 
-rtl8180-objs           := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
-rtl8187-objs           := rtl8187_dev.o rtl8187_rtl8225.o
-
-obj-$(CONFIG_RTL8180)  += rtl8180.o
-obj-$(CONFIG_RTL8187)  += rtl8187.o
-
 obj-$(CONFIG_ADM8211)  += adm8211.o
 
 obj-$(CONFIG_IWLWIFI)  += iwlwifi/
index c7ffcbb..34cd1a4 100644 (file)
@@ -2219,9 +2219,9 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
         */
        sc->curchan = sc->hw->conf.channel;
        sc->curband = &sc->sbands[sc->curchan->band];
-       sc->imask = AR5K_INT_RXOK | AR5K_INT_TXOK | AR5K_INT_RXEOL |
-               AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
-               AR5K_INT_MIB;
+       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
+               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
+               AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
        ret = ath5k_reset(sc, false, false);
        if (ret)
                goto done;
@@ -2953,9 +2953,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
                test_bit(ATH_STAT_PROMISC, sc->status))
                rfilt |= AR5K_RX_FILTER_PROM;
        if (sc->opmode == NL80211_IFTYPE_STATION ||
-               sc->opmode == NL80211_IFTYPE_ADHOC) {
+               sc->opmode == NL80211_IFTYPE_ADHOC ||
+               sc->opmode == NL80211_IFTYPE_AP)
                rfilt |= AR5K_RX_FILTER_BEACON;
-       }
        if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
                rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
                        AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
index 69625bf..7ba18e0 100644 (file)
@@ -2196,9 +2196,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
                return ret;
        }
 
-       ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-       if (ret)
-               return ret;
+       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
 
        /*
         * Re-enable RX/TX and beacons
index b51bc03..5003263 100644 (file)
@@ -842,9 +842,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
         *
         * XXX: Find an interval that's OK for all cards...
         */
-       ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-       if (ret)
-               return ret;
+       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
 
        /*
         * Reset queues and start beacon timers at the end of the reset routine
index e05c9ef..ff6457e 100644 (file)
@@ -382,8 +382,9 @@ static const char *ath9k_hw_devname(u16 devid)
 {
        switch (devid) {
        case AR5416_DEVID_PCI:
-       case AR5416_DEVID_PCIE:
                return "Atheros 5416";
+       case AR5416_DEVID_PCIE:
+               return "Atheros 5418";
        case AR9160_DEVID_PCI:
                return "Atheros 9160";
        case AR9280_DEVID_PCI:
index f830fe1..fbb2dd2 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/nl80211.h>
 #include "core.h"
+#include "reg.h"
 
 #define ATH_PCI_VERSION "0.1"
 
@@ -1519,15 +1520,74 @@ static struct ieee80211_ops ath9k_ops = {
        .set_frag_threshold = ath9k_no_fragmentation,
 };
 
+static struct {
+       u32 version;
+       const char * name;
+} ath_mac_bb_names[] = {
+       { AR_SREV_VERSION_5416_PCI,     "5416" },
+       { AR_SREV_VERSION_5416_PCIE,    "5418" },
+       { AR_SREV_VERSION_9100,         "9100" },
+       { AR_SREV_VERSION_9160,         "9160" },
+       { AR_SREV_VERSION_9280,         "9280" },
+       { AR_SREV_VERSION_9285,         "9285" }
+};
+
+static struct {
+       u16 version;
+       const char * name;
+} ath_rf_names[] = {
+       { 0,                            "5133" },
+       { AR_RAD5133_SREV_MAJOR,        "5133" },
+       { AR_RAD5122_SREV_MAJOR,        "5122" },
+       { AR_RAD2133_SREV_MAJOR,        "2133" },
+       { AR_RAD2122_SREV_MAJOR,        "2122" }
+};
+
+/*
+ * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
+ */
+
+static const char *
+ath_mac_bb_name(u32 mac_bb_version)
+{
+       int i;
+
+       for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
+               if (ath_mac_bb_names[i].version == mac_bb_version) {
+                       return ath_mac_bb_names[i].name;
+               }
+       }
+
+       return "????";
+}
+
+/*
+ * Return the RF name. "????" is returned if the RF is unknown.
+ */
+
+static const char *
+ath_rf_name(u16 rf_version)
+{
+       int i;
+
+       for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
+               if (ath_rf_names[i].version == rf_version) {
+                       return ath_rf_names[i].name;
+               }
+       }
+
+       return "????";
+}
+
 static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        void __iomem *mem;
        struct ath_softc *sc;
        struct ieee80211_hw *hw;
-       const char *athname;
        u8 csz;
        u32 val;
        int ret = 0;
+       struct ath_hal *ah;
 
        if (pci_enable_device(pdev))
                return -EIO;
@@ -1614,11 +1674,15 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto bad4;
        }
 
-       athname = ath9k_hw_probe(id->vendor, id->device);
-
-       printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n",
+       ah = sc->sc_ah;
+       printk(KERN_INFO
+              "%s: Atheros AR%s MAC/BB Rev:%x "
+              "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
               wiphy_name(hw->wiphy),
-              athname ? athname : "Atheros ???",
+              ath_mac_bb_name(ah->ah_macVersion),
+              ah->ah_macRev,
+              ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+              ah->ah_phyRev,
               (unsigned long)mem, pdev->irq);
 
        return 0;
index aa6bfd7..517992d 100644 (file)
@@ -1272,8 +1272,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
                                rate_ctrl->state[tx_rate].per = 100;
                } else {
                        /* xretries == 2 */
-                       count = sizeof(nretry_to_per_lookup) /
-                               sizeof(nretry_to_per_lookup[0]);
+                       count = ARRAY_SIZE(nretry_to_per_lookup);
                        if (retries >= count)
                                retries = count - 1;
                        /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
@@ -1291,8 +1290,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
        } else {        /* xretries == 0 */
                /* Update the PER. */
                /* Make sure it doesn't index out of array's bounds. */
-               count = sizeof(nretry_to_per_lookup) /
-                       sizeof(nretry_to_per_lookup[0]);
+               count = ARRAY_SIZE(nretry_to_per_lookup);
                if (retries >= count)
                        retries = count - 1;
                if (info_priv->n_bad_frames) {
index 2ecb0a0..2d72ac1 100644 (file)
@@ -296,9 +296,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
                rfilt &= ~ATH9K_RX_FILTER_UCAST;
        }
 
-       if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
-            (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) ||
-           (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))
+       if (sc->sc_ah->ah_opmode == ATH9K_M_STA ||
+                       sc->sc_ah->ah_opmode == ATH9K_M_IBSS)
                rfilt |= ATH9K_RX_FILTER_BEACON;
 
        /* If in HOSTAP mode, want to enable reception of PSPOLL frames
index adba89b..eae9b80 100644 (file)
@@ -46,7 +46,6 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
        case 0x6E:
                return 3;
        }
-       B43_WARN_ON(1);
        return -1;
 }
 
@@ -73,7 +72,6 @@ static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
        case 0xC:
                return base + 7;
        }
-       B43_WARN_ON(1);
        return -1;
 }
 
@@ -608,6 +606,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
                                                phytype == B43_PHYTYPE_A);
        else
                status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
+       if (unlikely(status.rate_idx == -1))
+               goto drop;
        status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
 
        /*
index c40078e..97b0e06 100644 (file)
 #define B43legacy_SHM_SH_PRMAXTIME     0x0074 /* Probe Response max time */
 #define B43legacy_SHM_SH_PRPHYCTL      0x0188 /* Probe Resp PHY TX control */
 /* SHM_SHARED rate tables */
+#define B43legacy_SHM_SH_OFDMDIRECT    0x0480 /* Pointer to OFDM direct map */
+#define B43legacy_SHM_SH_OFDMBASIC     0x04A0 /* Pointer to OFDM basic rate map */
+#define B43legacy_SHM_SH_CCKDIRECT     0x04C0 /* Pointer to CCK direct map */
+#define B43legacy_SHM_SH_CCKBASIC      0x04E0 /* Pointer to CCK basic rate map */
 /* SHM_SHARED microcode soft registers */
 #define B43legacy_SHM_SH_UCODEREV      0x0000 /* Microcode revision */
 #define B43legacy_SHM_SH_UCODEPATCH    0x0002 /* Microcode patchlevel */
@@ -663,7 +667,6 @@ struct b43legacy_wldev {
        bool bad_frames_preempt;/* Use "Bad Frames Preemption". */
        bool dfq_valid;         /* Directed frame queue valid (IBSS PS mode, ATIM). */
        bool short_preamble;    /* TRUE if using short preamble. */
-       bool short_slot;        /* TRUE if using short slot timing. */
        bool radio_hw_enable;   /* State of radio hardware enable bit. */
 
        /* PHY/Radio device. */
index 6c8eb4d..c1324e3 100644 (file)
@@ -576,13 +576,11 @@ static void b43legacy_set_slot_time(struct b43legacy_wldev *dev,
 static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev)
 {
        b43legacy_set_slot_time(dev, 9);
-       dev->short_slot = 1;
 }
 
 static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
 {
        b43legacy_set_slot_time(dev, 20);
-       dev->short_slot = 0;
 }
 
 /* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
@@ -2608,16 +2606,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
        if (conf->channel->hw_value != phy->channel)
                b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
 
-       /* Enable/Disable ShortSlot timing. */
-       if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME))
-            != dev->short_slot) {
-               B43legacy_WARN_ON(phy->type != B43legacy_PHYTYPE_G);
-               if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)
-                       b43legacy_short_slot_timing_enable(dev);
-               else
-                       b43legacy_short_slot_timing_disable(dev);
-       }
-
        dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
 
        /* Adjust the desired TX power level. */
@@ -2662,6 +2650,104 @@ out_unlock_mutex:
        return err;
 }
 
+static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates)
+{
+       struct ieee80211_supported_band *sband =
+               dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
+       struct ieee80211_rate *rate;
+       int i;
+       u16 basic, direct, offset, basic_offset, rateptr;
+
+       for (i = 0; i < sband->n_bitrates; i++) {
+               rate = &sband->bitrates[i];
+
+               if (b43legacy_is_cck_rate(rate->hw_value)) {
+                       direct = B43legacy_SHM_SH_CCKDIRECT;
+                       basic = B43legacy_SHM_SH_CCKBASIC;
+                       offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
+                       offset &= 0xF;
+               } else {
+                       direct = B43legacy_SHM_SH_OFDMDIRECT;
+                       basic = B43legacy_SHM_SH_OFDMBASIC;
+                       offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
+                       offset &= 0xF;
+               }
+
+               rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
+
+               if (b43legacy_is_cck_rate(rate->hw_value)) {
+                       basic_offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
+                       basic_offset &= 0xF;
+               } else {
+                       basic_offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
+                       basic_offset &= 0xF;
+               }
+
+               /*
+                * Get the pointer that we need to point to
+                * from the direct map
+                */
+               rateptr = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
+                                              direct + 2 * basic_offset);
+               /* and write it to the basic map */
+               b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
+                                     basic + 2 * offset, rateptr);
+       }
+}
+
+static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+                                   struct ieee80211_bss_conf *conf,
+                                   u32 changed)
+{
+       struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
+       struct b43legacy_wldev *dev;
+       struct b43legacy_phy *phy;
+       unsigned long flags;
+       u32 savedirqs;
+
+       mutex_lock(&wl->mutex);
+
+       dev = wl->current_dev;
+       phy = &dev->phy;
+
+       /* Disable IRQs while reconfiguring the device.
+        * This makes it possible to drop the spinlock throughout
+        * the reconfiguration process. */
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       if (b43legacy_status(dev) < B43legacy_STAT_STARTED) {
+               spin_unlock_irqrestore(&wl->irq_lock, flags);
+               goto out_unlock_mutex;
+       }
+       savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+       b43legacy_synchronize_irq(dev);
+
+       b43legacy_mac_suspend(dev);
+
+       if (changed & BSS_CHANGED_BASIC_RATES)
+               b43legacy_update_basic_rates(dev, conf->basic_rates);
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               if (conf->use_short_slot)
+                       b43legacy_short_slot_timing_enable(dev);
+               else
+                       b43legacy_short_slot_timing_disable(dev);
+       }
+
+       b43legacy_mac_enable(dev);
+
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       b43legacy_interrupt_enable(dev, savedirqs);
+       /* XXX: why? */
+       mmiowb();
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+ out_unlock_mutex:
+       mutex_unlock(&wl->mutex);
+
+       return;
+}
+
 static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
                                          unsigned int changed,
                                          unsigned int *fflags,
@@ -3370,6 +3456,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
        .add_interface          = b43legacy_op_add_interface,
        .remove_interface       = b43legacy_op_remove_interface,
        .config                 = b43legacy_op_dev_config,
+       .bss_info_changed       = b43legacy_op_bss_info_changed,
        .config_interface       = b43legacy_op_config_interface,
        .configure_filter       = b43legacy_op_configure_filter,
        .get_stats              = b43legacy_op_get_stats,
index 1fef331..87bbd4d 100644 (file)
@@ -2,8 +2,10 @@ config HOSTAP
        tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
        depends on WLAN_80211
        select WIRELESS_EXT
-       select IEEE80211
-       select IEEE80211_CRYPT_WEP
+       select LIB80211
+       select LIB80211_CRYPT_WEP
+       select LIB80211_CRYPT_TKIP
+       select LIB80211_CRYPT_CCMP
        ---help---
        Shared driver code for IEEE 802.11b wireless cards based on
        Intersil Prism2/2.5/3 chipset. This driver supports so called
index 3a386a6..2453dea 100644 (file)
@@ -63,7 +63,7 @@ void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
 int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac);
 void ap_control_kickall(struct ap_data *ap);
 void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
-                        struct ieee80211_crypt_data ***crypt);
+                        struct lib80211_crypt_data ***crypt);
 int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
                           struct iw_quality qual[], int buf_size,
                           int aplist);
index 3694b1e..3a9474d 100644 (file)
@@ -2,7 +2,7 @@
 #define HOSTAP_80211_H
 
 #include <linux/types.h>
-#include <net/ieee80211_crypt.h>
+#include <net/ieee80211.h>
 
 struct hostap_ieee80211_mgmt {
        __le16 frame_control;
index 5f64461..19b1bf0 100644 (file)
@@ -1,5 +1,5 @@
 #include <linux/etherdevice.h>
-#include <net/ieee80211_crypt.h>
+#include <net/lib80211.h>
 
 #include "hostap_80211.h"
 #include "hostap.h"
@@ -649,7 +649,7 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
 /* Called only as a tasklet (software IRQ) */
 static int
 hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
-                       struct ieee80211_crypt_data *crypt)
+                       struct lib80211_crypt_data *crypt)
 {
        struct ieee80211_hdr_4addr *hdr;
        int res, hdrlen;
@@ -687,7 +687,7 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
 /* Called only as a tasklet (software IRQ) */
 static int
 hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
-                            int keyidx, struct ieee80211_crypt_data *crypt)
+                            int keyidx, struct lib80211_crypt_data *crypt)
 {
        struct ieee80211_hdr_4addr *hdr;
        int res, hdrlen;
@@ -733,7 +733,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
        int from_assoc_ap = 0;
        u8 dst[ETH_ALEN];
        u8 src[ETH_ALEN];
-       struct ieee80211_crypt_data *crypt = NULL;
+       struct lib80211_crypt_data *crypt = NULL;
        void *sta = NULL;
        int keyidx = 0;
 
@@ -785,7 +785,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                int idx = 0;
                if (skb->len >= hdrlen + 3)
                        idx = skb->data[hdrlen + 3] >> 6;
-               crypt = local->crypt[idx];
+               crypt = local->crypt_info.crypt[idx];
                sta = NULL;
 
                /* Use station specific key to override default keys if the
index 0752471..078a010 100644 (file)
@@ -306,7 +306,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 /* Called only from software IRQ */
 static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
-                                         struct ieee80211_crypt_data *crypt)
+                                         struct lib80211_crypt_data *crypt)
 {
        struct hostap_interface *iface;
        local_info_t *local;
@@ -405,7 +405,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (local->host_encrypt) {
                /* Set crypt to default algorithm and key; will be replaced in
                 * AP code if STA has own alg/key */
-               tx.crypt = local->crypt[local->tx_keyidx];
+               tx.crypt = local->crypt_info.crypt[local->crypt_info.tx_keyidx];
                tx.host_encrypt = 1;
        } else {
                tx.crypt = NULL;
@@ -487,7 +487,9 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu))
                tx.crypt = NULL;
-       else if ((tx.crypt || local->crypt[local->tx_keyidx]) && !no_encrypt) {
+       else if ((tx.crypt ||
+                local->crypt_info.crypt[local->crypt_info.tx_keyidx]) &&
+                !no_encrypt) {
                /* Add ISWEP flag both for firmware and host based encryption
                 */
                fc |= IEEE80211_FCTL_PROTECTED;
index dec3dbe..0903db7 100644 (file)
@@ -1206,7 +1206,7 @@ static void prism2_check_tx_rates(struct sta_info *sta)
 
 static void ap_crypt_init(struct ap_data *ap)
 {
-       ap->crypt = ieee80211_get_crypto_ops("WEP");
+       ap->crypt = lib80211_get_crypto_ops("WEP");
 
        if (ap->crypt) {
                if (ap->crypt->init) {
@@ -1224,7 +1224,7 @@ static void ap_crypt_init(struct ap_data *ap)
 
        if (ap->crypt == NULL) {
                printk(KERN_WARNING "AP could not initialize WEP: load module "
-                      "ieee80211_crypt_wep.ko\n");
+                      "lib80211_crypt_wep.ko\n");
        }
 }
 
@@ -1293,7 +1293,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
        __le16 *pos;
        u16 resp = WLAN_STATUS_SUCCESS, fc;
        struct sta_info *sta = NULL;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
        char *txt = "";
 
        len = skb->len - IEEE80211_MGMT_HDR_LEN;
@@ -1319,7 +1319,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
                int idx = 0;
                if (skb->len >= hdrlen + 3)
                        idx = skb->data[hdrlen + 3] >> 6;
-               crypt = local->crypt[idx];
+               crypt = local->crypt_info.crypt[idx];
        }
 
        pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
@@ -3065,7 +3065,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
 /* Called only as a tasklet (software IRQ) */
 int hostap_handle_sta_crypto(local_info_t *local,
                             struct ieee80211_hdr_4addr *hdr,
-                            struct ieee80211_crypt_data **crypt,
+                            struct lib80211_crypt_data **crypt,
                             void **sta_ptr)
 {
        struct sta_info *sta;
@@ -3213,7 +3213,7 @@ void hostap_update_rates(local_info_t *local)
 
 
 void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
-                        struct ieee80211_crypt_data ***crypt)
+                        struct lib80211_crypt_data ***crypt)
 {
        struct sta_info *sta;
 
index 2fa2452..d36e4b1 100644 (file)
@@ -74,7 +74,7 @@ struct sta_info {
        u32 tx_since_last_failure;
        u32 tx_consecutive_exc;
 
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
 
        int ap; /* whether this station is an AP */
 
@@ -209,7 +209,7 @@ struct ap_data {
 
        /* WEP operations for generating challenges to be used with shared key
         * authentication */
-       struct ieee80211_crypto_ops *crypt;
+       struct lib80211_crypto_ops *crypt;
        void *crypt_priv;
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 };
@@ -229,7 +229,7 @@ typedef enum {
 struct hostap_tx_data {
        struct sk_buff *skb;
        int host_encrypt;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
        void *sta_ptr;
 };
 ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
@@ -244,7 +244,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                               struct hostap_80211_rx_status *rx_stats,
                               int wds);
 int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
-                            struct ieee80211_crypt_data **crypt,
+                            struct lib80211_crypt_data **crypt,
                             void **sta_ptr);
 int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
 int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
index fd7f7ce..0f27059 100644 (file)
@@ -47,7 +47,7 @@
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 #include <net/ieee80211.h>
-#include <net/ieee80211_crypt.h>
+#include <net/lib80211.h>
 #include <asm/irq.h>
 
 #include "hostap_80211.h"
@@ -2788,45 +2788,6 @@ static void prism2_check_sta_fw_version(local_info_t *local)
 }
 
 
-static void prism2_crypt_deinit_entries(local_info_t *local, int force)
-{
-       struct list_head *ptr, *n;
-       struct ieee80211_crypt_data *entry;
-
-       for (ptr = local->crypt_deinit_list.next, n = ptr->next;
-            ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) {
-               entry = list_entry(ptr, struct ieee80211_crypt_data, list);
-
-               if (atomic_read(&entry->refcnt) != 0 && !force)
-                       continue;
-
-               list_del(ptr);
-
-               if (entry->ops)
-                       entry->ops->deinit(entry->priv);
-               kfree(entry);
-       }
-}
-
-
-static void prism2_crypt_deinit_handler(unsigned long data)
-{
-       local_info_t *local = (local_info_t *) data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&local->lock, flags);
-       prism2_crypt_deinit_entries(local, 0);
-       if (!list_empty(&local->crypt_deinit_list)) {
-               printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
-                      "deletion list\n", local->dev->name);
-               local->crypt_deinit_timer.expires = jiffies + HZ;
-               add_timer(&local->crypt_deinit_timer);
-       }
-       spin_unlock_irqrestore(&local->lock, flags);
-
-}
-
-
 static void hostap_passive_scan(unsigned long data)
 {
        local_info_t *local = (local_info_t *) data;
@@ -3250,10 +3211,8 @@ while (0)
 
        INIT_LIST_HEAD(&local->cmd_queue);
        init_waitqueue_head(&local->hostscan_wq);
-       INIT_LIST_HEAD(&local->crypt_deinit_list);
-       init_timer(&local->crypt_deinit_timer);
-       local->crypt_deinit_timer.data = (unsigned long) local;
-       local->crypt_deinit_timer.function = prism2_crypt_deinit_handler;
+
+       lib80211_crypt_info_init(&local->crypt_info, dev->name, &local->lock);
 
        init_timer(&local->passive_scan_timer);
        local->passive_scan_timer.data = (unsigned long) local;
@@ -3354,9 +3313,7 @@ static void prism2_free_local_data(struct net_device *dev)
 
        flush_scheduled_work();
 
-       if (timer_pending(&local->crypt_deinit_timer))
-               del_timer(&local->crypt_deinit_timer);
-       prism2_crypt_deinit_entries(local, 1);
+       lib80211_crypt_info_free(&local->crypt_info);
 
        if (timer_pending(&local->passive_scan_timer))
                del_timer(&local->passive_scan_timer);
@@ -3373,16 +3330,6 @@ static void prism2_free_local_data(struct net_device *dev)
        if (local->dev_enabled)
                prism2_callback(local, PRISM2_CALLBACK_DISABLE);
 
-       for (i = 0; i < WEP_KEYS; i++) {
-               struct ieee80211_crypt_data *crypt = local->crypt[i];
-               if (crypt) {
-                       if (crypt->ops)
-                               crypt->ops->deinit(crypt->priv);
-                       kfree(crypt);
-                       local->crypt[i] = NULL;
-               }
-       }
-
        if (local->ap != NULL)
                hostap_free_data(local->ap);
 
index 2318c5d..c40fdf4 100644 (file)
@@ -2,7 +2,7 @@
 
 #include <linux/types.h>
 #include <linux/ethtool.h>
-#include <net/ieee80211_crypt.h>
+#include <net/lib80211.h>
 
 #include "hostap_wlan.h"
 #include "hostap.h"
@@ -116,32 +116,6 @@ static int prism2_get_name(struct net_device *dev,
 }
 
 
-static void prism2_crypt_delayed_deinit(local_info_t *local,
-                                       struct ieee80211_crypt_data **crypt)
-{
-       struct ieee80211_crypt_data *tmp;
-       unsigned long flags;
-
-       tmp = *crypt;
-       *crypt = NULL;
-
-       if (tmp == NULL)
-               return;
-
-       /* must not run ops->deinit() while there may be pending encrypt or
-        * decrypt operations. Use a list of delayed deinits to avoid needing
-        * locking. */
-
-       spin_lock_irqsave(&local->lock, flags);
-       list_add(&tmp->list, &local->crypt_deinit_list);
-       if (!timer_pending(&local->crypt_deinit_timer)) {
-               local->crypt_deinit_timer.expires = jiffies + HZ;
-               add_timer(&local->crypt_deinit_timer);
-       }
-       spin_unlock_irqrestore(&local->lock, flags);
-}
-
-
 static int prism2_ioctl_siwencode(struct net_device *dev,
                                  struct iw_request_info *info,
                                  struct iw_point *erq, char *keybuf)
@@ -149,47 +123,47 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
        struct hostap_interface *iface;
        local_info_t *local;
        int i;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypt_data **crypt;
 
        iface = netdev_priv(dev);
        local = iface->local;
 
        i = erq->flags & IW_ENCODE_INDEX;
        if (i < 1 || i > 4)
-               i = local->tx_keyidx;
+               i = local->crypt_info.tx_keyidx;
        else
                i--;
        if (i < 0 || i >= WEP_KEYS)
                return -EINVAL;
 
-       crypt = &local->crypt[i];
+       crypt = &local->crypt_info.crypt[i];
 
        if (erq->flags & IW_ENCODE_DISABLED) {
                if (*crypt)
-                       prism2_crypt_delayed_deinit(local, crypt);
+                       lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
                goto done;
        }
 
        if (*crypt != NULL && (*crypt)->ops != NULL &&
            strcmp((*crypt)->ops->name, "WEP") != 0) {
                /* changing to use WEP; deinit previously used algorithm */
-               prism2_crypt_delayed_deinit(local, crypt);
+               lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
        }
 
        if (*crypt == NULL) {
-               struct ieee80211_crypt_data *new_crypt;
+               struct lib80211_crypt_data *new_crypt;
 
                /* take WEP into use */
-               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL)
                        return -ENOMEM;
-               new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+               new_crypt->ops = lib80211_get_crypto_ops("WEP");
                if (!new_crypt->ops) {
-                       request_module("ieee80211_crypt_wep");
-                       new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+                       request_module("lib80211_crypt_wep");
+                       new_crypt->ops = lib80211_get_crypto_ops("WEP");
                }
-               if (new_crypt->ops)
+               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
                        new_crypt->priv = new_crypt->ops->init(i);
                if (!new_crypt->ops || !new_crypt->priv) {
                        kfree(new_crypt);
@@ -210,16 +184,16 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
                        memset(keybuf + erq->length, 0, len - erq->length);
                (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
                for (j = 0; j < WEP_KEYS; j++) {
-                       if (j != i && local->crypt[j]) {
+                       if (j != i && local->crypt_info.crypt[j]) {
                                first = 0;
                                break;
                        }
                }
                if (first)
-                       local->tx_keyidx = i;
+                       local->crypt_info.tx_keyidx = i;
        } else {
                /* No key data - just set the default TX key index */
-               local->tx_keyidx = i;
+               local->crypt_info.tx_keyidx = i;
        }
 
  done:
@@ -252,20 +226,20 @@ static int prism2_ioctl_giwencode(struct net_device *dev,
        local_info_t *local;
        int i, len;
        u16 val;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
 
        iface = netdev_priv(dev);
        local = iface->local;
 
        i = erq->flags & IW_ENCODE_INDEX;
        if (i < 1 || i > 4)
-               i = local->tx_keyidx;
+               i = local->crypt_info.tx_keyidx;
        else
                i--;
        if (i < 0 || i >= WEP_KEYS)
                return -EINVAL;
 
-       crypt = local->crypt[i];
+       crypt = local->crypt_info.crypt[i];
        erq->flags = i + 1;
 
        if (crypt == NULL || crypt->ops == NULL) {
@@ -3227,8 +3201,8 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        local_info_t *local = iface->local;
        struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
        int i, ret = 0;
-       struct ieee80211_crypto_ops *ops;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypto_ops *ops;
+       struct lib80211_crypt_data **crypt;
        void *sta_ptr;
        u8 *addr;
        const char *alg, *module;
@@ -3237,7 +3211,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        if (i > WEP_KEYS)
                return -EINVAL;
        if (i < 1 || i > WEP_KEYS)
-               i = local->tx_keyidx;
+               i = local->crypt_info.tx_keyidx;
        else
                i--;
        if (i < 0 || i >= WEP_KEYS)
@@ -3247,7 +3221,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
            addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
                sta_ptr = NULL;
-               crypt = &local->crypt[i];
+               crypt = &local->crypt_info.crypt[i];
        } else {
                if (i != 0)
                        return -EINVAL;
@@ -3260,7 +3234,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
                                 * is emulated by using default key idx 0.
                                 */
                                i = 0;
-                               crypt = &local->crypt[i];
+                               crypt = &local->crypt_info.crypt[i];
                        } else
                                return -EINVAL;
                }
@@ -3269,22 +3243,22 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        if ((erq->flags & IW_ENCODE_DISABLED) ||
            ext->alg == IW_ENCODE_ALG_NONE) {
                if (*crypt)
-                       prism2_crypt_delayed_deinit(local, crypt);
+                       lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
                goto done;
        }
 
        switch (ext->alg) {
        case IW_ENCODE_ALG_WEP:
                alg = "WEP";
-               module = "ieee80211_crypt_wep";
+               module = "lib80211_crypt_wep";
                break;
        case IW_ENCODE_ALG_TKIP:
                alg = "TKIP";
-               module = "ieee80211_crypt_tkip";
+               module = "lib80211_crypt_tkip";
                break;
        case IW_ENCODE_ALG_CCMP:
                alg = "CCMP";
-               module = "ieee80211_crypt_ccmp";
+               module = "lib80211_crypt_ccmp";
                break;
        default:
                printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
@@ -3293,10 +3267,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
                goto done;
        }
 
-       ops = ieee80211_get_crypto_ops(alg);
+       ops = lib80211_get_crypto_ops(alg);
        if (ops == NULL) {
                request_module(module);
-               ops = ieee80211_get_crypto_ops(alg);
+               ops = lib80211_get_crypto_ops(alg);
        }
        if (ops == NULL) {
                printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
@@ -3315,18 +3289,19 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
        }
 
        if (*crypt == NULL || (*crypt)->ops != ops) {
-               struct ieee80211_crypt_data *new_crypt;
+               struct lib80211_crypt_data *new_crypt;
 
-               prism2_crypt_delayed_deinit(local, crypt);
+               lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
 
-               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL) {
                        ret = -ENOMEM;
                        goto done;
                }
                new_crypt->ops = ops;
-               new_crypt->priv = new_crypt->ops->init(i);
+               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+                       new_crypt->priv = new_crypt->ops->init(i);
                if (new_crypt->priv == NULL) {
                        kfree(new_crypt);
                        ret = -EINVAL;
@@ -3354,20 +3329,20 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
 
        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
                if (!sta_ptr)
-                       local->tx_keyidx = i;
+                       local->crypt_info.tx_keyidx = i;
        }
 
 
        if (sta_ptr == NULL && ext->key_len > 0) {
                int first = 1, j;
                for (j = 0; j < WEP_KEYS; j++) {
-                       if (j != i && local->crypt[j]) {
+                       if (j != i && local->crypt_info.crypt[j]) {
                                first = 0;
                                break;
                        }
                }
                if (first)
-                       local->tx_keyidx = i;
+                       local->crypt_info.tx_keyidx = i;
        }
 
  done:
@@ -3399,7 +3374,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
 {
        struct hostap_interface *iface = netdev_priv(dev);
        local_info_t *local = iface->local;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypt_data **crypt;
        void *sta_ptr;
        int max_key_len, i;
        struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
@@ -3411,7 +3386,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
 
        i = erq->flags & IW_ENCODE_INDEX;
        if (i < 1 || i > WEP_KEYS)
-               i = local->tx_keyidx;
+               i = local->crypt_info.tx_keyidx;
        else
                i--;
 
@@ -3419,7 +3394,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
        if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
            addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
                sta_ptr = NULL;
-               crypt = &local->crypt[i];
+               crypt = &local->crypt_info.crypt[i];
        } else {
                i = 0;
                sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
@@ -3468,8 +3443,8 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
                                       int param_len)
 {
        int ret = 0;
-       struct ieee80211_crypto_ops *ops;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypto_ops *ops;
+       struct lib80211_crypt_data **crypt;
        void *sta_ptr;
 
        param->u.crypt.err = 0;
@@ -3486,7 +3461,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
                if (param->u.crypt.idx >= WEP_KEYS)
                        return -EINVAL;
                sta_ptr = NULL;
-               crypt = &local->crypt[param->u.crypt.idx];
+               crypt = &local->crypt_info.crypt[param->u.crypt.idx];
        } else {
                if (param->u.crypt.idx)
                        return -EINVAL;
@@ -3503,20 +3478,20 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
 
        if (strcmp(param->u.crypt.alg, "none") == 0) {
                if (crypt)
-                       prism2_crypt_delayed_deinit(local, crypt);
+                       lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
                goto done;
        }
 
-       ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+       ops = lib80211_get_crypto_ops(param->u.crypt.alg);
        if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
-               request_module("ieee80211_crypt_wep");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+               request_module("lib80211_crypt_wep");
+               ops = lib80211_get_crypto_ops(param->u.crypt.alg);
        } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
-               request_module("ieee80211_crypt_tkip");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+               request_module("lib80211_crypt_tkip");
+               ops = lib80211_get_crypto_ops(param->u.crypt.alg);
        } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
-               request_module("ieee80211_crypt_ccmp");
-               ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+               request_module("lib80211_crypt_ccmp");
+               ops = lib80211_get_crypto_ops(param->u.crypt.alg);
        }
        if (ops == NULL) {
                printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
@@ -3531,11 +3506,11 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
        local->host_decrypt = local->host_encrypt = 1;
 
        if (*crypt == NULL || (*crypt)->ops != ops) {
-               struct ieee80211_crypt_data *new_crypt;
+               struct lib80211_crypt_data *new_crypt;
 
-               prism2_crypt_delayed_deinit(local, crypt);
+               lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
 
-               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
                                GFP_KERNEL);
                if (new_crypt == NULL) {
                        ret = -ENOMEM;
@@ -3568,7 +3543,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
 
        if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
                if (!sta_ptr)
-                       local->tx_keyidx = param->u.crypt.idx;
+                       local->crypt_info.tx_keyidx = param->u.crypt.idx;
                else if (param->u.crypt.idx) {
                        printk(KERN_DEBUG "%s: TX key idx setting failed\n",
                               local->dev->name);
@@ -3604,7 +3579,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
                                       struct prism2_hostapd_param *param,
                                       int param_len)
 {
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypt_data **crypt;
        void *sta_ptr;
        int max_key_len;
 
@@ -3620,8 +3595,8 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
            param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
                sta_ptr = NULL;
                if (param->u.crypt.idx >= WEP_KEYS)
-                       param->u.crypt.idx = local->tx_keyidx;
-               crypt = &local->crypt[param->u.crypt.idx];
+                       param->u.crypt.idx = local->crypt_info.tx_keyidx;
+               crypt = &local->crypt_info.crypt[param->u.crypt.idx];
        } else {
                param->u.crypt.idx = 0;
                sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
index 4c36eb2..02a312c 100644 (file)
@@ -27,7 +27,7 @@
 #include <net/net_namespace.h>
 #include <net/iw_handler.h>
 #include <net/ieee80211.h>
-#include <net/ieee80211_crypt.h>
+#include <net/lib80211.h>
 #include <asm/uaccess.h>
 
 #include "hostap_wlan.h"
@@ -343,10 +343,11 @@ int hostap_set_encryption(local_info_t *local)
        char keybuf[WEP_KEY_LEN + 1];
        enum { NONE, WEP, OTHER } encrypt_type;
 
-       idx = local->tx_keyidx;
-       if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL)
+       idx = local->crypt_info.tx_keyidx;
+       if (local->crypt_info.crypt[idx] == NULL ||
+           local->crypt_info.crypt[idx]->ops == NULL)
                encrypt_type = NONE;
-       else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0)
+       else if (strcmp(local->crypt_info.crypt[idx]->ops->name, "WEP") == 0)
                encrypt_type = WEP;
        else
                encrypt_type = OTHER;
@@ -394,17 +395,17 @@ int hostap_set_encryption(local_info_t *local)
        /* 104-bit support seems to require that all the keys are set to the
         * same keylen */
        keylen = 6; /* first 5 octets */
-       len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf),
-                                             NULL, local->crypt[idx]->priv);
+       len = local->crypt_info.crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), NULL,
+                                                          local->crypt_info.crypt[idx]->priv);
        if (idx >= 0 && idx < WEP_KEYS && len > 5)
                keylen = WEP_KEY_LEN + 1; /* first 13 octets */
 
        for (i = 0; i < WEP_KEYS; i++) {
                memset(keybuf, 0, sizeof(keybuf));
-               if (local->crypt[i]) {
-                       (void) local->crypt[i]->ops->get_key(
+               if (local->crypt_info.crypt[i]) {
+                       (void) local->crypt_info.crypt[i]->ops->get_key(
                                keybuf, sizeof(keybuf),
-                               NULL, local->crypt[i]->priv);
+                               NULL, local->crypt_info.crypt[i]->priv);
                }
                if (local->func->set_rid(local->dev,
                                         HFA384X_RID_CNFDEFAULTKEY0 + i,
index ae7d3ca..005ff25 100644 (file)
@@ -2,7 +2,7 @@
 
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include <net/ieee80211_crypt.h>
+#include <net/lib80211.h>
 
 #include "hostap_wlan.h"
 #include "hostap.h"
@@ -36,9 +36,10 @@ static int prism2_debug_proc_read(char *page, char **start, off_t off,
        p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled);
        p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
        for (i = 0; i < WEP_KEYS; i++) {
-               if (local->crypt[i] && local->crypt[i]->ops) {
-                       p += sprintf(p, "crypt[%d]=%s\n",
-                                    i, local->crypt[i]->ops->name);
+               if (local->crypt_info.crypt[i] &&
+                   local->crypt_info.crypt[i]->ops) {
+                       p += sprintf(p, "crypt[%d]=%s\n", i,
+                                    local->crypt_info.crypt[i]->ops->name);
                }
        }
        p += sprintf(p, "pri_only=%d\n", local->pri_only);
@@ -206,12 +207,13 @@ static int prism2_crypt_proc_read(char *page, char **start, off_t off,
                return 0;
        }
 
-       p += sprintf(p, "tx_keyidx=%d\n", local->tx_keyidx);
+       p += sprintf(p, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx);
        for (i = 0; i < WEP_KEYS; i++) {
-               if (local->crypt[i] && local->crypt[i]->ops &&
-                   local->crypt[i]->ops->print_stats) {
-                       p = local->crypt[i]->ops->print_stats(
-                               p, local->crypt[i]->priv);
+               if (local->crypt_info.crypt[i] &&
+                   local->crypt_info.crypt[i]->ops &&
+                   local->crypt_info.crypt[i]->ops->print_stats) {
+                       p = local->crypt_info.crypt[i]->ops->print_stats(
+                               p, local->crypt_info.crypt[i]->priv);
                }
        }
 
index d2c7a56..4d8d51a 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/mutex.h>
 #include <net/iw_handler.h>
 #include <net/ieee80211_radiotap.h>
+#include <net/lib80211.h>
 
 #include "hostap_config.h"
 #include "hostap_common.h"
@@ -763,10 +764,7 @@ struct local_info {
 
 #define WEP_KEYS 4
 #define WEP_KEY_LEN 13
-       struct ieee80211_crypt_data *crypt[WEP_KEYS];
-       int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
-       struct timer_list crypt_deinit_timer;
-       struct list_head crypt_deinit_list;
+       struct lib80211_crypt_info crypt_info;
 
        int open_wep; /* allow unencrypted frames */
        int host_encrypt;
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig
new file mode 100644 (file)
index 0000000..3d5cc44
--- /dev/null
@@ -0,0 +1,191 @@
+#
+# Intel Centrino wireless drivers
+#
+
+config IPW2100
+       tristate "Intel PRO/Wireless 2100 Network Connection"
+       depends on PCI && WLAN_80211
+       select WIRELESS_EXT
+       select FW_LOADER
+       select LIB80211
+       select LIBIPW
+       ---help---
+          A driver for the Intel PRO/Wireless 2100 Network 
+         Connection 802.11b wireless network adapter.
+
+          See <file:Documentation/networking/README.ipw2100> for information on
+          the capabilities currently enabled in this driver and for tips
+          for debugging issues and problems.
+
+         In order to use this driver, you will need a firmware image for it.
+          You can obtain the firmware from
+         <http://ipw2100.sf.net/>.  Once you have the firmware image, you 
+         will need to place it in /lib/firmware.
+
+          You will also very likely need the Wireless Tools in order to
+          configure your card:
+
+          <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+
+          It is recommended that you compile this driver as a module (M)
+          rather than built-in (Y). This driver requires firmware at device
+          initialization time, and when built-in this typically happens
+          before the filesystem is accessible (hence firmware will be
+          unavailable and initialization will fail). If you do choose to build
+          this driver into your kernel image, you can avoid this problem by
+          including the firmware and a firmware loader in an initramfs.
+config IPW2100_MONITOR
+        bool "Enable promiscuous mode"
+        depends on IPW2100
+        ---help---
+         Enables promiscuous/monitor mode support for the ipw2100 driver.
+         With this feature compiled into the driver, you can switch to 
+         promiscuous mode via the Wireless Tool's Monitor mode.  While in this
+         mode, no packets can be sent.
+
+config IPW2100_DEBUG
+       bool "Enable full debugging output in IPW2100 module."
+       depends on IPW2100
+       ---help---
+         This option will enable debug tracing output for the IPW2100.  
+
+         This will result in the kernel module being ~60k larger.  You can 
+         control which debug output is sent to the kernel log by setting the 
+         value in 
+
+         /sys/bus/pci/drivers/ipw2100/debug_level
+
+         This entry will only exist if this option is enabled.
+
+         If you are not trying to debug or develop the IPW2100 driver, you 
+         most likely want to say N here.
+
+config IPW2200
+       tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
+       depends on PCI && WLAN_80211
+       select WIRELESS_EXT
+       select FW_LOADER
+       select LIB80211
+       select LIBIPW
+       ---help---
+          A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
+         Connection adapters. 
+
+          See <file:Documentation/networking/README.ipw2200> for 
+         information on the capabilities currently enabled in this 
+         driver and for tips for debugging issues and problems.
+
+         In order to use this driver, you will need a firmware image for it.
+          You can obtain the firmware from
+         <http://ipw2200.sf.net/>.  See the above referenced README.ipw2200 
+         for information on where to install the firmware images.
+
+          You will also very likely need the Wireless Tools in order to
+          configure your card:
+
+          <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+
+          It is recommended that you compile this driver as a module (M)
+          rather than built-in (Y). This driver requires firmware at device
+          initialization time, and when built-in this typically happens
+          before the filesystem is accessible (hence firmware will be
+          unavailable and initialization will fail). If you do choose to build
+          this driver into your kernel image, you can avoid this problem by
+          including the firmware and a firmware loader in an initramfs.
+
+config IPW2200_MONITOR
+        bool "Enable promiscuous mode"
+        depends on IPW2200
+        ---help---
+         Enables promiscuous/monitor mode support for the ipw2200 driver.
+         With this feature compiled into the driver, you can switch to 
+         promiscuous mode via the Wireless Tool's Monitor mode.  While in this
+         mode, no packets can be sent.
+
+config IPW2200_RADIOTAP
+       bool "Enable radiotap format 802.11 raw packet support"
+       depends on IPW2200_MONITOR
+
+config IPW2200_PROMISCUOUS
+       bool "Enable creation of a RF radiotap promiscuous interface"
+       depends on IPW2200_MONITOR
+       select IPW2200_RADIOTAP
+       ---help---
+          Enables the creation of a second interface prefixed 'rtap'. 
+          This second interface will provide every received in radiotap
+         format.
+
+          This is useful for performing wireless network analysis while
+          maintaining an active association.
+
+          Example usage:
+
+            % modprobe ipw2200 rtap_iface=1
+            % ifconfig rtap0 up
+            % tethereal -i rtap0
+
+          If you do not specify 'rtap_iface=1' as a module parameter then 
+          the rtap interface will not be created and you will need to turn 
+          it on via sysfs:
+       
+            % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
+
+config IPW2200_QOS
+        bool "Enable QoS support"
+        depends on IPW2200 && EXPERIMENTAL
+
+config IPW2200_DEBUG
+       bool "Enable full debugging output in IPW2200 module."
+       depends on IPW2200
+       ---help---
+         This option will enable low level debug tracing output for IPW2200.
+
+         Note, normal debug code is already compiled in. This low level
+         debug option enables debug on hot paths (e.g Tx, Rx, ISR) and
+         will result in the kernel module being ~70 larger.  Most users
+         will typically not need this high verbosity debug information.
+
+         If you are not sure, say N here.
+
+config LIBIPW
+       tristate
+       select WIRELESS_EXT
+       select CRYPTO
+       select CRYPTO_ARC4
+       select CRYPTO_ECB
+       select CRYPTO_AES
+       select CRYPTO_MICHAEL_MIC
+       select CRYPTO_ECB
+       select CRC32
+       select LIB80211
+       select LIB80211_CRYPT_WEP
+       select LIB80211_CRYPT_TKIP
+       select LIB80211_CRYPT_CCMP
+       ---help---
+       This option enables the hardware independent IEEE 802.11
+       networking stack.  This component is deprecated in favor of the
+       mac80211 component.
+
+config LIBIPW_DEBUG
+       bool "Full debugging output for the LIBIPW component"
+       depends on LIBIPW
+       ---help---
+         This option will enable debug tracing output for the
+         libipw component.
+
+         This will result in the kernel module being ~70k larger.  You
+         can control which debug output is sent to the kernel log by
+         setting the value in
+
+         /proc/net/ieee80211/debug_level
+
+         For example:
+
+         % echo 0x00000FFO > /proc/net/ieee80211/debug_level
+
+         For a list of values you can assign to debug_level, you
+         can look at the bit mask values in <net/ieee80211.h>
+
+         If you are not trying to debug or develop the libipw
+         component, you most likely want to say N here.
diff --git a/drivers/net/wireless/ipw2x00/Makefile b/drivers/net/wireless/ipw2x00/Makefile
new file mode 100644 (file)
index 0000000..aecd2cf
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# Makefile for the Intel Centrino wireless drivers
+#
+
+obj-$(CONFIG_IPW2100) += ipw2100.o
+obj-$(CONFIG_IPW2200) += ipw2200.o
+
+obj-$(CONFIG_LIBIPW) += libipw.o
+libipw-objs := \
+       libipw_module.o \
+       libipw_tx.o \
+       libipw_rx.o \
+       libipw_wx.o \
+       libipw_geo.o
similarity index 99%
rename from drivers/net/wireless/ipw2100.c
rename to drivers/net/wireless/ipw2x00/ipw2100.c
index 062c9f2..2d2044d 100644 (file)
@@ -4010,7 +4010,7 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr,
        else
                len += sprintf(buf + len, "not connected\n");
 
-       DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p");
+       DUMP_VAR(ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx], "p");
        DUMP_VAR(status, "08lx");
        DUMP_VAR(config, "08lx");
        DUMP_VAR(capability, "08lx");
@@ -5514,7 +5514,7 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
                        }
                }
 
-               ipw2100_set_key_index(priv, priv->ieee->tx_keyidx, 1);
+               ipw2100_set_key_index(priv, priv->ieee->crypt_info.tx_keyidx, 1);
        }
 
        /* Always enable privacy so the Host can filter WEP packets if
@@ -7620,7 +7620,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee;
        struct iw_param *param = &wrqu->param;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
        unsigned long flags;
        int ret = 0;
 
@@ -7635,7 +7635,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
                break;
 
        case IW_AUTH_TKIP_COUNTERMEASURES:
-               crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+               crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
                if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
                        break;
 
@@ -7712,7 +7712,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
 {
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
        struct iw_param *param = &wrqu->param;
        int ret = 0;
 
@@ -7728,7 +7728,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
                break;
 
        case IW_AUTH_TKIP_COUNTERMEASURES:
-               crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+               crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
                if (!crypt || !crypt->ops->get_flags) {
                        IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
                                          "crypt not set!\n");
similarity index 99%
rename from drivers/net/wireless/ipw2200.c
rename to drivers/net/wireless/ipw2x00/ipw2200.c
index 051ae92..d2a2b75 100644 (file)
@@ -6600,7 +6600,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
        struct ipw_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee;
        struct iw_param *param = &wrqu->param;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
        unsigned long flags;
        int ret = 0;
 
@@ -6622,7 +6622,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
                break;
 
        case IW_AUTH_TKIP_COUNTERMEASURES:
-               crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+               crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
                if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
                        break;
 
@@ -6699,7 +6699,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
 {
        struct ipw_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
        struct iw_param *param = &wrqu->param;
        int ret = 0;
 
@@ -6715,7 +6715,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
                break;
 
        case IW_AUTH_TKIP_COUNTERMEASURES:
-               crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+               crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
                if (!crypt || !crypt->ops->get_flags)
                        break;
 
@@ -7575,8 +7575,7 @@ static int ipw_associate(void *data)
        }
 
        if (!(priv->config & CFG_ASSOCIATE) &&
-           !(priv->config & (CFG_STATIC_ESSID |
-                             CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
+           !(priv->config & (CFG_STATIC_ESSID | CFG_STATIC_BSSID))) {
                IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
                return 0;
        }
@@ -10252,8 +10251,8 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
                case SEC_LEVEL_1:
                        tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
                            cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-                       tfd->u.data.key_index = priv->ieee->tx_keyidx;
-                       if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
+                       tfd->u.data.key_index = priv->ieee->crypt_info.tx_keyidx;
+                       if (priv->ieee->sec.key_sizes[priv->ieee->crypt_info.tx_keyidx] <=
                            40)
                                tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
                        else
similarity index 93%
rename from net/ieee80211/ieee80211_module.c
rename to drivers/net/wireless/ipw2x00/libipw_module.c
index d34d4e7..a2f5616 100644 (file)
@@ -180,13 +180,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        ieee->host_open_frag = 1;
        ieee->ieee802_1x = 1;   /* Default to supporting 802.1x */
 
-       INIT_LIST_HEAD(&ieee->crypt_deinit_list);
-       setup_timer(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler,
-                       (unsigned long)ieee);
-       ieee->crypt_quiesced = 0;
-
        spin_lock_init(&ieee->lock);
 
+       lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
+
        ieee->wpa_enabled = 0;
        ieee->drop_unencrypted = 0;
        ieee->privacy_invoked = 0;
@@ -203,23 +200,7 @@ void free_ieee80211(struct net_device *dev)
 {
        struct ieee80211_device *ieee = netdev_priv(dev);
 
-       int i;
-
-       ieee80211_crypt_quiescing(ieee);
-       del_timer_sync(&ieee->crypt_deinit_timer);
-       ieee80211_crypt_deinit_entries(ieee, 1);
-
-       for (i = 0; i < WEP_KEYS; i++) {
-               struct ieee80211_crypt_data *crypt = ieee->crypt[i];
-               if (crypt) {
-                       if (crypt->ops) {
-                               crypt->ops->deinit(crypt->priv);
-                               module_put(crypt->ops->owner);
-                       }
-                       kfree(crypt);
-                       ieee->crypt[i] = NULL;
-               }
-       }
+       lib80211_crypt_info_free(&ieee->crypt_info);
 
        ieee80211_networks_free(ieee);
        free_netdev(dev);
similarity index 99%
rename from net/ieee80211/ieee80211_rx.c
rename to drivers/net/wireless/ipw2x00/libipw_rx.c
index 3dd58b5..9c67dfa 100644 (file)
@@ -268,7 +268,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
 /* Called only as a tasklet (software IRQ), by ieee80211_rx */
 static int
 ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
-                          struct ieee80211_crypt_data *crypt)
+                          struct lib80211_crypt_data *crypt)
 {
        struct ieee80211_hdr_3addr *hdr;
        int res, hdrlen;
@@ -300,7 +300,7 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
 static int
 ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
                                struct sk_buff *skb, int keyidx,
-                               struct ieee80211_crypt_data *crypt)
+                               struct lib80211_crypt_data *crypt)
 {
        struct ieee80211_hdr_3addr *hdr;
        int res, hdrlen;
@@ -348,7 +348,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 #endif
        u8 dst[ETH_ALEN];
        u8 src[ETH_ALEN];
-       struct ieee80211_crypt_data *crypt = NULL;
+       struct lib80211_crypt_data *crypt = NULL;
        int keyidx = 0;
        int can_be_decrypted = 0;
 
@@ -431,7 +431,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                 * is only allowed 2-bits of storage, no value of keyidx can
                 * be provided via above code that would result in keyidx
                 * being out of range */
-               crypt = ieee->crypt[keyidx];
+               crypt = ieee->crypt_info.crypt[keyidx];
 
 #ifdef NOT_YET
                sta = NULL;
similarity index 98%
rename from net/ieee80211/ieee80211_tx.c
rename to drivers/net/wireless/ipw2x00/libipw_tx.c
index d996547..f78f57e 100644 (file)
@@ -152,7 +152,8 @@ static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
 static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
                                             struct sk_buff *frag, int hdr_len)
 {
-       struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
+       struct lib80211_crypt_data *crypt =
+               ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
        int res;
 
        if (crypt == NULL)
@@ -270,7 +271,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
                .qos_ctl = 0
        };
        u8 dest[ETH_ALEN], src[ETH_ALEN];
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
        int priority = skb->priority;
        int snapped = 0;
 
@@ -294,7 +295,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 
        ether_type = ((struct ethhdr *)skb->data)->h_proto;
 
-       crypt = ieee->crypt[ieee->tx_keyidx];
+       crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
 
        encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
            ieee->sec.encrypt;
similarity index 93%
rename from net/ieee80211/ieee80211_wx.c
rename to drivers/net/wireless/ipw2x00/libipw_wx.c
index 7cc4e5e..31ea3ab 100644 (file)
@@ -307,7 +307,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                .flags = 0
        };
        int i, key, key_provided, len;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypt_data **crypt;
        int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
        DECLARE_SSID_BUF(ssid);
 
@@ -321,30 +321,30 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                key_provided = 1;
        } else {
                key_provided = 0;
-               key = ieee->tx_keyidx;
+               key = ieee->crypt_info.tx_keyidx;
        }
 
        IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
                           "provided" : "default");
 
-       crypt = &ieee->crypt[key];
+       crypt = &ieee->crypt_info.crypt[key];
 
        if (erq->flags & IW_ENCODE_DISABLED) {
                if (key_provided && *crypt) {
                        IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
                                           key);
-                       ieee80211_crypt_delayed_deinit(ieee, crypt);
+                       lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
                } else
                        IEEE80211_DEBUG_WX("Disabling encryption.\n");
 
                /* Check all the keys to see if any are still configured,
                 * and if no key index was provided, de-init them all */
                for (i = 0; i < WEP_KEYS; i++) {
-                       if (ieee->crypt[i] != NULL) {
+                       if (ieee->crypt_info.crypt[i] != NULL) {
                                if (key_provided)
                                        break;
-                               ieee80211_crypt_delayed_deinit(ieee,
-                                                              &ieee->crypt[i]);
+                               lib80211_crypt_delayed_deinit(&ieee->crypt_info,
+                                                              &ieee->crypt_info.crypt[i]);
                        }
                }
 
@@ -366,21 +366,21 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
            strcmp((*crypt)->ops->name, "WEP") != 0) {
                /* changing to use WEP; deinit previously used algorithm
                 * on this key */
-               ieee80211_crypt_delayed_deinit(ieee, crypt);
+               lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
        }
 
        if (*crypt == NULL && host_crypto) {
-               struct ieee80211_crypt_data *new_crypt;
+               struct lib80211_crypt_data *new_crypt;
 
                /* take WEP into use */
-               new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
+               new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
                                    GFP_KERNEL);
                if (new_crypt == NULL)
                        return -ENOMEM;
-               new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+               new_crypt->ops = lib80211_get_crypto_ops("WEP");
                if (!new_crypt->ops) {
-                       request_module("ieee80211_crypt_wep");
-                       new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+                       request_module("lib80211_crypt_wep");
+                       new_crypt->ops = lib80211_get_crypto_ops("WEP");
                }
 
                if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
@@ -391,7 +391,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                        new_crypt = NULL;
 
                        printk(KERN_WARNING "%s: could not initialize WEP: "
-                              "load module ieee80211_crypt_wep\n", dev->name);
+                              "load module lib80211_crypt_wep\n", dev->name);
                        return -EOPNOTSUPP;
                }
                *crypt = new_crypt;
@@ -440,7 +440,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                if (key_provided) {
                        IEEE80211_DEBUG_WX("Setting key %d to default Tx "
                                           "key.\n", key);
-                       ieee->tx_keyidx = key;
+                       ieee->crypt_info.tx_keyidx = key;
                        sec.active_key = key;
                        sec.flags |= SEC_ACTIVE_KEY;
                }
@@ -485,7 +485,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
 {
        struct iw_point *erq = &(wrqu->encoding);
        int len, key;
-       struct ieee80211_crypt_data *crypt;
+       struct lib80211_crypt_data *crypt;
        struct ieee80211_security *sec = &ieee->sec;
 
        IEEE80211_DEBUG_WX("GET_ENCODE\n");
@@ -496,9 +496,9 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
                        return -EINVAL;
                key--;
        } else
-               key = ieee->tx_keyidx;
+               key = ieee->crypt_info.tx_keyidx;
 
-       crypt = ieee->crypt[key];
+       crypt = ieee->crypt_info.crypt[key];
        erq->flags = key + 1;
 
        if (!sec->enabled) {
@@ -531,8 +531,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
        int i, idx, ret = 0;
        int group_key = 0;
        const char *alg, *module;
-       struct ieee80211_crypto_ops *ops;
-       struct ieee80211_crypt_data **crypt;
+       struct lib80211_crypto_ops *ops;
+       struct lib80211_crypt_data **crypt;
 
        struct ieee80211_security sec = {
                .flags = 0,
@@ -544,17 +544,17 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
                        return -EINVAL;
                idx--;
        } else
-               idx = ieee->tx_keyidx;
+               idx = ieee->crypt_info.tx_keyidx;
 
        if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-               crypt = &ieee->crypt[idx];
+               crypt = &ieee->crypt_info.crypt[idx];
                group_key = 1;
        } else {
                /* some Cisco APs use idx>0 for unicast in dynamic WEP */
                if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
                        return -EINVAL;
                if (ieee->iw_mode == IW_MODE_INFRA)
-                       crypt = &ieee->crypt[idx];
+                       crypt = &ieee->crypt_info.crypt[idx];
                else
                        return -EINVAL;
        }
@@ -563,10 +563,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
        if ((encoding->flags & IW_ENCODE_DISABLED) ||
            ext->alg == IW_ENCODE_ALG_NONE) {
                if (*crypt)
-                       ieee80211_crypt_delayed_deinit(ieee, crypt);
+                       lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 
                for (i = 0; i < WEP_KEYS; i++)
-                       if (ieee->crypt[i] != NULL)
+                       if (ieee->crypt_info.crypt[i] != NULL)
                                break;
 
                if (i == WEP_KEYS) {
@@ -589,15 +589,15 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
        switch (ext->alg) {
        case IW_ENCODE_ALG_WEP:
                alg = "WEP";
-               module = "ieee80211_crypt_wep";
+               module = "lib80211_crypt_wep";
                break;
        case IW_ENCODE_ALG_TKIP:
                alg = "TKIP";
-               module = "ieee80211_crypt_tkip";
+               module = "lib80211_crypt_tkip";
                break;
        case IW_ENCODE_ALG_CCMP:
                alg = "CCMP";
-               module = "ieee80211_crypt_ccmp";
+               module = "lib80211_crypt_ccmp";
                break;
        default:
                IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -606,10 +606,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
                goto done;
        }
 
-       ops = ieee80211_get_crypto_ops(alg);
+       ops = lib80211_get_crypto_ops(alg);
        if (ops == NULL) {
                request_module(module);
-               ops = ieee80211_get_crypto_ops(alg);
+               ops = lib80211_get_crypto_ops(alg);
        }
        if (ops == NULL) {
                IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -619,9 +619,9 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
        }
 
        if (*crypt == NULL || (*crypt)->ops != ops) {
-               struct ieee80211_crypt_data *new_crypt;
+               struct lib80211_crypt_data *new_crypt;
 
-               ieee80211_crypt_delayed_deinit(ieee, crypt);
+               lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 
                new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
                if (new_crypt == NULL) {
@@ -649,7 +649,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
 
       skip_host_crypt:
        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-               ieee->tx_keyidx = idx;
+               ieee->crypt_info.tx_keyidx = idx;
                sec.active_key = idx;
                sec.flags |= SEC_ACTIVE_KEY;
        }
@@ -715,7 +715,7 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
                        return -EINVAL;
                idx--;
        } else
-               idx = ieee->tx_keyidx;
+               idx = ieee->crypt_info.tx_keyidx;
 
        if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
            ext->alg != IW_ENCODE_ALG_WEP)
index 47aa28f..8b45b30 100644 (file)
@@ -5,6 +5,7 @@ iwlcore-objs            += iwl-scan.o
 iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
 iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
 iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
+iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
 
 obj-$(CONFIG_IWLAGN)   += iwlagn.o
 iwlagn-objs            := iwl-agn.o iwl-agn-rs.o
index 9da7c7b..fb0fd77 100644 (file)
@@ -819,64 +819,6 @@ enum {
 #define IWL49_NUM_QUEUES       16
 #define IWL49_NUM_AMPDU_QUEUES 8
 
-#define IWL_TX_DMA_MASK        (DMA_BIT_MASK(36) & ~0x3)
-#define IWL_NUM_OF_TBS         20
-
-static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
-{
-       return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF;
-}
-/**
- * struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor
- *
- * This structure contains dma address and length of transmission address
- *
- * @lo: low [31:0] portion of the dma address of TX buffer
- *     every even is unaligned on 16 bit boundary
- * @hi_n_len 0-3 [35:32] portion of dma
- *          4-16 length of the tx buffer
- */
-struct iwl_tfd_tb {
-       __le32 lo;
-       __le16 hi_n_len;
-} __attribute__((packed));
-
-/**
- * struct iwl_tfd
- *
- * Transmit Frame Descriptor (TFD)
- *
- * @ __reserved1[3] reserved
- * @ num_tbs 0-5 number of active tbs
- *          6-7 padding (not used)
- * @ tbs[20]   transmit frame buffer descriptors
- * @ __pad     padding
- *
- * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
- * Both driver and device share these circular buffers, each of which must be
- * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes
- *
- * Driver must indicate the physical address of the base of each
- * circular buffer via the FH_MEM_CBBC_QUEUE registers.
- *
- * Each TFD contains pointer/size information for up to 20 data buffers
- * in host DRAM.  These buffers collectively contain the (one) frame described
- * by the TFD.  Each buffer must be a single contiguous block of memory within
- * itself, but buffers may be scattered in host DRAM.  Each buffer has max size
- * of (4K - 4).  The concatenates all of a TFD's buffers into a single
- * Tx frame, up to 8 KBytes in size.
- *
- * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
- *
- * Bit fields in the control dword (val0):
- */
-struct iwl_tfd {
-       u8 __reserved1[3];
-       u8 num_tbs;
-       struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS];
-       __le32 __pad;
-} __attribute__ ((packed));
-
 
 /**
  * struct iwl4965_schedq_bc_tbl
@@ -896,64 +838,9 @@ struct iwl_tfd {
  * padding puts each byte count table on a 1024-byte boundary;
  * 4965 assumes tables are separated by 1024 bytes.
  */
-struct iwl4965_schedq_bc_tbl {
+struct iwl4965_scd_bc_tbl {
        __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
        u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)];
 } __attribute__ ((packed));
 
-
-/**
- * struct iwl4965_shared - handshake area for Tx and Rx
- *
- * For convenience in allocating memory, this structure combines 2 areas of
- * DRAM which must be shared between driver and 4965.  These do not need to
- * be combined, if better allocation would result from keeping them separate:
- *
- * 1)  The Tx byte count tables occupy 1024 bytes each (16 KBytes total for
- *     16 queues).  Driver uses SCD_DRAM_BASE_ADDR to tell 4965 where to find
- *     the first of these tables.  4965 assumes tables are 1024 bytes apart.
- *
- * 2)  The Rx status (val0 and val1) occupies only 8 bytes.  Driver uses
- *     FH_RSCSR_CHNL0_STTS_WPTR_REG to tell 4965 where to find this area.
- *     Driver reads val0 to determine the latest Receive Buffer Descriptor (RBD)
- *     that has been filled by the 4965.
- *
- * Bit fields val0:
- * 31-12:  Not used
- * 11- 0:  Index of last filled Rx buffer descriptor (4965 writes, driver reads)
- *
- * Bit fields val1:
- * 31- 0:  Not used
- */
-struct iwl4965_shared {
-       struct iwl4965_schedq_bc_tbl queues_bc_tbls[IWL49_NUM_QUEUES];
-       __le32 rb_closed;
-
-       /* __le32 rb_closed_stts_rb_num:12; */
-#define IWL_rb_closed_stts_rb_num_POS 0
-#define IWL_rb_closed_stts_rb_num_LEN 12
-#define IWL_rb_closed_stts_rb_num_SYM rb_closed
-       /* __le32 rsrv1:4; */
-       /* __le32 rb_closed_stts_rx_frame_num:12; */
-#define IWL_rb_closed_stts_rx_frame_num_POS 16
-#define IWL_rb_closed_stts_rx_frame_num_LEN 12
-#define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed
-       /* __le32 rsrv2:4; */
-
-       __le32 frm_finished;
-       /* __le32 frame_finished_stts_rb_num:12; */
-#define IWL_frame_finished_stts_rb_num_POS 0
-#define IWL_frame_finished_stts_rb_num_LEN 12
-#define IWL_frame_finished_stts_rb_num_SYM frm_finished
-       /* __le32 rsrv3:4; */
-       /* __le32 frame_finished_stts_rx_frame_num:12; */
-#define IWL_frame_finished_stts_rx_frame_num_POS 16
-#define IWL_frame_finished_stts_rx_frame_num_LEN 12
-#define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished
-       /* __le32 rsrv4:4; */
-
-       __le32 padding1;  /* so that allocation will be aligned to 16B */
-       __le32 padding2;
-} __attribute__ ((packed));
-
-#endif /* __iwl4965_4965_hw_h__ */
+#endif /* !__iwl_4965_hw_h__ */
index 157cad4..c43cf2f 100644 (file)
@@ -715,8 +715,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
 
        /* Tel 4965 where to find Tx byte count tables */
        iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
-               (priv->shared_phys +
-                offsetof(struct iwl4965_shared, queues_bc_tbls)) >> 10);
+                       priv->scd_bc_tbls.dma >> 10);
 
        /* Disable chain mode for all queues */
        iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
@@ -804,6 +803,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
        }
 
        priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
+       priv->hw_params.scd_bc_tbls_size =
+                       IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
        priv->hw_params.max_stations = IWL4965_STATION_COUNT;
        priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
        priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -1631,36 +1632,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 }
 #endif
 
-static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
-{
-       struct iwl4965_shared *s = priv->shared_virt;
-       return le32_to_cpu(s->rb_closed) & 0xFFF;
-}
-
-static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
-{
-       priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
-                                       sizeof(struct iwl4965_shared),
-                                       &priv->shared_phys);
-       if (!priv->shared_virt)
-               return -ENOMEM;
-
-       memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));
-
-       priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed);
-
-       return 0;
-}
-
-static void iwl4965_free_shared_mem(struct iwl_priv *priv)
-{
-       if (priv->shared_virt)
-               pci_free_consistent(priv->pci_dev,
-                                   sizeof(struct iwl4965_shared),
-                                   priv->shared_virt,
-                                   priv->shared_phys);
-}
-
 /**
  * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
  */
@@ -1668,7 +1639,7 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
                                            struct iwl_tx_queue *txq,
                                            u16 byte_cnt)
 {
-       struct iwl4965_shared *shared_data = priv->shared_virt;
+       struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
        int txq_id = txq->q.id;
        int write_ptr = txq->q.write_ptr;
        int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
@@ -1678,11 +1649,11 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
 
        bc_ent = cpu_to_le16(len & 0xFFF);
        /* Set up byte count within first 256 entries */
-       shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent;
+       scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
 
        /* If within first 64 entries, duplicate at end */
        if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
-               shared_data->queues_bc_tbls[txq_id].
+               scd_bc_tbl[txq_id].
                        tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
 }
 
@@ -2304,9 +2275,6 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
 
 static struct iwl_lib_ops iwl4965_lib = {
        .set_hw_params = iwl4965_hw_set_hw_params,
-       .alloc_shared_mem = iwl4965_alloc_shared_mem,
-       .free_shared_mem = iwl4965_free_shared_mem,
-       .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx,
        .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
        .txq_set_sched = iwl4965_txq_set_sched,
        .txq_agg_enable = iwl4965_txq_agg_enable,
index 12c7404..c6595e8 100644 (file)
  * @tfd_offset  0-12 - tx command byte count
  *            12-16 - station index
  */
-struct iwl5000_schedq_bc_tbl {
+struct iwl5000_scd_bc_tbl {
        __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
 } __attribute__ ((packed));
 
-/**
- * struct iwl5000_shared
- * @rb_closed
- *     address is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG
- */
-struct iwl5000_shared {
-       struct iwl5000_schedq_bc_tbl queues_bc_tbls[IWL50_NUM_QUEUES];
-       __le32 rb_closed;
-
-       /* __le32 rb_closed_stts_rb_num:12; */
-#define IWL_rb_closed_stts_rb_num_POS 0
-#define IWL_rb_closed_stts_rb_num_LEN 12
-#define IWL_rb_closed_stts_rb_num_SYM rb_closed
-       /* __le32 rsrv1:4; */
-       /* __le32 rb_closed_stts_rx_frame_num:12; */
-#define IWL_rb_closed_stts_rx_frame_num_POS 16
-#define IWL_rb_closed_stts_rx_frame_num_LEN 12
-#define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed
-       /* __le32 rsrv2:4; */
-
-       __le32 frm_finished;
-       /* __le32 frame_finished_stts_rb_num:12; */
-#define IWL_frame_finished_stts_rb_num_POS 0
-#define IWL_frame_finished_stts_rb_num_LEN 12
-#define IWL_frame_finished_stts_rb_num_SYM frm_finished
-       /* __le32 rsrv3:4; */
-       /* __le32 frame_finished_stts_rx_frame_num:12; */
-#define IWL_frame_finished_stts_rx_frame_num_POS 16
-#define IWL_frame_finished_stts_rx_frame_num_LEN 12
-#define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished
-       /* __le32 rsrv4:4; */
-
-       __le32 padding1;  /* so that allocation will be aligned to 16B */
-       __le32 padding2;
-} __attribute__ ((packed));
 
 #endif /* __iwl_5000_hw_h__ */
 
index 31e62a8..ee3613d 100644 (file)
@@ -721,11 +721,9 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
                iwl_write_targ_mem(priv, a, 0);
 
        iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
-               (priv->shared_phys +
-                offsetof(struct iwl5000_shared, queues_bc_tbls)) >> 10);
+                      priv->scd_bc_tbls.dma >> 10);
        iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
-               IWL50_SCD_QUEUECHAIN_SEL_ALL(
-                       priv->hw_params.max_txq_num));
+               IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
        iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
 
        /* initiate the queues */
@@ -788,6 +786,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
        }
 
        priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
+       priv->hw_params.scd_bc_tbls_size =
+                       IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
        priv->hw_params.max_stations = IWL5000_STATION_COUNT;
        priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
        priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
@@ -853,36 +853,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
        return 0;
 }
 
-static int iwl5000_alloc_shared_mem(struct iwl_priv *priv)
-{
-       priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
-                                       sizeof(struct iwl5000_shared),
-                                       &priv->shared_phys);
-       if (!priv->shared_virt)
-               return -ENOMEM;
-
-       memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared));
-
-       priv->rb_closed_offset = offsetof(struct iwl5000_shared, rb_closed);
-
-       return 0;
-}
-
-static void iwl5000_free_shared_mem(struct iwl_priv *priv)
-{
-       if (priv->shared_virt)
-               pci_free_consistent(priv->pci_dev,
-                                   sizeof(struct iwl5000_shared),
-                                   priv->shared_virt,
-                                   priv->shared_phys);
-}
-
-static int iwl5000_shared_mem_rx_idx(struct iwl_priv *priv)
-{
-       struct iwl5000_shared *s = priv->shared_virt;
-       return le32_to_cpu(s->rb_closed) & 0xFFF;
-}
-
 /**
  * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
  */
@@ -890,7 +860,7 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
                                            struct iwl_tx_queue *txq,
                                            u16 byte_cnt)
 {
-       struct iwl5000_shared *shared_data = priv->shared_virt;
+       struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
        int write_ptr = txq->q.write_ptr;
        int txq_id = txq->q.id;
        u8 sec_ctl = 0;
@@ -919,17 +889,17 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
 
        bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
 
-       shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent;
+       scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
 
        if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
-               shared_data->queues_bc_tbls[txq_id].
+               scd_bc_tbl[txq_id].
                        tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
 }
 
 static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
                                           struct iwl_tx_queue *txq)
 {
-       struct iwl5000_shared *shared_data = priv->shared_virt;
+       struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
        int txq_id = txq->q.id;
        int read_ptr = txq->q.read_ptr;
        u8 sta_id = 0;
@@ -941,11 +911,10 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
                sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
 
        bc_ent =  cpu_to_le16(1 | (sta_id << 12));
-       shared_data->queues_bc_tbls[txq_id].
-                       tfd_offset[read_ptr] = bc_ent;
+       scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
 
        if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
-               shared_data->queues_bc_tbls[txq_id].
+               scd_bc_tbl[txq_id].
                        tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] =  bc_ent;
 }
 
@@ -1458,9 +1427,6 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
 
 static struct iwl_lib_ops iwl5000_lib = {
        .set_hw_params = iwl5000_hw_set_hw_params,
-       .alloc_shared_mem = iwl5000_alloc_shared_mem,
-       .free_shared_mem = iwl5000_free_shared_mem,
-       .shared_mem_rx_idx = iwl5000_shared_mem_rx_idx,
        .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
        .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
        .txq_set_sched = iwl5000_txq_set_sched,
index 35cfa15..8fa4f7a 100644 (file)
@@ -871,138 +871,6 @@ static void iwl_set_rate(struct iwl_priv *priv)
                   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
 }
 
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
-
-#include "iwl-spectrum.h"
-
-#define BEACON_TIME_MASK_LOW   0x00FFFFFF
-#define BEACON_TIME_MASK_HIGH  0xFF000000
-#define TIME_UNIT              1024
-
-/*
- * extended beacon time format
- * time in usec will be changed into a 32-bit value in 8:24 format
- * the high 1 byte is the beacon counts
- * the lower 3 bytes is the time in usec within one beacon interval
- */
-
-static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
-{
-       u32 quot;
-       u32 rem;
-       u32 interval = beacon_interval * 1024;
-
-       if (!interval || !usec)
-               return 0;
-
-       quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
-       rem = (usec % interval) & BEACON_TIME_MASK_LOW;
-
-       return (quot << 24) + rem;
-}
-
-/* base is usually what we get from ucode with each received frame,
- * the same as HW timer counter counting down
- */
-
-static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
-{
-       u32 base_low = base & BEACON_TIME_MASK_LOW;
-       u32 addon_low = addon & BEACON_TIME_MASK_LOW;
-       u32 interval = beacon_interval * TIME_UNIT;
-       u32 res = (base & BEACON_TIME_MASK_HIGH) +
-           (addon & BEACON_TIME_MASK_HIGH);
-
-       if (base_low > addon_low)
-               res += base_low - addon_low;
-       else if (base_low < addon_low) {
-               res += interval + base_low - addon_low;
-               res += (1 << 24);
-       } else
-               res += (1 << 24);
-
-       return cpu_to_le32(res);
-}
-
-static int iwl_get_measurement(struct iwl_priv *priv,
-                              struct ieee80211_measurement_params *params,
-                              u8 type)
-{
-       struct iwl4965_spectrum_cmd spectrum;
-       struct iwl_rx_packet *res;
-       struct iwl_host_cmd cmd = {
-               .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
-               .data = (void *)&spectrum,
-               .meta.flags = CMD_WANT_SKB,
-       };
-       u32 add_time = le64_to_cpu(params->start_time);
-       int rc;
-       int spectrum_resp_status;
-       int duration = le16_to_cpu(params->duration);
-
-       if (iwl_is_associated(priv))
-               add_time =
-                   iwl_usecs_to_beacons(
-                       le64_to_cpu(params->start_time) - priv->last_tsf,
-                       le16_to_cpu(priv->rxon_timing.beacon_interval));
-
-       memset(&spectrum, 0, sizeof(spectrum));
-
-       spectrum.channel_count = cpu_to_le16(1);
-       spectrum.flags =
-           RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
-       spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
-       cmd.len = sizeof(spectrum);
-       spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
-
-       if (iwl_is_associated(priv))
-               spectrum.start_time =
-                   iwl_add_beacon_time(priv->last_beacon_time,
-                               add_time,
-                               le16_to_cpu(priv->rxon_timing.beacon_interval));
-       else
-               spectrum.start_time = 0;
-
-       spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
-       spectrum.channels[0].channel = params->channel;
-       spectrum.channels[0].type = type;
-       if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
-               spectrum.flags |= RXON_FLG_BAND_24G_MSK |
-                   RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
-
-       rc = iwl_send_cmd_sync(priv, &cmd);
-       if (rc)
-               return rc;
-
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
-       if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-               IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
-               rc = -EIO;
-       }
-
-       spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
-       switch (spectrum_resp_status) {
-       case 0:         /* Command will be handled */
-               if (res->u.spectrum.id != 0xff) {
-                       IWL_DEBUG_INFO
-                           ("Replaced existing measurement: %d\n",
-                            res->u.spectrum.id);
-                       priv->measurement_status &= ~MEASUREMENT_READY;
-               }
-               priv->measurement_status |= MEASUREMENT_ACTIVE;
-               rc = 0;
-               break;
-
-       case 1:         /* Command will not be handled */
-               rc = -EAGAIN;
-               break;
-       }
-
-       dev_kfree_skb_any(cmd.meta.u.skb);
-
-       return rc;
-}
-#endif
 
 /******************************************************************************
  *
@@ -1072,24 +940,6 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        priv->staging_rxon.channel = csa->channel;
 }
 
-static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
-                                         struct iwl_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-       struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
-
-       if (!report->state) {
-               IWL_DEBUG(IWL_DL_11H,
-                       "Spectrum Measure Notification: Start\n");
-               return;
-       }
-
-       memcpy(&priv->measure_report, report, sizeof(*report));
-       priv->measurement_status |= MEASUREMENT_READY;
-#endif
-}
-
 static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
                                      struct iwl_rx_mem_buffer *rxb)
 {
@@ -1298,8 +1148,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
        priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
        priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
        priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
-       priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
-           iwl_rx_spectrum_measure_notif;
        priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
        priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
            iwl_rx_pm_debug_statistics_notif;
@@ -1313,6 +1161,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
        priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
        priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
 
+       iwl_setup_spectrum_handlers(priv);
        iwl_setup_rx_scan_handlers(priv);
 
        /* status change handler */
@@ -1359,7 +1208,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
-       r = priv->cfg->ops->lib->shared_mem_rx_idx(priv);
+       r = le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF;
        i = rxq->read;
 
        /* Rx interrupt, but nothing sent from uCode */
@@ -2002,6 +1851,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        return ret;
 }
 
+/* temporary */
+static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
+                                struct sk_buff *skb);
+
 /**
  * iwl_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
@@ -2084,6 +1937,15 @@ static void iwl_alive_start(struct iwl_priv *priv)
 
        iwl_power_update_mode(priv, 1);
 
+       /* reassociate for ADHOC mode */
+       if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
+               struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
+                                                               priv->vif);
+               if (beacon)
+                       iwl_mac_beacon_update(priv->hw, beacon);
+       }
+
+
        if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
                iwl_set_mode(priv, priv->iw_mode);
 
@@ -2183,8 +2045,6 @@ static void __iwl_down(struct iwl_priv *priv)
                priv->cfg->ops->lib->apm_ops.stop(priv);
        else
                priv->cfg->ops->lib->apm_ops.reset(priv);
-       priv->cfg->ops->lib->free_shared_mem(priv);
-
  exit:
        memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
 
@@ -2237,12 +2097,6 @@ static int __iwl_up(struct iwl_priv *priv)
 
        iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
 
-       ret = priv->cfg->ops->lib->alloc_shared_mem(priv);
-       if (ret) {
-               IWL_ERROR("Unable to allocate shared memory\n");
-               return ret;
-       }
-
        ret = iwl_hw_nic_init(priv);
        if (ret) {
                IWL_ERROR("Unable to init nic\n");
@@ -2930,8 +2784,6 @@ static void iwl_config_ap(struct iwl_priv *priv)
         * clear sta table, add BCAST sta... */
 }
 
-/* temporary */
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
 
 static int iwl_mac_config_interface(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif,
@@ -2953,7 +2805,9 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
                struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
                if (!beacon)
                        return -ENOMEM;
+               mutex_lock(&priv->mutex);
                rc = iwl_mac_beacon_update(hw, beacon);
+               mutex_unlock(&priv->mutex);
                if (rc)
                        return rc;
        }
@@ -3529,18 +3383,15 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
        unsigned long flags;
        __le64 timestamp;
 
-       mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
        if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
-               mutex_unlock(&priv->mutex);
                return -EIO;
        }
 
        if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
                IWL_DEBUG_MAC80211("leave - not IBSS\n");
-               mutex_unlock(&priv->mutex);
                return -EIO;
        }
 
@@ -3562,7 +3413,6 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 
        iwl_post_associate(priv);
 
-       mutex_unlock(&priv->mutex);
 
        return 0;
 }
@@ -3766,79 +3616,6 @@ static ssize_t store_filter_flags(struct device *d,
 static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
                   store_filter_flags);
 
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
-
-static ssize_t show_measurement(struct device *d,
-                               struct device_attribute *attr, char *buf)
-{
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       struct iwl4965_spectrum_notification measure_report;
-       u32 size = sizeof(measure_report), len = 0, ofs = 0;
-       u8 *data = (u8 *)&measure_report;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       if (!(priv->measurement_status & MEASUREMENT_READY)) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return 0;
-       }
-       memcpy(&measure_report, &priv->measure_report, size);
-       priv->measurement_status = 0;
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       while (size && (PAGE_SIZE - len)) {
-               hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
-                                  PAGE_SIZE - len, 1);
-               len = strlen(buf);
-               if (PAGE_SIZE - len)
-                       buf[len++] = '\n';
-
-               ofs += 16;
-               size -= min(size, 16U);
-       }
-
-       return len;
-}
-
-static ssize_t store_measurement(struct device *d,
-                                struct device_attribute *attr,
-                                const char *buf, size_t count)
-{
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       struct ieee80211_measurement_params params = {
-               .channel = le16_to_cpu(priv->active_rxon.channel),
-               .start_time = cpu_to_le64(priv->last_tsf),
-               .duration = cpu_to_le16(1),
-       };
-       u8 type = IWL_MEASURE_BASIC;
-       u8 buffer[32];
-       u8 channel;
-
-       if (count) {
-               char *p = buffer;
-               strncpy(buffer, buf, min(sizeof(buffer), count));
-               channel = simple_strtoul(p, NULL, 0);
-               if (channel)
-                       params.channel = channel;
-
-               p = buffer;
-               while (*p && *p != ' ')
-                       p++;
-               if (*p)
-                       type = simple_strtoul(p + 1, NULL, 0);
-       }
-
-       IWL_DEBUG_INFO("Invoking measurement of type %d on "
-                      "channel %d (for '%s')\n", type, params.channel, buf);
-       iwl_get_measurement(priv, &params, type);
-
-       return count;
-}
-
-static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
-                  show_measurement, store_measurement);
-#endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
-
 static ssize_t store_retry_rate(struct device *d,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
@@ -4091,9 +3868,6 @@ static struct attribute *iwl_sysfs_entries[] = {
        &dev_attr_channels.attr,
        &dev_attr_flags.attr,
        &dev_attr_filter_flags.attr,
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
-       &dev_attr_measurement.attr,
-#endif
        &dev_attr_power_level.attr,
        &dev_attr_retry_rate.attr,
        &dev_attr_statistics.attr,
index 8aade00..1fe83d4 100644 (file)
@@ -213,10 +213,11 @@ struct iwl_cmd_header {
 } __attribute__ ((packed));
 
 /**
- * 4965 rate_n_flags bit fields
+ * iwlagn rate_n_flags bit fields
  *
- * rate_n_flags format is used in following 4965 commands:
+ * rate_n_flags format is used in following iwlagn commands:
  *  REPLY_RX (response only)
+ *  REPLY_RX_MPDU (response only)
  *  REPLY_TX (both command and response)
  *  REPLY_TX_LINK_QUALITY_CMD
  *
@@ -230,8 +231,9 @@ struct iwl_cmd_header {
  *        6)  54 Mbps
  *        7)  60 Mbps
  *
- *    3:  0)  Single stream (SISO)
+ *  4-3:  0)  Single stream (SISO)
  *        1)  Dual stream (MIMO)
+ *        2)  Triple stream (MIMO)
  *
  *    5:  Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data
  *
@@ -252,8 +254,8 @@ struct iwl_cmd_header {
  *        110)  11 Mbps
  */
 #define RATE_MCS_CODE_MSK 0x7
-#define RATE_MCS_MIMO_POS 3
-#define RATE_MCS_MIMO_MSK 0x8
+#define RATE_MCS_SPATIAL_POS 3
+#define RATE_MCS_SPATIAL_MSK 0x18
 #define RATE_MCS_HT_DUP_POS 5
 #define RATE_MCS_HT_DUP_MSK 0x20
 
index 8eb0203..8bd4d08 100644 (file)
 #include <linux/module.h>
 #include <net/mac80211.h>
 
-struct iwl_priv; /* FIXME: remove */
-#include "iwl-debug.h"
 #include "iwl-eeprom.h"
 #include "iwl-dev.h" /* FIXME: remove */
+#include "iwl-debug.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-rfkill.h"
@@ -190,52 +189,6 @@ void iwl_hw_detect(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_hw_detect);
 
-/* Tell nic where to find the "keep warm" buffer */
-int iwl_kw_init(struct iwl_priv *priv)
-{
-       unsigned long flags;
-       int ret;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               goto out;
-
-       iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG,
-                            priv->kw.dma_addr >> 4);
-       iwl_release_nic_access(priv);
-out:
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return ret;
-}
-
-int iwl_kw_alloc(struct iwl_priv *priv)
-{
-       struct pci_dev *dev = priv->pci_dev;
-       struct iwl_kw *kw = &priv->kw;
-
-       kw->size = IWL_KW_SIZE;
-       kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr);
-       if (!kw->v_addr)
-               return -ENOMEM;
-
-       return 0;
-}
-
-/**
- * iwl_kw_free - Free the "keep warm" buffer
- */
-void iwl_kw_free(struct iwl_priv *priv)
-{
-       struct pci_dev *dev = priv->pci_dev;
-       struct iwl_kw *kw = &priv->kw;
-
-       if (kw->v_addr) {
-               pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr);
-               memset(kw, 0, sizeof(*kw));
-       }
-}
-
 int iwl_hw_nic_init(struct iwl_priv *priv)
 {
        unsigned long flags;
index 10f07f6..ff966b8 100644 (file)
@@ -102,10 +102,6 @@ struct iwl_hcmd_utils_ops {
 struct iwl_lib_ops {
        /* set hw dependent parameters */
        int (*set_hw_params)(struct iwl_priv *priv);
-       /* ucode shared memory */
-       int (*alloc_shared_mem)(struct iwl_priv *priv);
-       void (*free_shared_mem)(struct iwl_priv *priv);
-       int (*shared_mem_rx_idx)(struct iwl_priv *priv);
        /* Handling TX */
        void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
                                        struct iwl_tx_queue *txq,
@@ -198,10 +194,6 @@ int iwl_setup_mac(struct iwl_priv *priv);
 int iwl_set_hw_params(struct iwl_priv *priv);
 int iwl_init_drv(struct iwl_priv *priv);
 void iwl_uninit_drv(struct iwl_priv *priv);
-/* "keep warm" functions */
-int iwl_kw_init(struct iwl_priv *priv);
-int iwl_kw_alloc(struct iwl_priv *priv);
-void iwl_kw_free(struct iwl_priv *priv);
 
 /*****************************************************
 * RX
@@ -297,6 +289,14 @@ int iwl_send_calib_results(struct iwl_priv *priv);
 int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
 void iwl_calib_free_results(struct iwl_priv *priv);
 
+/*******************************************************************************
+ * Spectrum Measureemtns in  iwl-spectrum.c
+ ******************************************************************************/
+#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
+#else
+static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
+#endif
 /*****************************************************
  *   S e n d i n g     H o s t     C o m m a n d s   *
  *****************************************************/
index 84b7772..0e79a6a 100644 (file)
@@ -40,6 +40,13 @@ do { if ((priv->debug_level & (level)) && net_ratelimit()) \
   dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
         in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
 
+#define iwl_print_hex_dump(priv, level, p, len)                        \
+do {                                                                   \
+       if (priv->debug_level & level)                                  \
+               print_hex_dump(KERN_DEBUG, "iwl data: ",                \
+                              DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);   \
+} while (0)
+
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 struct iwl_debugfs {
        const char *name;
@@ -70,6 +77,9 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
 #else
 #define IWL_DEBUG(level, fmt, args...)
 #define IWL_DEBUG_LIMIT(level, fmt, args...)
+static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
+                                     void *p, u32 len)
+{}
 #endif                         /* CONFIG_IWLWIFI_DEBUG */
 
 
index d509aed..bd3df55 100644 (file)
@@ -301,7 +301,6 @@ struct iwl_host_cmd {
 
 /**
  * struct iwl_rx_queue - Rx queue
- * @processed: Internal index to last handled Rx packet
  * @read: Shared index to newest available Rx buffer
  * @write: Shared index to oldest written Rx packet
  * @free_count: Number of pre-allocated buffers in rx_free
@@ -316,13 +315,14 @@ struct iwl_rx_queue {
        dma_addr_t dma_addr;
        struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
        struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
-       u32 processed;
        u32 read;
        u32 write;
        u32 free_count;
        struct list_head rx_free;
        struct list_head rx_used;
        int need_update;
+       struct iwl_rb_status *rb_stts;
+       dma_addr_t rb_stts_dma;
        spinlock_t lock;
 };
 
@@ -507,6 +507,7 @@ struct iwl_sensitivity_ranges {
 /**
  * struct iwl_hw_params
  * @max_txq_num: Max # Tx queues supported
+ * @scd_bc_tbls_size: size of scheduler byte count tables
  * @tx/rx_chains_num: Number of TX/RX chains
  * @valid_tx/rx_ant: usable antennas
  * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
@@ -524,6 +525,7 @@ struct iwl_sensitivity_ranges {
  */
 struct iwl_hw_params {
        u16 max_txq_num;
+       u16 scd_bc_tbls_size;
        u8  tx_chains_num;
        u8  rx_chains_num;
        u8  valid_tx_ant;
@@ -605,13 +607,9 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
 struct iwl_priv;
 
 
-/* Structures, enum, and defines specific to the 4965 */
-
-#define IWL_KW_SIZE 0x1000     /*4k */
-
-struct iwl_kw {
-       dma_addr_t dma_addr;
-       void *v_addr;
+struct iwl_dma_ptr {
+       dma_addr_t dma;
+       void *addr;
        size_t size;
 };
 
@@ -907,7 +905,9 @@ struct iwl_priv {
        struct iwl_rx_queue rxq;
        struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES];
        unsigned long txq_ctx_active_msk;
-       struct iwl_kw kw;       /* keep warm address */
+       struct iwl_dma_ptr  kw; /* keep warm address */
+       struct iwl_dma_ptr  scd_bc_tbls;
+
        u32 scd_base_addr;      /* scheduler sram base address */
 
        unsigned long status;
@@ -967,11 +967,7 @@ struct iwl_priv {
        struct ieee80211_vif *vif;
 
        struct iwl_hw_params hw_params;
-       /* driver/uCode shared Tx Byte Counts and Rx status */
-       void *shared_virt;
-       int rb_closed_offset;
-       /* Physical Pointer to Tx Byte Counts and Rx status */
-       dma_addr_t shared_phys;
+
 
        /* Current association information needed to configure the
         * hardware */
@@ -1093,23 +1089,6 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch)
        return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
-                                     void *p, u32 len)
-{
-       if (!(priv->debug_level & level))
-               return;
-
-       print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
-                       p, len, 1);
-}
-#else
-static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
-                                     void *p, u32 len)
-{
-}
-#endif
-
 extern const struct iwl_channel_info *iwl_get_channel_info(
        const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
 
index 97e2cf4..e46300c 100644 (file)
 #define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL    (0x00000000)
 #define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL  (0x00001000)
 
+#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME   (0x00008000)
+
 
 /**
  * Rx Shared Status Registers (RSSR)
 #define TFD_QUEUE_SIZE_BC_DUP  (64)
 #define TFD_QUEUE_BC_SIZE      (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP)
 
+/**
+ * struct iwl_rb_status - reseve buffer status
+ *     host memory mapped FH registers
+ * @closed_rb_num [0:11] - Indicates the index of the RB which was closed
+ * @closed_fr_num [0:11] - Indicates the index of the RX Frame which was closed
+ * @finished_rb_num [0:11] - Indicates the index of the current RB
+ *     in which the last frame was written to
+ * @finished_fr_num [0:11] - Indicates the index of the RX Frame
+ *     which was transfered
+ */
+struct iwl_rb_status {
+       __le16 closed_rb_num;
+       __le16 closed_fr_num;
+       __le16 finished_rb_num;
+       __le16 finished_fr_nam;
+} __attribute__ ((packed));
+
+
+
+#define IWL_TX_DMA_MASK        DMA_BIT_MASK(36)
+
+#define IWL_NUM_OF_TBS         20
+
+static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
+{
+       return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF;
+}
+/**
+ * struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor
+ *
+ * This structure contains dma address and length of transmission address
+ *
+ * @lo: low [31:0] portion of the dma address of TX buffer
+ *     every even is unaligned on 16 bit boundary
+ * @hi_n_len 0-3 [35:32] portion of dma
+ *          4-16 length of the tx buffer
+ */
+struct iwl_tfd_tb {
+       __le32 lo;
+       __le16 hi_n_len;
+} __attribute__((packed));
+
+/**
+ * struct iwl_tfd
+ *
+ * Transmit Frame Descriptor (TFD)
+ *
+ * @ __reserved1[3] reserved
+ * @ num_tbs 0-5 number of active tbs
+ *          6-7 padding (not used)
+ * @ tbs[20]   transmit frame buffer descriptors
+ * @ __pad     padding
+ *
+ * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
+ * Both driver and device share these circular buffers, each of which must be
+ * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes
+ *
+ * Driver must indicate the physical address of the base of each
+ * circular buffer via the FH_MEM_CBBC_QUEUE registers.
+ *
+ * Each TFD contains pointer/size information for up to 20 data buffers
+ * in host DRAM.  These buffers collectively contain the (one) frame described
+ * by the TFD.  Each buffer must be a single contiguous block of memory within
+ * itself, but buffers may be scattered in host DRAM.  Each buffer has max size
+ * of (4K - 4).  The concatenates all of a TFD's buffers into a single
+ * Tx frame, up to 8 KBytes in size.
+ *
+ * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
+ *
+ * Bit fields in the control dword (val0):
+ */
+struct iwl_tfd {
+       u8 __reserved1[3];
+       u8 num_tbs;
+       struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS];
+       __le32 __pad;
+} __attribute__ ((packed));
+
+
+/* Keep Warm Size */
+#define IWL_KW_SIZE 0x1000     /*4k */
 
 #endif /* !__iwl_fh_h__ */
index 07a5f60..b429daa 100644 (file)
@@ -257,15 +257,11 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
        struct iwl_power_mgr *setting = &(priv->power_data);
        int ret = 0;
        u16 uninitialized_var(final_mode);
+       bool update_chains;
 
        /* Don't update the RX chain when chain noise calibration is running */
-       if (priv->chain_noise_data.state != IWL_CHAIN_NOISE_DONE &&
-           priv->chain_noise_data.state != IWL_CHAIN_NOISE_ALIVE) {
-               IWL_DEBUG_POWER("Cannot update the power, chain noise "
-                       "calibration running: %d\n",
-                       priv->chain_noise_data.state);
-               return -EAGAIN;
-       }
+       update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
+                       priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
 
        /* If on battery, set to 3,
         * if plugged into AC power, set to CAM ("continuously aware mode"),
@@ -313,9 +309,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
                else
                        set_bit(STATUS_POWER_PMI, &priv->status);
 
-               if (priv->cfg->ops->lib->update_chain_flags)
+               if (priv->cfg->ops->lib->update_chain_flags && update_chains)
                        priv->cfg->ops->lib->update_chain_flags(priv);
-
+               else
+                       IWL_DEBUG_POWER("Cannot update the power, chain noise "
+                                       "calibration running: %d\n",
+                                       priv->chain_noise_data.state);
                if (!ret)
                        setting->power_mode = final_mode;
        }
index b3c35c6..876afd4 100644 (file)
@@ -218,8 +218,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
 
        /* If we've added more space for the firmware to place data, tell it.
         * Increment device's write pointer in multiples of 8. */
-       if ((write != (rxq->write & ~0x7))
-           || (abs(rxq->write - rxq->read) > 7)) {
+       if (write != (rxq->write & ~0x7)) {
                spin_lock_irqsave(&rxq->lock, flags);
                rxq->need_update = 1;
                spin_unlock_irqrestore(&rxq->lock, flags);
@@ -317,7 +316,10 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 
        pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
                            rxq->dma_addr);
+       pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),
+                           rxq->rb_stts, rxq->rb_stts_dma);
        rxq->bd = NULL;
+       rxq->rb_stts  = NULL;
 }
 EXPORT_SYMBOL(iwl_rx_queue_free);
 
@@ -334,7 +336,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
        /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
        rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
        if (!rxq->bd)
-               return -ENOMEM;
+               goto err_bd;
+
+       rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status),
+                                       &rxq->rb_stts_dma);
+       if (!rxq->rb_stts)
+               goto err_rb;
 
        /* Fill the rx_used queue with _all_ of the Rx buffers */
        for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
@@ -346,6 +353,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
        rxq->free_count = 0;
        rxq->need_update = 0;
        return 0;
+
+err_rb:
+       pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
+                           rxq->dma_addr);
+err_bd:
+       return -ENOMEM;
 }
 EXPORT_SYMBOL(iwl_rx_queue_alloc);
 
@@ -412,7 +425,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 
        /* Tell device where in DRAM to update its Rx status */
        iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
-                          (priv->shared_phys + priv->rb_closed_offset) >> 4);
+                          rxq->rb_stts_dma >> 4);
 
        /* Enable Rx DMA
         * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
@@ -426,6 +439,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
                           FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
                           FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
                           FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
+                          FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME |
                           rb_size|
                           (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
                           (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
new file mode 100644 (file)
index 0000000..ad319a1
--- /dev/null
@@ -0,0 +1,198 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+
+#include <net/mac80211.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-spectrum.h"
+
+#define BEACON_TIME_MASK_LOW   0x00FFFFFF
+#define BEACON_TIME_MASK_HIGH  0xFF000000
+#define TIME_UNIT              1024
+
+/*
+ * extended beacon time format
+ * time in usec will be changed into a 32-bit value in 8:24 format
+ * the high 1 byte is the beacon counts
+ * the lower 3 bytes is the time in usec within one beacon interval
+ */
+
+/* TOOD: was used in sysfs debug interface need to add to mac */
+#if 0
+static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
+{
+       u32 quot;
+       u32 rem;
+       u32 interval = beacon_interval * 1024;
+
+       if (!interval || !usec)
+               return 0;
+
+       quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
+       rem = (usec % interval) & BEACON_TIME_MASK_LOW;
+
+       return (quot << 24) + rem;
+}
+
+/* base is usually what we get from ucode with each received frame,
+ * the same as HW timer counter counting down
+ */
+
+static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
+{
+       u32 base_low = base & BEACON_TIME_MASK_LOW;
+       u32 addon_low = addon & BEACON_TIME_MASK_LOW;
+       u32 interval = beacon_interval * TIME_UNIT;
+       u32 res = (base & BEACON_TIME_MASK_HIGH) +
+           (addon & BEACON_TIME_MASK_HIGH);
+
+       if (base_low > addon_low)
+               res += base_low - addon_low;
+       else if (base_low < addon_low) {
+               res += interval + base_low - addon_low;
+               res += (1 << 24);
+       } else
+               res += (1 << 24);
+
+       return cpu_to_le32(res);
+}
+static int iwl_get_measurement(struct iwl_priv *priv,
+                              struct ieee80211_measurement_params *params,
+                              u8 type)
+{
+       struct iwl4965_spectrum_cmd spectrum;
+       struct iwl_rx_packet *res;
+       struct iwl_host_cmd cmd = {
+               .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
+               .data = (void *)&spectrum,
+               .meta.flags = CMD_WANT_SKB,
+       };
+       u32 add_time = le64_to_cpu(params->start_time);
+       int rc;
+       int spectrum_resp_status;
+       int duration = le16_to_cpu(params->duration);
+
+       if (iwl_is_associated(priv))
+               add_time =
+                   iwl_usecs_to_beacons(
+                       le64_to_cpu(params->start_time) - priv->last_tsf,
+                       le16_to_cpu(priv->rxon_timing.beacon_interval));
+
+       memset(&spectrum, 0, sizeof(spectrum));
+
+       spectrum.channel_count = cpu_to_le16(1);
+       spectrum.flags =
+           RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
+       spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
+       cmd.len = sizeof(spectrum);
+       spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
+
+       if (iwl_is_associated(priv))
+               spectrum.start_time =
+                   iwl_add_beacon_time(priv->last_beacon_time,
+                               add_time,
+                               le16_to_cpu(priv->rxon_timing.beacon_interval));
+       else
+               spectrum.start_time = 0;
+
+       spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
+       spectrum.channels[0].channel = params->channel;
+       spectrum.channels[0].type = type;
+       if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
+               spectrum.flags |= RXON_FLG_BAND_24G_MSK |
+                   RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
+
+       rc = iwl_send_cmd_sync(priv, &cmd);
+       if (rc)
+               return rc;
+
+       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+               IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+               rc = -EIO;
+       }
+
+       spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
+       switch (spectrum_resp_status) {
+       case 0:         /* Command will be handled */
+               if (res->u.spectrum.id != 0xff) {
+                       IWL_DEBUG_INFO
+                           ("Replaced existing measurement: %d\n",
+                            res->u.spectrum.id);
+                       priv->measurement_status &= ~MEASUREMENT_READY;
+               }
+               priv->measurement_status |= MEASUREMENT_ACTIVE;
+               rc = 0;
+               break;
+
+       case 1:         /* Command will not be handled */
+               rc = -EAGAIN;
+               break;
+       }
+
+       dev_kfree_skb_any(cmd.meta.u.skb);
+
+       return rc;
+}
+#endif
+
+static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
+                                         struct iwl_rx_mem_buffer *rxb)
+{
+       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+       struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
+
+       if (!report->state) {
+               IWL_DEBUG(IWL_DL_11H,
+                       "Spectrum Measure Notification: Start\n");
+               return;
+       }
+
+       memcpy(&priv->measure_report, report, sizeof(*report));
+       priv->measurement_status |= MEASUREMENT_READY;
+}
+
+void iwl_setup_spectrum_handlers(struct iwl_priv *priv)
+{
+       priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
+                       iwl_rx_spectrum_measure_notif;
+}
+EXPORT_SYMBOL(iwl_setup_spectrum_handlers);
index a40a217..fa990a1 100644 (file)
@@ -88,4 +88,5 @@ struct ieee80211_measurement_report {
                struct ieee80211_basic_report basic[0];
        } u;
 } __attribute__ ((packed));
+
 #endif
index 7d8b4e2..166f000 100644 (file)
@@ -56,6 +56,26 @@ static const u16 default_tid_to_tx_fifo[] = {
        IWL_TX_FIFO_AC3
 };
 
+static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
+                                   struct iwl_dma_ptr *ptr, size_t size)
+{
+       ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma);
+       if (!ptr->addr)
+               return -ENOMEM;
+       ptr->size = size;
+       return 0;
+}
+
+static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
+                                   struct iwl_dma_ptr *ptr)
+{
+       if (unlikely(!ptr->addr))
+               return;
+
+       pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma);
+       memset(ptr, 0, sizeof(*ptr));
+}
+
 static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
 {
        struct iwl_tfd_tb *tb = &tfd->tbs[idx];
@@ -517,8 +537,9 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
                else
                        iwl_tx_queue_free(priv, txq_id);
 
-       /* Keep-warm buffer */
-       iwl_kw_free(priv);
+       iwl_free_dma_ptr(priv, &priv->kw);
+
+       iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
 }
 EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
 
@@ -535,13 +556,17 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
        int txq_id, slots_num;
        unsigned long flags;
 
-       iwl_kw_free(priv);
-
        /* Free all tx/cmd queues and keep-warm buffer */
        iwl_hw_txq_ctx_free(priv);
 
+       ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
+                               priv->hw_params.scd_bc_tbls_size);
+       if (ret) {
+               IWL_ERROR("Scheduler BC Table allocation failed\n");
+               goto error_bc_tbls;
+       }
        /* Alloc keep-warm buffer */
-       ret = iwl_kw_alloc(priv);
+       ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
        if (ret) {
                IWL_ERROR("Keep Warm allocation failed\n");
                goto error_kw;
@@ -556,16 +581,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
        /* Turn off all Tx DMA fifos */
        priv->cfg->ops->lib->txq_set_sched(priv, 0);
 
+       /* Tell NIC where to find the "keep warm" buffer */
+       iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
+
        iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
 
-       /* Tell nic where to find the keep-warm buffer */
-       ret = iwl_kw_init(priv);
-       if (ret) {
-               IWL_ERROR("kw_init failed\n");
-               goto error_reset;
-       }
 
        /* Alloc and init all Tx queues, including the command queue (#4) */
        for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
@@ -584,8 +606,10 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
  error:
        iwl_hw_txq_ctx_free(priv);
  error_reset:
-       iwl_kw_free(priv);
+       iwl_free_dma_ptr(priv, &priv->kw);
  error_kw:
+       iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
+ error_bc_tbls:
        return ret;
 }
 
@@ -1236,8 +1260,13 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
         * command queue then there a command routing bug has been introduced
         * in the queue management code. */
        if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
-                "wrong command queue %d, command id 0x%X\n", txq_id, pkt->hdr.cmd))
+                "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n",
+                 txq_id, sequence,
+                 priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
+                 priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
+               iwl_print_hex_dump(priv, IWL_DL_INFO , rxb, 32);
                return;
+       }
 
        cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
        cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
index a3ec4d0..3344841 100644 (file)
@@ -1418,9 +1418,16 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
        return priv->ibss_beacon->len;
 }
 
-static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
+static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
 {
        u8 i;
+       int rate_mask;
+
+       /* Set rate mask*/
+       if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+               rate_mask = priv->active_rate_basic & 0xF;
+       else
+               rate_mask = priv->active_rate_basic & 0xFF0;
 
        for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
             i = iwl3945_rates[i].next_ieee) {
@@ -1428,7 +1435,11 @@ static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
                        return iwl3945_rates[i].plcp;
        }
 
-       return IWL_RATE_INVALID;
+       /* No valid rate was found. Assign the lowest one */
+       if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+               return IWL_RATE_1M_PLCP;
+       else
+               return IWL_RATE_6M_PLCP;
 }
 
 static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
@@ -1446,16 +1457,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
                return -ENOMEM;
        }
 
-       if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
-               rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic &
-                                               0xFF0);
-               if (rate == IWL_INVALID_RATE)
-                       rate = IWL_RATE_6M_PLCP;
-       } else {
-               rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
-               if (rate == IWL_INVALID_RATE)
-                       rate = IWL_RATE_1M_PLCP;
-       }
+       rate = iwl3945_rate_get_lowest_plcp(priv);
 
        frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
 
@@ -4741,7 +4743,7 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
 
-#define IWL_SCAN_PROBE_MASK(n)  cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+#define IWL_SCAN_PROBE_MASK(n)  (BIT(n) | (BIT(n) - BIT(1)))
 
 static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
                                                enum ieee80211_band band,
@@ -5601,6 +5603,10 @@ static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
 }
 
 
+/* temporary */
+static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
+                                    struct sk_buff *skb);
+
 /**
  * iwl3945_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
@@ -5704,6 +5710,14 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
        if (priv->error_recovering)
                iwl3945_error_recovery(priv);
 
+       /* reassociate for ADHOC mode */
+       if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
+               struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
+                                                               priv->vif);
+               if (beacon)
+                       iwl3945_mac_beacon_update(priv->hw, beacon);
+       }
+
        return;
 
  restart:
@@ -6710,9 +6724,6 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
         * clear sta table, add BCAST sta... */
 }
 
-/* temporary */
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
-
 static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif,
                                    struct ieee80211_if_conf *conf)
@@ -6734,7 +6745,9 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
                struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
                if (!beacon)
                        return -ENOMEM;
+               mutex_lock(&priv->mutex);
                rc = iwl3945_mac_beacon_update(hw, beacon);
+               mutex_unlock(&priv->mutex);
                if (rc)
                        return rc;
        }
@@ -7188,18 +7201,15 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
        struct iwl3945_priv *priv = hw->priv;
        unsigned long flags;
 
-       mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
        if (!iwl3945_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
-               mutex_unlock(&priv->mutex);
                return -EIO;
        }
 
        if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
                IWL_DEBUG_MAC80211("leave - not IBSS\n");
-               mutex_unlock(&priv->mutex);
                return -EIO;
        }
 
@@ -7219,7 +7229,6 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
 
        iwl3945_post_associate(priv);
 
-       mutex_unlock(&priv->mutex);
 
        return 0;
 }
index 957fd5a..639dd02 100644 (file)
@@ -159,7 +159,8 @@ out:
        return ret;
 }
 
-int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
+               struct wol_config *p_wol_config)
 {
        struct cmd_ds_host_sleep cmd_config;
        int ret;
@@ -169,10 +170,21 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
        cmd_config.gpio = priv->wol_gpio;
        cmd_config.gap = priv->wol_gap;
 
+       if (p_wol_config != NULL)
+               memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
+                               sizeof(struct wol_config));
+       else
+               cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
+
        ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
        if (!ret) {
-               lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
-               priv->wol_criteria = criteria;
+               if (criteria) {
+                       lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
+                       priv->wol_criteria = criteria;
+               } else
+                       memcpy((uint8_t *) p_wol_config,
+                                       (uint8_t *)&cmd_config.wol_conf,
+                                       sizeof(struct wol_config));
        } else {
                lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
        }
index 36be4c9..392e578 100644 (file)
@@ -56,7 +56,8 @@ int lbs_mesh_config_send(struct lbs_private *priv,
                         uint16_t action, uint16_t type);
 int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
 
-int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
+               struct wol_config *p_wol_config);
 int lbs_suspend(struct lbs_private *priv);
 void lbs_resume(struct lbs_private *priv);
 
index 2d4666f..c364e4c 100644 (file)
@@ -149,6 +149,18 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 #define EHS_WAKE_ON_MAC_EVENT          0x0004
 #define EHS_WAKE_ON_MULTICAST_DATA     0x0008
 #define EHS_REMOVE_WAKEUP              0xFFFFFFFF
+/* Wake rules for Host_Sleep_CFG command */
+#define WOL_RULE_NET_TYPE_INFRA_OR_IBSS        0x00
+#define WOL_RULE_NET_TYPE_MESH         0x10
+#define WOL_RULE_ADDR_TYPE_BCAST       0x01
+#define WOL_RULE_ADDR_TYPE_MCAST       0x08
+#define WOL_RULE_ADDR_TYPE_UCAST       0x02
+#define WOL_RULE_OP_AND                        0x01
+#define WOL_RULE_OP_OR                 0x02
+#define WOL_RULE_OP_INVALID            0xFF
+#define WOL_RESULT_VALID_CMD           0
+#define WOL_RESULT_NOSPC_ERR           1
+#define WOL_RESULT_EEXIST_ERR          2
 
 /** Misc constants */
 /* This section defines 802.11 specific contants */
index 156f471..61d2f50 100644 (file)
@@ -180,7 +180,7 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
        if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
        if (wol->wolopts & WAKE_PHY)   criteria |= EHS_WAKE_ON_MAC_EVENT;
 
-       return lbs_host_sleep_cfg(priv, criteria);
+       return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
 }
 
 struct ethtool_ops lbs_ethtool_ops = {
index 5004d76..a17b778 100644 (file)
@@ -220,6 +220,14 @@ enum cmd_fwt_access_opts {
        CMD_ACT_FWT_ACCESS_TIME,
 };
 
+/* Define action or option for CMD_802_11_HOST_SLEEP_CFG */
+enum cmd_wol_cfg_opts {
+       CMD_ACT_ACTION_NONE = 0,
+       CMD_ACT_SET_WOL_RULE,
+       CMD_ACT_GET_WOL_RULE,
+       CMD_ACT_RESET_WOL_RULE,
+};
+
 /* Define action or option for CMD_MESH_ACCESS */
 enum cmd_mesh_access_opts {
        CMD_ACT_MESH_GET_TTL = 1,
index d9f9a12..e173b1b 100644 (file)
@@ -580,13 +580,37 @@ struct MrvlIEtype_keyParamSet {
        u8 key[32];
 };
 
+#define MAX_WOL_RULES          16
+
+struct host_wol_rule {
+       uint8_t rule_no;
+       uint8_t rule_ops;
+       __le16 sig_offset;
+       __le16 sig_length;
+       __le16 reserve;
+       __be32 sig_mask;
+       __be32 signature;
+};
+
+struct wol_config {
+       uint8_t action;
+       uint8_t pattern;
+       uint8_t no_rules_in_cmd;
+       uint8_t result;
+       struct host_wol_rule rule[MAX_WOL_RULES];
+};
+
+
 struct cmd_ds_host_sleep {
        struct cmd_header hdr;
        __le32 criteria;
        uint8_t gpio;
-       uint8_t gap;
+       uint16_t gap;
+       struct wol_config wol_conf;
 } __attribute__ ((packed));
 
+
+
 struct cmd_ds_802_11_key_material {
        struct cmd_header hdr;
 
index cafbccb..fcd3fe6 100644 (file)
@@ -178,7 +178,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
 
        priv->wol_gpio = 2; /* Wake via GPIO2... */
        priv->wol_gap = 20; /* ... after 20ms    */
-       lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
+       lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
+                       (struct wol_config *) NULL);
 
        wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
        wake_method.action = cpu_to_le16(CMD_ACT_GET);
index b9230da..d8b5cf3 100644 (file)
@@ -368,7 +368,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
 
        hwsim_check_magic(vif);
 
-       if (vif->type != NL80211_IFTYPE_AP)
+       if (vif->type != NL80211_IFTYPE_AP &&
+           vif->type != NL80211_IFTYPE_MESH_POINT)
                return;
 
        skb = ieee80211_beacon_get(hw, vif);
@@ -774,7 +775,8 @@ static int __init init_mac80211_hwsim(void)
                hw->queues = 4;
                hw->wiphy->interface_modes =
                        BIT(NL80211_IFTYPE_STATION) |
-                       BIT(NL80211_IFTYPE_AP);
+                       BIT(NL80211_IFTYPE_AP) |
+                       BIT(NL80211_IFTYPE_MESH_POINT);
                hw->ampdu_queues = 1;
 
                /* ask mac80211 to reserve space for magic */
index 072be44..fd92639 100644 (file)
@@ -5444,7 +5444,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
                                           char *current_ev,
                                           char *end_buf,
                                           union hermes_scan_info *bss,
-                                          unsigned int last_scanned)
+                                          unsigned long last_scanned)
 {
        struct orinoco_private *priv = netdev_priv(dev);
        u16                     capabilities;
@@ -5591,7 +5591,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev,
                                               char *current_ev,
                                               char *end_buf,
                                               struct agere_ext_scan_info *bss,
-                                              unsigned int last_scanned)
+                                              unsigned long last_scanned)
 {
        u16                     capabilities;
        u16                     channel;
index 42bd38a..78fca1b 100644 (file)
@@ -69,14 +69,14 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt2400pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
-               ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
-               return;
-       }
+       if (rt2x00_get_field32(reg, BBPCSR_BUSY))
+               goto exit_fail;
 
        /*
         * Write the data into the BBP.
@@ -88,6 +88,15 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);
 
        rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
 }
 
 static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -95,14 +104,14 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt2400pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
-               ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
-               return;
-       }
+       if (rt2x00_get_field32(reg, BBPCSR_BUSY))
+               goto exit_fail;
 
        /*
         * Write the request into the BBP.
@@ -118,13 +127,20 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt2400pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
-               ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
-               *value = 0xff;
-               return;
-       }
+       if (rt2x00_get_field32(reg, BBPCSR_BUSY))
+               goto exit_fail;
 
        *value = rt2x00_get_field32(reg, BBPCSR_VALUE);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
+       *value = 0xff;
 }
 
 static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
@@ -136,6 +152,8 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
        if (!word)
                return;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                rt2x00pci_register_read(rt2x00dev, RFCSR, &reg);
                if (!rt2x00_get_field32(reg, RFCSR_BUSY))
@@ -143,6 +161,7 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
                udelay(REGISTER_BUSY_DELAY);
        }
 
+       mutex_unlock(&rt2x00dev->csr_mutex);
        ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
        return;
 
@@ -155,6 +174,8 @@ rf_write:
 
        rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
        rt2x00_rf_write(rt2x00dev, word, value);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
 static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -322,7 +343,7 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
                /*
                 * Enable beacon config
                 */
-               bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20);
+               bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
                rt2x00pci_register_read(rt2x00dev, BCNCSR1, &reg);
                rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
                rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg);
@@ -367,25 +388,25 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
        rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
        rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
-       rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10));
+       rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
        rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
        rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
        rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
-       rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20));
+       rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
        rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
        rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
        rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
-       rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55));
+       rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
        rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
        rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
        rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
-       rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
+       rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
        rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
 
        rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
@@ -626,36 +647,47 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
 /*
  * Initialization functions.
  */
-static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
-                                  struct queue_entry *entry)
+static bool rt2400pci_get_entry_state(struct queue_entry *entry)
 {
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        u32 word;
 
-       rt2x00_desc_read(entry_priv->desc, 2, &word);
-       rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
-       rt2x00_desc_write(entry_priv->desc, 2, word);
+       if (entry->queue->qid == QID_RX) {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
 
-       rt2x00_desc_read(entry_priv->desc, 1, &word);
-       rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
-       rt2x00_desc_write(entry_priv->desc, 1, word);
+               return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
+       } else {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
 
-       rt2x00_desc_read(entry_priv->desc, 0, &word);
-       rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
-       rt2x00_desc_write(entry_priv->desc, 0, word);
+               return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
+                       rt2x00_get_field32(word, TXD_W0_VALID));
+       }
 }
 
-static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev,
-                                  struct queue_entry *entry)
+static void rt2400pci_clear_entry(struct queue_entry *entry)
 {
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        u32 word;
 
-       rt2x00_desc_read(entry_priv->desc, 0, &word);
-       rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-       rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
-       rt2x00_desc_write(entry_priv->desc, 0, word);
+       if (entry->queue->qid == QID_RX) {
+               rt2x00_desc_read(entry_priv->desc, 2, &word);
+               rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
+               rt2x00_desc_write(entry_priv->desc, 2, word);
+
+               rt2x00_desc_read(entry_priv->desc, 1, &word);
+               rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+               rt2x00_desc_write(entry_priv->desc, 1, word);
+
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
+               rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
+               rt2x00_desc_write(entry_priv->desc, 0, word);
+       } else {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
+               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
+               rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
+               rt2x00_desc_write(entry_priv->desc, 0, word);
+       }
 }
 
 static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -1570,8 +1602,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
        .probe_hw               = rt2400pci_probe_hw,
        .initialize             = rt2x00pci_initialize,
        .uninitialize           = rt2x00pci_uninitialize,
-       .init_rxentry           = rt2400pci_init_rxentry,
-       .init_txentry           = rt2400pci_init_txentry,
+       .get_entry_state        = rt2400pci_get_entry_state,
+       .clear_entry            = rt2400pci_clear_entry,
        .set_device_state       = rt2400pci_set_device_state,
        .rfkill_poll            = rt2400pci_rfkill_poll,
        .link_stats             = rt2400pci_link_stats,
index 928452f..972b5a5 100644 (file)
@@ -69,14 +69,14 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt2500pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
-               ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
-               return;
-       }
+       if (rt2x00_get_field32(reg, BBPCSR_BUSY))
+               goto exit_fail;
 
        /*
         * Write the data into the BBP.
@@ -88,6 +88,15 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);
 
        rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
 }
 
 static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -95,14 +104,14 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt2500pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
-               ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
-               return;
-       }
+       if (rt2x00_get_field32(reg, BBPCSR_BUSY))
+               goto exit_fail;
 
        /*
         * Write the request into the BBP.
@@ -118,13 +127,20 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt2500pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
-               ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
-               *value = 0xff;
-               return;
-       }
+       if (rt2x00_get_field32(reg, BBPCSR_BUSY))
+               goto exit_fail;
 
        *value = rt2x00_get_field32(reg, BBPCSR_VALUE);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
+       *value = 0xff;
 }
 
 static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
@@ -136,6 +152,8 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
        if (!word)
                return;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                rt2x00pci_register_read(rt2x00dev, RFCSR, &reg);
                if (!rt2x00_get_field32(reg, RFCSR_BUSY))
@@ -143,6 +161,7 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
                udelay(REGISTER_BUSY_DELAY);
        }
 
+       mutex_unlock(&rt2x00dev->csr_mutex);
        ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
        return;
 
@@ -155,6 +174,8 @@ rf_write:
 
        rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
        rt2x00_rf_write(rt2x00dev, word, value);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
 static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -327,7 +348,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
                /*
                 * Enable beacon config
                 */
-               bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20);
+               bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
                rt2x00pci_register_read(rt2x00dev, BCNCSR1, &reg);
                rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
                rt2x00_set_field32(&reg, BCNCSR1_BEACON_CWMIN, queue->cw_min);
@@ -373,25 +394,25 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
        rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
        rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
-       rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10));
+       rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
        rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
        rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
        rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
-       rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20));
+       rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
        rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
        rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
        rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
-       rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55));
+       rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
        rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
        rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
        rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
-       rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
+       rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
        rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
 
        rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
@@ -722,32 +743,43 @@ dynamic_cca_tune:
 /*
  * Initialization functions.
  */
-static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
-                                  struct queue_entry *entry)
+static bool rt2500pci_get_entry_state(struct queue_entry *entry)
 {
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        u32 word;
 
-       rt2x00_desc_read(entry_priv->desc, 1, &word);
-       rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
-       rt2x00_desc_write(entry_priv->desc, 1, word);
+       if (entry->queue->qid == QID_RX) {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
 
-       rt2x00_desc_read(entry_priv->desc, 0, &word);
-       rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
-       rt2x00_desc_write(entry_priv->desc, 0, word);
+               return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
+       } else {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
+
+               return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
+                       rt2x00_get_field32(word, TXD_W0_VALID));
+       }
 }
 
-static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev,
-                                  struct queue_entry *entry)
+static void rt2500pci_clear_entry(struct queue_entry *entry)
 {
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        u32 word;
 
-       rt2x00_desc_read(entry_priv->desc, 0, &word);
-       rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-       rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
-       rt2x00_desc_write(entry_priv->desc, 0, word);
+       if (entry->queue->qid == QID_RX) {
+               rt2x00_desc_read(entry_priv->desc, 1, &word);
+               rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+               rt2x00_desc_write(entry_priv->desc, 1, word);
+
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
+               rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
+               rt2x00_desc_write(entry_priv->desc, 0, word);
+       } else {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
+               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
+               rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
+               rt2x00_desc_write(entry_priv->desc, 0, word);
+       }
 }
 
 static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -1871,8 +1903,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
        .probe_hw               = rt2500pci_probe_hw,
        .initialize             = rt2x00pci_initialize,
        .uninitialize           = rt2x00pci_uninitialize,
-       .init_rxentry           = rt2500pci_init_rxentry,
-       .init_txentry           = rt2500pci_init_txentry,
+       .get_entry_state        = rt2500pci_get_entry_state,
+       .clear_entry            = rt2500pci_clear_entry,
        .set_device_state       = rt2500pci_set_device_state,
        .rfkill_poll            = rt2500pci_rfkill_poll,
        .link_stats             = rt2500pci_link_stats,
index 639d5a2..e6bae4a 100644 (file)
@@ -47,7 +47,7 @@
  * between each attampt. When the busy bit is still set at that time,
  * the access attempt is considered to have failed,
  * and we will print an error.
- * If the usb_cache_mutex is already held then the _lock variants must
+ * If the csr_mutex is already held then the _lock variants must
  * be used instead.
  */
 static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
@@ -132,7 +132,7 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
 {
        u16 reg;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
         * Wait until the BBP becomes ready.
@@ -151,12 +151,12 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
 
        rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
 
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        return;
 
 exit_fail:
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
 }
@@ -166,7 +166,7 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
 {
        u16 reg;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
         * Wait until the BBP becomes ready.
@@ -194,12 +194,12 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
        rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
        *value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
 
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        return;
 
 exit_fail:
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
        *value = 0xff;
@@ -214,7 +214,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
        if (!word)
                return;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg);
@@ -223,7 +223,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
                udelay(REGISTER_BUSY_DELAY);
        }
 
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
        ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
        return;
 
@@ -241,7 +241,7 @@ rf_write:
        rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
        rt2x00_rf_write(rt2x00dev, word, value);
 
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
@@ -385,7 +385,7 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
                /*
                 * Enable beacon config
                 */
-               bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20);
+               bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
                rt2500usb_register_read(rt2x00dev, TXRX_CSR20, &reg);
                rt2x00_set_field16(&reg, TXRX_CSR20_OFFSET, bcn_preload >> 6);
                rt2x00_set_field16(&reg, TXRX_CSR20_BCN_EXPECT_WINDOW,
@@ -1777,8 +1777,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
        .probe_hw               = rt2500usb_probe_hw,
        .initialize             = rt2x00usb_initialize,
        .uninitialize           = rt2x00usb_uninitialize,
-       .init_rxentry           = rt2x00usb_init_rxentry,
-       .init_txentry           = rt2x00usb_init_txentry,
+       .clear_entry            = rt2x00usb_clear_entry,
        .set_device_state       = rt2500usb_set_device_state,
        .link_stats             = rt2500usb_link_stats,
        .reset_tuner            = rt2500usb_reset_tuner,
index f85eedb..fee61be 100644 (file)
        DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args)
 
 /*
+ * Duration calculations
+ * The rate variable passed is: 100kbs.
+ * To convert from bytes to bits we multiply size with 8,
+ * then the size is multiplied with 10 to make the
+ * real rate -> rate argument correction.
+ */
+#define GET_DURATION(__size, __rate)   (((__size) * 8 * 10) / (__rate))
+#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
+
+/*
  * Standard timing and size defines.
  * These values should follow the ieee80211 specifications.
  */
 #define DIFS                   ( PIFS + SLOT_TIME )
 #define SHORT_DIFS             ( SHORT_PIFS + SHORT_SLOT_TIME )
 #define EIFS                   ( SIFS + DIFS + \
-                                 (8 * (IEEE80211_HEADER + ACK_SIZE)) )
+                                 GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
 #define SHORT_EIFS             ( SIFS + SHORT_DIFS + \
-                                 (8 * (IEEE80211_HEADER + ACK_SIZE)) )
+                                 GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
 
 /*
  * Chipset identification
@@ -523,10 +533,8 @@ struct rt2x00lib_ops {
        /*
         * queue initialization handlers
         */
-       void (*init_rxentry) (struct rt2x00_dev *rt2x00dev,
-                             struct queue_entry *entry);
-       void (*init_txentry) (struct rt2x00_dev *rt2x00dev,
-                             struct queue_entry *entry);
+       bool (*get_entry_state) (struct queue_entry *entry);
+       void (*clear_entry) (struct queue_entry *entry);
 
        /*
         * Radio control handlers.
@@ -723,8 +731,7 @@ struct rt2x00_dev {
 
        /*
         * This is the default TX/RX antenna setup as indicated
-        * by the device's EEPROM. When mac80211 sets its
-        * antenna value to 0 we should be using these values.
+        * by the device's EEPROM.
         */
        struct antenna_setup default_ant;
 
@@ -739,16 +746,15 @@ struct rt2x00_dev {
        } csr;
 
        /*
-        * Mutex to protect register accesses on USB devices.
-        * There are 2 reasons this is needed, one is to ensure
-        * use of the csr_cache (for USB devices) by one thread
-        * isn't corrupted by another thread trying to access it.
-        * The other is that access to BBP and RF registers
-        * require multiple BUS transactions and if another thread
-        * attempted to access one of those registers at the same
-        * time one of the writes could silently fail.
+        * Mutex to protect register accesses.
+        * For PCI and USB devices it protects against concurrent indirect
+        * register access (BBP, RF, MCU) since accessing those
+        * registers require multiple calls to the CSR registers.
+        * For USB devices it also protects the csr_cache since that
+        * field is used for normal CSR access and it cannot support
+        * multiple callers simultaneously.
         */
-       struct mutex usb_cache_mutex;
+       struct mutex csr_mutex;
 
        /*
         * Current packet filter configuration for the device.
@@ -923,23 +929,6 @@ static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
                !!(chipset->rev & 0x0000f));
 }
 
-/*
- * Duration calculations
- * The rate variable passed is: 100kbs.
- * To convert from bytes to bits we multiply size with 8,
- * then the size is multiplied with 10 to make the
- * real rate -> rate argument correction.
- */
-static inline u16 get_duration(const unsigned int size, const u8 rate)
-{
-       return ((size * 8 * 10) / rate);
-}
-
-static inline u16 get_duration_res(const unsigned int size, const u8 rate)
-{
-       return ((size * 8 * 10) % rate);
-}
-
 /**
  * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
index 3e4eee3..7c62ce1 100644 (file)
@@ -92,8 +92,8 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
        erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS;
        erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
 
-       erp.ack_timeout = PLCP + erp.difs + get_duration(ACK_SIZE, 10);
-       erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
+       erp.ack_timeout = PLCP + erp.difs + GET_DURATION(ACK_SIZE, 10);
+       erp.ack_consume_time = SIFS + PLCP + GET_DURATION(ACK_SIZE, 10);
 
        if (bss_conf->use_short_preamble) {
                erp.ack_timeout += SHORT_PREAMBLE;
@@ -109,15 +109,32 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
 }
 
 void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
-                             enum antenna rx, enum antenna tx)
+                             struct antenna_setup *ant)
 {
-       struct antenna_setup ant;
-
-       ant.rx = rx;
-       ant.tx = tx;
+       /*
+        * Failsafe: Make sure we are not sending the
+        * ANTENNA_SW_DIVERSITY state to the driver.
+        * If that happes fallback to hardware default,
+        * or our own default.
+        */
+       if (ant->rx == ANTENNA_SW_DIVERSITY) {
+               if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+                       ant->rx = ANTENNA_B;
+               else
+                       ant->rx = rt2x00dev->default_ant.rx;
+       }
+       if (ant->tx == ANTENNA_SW_DIVERSITY) {
+               if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+                       ant->tx = ANTENNA_B;
+               else
+                       ant->tx = rt2x00dev->default_ant.tx;
+       }
 
-       if (rx == rt2x00dev->link.ant.active.rx &&
-           tx == rt2x00dev->link.ant.active.tx)
+       /*
+        * Only reconfigure when something has changed.
+        */
+       if (ant->rx == rt2x00dev->link.ant.active.rx &&
+           ant->tx == rt2x00dev->link.ant.active.tx)
                return;
 
        /*
@@ -132,12 +149,12 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
         * The latter is required since we need to recalibrate the
         * noise-sensitivity ratio for the new setup.
         */
-       rt2x00dev->ops->lib->config_ant(rt2x00dev, &ant);
+       rt2x00dev->ops->lib->config_ant(rt2x00dev, ant);
 
        rt2x00lib_reset_link_tuner(rt2x00dev);
        rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
 
-       memcpy(&rt2x00dev->link.ant.active, &ant, sizeof(ant));
+       memcpy(&rt2x00dev->link.ant.active, ant, sizeof(*ant));
 
        if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
index 477a944..7fc1d76 100644 (file)
@@ -101,8 +101,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize all data queues.
         */
-       rt2x00queue_init_rx(rt2x00dev);
-       rt2x00queue_init_tx(rt2x00dev);
+       rt2x00queue_init_queues(rt2x00dev);
 
        /*
         * Enable radio.
@@ -176,13 +175,14 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
 
 static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
 {
-       enum antenna rx = rt2x00dev->link.ant.active.rx;
-       enum antenna tx = rt2x00dev->link.ant.active.tx;
+       struct antenna_setup ant;
        int sample_a =
            rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
        int sample_b =
            rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
 
+       memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
+
        /*
         * We are done sampling. Now we should evaluate the results.
         */
@@ -200,21 +200,22 @@ static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
                return;
 
        if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
-               rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+               ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
 
        if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
-               tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+               ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
 
-       rt2x00lib_config_antenna(rt2x00dev, rx, tx);
+       rt2x00lib_config_antenna(rt2x00dev, &ant);
 }
 
 static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
 {
-       enum antenna rx = rt2x00dev->link.ant.active.rx;
-       enum antenna tx = rt2x00dev->link.ant.active.tx;
+       struct antenna_setup ant;
        int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
        int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
 
+       memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
+
        /*
         * Legacy driver indicates that we should swap antenna's
         * when the difference in RSSI is greater that 5. This
@@ -230,12 +231,12 @@ static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
        rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
 
        if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
-               rx = (rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+               ant.rx = (ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
 
        if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
-               tx = (tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+               ant.tx = (ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
 
-       rt2x00lib_config_antenna(rt2x00dev, rx, tx);
+       rt2x00lib_config_antenna(rt2x00dev, &ant);
 }
 
 static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
@@ -574,7 +575,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        entry->skb = NULL;
        entry->flags = 0;
 
-       rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
+       rt2x00dev->ops->lib->clear_entry(entry);
 
        clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
        rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
@@ -706,7 +707,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
        entry->skb = skb;
        entry->flags = 0;
 
-       rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry);
+       rt2x00dev->ops->lib->clear_entry(entry);
 
        rt2x00queue_index_inc(entry->queue, Q_INDEX);
 }
@@ -717,31 +718,31 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
  */
 const struct rt2x00_rate rt2x00_supported_rates[12] = {
        {
-               .flags = DEV_RATE_CCK | DEV_RATE_BASIC,
+               .flags = DEV_RATE_CCK,
                .bitrate = 10,
                .ratemask = BIT(0),
                .plcp = 0x00,
        },
        {
-               .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
+               .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
                .bitrate = 20,
                .ratemask = BIT(1),
                .plcp = 0x01,
        },
        {
-               .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
+               .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
                .bitrate = 55,
                .ratemask = BIT(2),
                .plcp = 0x02,
        },
        {
-               .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
+               .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
                .bitrate = 110,
                .ratemask = BIT(3),
                .plcp = 0x03,
        },
        {
-               .flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
+               .flags = DEV_RATE_OFDM,
                .bitrate = 60,
                .ratemask = BIT(4),
                .plcp = 0x0b,
@@ -753,7 +754,7 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
                .plcp = 0x0f,
        },
        {
-               .flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
+               .flags = DEV_RATE_OFDM,
                .bitrate = 120,
                .ratemask = BIT(6),
                .plcp = 0x0a,
@@ -765,7 +766,7 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
                .plcp = 0x0e,
        },
        {
-               .flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
+               .flags = DEV_RATE_OFDM,
                .bitrate = 240,
                .ratemask = BIT(8),
                .plcp = 0x09,
@@ -1050,6 +1051,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 {
        int retval = -ENOMEM;
 
+       mutex_init(&rt2x00dev->csr_mutex);
+
        /*
         * Make room for rt2x00_intf inside the per-interface
         * structure ieee80211_vif.
index b362a1c..66c61b1 100644 (file)
@@ -72,49 +72,33 @@ void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi)
        }
 }
 
-void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled)
+static void rt2x00led_led_simple(struct rt2x00_led *led, bool enabled)
 {
-       struct rt2x00_led *led = &rt2x00dev->led_qual;
-       unsigned int brightness;
+       unsigned int brightness = enabled ? LED_FULL : LED_OFF;
 
-       if ((led->type != LED_TYPE_ACTIVITY) || !(led->flags & LED_REGISTERED))
+       if (!(led->flags & LED_REGISTERED))
                return;
 
-       brightness = enabled ? LED_FULL : LED_OFF;
-       if (brightness != led->led_dev.brightness) {
-               led->led_dev.brightness_set(&led->led_dev, brightness);
-               led->led_dev.brightness = brightness;
-       }
+       led->led_dev.brightness_set(&led->led_dev, brightness);
+       led->led_dev.brightness = brightness;
 }
 
-void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled)
+void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled)
 {
-       struct rt2x00_led *led = &rt2x00dev->led_assoc;
-       unsigned int brightness;
-
-       if ((led->type != LED_TYPE_ASSOC) || !(led->flags & LED_REGISTERED))
-               return;
+       if (rt2x00dev->led_qual.type == LED_TYPE_ACTIVITY)
+               rt2x00led_led_simple(&rt2x00dev->led_qual, enabled);
+}
 
-       brightness = enabled ? LED_FULL : LED_OFF;
-       if (brightness != led->led_dev.brightness) {
-               led->led_dev.brightness_set(&led->led_dev, brightness);
-               led->led_dev.brightness = brightness;
-       }
+void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled)
+{
+       if (rt2x00dev->led_assoc.type == LED_TYPE_ASSOC)
+               rt2x00led_led_simple(&rt2x00dev->led_assoc, enabled);
 }
 
 void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled)
 {
-       struct rt2x00_led *led = &rt2x00dev->led_radio;
-       unsigned int brightness;
-
-       if ((led->type != LED_TYPE_RADIO) || !(led->flags & LED_REGISTERED))
-               return;
-
-       brightness = enabled ? LED_FULL : LED_OFF;
-       if (brightness != led->led_dev.brightness) {
-               led->led_dev.brightness_set(&led->led_dev, brightness);
-               led->led_dev.brightness = brightness;
-       }
+       if (rt2x00dev->led_radio.type == LED_TYPE_ASSOC)
+               rt2x00led_led_simple(&rt2x00dev->led_radio, enabled);
 }
 
 static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
@@ -125,6 +109,13 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
        int retval;
 
        led->led_dev.name = name;
+       led->led_dev.brightness = LED_OFF;
+
+       /*
+        * Ensure the LED is off, it might have been enabled
+        * by the hardware when the device was powered on.
+        */
+       led->led_dev.brightness_set(&led->led_dev, LED_OFF);
 
        retval = led_classdev_register(device, &led->led_dev);
        if (retval) {
@@ -199,7 +190,16 @@ exit_fail:
 static void rt2x00leds_unregister_led(struct rt2x00_led *led)
 {
        led_classdev_unregister(&led->led_dev);
-       led->led_dev.brightness_set(&led->led_dev, LED_OFF);
+
+       /*
+        * This might look weird, but when we are unregistering while
+        * suspended the led is already off, and since we haven't
+        * fully resumed yet, access to the device might not be
+        * possible yet.
+        */
+       if (!(led->led_dev.flags & LED_SUSPENDED))
+               led->led_dev.brightness_set(&led->led_dev, LED_OFF);
+
        led->flags &= ~LED_REGISTERED;
 }
 
@@ -213,22 +213,40 @@ void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev)
                rt2x00leds_unregister_led(&rt2x00dev->led_radio);
 }
 
+static inline void rt2x00leds_suspend_led(struct rt2x00_led *led)
+{
+       led_classdev_suspend(&led->led_dev);
+
+       /* This shouldn't be needed, but just to be safe */
+       led->led_dev.brightness_set(&led->led_dev, LED_OFF);
+       led->led_dev.brightness = LED_OFF;
+}
+
 void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev)
 {
        if (rt2x00dev->led_qual.flags & LED_REGISTERED)
-               led_classdev_suspend(&rt2x00dev->led_qual.led_dev);
+               rt2x00leds_suspend_led(&rt2x00dev->led_qual);
        if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
-               led_classdev_suspend(&rt2x00dev->led_assoc.led_dev);
+               rt2x00leds_suspend_led(&rt2x00dev->led_assoc);
        if (rt2x00dev->led_radio.flags & LED_REGISTERED)
-               led_classdev_suspend(&rt2x00dev->led_radio.led_dev);
+               rt2x00leds_suspend_led(&rt2x00dev->led_radio);
+}
+
+static inline void rt2x00leds_resume_led(struct rt2x00_led *led)
+{
+       led_classdev_resume(&led->led_dev);
+
+       /* Device might have enabled the LEDS during resume */
+       led->led_dev.brightness_set(&led->led_dev, LED_OFF);
+       led->led_dev.brightness = LED_OFF;
 }
 
 void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev)
 {
        if (rt2x00dev->led_radio.flags & LED_REGISTERED)
-               led_classdev_resume(&rt2x00dev->led_radio.led_dev);
+               rt2x00leds_resume_led(&rt2x00dev->led_radio);
        if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
-               led_classdev_resume(&rt2x00dev->led_assoc.led_dev);
+               rt2x00leds_resume_led(&rt2x00dev->led_assoc);
        if (rt2x00dev->led_qual.flags & LED_REGISTERED)
-               led_classdev_resume(&rt2x00dev->led_qual.led_dev);
+               rt2x00leds_resume_led(&rt2x00dev->led_qual);
 }
index 9f214f8..9399733 100644 (file)
@@ -43,7 +43,6 @@ struct rt2x00_rate {
 #define DEV_RATE_CCK                   0x0001
 #define DEV_RATE_OFDM                  0x0002
 #define DEV_RATE_SHORT_PREAMBLE                0x0004
-#define DEV_RATE_BASIC                 0x0008
 
        unsigned short bitrate; /* In 100kbit/s */
        unsigned short ratemask;
@@ -94,7 +93,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
                          struct rt2x00_intf *intf,
                          struct ieee80211_bss_conf *conf);
 void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
-                             enum antenna rx, enum antenna tx);
+                             struct antenna_setup *ant);
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                      struct ieee80211_conf *conf,
                      const unsigned int changed_flags);
@@ -151,8 +150,16 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
  */
 void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
 
-void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev);
-void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev);
+/**
+ * rt2x00queue_init_queues - Initialize all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This function will loop through all available queues to clear all
+ * index numbers and set the queue entry to the correct initialization
+ * state.
+ */
+void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev);
+
 int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
 void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev);
 int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev);
index 8fc2315..48636b0 100644 (file)
@@ -339,7 +339,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
-       int radio_on;
        int status;
 
        /*
@@ -356,7 +355,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
         * some configuration parameters (e.g. channel and antenna values) can
         * only be set when the radio is enabled.
         */
-       radio_on = test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
        if (conf->radio_enabled) {
                /* For programming the values, we have to turn RX off */
                rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
@@ -372,6 +370,17 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
                 */
                rt2x00lib_config(rt2x00dev, conf, changed);
 
+               /*
+                * The radio was enabled, configure the antenna to the
+                * default settings, the link tuner will later start
+                * continue configuring the antenna based on the software
+                * diversity. But for non-diversity configurations, we need
+                * to have configured the correct state now.
+                */
+               if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED)
+                       rt2x00lib_config_antenna(rt2x00dev,
+                                                &rt2x00dev->default_ant);
+
                /* Turn RX back on */
                rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
        } else {
@@ -486,7 +495,9 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                        struct ieee80211_key_conf *key);
        struct rt2x00lib_crypto crypto;
 
-       if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return 0;
+       else if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
                return -EOPNOTSUPP;
        else if (key->keylen > 32)
                return -ENOSPC;
index 62449da..e33bd0f 100644 (file)
  */
 int rt2x00pci_write_tx_data(struct queue_entry *entry)
 {
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
        struct skb_frame_desc *skbdesc;
-       u32 word;
-
-       rt2x00_desc_read(entry_priv->desc, 0, &word);
 
        /*
         * This should not happen, we already checked the entry
         * was ours. When the hardware disagrees there has been
         * a queue corruption!
         */
-       if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||
-                    rt2x00_get_field32(word, TXD_ENTRY_VALID))) {
-               ERROR(entry->queue->rt2x00dev,
+       if (unlikely(rt2x00dev->ops->lib->get_entry_state(entry))) {
+               ERROR(rt2x00dev,
                      "Corrupt queue %d, accessing entry which is not ours.\n"
                      "Please file bug report to %s.\n",
                      entry->queue->qid, DRV_PROJECT);
@@ -76,14 +73,12 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
        struct queue_entry *entry;
        struct queue_entry_priv_pci *entry_priv;
        struct skb_frame_desc *skbdesc;
-       u32 word;
 
        while (1) {
                entry = rt2x00queue_get_entry(queue, Q_INDEX);
                entry_priv = entry->priv_data;
-               rt2x00_desc_read(entry_priv->desc, 0, &word);
 
-               if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
+               if (rt2x00dev->ops->lib->get_entry_state(entry))
                        break;
 
                /*
index a83f45f..96a2082 100644 (file)
 #define REGISTER_BUSY_DELAY    100
 
 /*
- * Descriptor availability flags.
- * All PCI device descriptors have these 2 flags
- * with the exact same definition.
- * By storing them here we can use them inside rt2x00pci
- * for some simple entry availability checking.
- */
-#define TXD_ENTRY_OWNER_NIC    FIELD32(0x00000001)
-#define TXD_ENTRY_VALID                FIELD32(0x00000002)
-#define RXD_ENTRY_OWNER_NIC    FIELD32(0x00000001)
-
-/*
  * Register access.
  */
 static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
index e9f4261..d7752db 100644 (file)
@@ -319,8 +319,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
                /*
                 * Convert length to microseconds.
                 */
-               residual = get_duration_res(data_length, hwrate->bitrate);
-               duration = get_duration(data_length, hwrate->bitrate);
+               residual = GET_DURATION_RES(data_length, hwrate->bitrate);
+               duration = GET_DURATION(data_length, hwrate->bitrate);
 
                if (residual != 0) {
                        duration++;
@@ -589,40 +589,18 @@ static void rt2x00queue_reset(struct data_queue *queue)
        spin_unlock_irqrestore(&queue->lock, irqflags);
 }
 
-void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev)
-{
-       struct data_queue *queue = rt2x00dev->rx;
-       unsigned int i;
-
-       rt2x00queue_reset(queue);
-
-       if (!rt2x00dev->ops->lib->init_rxentry)
-               return;
-
-       for (i = 0; i < queue->limit; i++) {
-               queue->entries[i].flags = 0;
-
-               rt2x00dev->ops->lib->init_rxentry(rt2x00dev,
-                                                 &queue->entries[i]);
-       }
-}
-
-void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)
+void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
 {
        struct data_queue *queue;
        unsigned int i;
 
-       txall_queue_for_each(rt2x00dev, queue) {
+       queue_for_each(rt2x00dev, queue) {
                rt2x00queue_reset(queue);
 
-               if (!rt2x00dev->ops->lib->init_txentry)
-                       continue;
-
                for (i = 0; i < queue->limit; i++) {
                        queue->entries[i].flags = 0;
 
-                       rt2x00dev->ops->lib->init_txentry(rt2x00dev,
-                                                         &queue->entries[i]);
+                       rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
                }
        }
 }
index b73a7e0..c507b0d 100644 (file)
@@ -79,7 +79,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
 {
        int status;
 
-       BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex));
+       BUG_ON(!mutex_is_locked(&rt2x00dev->csr_mutex));
 
        /*
         * Check for Cache availability.
@@ -110,13 +110,13 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
 {
        int status;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
                                                requesttype, offset, buffer,
                                                buffer_length, timeout);
 
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        return status;
 }
@@ -132,7 +132,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
        unsigned char *tb;
        u16 off, len, bsize;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        tb  = (char *)buffer;
        off = offset;
@@ -148,7 +148,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
                off += bsize;
        }
 
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        return status;
 }
@@ -351,28 +351,25 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
 /*
  * Device initialization handlers.
  */
-void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
-                           struct queue_entry *entry)
+void rt2x00usb_clear_entry(struct queue_entry *entry)
 {
-       struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+       struct usb_device *usb_dev =
+           to_usb_device_intf(entry->queue->rt2x00dev->dev);
        struct queue_entry_priv_usb *entry_priv = entry->priv_data;
 
-       usb_fill_bulk_urb(entry_priv->urb, usb_dev,
-                         usb_rcvbulkpipe(usb_dev, 1),
-                         entry->skb->data, entry->skb->len,
-                         rt2x00usb_interrupt_rxdone, entry);
+       if (entry->queue->qid == QID_RX) {
+               usb_fill_bulk_urb(entry_priv->urb, usb_dev,
+                               usb_rcvbulkpipe(usb_dev, 1),
+                               entry->skb->data, entry->skb->len,
+                               rt2x00usb_interrupt_rxdone, entry);
 
-       set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
-       usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
-}
-EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry);
-
-void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
-                           struct queue_entry *entry)
-{
-       entry->flags = 0;
+               set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+               usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+       } else {
+               entry->flags = 0;
+       }
 }
-EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry);
+EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
 
 static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
                               struct data_queue *queue)
@@ -534,7 +531,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
        rt2x00dev->dev = &usb_intf->dev;
        rt2x00dev->ops = ops;
        rt2x00dev->hw = hw;
-       mutex_init(&rt2x00dev->usb_cache_mutex);
 
        rt2x00dev->usb_maxpacket =
            usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
index 3b4a674..4104f0e 100644 (file)
@@ -286,10 +286,7 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 /*
  * Device initialization handlers.
  */
-void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
-                           struct queue_entry *entry);
-void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
-                           struct queue_entry *entry);
+void rt2x00usb_clear_entry(struct queue_entry *entry);
 int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev);
 void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev);
 
index 3f27279..89ac34f 100644 (file)
@@ -75,14 +75,14 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt61pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
-               return;
-       }
+       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+               goto exit_fail;
 
        /*
         * Write the data into the BBP.
@@ -94,6 +94,14 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0);
 
        rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
 }
 
 static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -101,14 +109,14 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt61pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
-               return;
-       }
+       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+               goto exit_fail;
 
        /*
         * Write the request into the BBP.
@@ -124,13 +132,19 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt61pci_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
-               *value = 0xff;
-               return;
-       }
+       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+               goto exit_fail;
 
        *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
+       *value = 0xff;
 }
 
 static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
@@ -142,6 +156,8 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
        if (!word)
                return;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                rt2x00pci_register_read(rt2x00dev, PHY_CSR4, &reg);
                if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY))
@@ -149,6 +165,7 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
                udelay(REGISTER_BUSY_DELAY);
        }
 
+       mutex_unlock(&rt2x00dev->csr_mutex);
        ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
        return;
 
@@ -161,6 +178,8 @@ rf_write:
 
        rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg);
        rt2x00_rf_write(rt2x00dev, word, value);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
@@ -175,14 +194,12 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->csr_mutex);
+
        rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, &reg);
 
-       if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER)) {
-               ERROR(rt2x00dev, "mcu request error. "
-                     "Request 0x%02x failed for token 0x%02x.\n",
-                     command, token);
-               return;
-       }
+       if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER))
+               goto exit_fail;
 
        rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1);
        rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
@@ -194,6 +211,17 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
        rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1);
        rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->csr_mutex);
+
+       ERROR(rt2x00dev,
+             "mcu request error. Request 0x%02x failed for token 0x%02x.\n",
+             command, token);
 }
 #endif /* CONFIG_RT2X00_LIB_LEDS */
 
@@ -1261,33 +1289,44 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
 /*
  * Initialization functions.
  */
-static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
-                                struct queue_entry *entry)
+static bool rt61pci_get_entry_state(struct queue_entry *entry)
 {
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
-       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        u32 word;
 
-       rt2x00_desc_read(entry_priv->desc, 5, &word);
-       rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
-                          skbdesc->skb_dma);
-       rt2x00_desc_write(entry_priv->desc, 5, word);
+       if (entry->queue->qid == QID_RX) {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
 
-       rt2x00_desc_read(entry_priv->desc, 0, &word);
-       rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
-       rt2x00_desc_write(entry_priv->desc, 0, word);
+               return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
+       } else {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
+
+               return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
+                       rt2x00_get_field32(word, TXD_W0_VALID));
+       }
 }
 
-static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev,
-                                struct queue_entry *entry)
+static void rt61pci_clear_entry(struct queue_entry *entry)
 {
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        u32 word;
 
-       rt2x00_desc_read(entry_priv->desc, 0, &word);
-       rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-       rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
-       rt2x00_desc_write(entry_priv->desc, 0, word);
+       if (entry->queue->qid == QID_RX) {
+               rt2x00_desc_read(entry_priv->desc, 5, &word);
+               rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
+                                  skbdesc->skb_dma);
+               rt2x00_desc_write(entry_priv->desc, 5, word);
+
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
+               rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
+               rt2x00_desc_write(entry_priv->desc, 0, word);
+       } else {
+               rt2x00_desc_read(entry_priv->desc, 0, &word);
+               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
+               rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
+               rt2x00_desc_write(entry_priv->desc, 0, word);
+       }
 }
 
 static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -2722,8 +2761,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
        .load_firmware          = rt61pci_load_firmware,
        .initialize             = rt2x00pci_initialize,
        .uninitialize           = rt2x00pci_uninitialize,
-       .init_rxentry           = rt61pci_init_rxentry,
-       .init_txentry           = rt61pci_init_txentry,
+       .get_entry_state        = rt61pci_get_entry_state,
+       .clear_entry            = rt61pci_clear_entry,
        .set_device_state       = rt61pci_set_device_state,
        .rfkill_poll            = rt61pci_rfkill_poll,
        .link_stats             = rt61pci_link_stats,
index 767e3c9..d1a63e0 100644 (file)
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
  * between each attampt. When the busy bit is still set at that time,
  * the access attempt is considered to have failed,
  * and we will print an error.
- * The _lock versions must be used if you already hold the usb_cache_mutex
+ * The _lock versions must be used if you already hold the csr_mutex
  */
 static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
                                         const unsigned int offset, u32 *value)
@@ -135,7 +135,7 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
         * Wait until the BBP becomes ready.
@@ -154,12 +154,12 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0);
 
        rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        return;
 
 exit_fail:
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
 }
@@ -169,7 +169,7 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        /*
         * Wait until the BBP becomes ready.
@@ -196,12 +196,12 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
                goto exit_fail;
 
        *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        return;
 
 exit_fail:
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
 
        ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
        *value = 0xff;
@@ -216,7 +216,7 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
        if (!word)
                return;
 
-       mutex_lock(&rt2x00dev->usb_cache_mutex);
+       mutex_lock(&rt2x00dev->csr_mutex);
 
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, &reg);
@@ -225,7 +225,7 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
                udelay(REGISTER_BUSY_DELAY);
        }
 
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+       mutex_unlock(&rt2x00dev->csr_mutex);
        ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
        return;
 
@@ -245,7 +245,8 @@ rf_write:
 
        rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
        rt2x00_rf_write(rt2x00dev, word, value);
-       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
@@ -2313,8 +2314,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .load_firmware          = rt73usb_load_firmware,
        .initialize             = rt2x00usb_initialize,
        .uninitialize           = rt2x00usb_uninitialize,
-       .init_rxentry           = rt2x00usb_init_rxentry,
-       .init_txentry           = rt2x00usb_init_txentry,
+       .clear_entry            = rt2x00usb_clear_entry,
        .set_device_state       = rt73usb_set_device_state,
        .link_stats             = rt73usb_link_stats,
        .reset_tuner            = rt73usb_reset_tuner,
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile
new file mode 100644 (file)
index 0000000..c113b3e
--- /dev/null
@@ -0,0 +1,7 @@
+rtl8180-objs           := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
+rtl8187-objs           := rtl8187_dev.o rtl8187_rtl8225.o
+
+obj-$(CONFIG_RTL8180)  += rtl8180.o
+obj-$(CONFIG_RTL8187)  += rtl8187.o
+
+
similarity index 98%
rename from drivers/net/wireless/rtl8180_dev.c
rename to drivers/net/wireless/rtl818x/rtl8180_dev.c
index 6c226c0..5f887fb 100644 (file)
@@ -720,6 +720,17 @@ static int rtl8180_config_interface(struct ieee80211_hw *dev,
        return 0;
 }
 
+static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
+                                    struct ieee80211_vif *vif,
+                                    struct ieee80211_bss_conf *info,
+                                    u32 changed)
+{
+       struct rtl8180_priv *priv = dev->priv;
+
+       if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
+               priv->rf->conf_erp(dev, info);
+}
+
 static void rtl8180_configure_filter(struct ieee80211_hw *dev,
                                     unsigned int changed_flags,
                                     unsigned int *total_flags,
@@ -760,6 +771,7 @@ static const struct ieee80211_ops rtl8180_ops = {
        .remove_interface       = rtl8180_remove_interface,
        .config                 = rtl8180_config,
        .config_interface       = rtl8180_config_interface,
+       .bss_info_changed       = rtl8180_bss_info_changed,
        .configure_filter       = rtl8180_configure_filter,
 };
 
similarity index 98%
rename from drivers/net/wireless/rtl8180_rtl8225.c
rename to drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
index cd22781..4d2be0d 100644 (file)
@@ -725,8 +725,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
 
        rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
        msleep(10);
+}
+
+static void rtl8225_rf_conf_erp(struct ieee80211_hw *dev,
+                               struct ieee80211_bss_conf *info)
+{
+       struct rtl8180_priv *priv = dev->priv;
 
-       if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
+       if (info->use_short_slot) {
                rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
                rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
                rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
@@ -745,14 +751,16 @@ static const struct rtl818x_rf_ops rtl8225_ops = {
        .name           = "rtl8225",
        .init           = rtl8225_rf_init,
        .stop           = rtl8225_rf_stop,
-       .set_chan       = rtl8225_rf_set_channel
+       .set_chan       = rtl8225_rf_set_channel,
+       .conf_erp       = rtl8225_rf_conf_erp,
 };
 
 static const struct rtl818x_rf_ops rtl8225z2_ops = {
        .name           = "rtl8225z2",
        .init           = rtl8225z2_rf_init,
        .stop           = rtl8225_rf_stop,
-       .set_chan       = rtl8225_rf_set_channel
+       .set_chan       = rtl8225_rf_set_channel,
+       .conf_erp       = rtl8225_rf_conf_erp,
 };
 
 const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
similarity index 99%
rename from drivers/net/wireless/rtl8187_dev.c
rename to drivers/net/wireless/rtl818x/rtl8187_dev.c
index e1399d0..4a9f76f 100644 (file)
@@ -7,6 +7,11 @@
  * Based on the r8187 driver, which is:
  * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
  *
+ * The driver was extended to the RTL8187B in 2008 by:
+ *     Herton Ronaldo Krzesinski <herton@mandriva.com.br>
+ *     Hin-Tak Leung <htl10@users.sourceforge.net>
+ *     Larry Finger <Larry.Finger@lwfinger.net>
+ *
  * Magic delays and register offsets below are taken from the original
  * r8187 driver sources.  Thanks to Realtek for their support!
  *
@@ -27,6 +32,9 @@
 
 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
 MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
+MODULE_AUTHOR("Herton Ronaldo Krzesinski <herton@mandriva.com.br>");
+MODULE_AUTHOR("Hin-Tak Leung <htl10@users.sourceforge.net>");
+MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
 MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
 MODULE_LICENSE("GPL");
 
similarity index 98%
rename from drivers/net/wireless/rtl818x.h
rename to drivers/net/wireless/rtl818x/rtl818x.h
index 3538b15..34a5555 100644 (file)
@@ -191,6 +191,7 @@ struct rtl818x_rf_ops {
        void (*init)(struct ieee80211_hw *);
        void (*stop)(struct ieee80211_hw *);
        void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
+       void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *);
 };
 
 /* Tx/Rx flags are common between RTL818X chips */
index 1134e2f..3404807 100644 (file)
@@ -743,7 +743,7 @@ static int zd1201_join(struct zd1201 *zd, char *essid, int essidlen)
 
 static int zd1201_net_open(struct net_device *dev)
 {
-       struct zd1201 *zd = (struct zd1201 *)dev->priv;
+       struct zd1201 *zd = netdev_priv(dev);
 
        /* Start MAC with wildcard if no essid set */
        if (!zd->mac_enabled)
@@ -781,7 +781,7 @@ static int zd1201_net_stop(struct net_device *dev)
  */
 static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct zd1201 *zd = (struct zd1201 *)dev->priv;
+       struct zd1201 *zd = netdev_priv(dev);
        unsigned char *txbuf = zd->txdata;
        int txbuflen, pad = 0, err;
        struct urb *urb = zd->tx_urb;
@@ -831,7 +831,7 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static void zd1201_tx_timeout(struct net_device *dev)
 {
-       struct zd1201 *zd = (struct zd1201 *)dev->priv;
+       struct zd1201 *zd = netdev_priv(dev);
 
        if (!zd)
                return;
@@ -846,7 +846,7 @@ static void zd1201_tx_timeout(struct net_device *dev)
 static int zd1201_set_mac_address(struct net_device *dev, void *p)
 {
        struct sockaddr *addr = p;
-       struct zd1201 *zd = (struct zd1201 *)dev->priv;
+       struct zd1201 *zd = netdev_priv(dev);
        int err;
 
        if (!zd)
@@ -863,21 +863,21 @@ static int zd1201_set_mac_address(struct net_device *dev, void *p)
 
 static struct net_device_stats *zd1201_get_stats(struct net_device *dev)
 {
-       struct zd1201 *zd = (struct zd1201 *)dev->priv;
+       struct zd1201 *zd = netdev_priv(dev);
 
        return &zd->stats;
 }
 
 static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
 {
-       struct zd1201 *zd = (struct zd1201 *)dev->priv;
+       struct zd1201 *zd = netdev_priv(dev);
 
        return &zd->iwstats;
 }
 
 static void zd1201_set_multicast(struct net_device *dev)
 {
-       struct zd1201 *zd = (struct zd1201 *)dev->priv;
+       struct zd1201 *zd = netdev_priv(dev);
        struct dev_mc_list *mc = dev->mc_list;
        unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI];
        int i;
@@ -897,7 +897,7 @@ static void zd1201_set_multicast(struct net_device *dev)
 static int zd1201_config_commit(struct net_device *dev, 
     struct iw_request_info *info, struct iw_point *data, char *essid)
 {
-       struct zd1201 *zd = (struct zd1201 *)dev->priv;
+       struct zd1201 *zd = netdev_priv(dev);
 
        return zd1201_mac_reset(zd);
 }
@@ -912,7