rpms/kernel/F-8 kernel.spec, 1.224, 1.225 linux-2.6-ath5k.patch, 1.4, 1.5

John W. Linville (linville) fedora-extras-commits at redhat.com
Tue Oct 16 01:36:27 UTC 2007


Author: linville

Update of /cvs/pkgs/rpms/kernel/F-8
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv23809

Modified Files:
	kernel.spec linux-2.6-ath5k.patch 
Log Message:
ath5k updates


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-8/kernel.spec,v
retrieving revision 1.224
retrieving revision 1.225
diff -u -r1.224 -r1.225
--- kernel.spec	16 Oct 2007 00:15:21 -0000	1.224
+++ kernel.spec	16 Oct 2007 01:35:52 -0000	1.225
@@ -1840,6 +1840,9 @@
 
 
 %changelog
+* Tue Oct 16 2007 John W. Linville <linville at redhat.com>
+- ath5k updates
+
 * Tue Oct 16 2007 Dave Airlie <airlied at redhat.com>
 - fix i915 drm memory allocation issue
 

linux-2.6-ath5k.patch:

Index: linux-2.6-ath5k.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-8/linux-2.6-ath5k.patch,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- linux-2.6-ath5k.patch	5 Oct 2007 15:17:09 -0000	1.4
+++ linux-2.6-ath5k.patch	16 Oct 2007 01:35:52 -0000	1.5
@@ -1,6 +1,6 @@
-diff -up linux-2.6.22.noarch/MAINTAINERS.orig linux-2.6.22.noarch/MAINTAINERS
---- linux-2.6.22.noarch/MAINTAINERS.orig	2007-09-27 19:25:02.000000000 -0400
-+++ linux-2.6.22.noarch/MAINTAINERS	2007-09-27 19:26:44.000000000 -0400
+diff -up linux-2.6.23.noarch/MAINTAINERS.orig linux-2.6.23.noarch/MAINTAINERS
+--- linux-2.6.23.noarch/MAINTAINERS.orig	2007-10-15 21:21:41.000000000 -0400
++++ linux-2.6.23.noarch/MAINTAINERS	2007-10-15 21:21:48.000000000 -0400
 @@ -642,6 +642,14 @@ M:	ecashin at coraid.com
  W:	http://www.coraid.com/support/linux
  S:	Supported
@@ -16,18 +16,18 @@
  ATL1 ETHERNET DRIVER
  P:	Jay Cliburn
  M:	jcliburn at gmail.com
-diff -up linux-2.6.22.noarch/drivers/net/wireless/Makefile.orig linux-2.6.22.noarch/drivers/net/wireless/Makefile
---- linux-2.6.22.noarch/drivers/net/wireless/Makefile.orig	2007-09-27 19:25:02.000000000 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/Makefile	2007-09-27 19:27:03.000000000 -0400
-@@ -61,3 +61,5 @@ obj-$(CONFIG_RT2X00)		+= rt2x00/
+diff -up linux-2.6.23.noarch/drivers/net/wireless/Makefile.orig linux-2.6.23.noarch/drivers/net/wireless/Makefile
+--- linux-2.6.23.noarch/drivers/net/wireless/Makefile.orig	2007-10-15 21:21:41.000000000 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/Makefile	2007-10-15 21:21:48.000000000 -0400
+@@ -62,3 +62,5 @@ obj-$(CONFIG_RT2X00)		+= rt2x00/
  obj-$(CONFIG_P54_COMMON)	+= p54common.o
  obj-$(CONFIG_P54_USB)		+= p54usb.o
  obj-$(CONFIG_P54_PCI)		+= p54pci.o
 +
 +obj-$(CONFIG_ATH5K)	+= ath5k/
-diff -up linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig linux-2.6.22.noarch/drivers/net/wireless/Kconfig
---- linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig	2007-09-27 19:25:02.000000000 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/Kconfig	2007-09-27 19:26:44.000000000 -0400
+diff -up linux-2.6.23.noarch/drivers/net/wireless/Kconfig.orig linux-2.6.23.noarch/drivers/net/wireless/Kconfig
+--- linux-2.6.23.noarch/drivers/net/wireless/Kconfig.orig	2007-10-15 21:21:41.000000000 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/Kconfig	2007-10-15 21:21:48.000000000 -0400
 @@ -598,6 +598,19 @@ config P54_PCI
  	tristate "Prism54 PCI support"
  	depends on P54_COMMON && PCI
@@ -48,47 +48,29 @@
  source "drivers/net/wireless/hostap/Kconfig"
  source "drivers/net/wireless/bcm43xx/Kconfig"
  source "drivers/net/wireless/b43/Kconfig"
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/phy.c
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/phy.c	2007-09-27 19:26:44.000000000 -0400
-@@ -0,0 +1,1704 @@
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/phy.c
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/phy.c	2007-10-15 21:22:03.000000000 -0400
+@@ -0,0 +1,1686 @@
 +/*
 + * PHY functions
 + *
-+ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm at gmail.com>
++ * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk at openbsd.org>
++ * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm at gmail.com>
++ * Copyright (c) 2007 Jiri Slaby <jirislaby at gmail.com>
++ *
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 + *
-+ *  This file is free software: you can copy, redistribute and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation, either version 2 of the License, or (at
-+ *  your option) any later version.
-+ *
-+ *  This file 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, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ *
-+ *     Copyright (c) 2007 Jiri Slaby <jirislaby at gmail.com>
-+ *     Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk at openbsd.org>
-+ *
-+ *     Permission to use, copy, modify, and distribute this software for
-+ *     any purpose with or without fee is hereby granted, provided that
-+ *     the above copyright notice and this permission notice appear in all
-+ *     copies.
-+ *
-+ *     THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
-+ *     WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
-+ *     WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
-+ *     AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
-+ *     CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-+ *     OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-+ *     NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-+ *     CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 + */
 +
 +#include <linux/delay.h>
@@ -1756,10 +1738,10 @@
 +#endif
 +	return ath5k_hw_txpower(hal, channel, power);
 +}
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/ath5k.h
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/ath5k.h	2007-09-27 19:26:44.000000000 -0400
-@@ -0,0 +1,1086 @@
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/ath5k.h
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/ath5k.h	2007-10-15 21:24:43.000000000 -0400
+@@ -0,0 +1,1138 @@
 +/*
 + * Copyright (c) 2004-2007 Reyk Floeter <reyk at openbsd.org>
 + * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm at gmail.com>
@@ -1976,6 +1958,9 @@
 +	MODE_ATHEROS_TURBOG
 +};
 +
++/* Number of supported mac80211 enum ieee80211_phymode modes by this driver */
++#define NUM_DRIVER_MODES	3
++
 +/* adding this flag to rate_code enables short preamble, see ar5212_reg.h */
 +#define AR5K_SET_SHORT_PREAMBLE 0x04
 +
@@ -2482,18 +2467,65 @@
 + * HAL interrupt abstraction
 + */
 +
-+/*
++/**
++ * enum ath5k_int - Hardware interrupt masks helpers
++ *
++ * @AR5K_INT_RX: mask to identify received frame interrupts, of type
++ * 	AR5K_ISR_RXOK or AR5K_ISR_RXERR
++ * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?)
++ * @AR5K_INT_RXNOFRM: No frame received (?)
++ * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The
++ * 	Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's
++ * 	LinkPtr is NULL. For more details, refer to:
++ * 	http://www.freepatentsonline.com/20030225739.html
++ * @AR5K_INT_RXORN: indicates a hardware reset is required on certain hardware.
++ * 	Note that Rx overrun is not always fatal, on some chips we can continue
++ * 	operation without reseting the card, that's why int_fatal is not
++ * 	common for all chips.
++ * @AR5K_INT_TX: mask to identify received frame interrupts, of type
++ * 	AR5K_ISR_TXOK or AR5K_ISR_TXERR
++ * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?)
++ * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
++ * 	We currently do increments on interrupt by
++ * 	(AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
++ * @AR5K_INT_MIB: Indicates the Management Information Base counters should be
++ * 	checked. We should do this with ath5k_hw_update_mib_counters() but
++ * 	it seems we should also then do some noise immunity work.
++ * @AR5K_INT_RXPHY: RX PHY Error
++ * @AR5K_INT_RXKCM: ??
++ * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
++ * 	beacon that must be handled in software. The alternative is if you
++ * 	have VEOL support, in that case you let the hardware deal with things.
++ * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing
++ * 	beacons from the AP have associated with, we should probably try to
++ * 	reassociate. When in IBSS mode this might mean we have not received
++ * 	any beacons from any local stations. Note that every station in an
++ * 	IBSS schedules to send beacons at the Target Beacon Transmission Time
++ * 	(TBTT) with a random backoff.
++ * @AR5K_INT_BNR: Beacon Not Ready interrupt - ??
++ * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now
++ * 	until properly handled
++ * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA
++ * 	errors. These types of errors we can enable seem to be of type
++ * 	AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
++ * @AR5K_INT_GLOBAL: Seems to be used to clear and set the IER
++ * @AR5K_INT_NOCARD: signals the card has been removed
++ * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same
++ * 	bit value
++ *
 + * These are mapped to take advantage of some common bits
-+ * between the MAC chips, to be able to set intr properties
-+ * easier. Some of them are not used yet inside OpenHAL.
++ * between the MACs, to be able to set intr properties
++ * easier. Some of them are not used yet inside hw.c. Most map
++ * to the respective hw interrupt value as they are common amogst different
++ * MACs.
 + */
 +enum ath5k_int {
-+	AR5K_INT_RX	= 0x00000001,
++	AR5K_INT_RX	= 0x00000001, /* Not common */
 +	AR5K_INT_RXDESC	= 0x00000002,
 +	AR5K_INT_RXNOFRM = 0x00000008,
 +	AR5K_INT_RXEOL	= 0x00000010,
 +	AR5K_INT_RXORN	= 0x00000020,
-+	AR5K_INT_TX	= 0x00000040,
++	AR5K_INT_TX	= 0x00000040, /* Not common */
 +	AR5K_INT_TXDESC	= 0x00000080,
 +	AR5K_INT_TXURN	= 0x00000800,
 +	AR5K_INT_MIB	= 0x00001000,
@@ -2501,12 +2533,11 @@
 +	AR5K_INT_RXKCM	= 0x00008000,
 +	AR5K_INT_SWBA	= 0x00010000,
 +	AR5K_INT_BMISS	= 0x00040000,
-+	AR5K_INT_BNR	= 0x00100000,
++	AR5K_INT_BNR	= 0x00100000, /* Not common */
 +	AR5K_INT_GPIO	= 0x01000000,
-+	AR5K_INT_FATAL	= 0x40000000,
++	AR5K_INT_FATAL	= 0x40000000, /* Not common */
 +	AR5K_INT_GLOBAL	= 0x80000000,
 +
-+	/*A sum of all the common bits*/
 +	AR5K_INT_COMMON  = AR5K_INT_RXNOFRM
 +			| AR5K_INT_RXDESC
 +			| AR5K_INT_RXEOL
@@ -2519,8 +2550,7 @@
 +			| AR5K_INT_SWBA
 +			| AR5K_INT_BMISS
 +			| AR5K_INT_GPIO,
-+	AR5K_INT_NOCARD	= 0xffffffff /*Declare that the card
-+				       has been removed*/
++	AR5K_INT_NOCARD	= 0xffffffff
 +};
 +
 +/*
@@ -2582,7 +2612,7 @@
 +	 * Supported PHY modes
 +	 * (ie. CHANNEL_A, CHANNEL_B, ...)
 +	 */
-+	DECLARE_BITMAP(cap_mode, NUM_IEEE80211_MODES);
++	DECLARE_BITMAP(cap_mode, NUM_DRIVER_MODES);
 +
 +	/*
 +	 * Frequency range (without regulation restrictions)
@@ -2639,6 +2669,10 @@
 +	enum ieee80211_if_types	ah_op_mode;
 +	enum ath5k_power_mode	ah_power_mode;
 +	struct ieee80211_channel ah_current_channel;
++	/* Current BSSID we are trying to assoc to / creating, this
++	 * comes from ieee80211_if_conf. This is passed by mac80211 on
++	 * config_interface() */
++	u8			bssid[ETH_ALEN];
 +	bool			ah_turbo;
 +	bool			ah_calibration;
 +	bool			ah_running;
@@ -2846,16 +2880,16 @@
 +}
 +
 +#endif
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/Makefile
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/Makefile	2007-09-27 19:26:44.000000000 -0400
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/Makefile
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/Makefile	2007-10-15 21:21:48.000000000 -0400
 @@ -0,0 +1,2 @@
 +ath5k-objs		= base.o hw.o regdom.o initvals.o phy.o
 +obj-$(CONFIG_ATH5K)	+= ath5k.o
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/reg.h
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/reg.h	2007-09-27 19:26:44.000000000 -0400
-@@ -0,0 +1,1977 @@
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/reg.h
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/reg.h	2007-10-15 21:24:43.000000000 -0400
+@@ -0,0 +1,1982 @@
 +/*
 + * Copyright (c) 2007 Nick Kossifidis <mickflemm at gmail.com>
 + * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk at openbsd.org>
@@ -4109,10 +4143,13 @@
 +#define	AR5K_RX_FILTER_RADARERR_5212 	0x00000200	/* Don't filter phy radar errors [5212+] */
 +#define AR5K_RX_FILTER_PHYERR_5211	0x00000040	/* [5211] */
 +#define AR5K_RX_FILTER_RADARERR_5211	0x00000080	/* [5211] */
-+#define AR5K_RX_FILTER_PHYERR	(ah->ah_version == AR5K_AR5211 ? \
-+				AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212)
-+#define	AR5K_RX_FILTER_RADARERR	(ah->ah_version == AR5K_AR5211 ? \
-+				AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212)
++#define AR5K_RX_FILTER_PHYERR  \
++	((ah->ah_version == AR5K_AR5211 ? \
++	AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
++#define        AR5K_RX_FILTER_RADARERR \
++	((ah->ah_version == AR5K_AR5211 ? \
++	AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
++
 +/*
 + * Multicast filter register (lower 32 bits)
 + */
@@ -4612,8 +4649,10 @@
 + * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
 + * for now. It's interesting that they are also used for some other operations.
 + *
-+ * Also check out ath5k_hw.h and U.S. Patent 6677779 B1 (about buffer
-+ * registers and control registers)
++ * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
++ * registers and control registers):
++ *
++ * http://www.google.com/patents?id=qNURAAAAEBAJ
 + */
 +
 +#define AR5K_RF_BUFFER			0x989c
@@ -4833,9 +4872,9 @@
 +#define	AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX	0x00fc0000
 +#define	AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S	18
 +#define	AR5K_PHY_GAIN_2GHZ_INI_5111	0x6480416c
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/regdom.h
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/regdom.h	2007-09-27 19:26:44.000000000 -0400
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/regdom.h
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/regdom.h	2007-10-15 21:21:48.000000000 -0400
 @@ -0,0 +1,500 @@
 +/*
 + * Copyright (c) 2004, 2005 Reyk Floeter <reyk at openbsd.org>
@@ -5337,10 +5376,10 @@
 +enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain);
 +
 +#endif
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/hw.c
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/hw.c	2007-09-27 19:26:44.000000000 -0400
-@@ -0,0 +1,4319 @@
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/hw.c
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/hw.c	2007-10-15 21:24:43.000000000 -0400
+@@ -0,0 +1,4410 @@
 + /*
 + * Copyright (c) 2004-2007 Reyk Floeter <reyk at openbsd.org>
 + * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm at gmail.com>
@@ -5649,15 +5688,6 @@
 +
 +	hal->ah_phy = AR5K_PHY(0);
 +
-+	/* Set MAC to bcast: ff:ff:ff:ff:ff:ff, this is using 'mac' as a
-+	 * temporary variable for setting our BSSID. Right bellow we update
-+	 * it with ath5k_hw_get_lladdr() */
-+	memset(mac, 0xff, ETH_ALEN);
-+	ath5k_hw_set_associd(hal, mac, 0);
-+
-+	ath5k_hw_get_lladdr(hal, mac);
-+	ath5k_hw_set_opmode(hal);
-+
 +#ifdef AR5K_DEBUG
 +	ath5k_hw_dump_state(hal);
 +#endif
@@ -5689,6 +5719,10 @@
 +	}
 +
 +	ath5k_hw_set_lladdr(hal, mac);
++	/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
++	memset(hal->bssid, 0xff, ETH_ALEN);
++	ath5k_hw_set_associd(hal, hal->bssid, 0);
++	ath5k_hw_set_opmode(hal);
 +
 +	ath5k_hw_set_rfgain_opt(hal);
 +
@@ -5886,7 +5920,6 @@
 +	const struct ath5k_rate_table *rt;
 +	struct ath5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom;
 +	u32 data, noise_floor, s_seq, s_ant, s_led[3];
-+	u8 mac[ETH_ALEN];
 +	unsigned int i, mode, freq, ee_mode, ant[2];
 +	int ret;
 +
@@ -6204,8 +6237,9 @@
 +	/*
 +	 * Misc
 +	 */
-+	memset(mac, 0xff, ETH_ALEN);
-+	ath5k_hw_set_associd(hal, mac, 0);
++	/* XXX: add hal->aid once mac80211 gives this to us */
++	ath5k_hw_set_associd(hal, hal->bssid, 0);
++
 +	ath5k_hw_set_opmode(hal);
 +	/*PISR/SISR Not available on 5210*/
 +	if (hal->ah_version != AR5K_AR5210) {
@@ -6401,7 +6435,9 @@
 +	ret = ath5k_hw_register_timeout(hal, AR5K_RESET_CTL, mask, val, false);
 +
 +	/*
-+	 * Reset configuration register (for hw byte-swap)
++	 * Reset configuration register (for hw byte-swap). Note that this
++	 * is only set for big endian. We do the necessary magic in
++	 * AR5K_INIT_CFG.
 +	 */
 +	if ((val & AR5K_RESET_CTL_PCU) == 0)
 +		ath5k_hw_reg_write(hal, AR5K_INIT_CFG, AR5K_CFG);
@@ -6813,14 +6849,15 @@
 +			*interrupt_mask = data;
 +			return -ENODEV;
 +		}
++	} else {
++		/*
++		 * Read interrupt status from the Read-And-Clear shadow register
++		 * Note: PISR/SISR Not available on 5210
++		 */
++		data = ath5k_hw_reg_read(hal, AR5K_RAC_PISR);
 +	}
 +
 +	/*
-+	 * Read interrupt status from the Read-And-Clear shadow register
-+	 */
-+	data = ath5k_hw_reg_read(hal, AR5K_RAC_PISR);
-+
-+	/*
 +	 * Get abstract interrupt mask (HAL-compatible)
 +	 */
 +	*interrupt_mask = (data & AR5K_INT_COMMON) & hal->ah_imr;
@@ -6846,7 +6883,9 @@
 +
 +	/*
 +	 * XXX: BMISS interrupts may occur after association.
-+	 * I found this on 5210 code but it needs testing
++	 * I found this on 5210 code but it needs testing. If this is
++	 * true we should disable them before assoc and re-enable them
++	 * after a successfull assoc + some jiffies.
 +	 */
 +#if 0
 +	interrupt_mask &= ~AR5K_INT_BMISS;
@@ -7471,8 +7510,8 @@
 +		hal->ah_capabilities.cap_range.range_2ghz_max = 0;
 +
 +		/* Set supported modes */
-+		set_bit(MODE_IEEE80211A, hal->ah_capabilities.cap_mode);
-+		set_bit(MODE_ATHEROS_TURBO, hal->ah_capabilities.cap_mode);
++		__set_bit(MODE_IEEE80211A, hal->ah_capabilities.cap_mode);
++		__set_bit(MODE_ATHEROS_TURBO, hal->ah_capabilities.cap_mode);
 +	} else {
 +		/*
 +		 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
@@ -7494,11 +7533,12 @@
 +			hal->ah_capabilities.cap_range.range_5ghz_max = 6100;
 +
 +			/* Set supported modes */
-+			set_bit(MODE_IEEE80211A, hal->ah_capabilities.cap_mode);
-+			set_bit(MODE_ATHEROS_TURBO,
++			__set_bit(MODE_IEEE80211A,
++					hal->ah_capabilities.cap_mode);
++			__set_bit(MODE_ATHEROS_TURBO,
 +					hal->ah_capabilities.cap_mode);
 +			if (hal->ah_version == AR5K_AR5212)
-+				set_bit(MODE_ATHEROS_TURBOG,
++				__set_bit(MODE_ATHEROS_TURBOG,
 +						hal->ah_capabilities.cap_mode);
 +		}
 +
@@ -7510,11 +7550,11 @@
 +			hal->ah_capabilities.cap_range.range_2ghz_max = 2732;
 +
 +			if (AR5K_EEPROM_HDR_11B(ee_header))
-+				set_bit(MODE_IEEE80211B,
++				__set_bit(MODE_IEEE80211B,
 +						hal->ah_capabilities.cap_mode);
 +
 +			if (AR5K_EEPROM_HDR_11G(ee_header))
-+				set_bit(MODE_IEEE80211G,
++				__set_bit(MODE_IEEE80211G,
 +						hal->ah_capabilities.cap_mode);
 +		}
 +	}
@@ -7663,9 +7703,99 @@
 +
 +	ath5k_hw_enable_pspoll(hal, NULL, 0);
 +}
-+
-+/*
-+ * Set BSSID mask on 5212
++/**
++ * ath5k_hw_set_bssid_mask - set common bits we should listen to
++ *
++ * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
++ * which bits of the interface's MAC address should be looked at when trying
++ * to decide which packets to ACK. In station mode every bit matters. In AP
++ * mode with a single BSS every bit matters as well. In AP mode with
++ * multiple BSSes not every bit matters.
++ *
++ * @hal: the &struct ath_hw
++ * @mask: the bssid_mask, a u8 array of size ETH_ALEN
++ *
++ * Note that this is a simple filter and *does* not filter out all
++ * relevant frames. Some non-relevant frames will get through, probability
++ * jocks are welcomed to compute.
++ *
++ * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
++ * computing the set of:
++ *
++ *     ~ ( MAC XOR BSSID )
++ *
++ * When you do this you are essentially computing the common bits. Later it
++ * is assumed the harware will "and" (&) the BSSID mask with the MAC address
++ * to obtain the relevant bits which should match on the destination frame.
++ *
++ * Simple example: on your card you have have two BSSes you have created with
++ * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
++ * There is another BSSID-03 but you are not part of it. For simplicity's sake,
++ * assuming only 4 bits for a mac address and for BSSIDs you can then have:
++ *
++ *                  \
++ * MAC:                0001 |
++ * BSSID-01:   0100 | --> Belongs to us
++ * BSSID-02:   1001 |
++ *                  /
++ * -------------------
++ * BSSID-03:   0110  | --> External
++ * -------------------
++ *
++ * Our bssid_mask would then be:
++ *
++ *             On loop iteration for BSSID-01:
++ *             ~(0001 ^ 0100)  -> ~(0101)
++ *                             ->   1010
++ *             bssid_mask      =    1010
++ *
++ *             On loop iteration for BSSID-02:
++ *             bssid_mask &= ~(0001   ^   1001)
++ *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
++ *             bssid_mask =   (1010)  & ~(1001)
++ *             bssid_mask =   (1010)  &  (0110)
++ *             bssid_mask =   0010
++ *
++ * A bssid_mask of 0010 means "only pay attention to the second least
++ * significant bit". This is because its the only bit common
++ * amongst the MAC and all BSSIDs we support. To findout what the real
++ * common bit is we can simply "&" the bssid_mask now with any BSSID we have
++ * or our MAC address (we assume the hardware uses the MAC address).
++ *
++ * Now, suppose there's an incoming frame for BSSID-03:
++ *
++ * IFRAME-01:  0110
++ *
++ * An easy eye-inspeciton of this already should tell you that this frame
++ * will not pass our check. This is beacuse the bssid_mask tells the
++ * hardware to only look at the second least significant bit and the
++ * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
++ * as 1, which does not match 0.
++ *
++ * So with IFRAME-01 we *assume* the hardware will do:
++ *
++ *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
++ *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
++ *  --> allow = (0010) == 0000 ? 1 : 0;
++ *  --> allow = 0
++ *
++ *  Lets now test a frame that should work:
++ *
++ * IFRAME-02:  0001 (we should allow)
++ *
++ *     allow = (0001 & 1010) == 1010
++ *
++ *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
++ *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
++ *  --> allow = (0010) == (0010)
++ *  --> allow = 1
++ *
++ * Other examples:
++ *
++ * IFRAME-03:  0100 --> allowed
++ * IFRAME-04:  1001 --> allowed
++ * IFRAME-05:  1101 --> allowed but its not for us!!!
++ *
 + */
 +int ath5k_hw_set_bssid_mask(struct ath_hw *hal, const u8 *mask)
 +{
@@ -9660,9 +9790,9 @@
 +
 +	return -EIO;
 +}
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/hw.h
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/hw.h	2007-09-27 19:26:44.000000000 -0400
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/hw.h
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/hw.h	2007-10-15 21:21:48.000000000 -0400
 @@ -0,0 +1,586 @@
 +/*
 + * Copyright (c) 2004-2007 Reyk Floeter <reyk at openbsd.org>
@@ -10250,47 +10380,28 @@
 +
 +	return retval;
 +}
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/initvals.c
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/initvals.c	2007-09-27 19:26:44.000000000 -0400
-@@ -0,0 +1,1121 @@
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/initvals.c
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/initvals.c	2007-10-15 21:22:03.000000000 -0400
+@@ -0,0 +1,1102 @@
 +/*
 + * Initial register settings functions
 + *
-+ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm at gmail.com>
++ * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk at openbsd.org>
++ * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm at gmail.com>
++ * Copyright (c) 2007 Jiri Slaby <jirislaby at gmail.com>
 + *
-+ *  This file is free software: you can copy, redistribute and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation, either version 2 of the License, or (at
-+ *  your option) any later version.
-+ *
-+ *  This file 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, see <http://www.gnu.org/licenses/>.
-+ *
-+ * This file incorporates work covered by the following copyright and
-+ * permission notice:
-+ *
-+ *     Copyright (c) 2007 Jiri Slaby <jirislaby at gmail.com>
-+ *     Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk at openbsd.org>
-+ *
-+ *     Permission to use, copy, modify, and distribute this software for
-+ *     any purpose with or without fee is hereby granted, provided that
-+ *     the above copyright notice and this permission notice appear in all
-+ *     copies.
-+ *
-+ *     THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
-+ *     WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
-+ *     WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
-+ *     AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
-+ *     CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-+ *     OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-+ *     NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-+ *     CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 + *
 + */
 +
@@ -11375,15 +11486,16 @@
 +
 +	return 0;
 +}
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/base.c
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/base.c	2007-09-27 19:26:44.000000000 -0400
-@@ -0,0 +1,2543 @@
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/base.c
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/base.c	2007-10-15 21:24:43.000000000 -0400
+@@ -0,0 +1,2601 @@
 +/*-
 + * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
 + * Copyright (c) 2004-2005 Atheros Communications, Inc.
 + * Copyright (c) 2006 Devicescape Software, Inc.
 + * Copyright (c) 2007 Jiri Slaby <jirislaby at gmail.com>
++ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof at winlab.rutgers.edu>
 + *
 + * All rights reserved.
 + *
@@ -11405,6 +11517,19 @@
 + * GNU General Public License ("GPL") version 2 as published by the Free
 + * Software Foundation.
 + *
++ * NO WARRANTY
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
++ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
++ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ * THE POSSIBILITY OF SUCH DAMAGES.
++ *
 + */
 +#define	ATH_PCI_VERSION	"0.9.5.0-BSD"
 +
@@ -11742,6 +11867,8 @@
 +	u16 len;
 +	u8 stat;
 +	int ret;
++	int hdrlen;
++	int pad;
 +
 +	spin_lock(&sc->rxbuflock);
 +	do {
@@ -11816,13 +11943,20 @@
 +				PCI_DMA_FROMDEVICE);
 +		bf->skb = NULL;
 +
-+		if (unlikely((ieee80211_get_hdrlen_from_skb(skb) & 3) &&
-+					net_ratelimit()))
-+			printk(KERN_DEBUG "rx len is not %%4: %u\n",
-+					ieee80211_get_hdrlen_from_skb(skb));
-+
 +		skb_put(skb, len);
 +
++		/*
++		 * the hardware adds a padding to 4 byte boundaries between
++		 * the header and the payload data if the header length is
++		 * not multiples of 4 - remove it
++		 */
++		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
++		if (hdrlen & 3) {
++			pad = hdrlen % 4;
++			memmove(skb->data + pad, skb->data, hdrlen);
++			skb_pull(skb, pad);
++		}
++
 +		if (sc->opmode == IEEE80211_IF_TYPE_MNTR)
 +			rxs.mactime = ath_extend_tsf(sc->ah,
 +					ds->ds_rxstat.rs_tstamp);
@@ -12123,14 +12257,8 @@
 +	if (opmode != IEEE80211_IF_TYPE_AP && test_bit(ATH_STAT_PROMISC,
 +				sc->status))
 +		rfilt |= AR5K_RX_FILTER_PROM;
-+	if (opmode == IEEE80211_IF_TYPE_STA || opmode == IEEE80211_IF_TYPE_IBSS) {
++	if (opmode == IEEE80211_IF_TYPE_STA || opmode == IEEE80211_IF_TYPE_IBSS)
 +		rfilt |= AR5K_RX_FILTER_BEACON;
-+		/* Note: AR5212 requires AR5K_RX_FILTER_PROM to receive broadcasts,
-+		 * perhaps the flags are off, for now to be safe we'll enable it for
-+		 * STA and ADHOC until we have this properly mapped */
-+		if (ah->ah_version == AR5K_AR5212)
-+			rfilt |= AR5K_RX_FILTER_PROM;
-+	}
 +
 +	return rfilt;
 +}
@@ -12568,7 +12696,7 @@
 +	struct ath_txq *txq = sc->txq;
 +	struct ath_desc *ds = bf->desc;
 +	struct sk_buff *skb = bf->skb;
-+	unsigned int hdrpad, pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
++	unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
 +	int ret;
 +
 +	flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
@@ -12580,12 +12708,7 @@
 +	if (ctl->flags & IEEE80211_TXCTL_NO_ACK)
 +		flags |= AR5K_TXDESC_NOACK;
 +
-+	if ((ieee80211_get_hdrlen_from_skb(skb) & 3) && net_ratelimit())
-+		printk(KERN_DEBUG "tx len is not %%4: %u\n",
-+				ieee80211_get_hdrlen_from_skb(skb));
-+
-+	hdrpad = 0;
-+	pktlen = skb->len - hdrpad + FCS_LEN;
++	pktlen = skb->len + FCS_LEN;
 +
 +	if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) {
 +		keyidx = ctl->key_idx;
@@ -12629,12 +12752,32 @@
 +	struct ath_softc *sc = hw->priv;
 +	struct ath_buf *bf;
 +	unsigned long flags;
++	int hdrlen;
++	int pad;
 +
 +	ath_dump_skb(skb, "t");
 +
 +	if (sc->opmode == IEEE80211_IF_TYPE_MNTR)
 +		DPRINTF(sc, ATH_DEBUG_XMIT, "tx in monitor (scan?)\n");
 +
++	/*
++	 * the hardware expects the header padded to 4 byte boundaries
++	 * if this is not the case we add the padding after the header
++	 */
++	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
++	if (hdrlen & 3) {
++		pad = hdrlen % 4;
++		if (skb_headroom(skb) < pad) {
++			if (net_ratelimit())
++				printk(KERN_ERR "ath: tx hdrlen not %%4: %d "
++					"not enough headroom to pad %d\n",
++					hdrlen, pad);
++			return -1;
++		}
++		skb_push(skb, pad);
++		memmove(skb->data, skb->data+pad, hdrlen);
++	}
++
 +	sc->led_txrate = ctl->tx_rate;
 +
 +	spin_lock_irqsave(&sc->txbuflock, flags);
@@ -12783,6 +12926,7 @@
 +		struct ieee80211_if_conf *conf)
 +{
 +	struct ath_softc *sc = hw->priv;
++	struct ath_hw *ah = sc->ah;
 +	int ret;
 +
 +	mutex_lock(&sc->lock);
@@ -12790,8 +12934,13 @@
 +		ret = -EIO;
 +		goto unlock;
 +	}
-+	if (conf->bssid)
-+		ath5k_hw_set_associd(sc->ah, conf->bssid, 0 /* FIXME: aid */);
++	if (conf->bssid) {
++		/* Cache for later use during resets */
++		memcpy(ah->bssid, conf->bssid, ETH_ALEN);
++		/* XXX: assoc id is set to 0 for now, mac80211 doesn't have
++		 * a clean way of letting us retrieve this yet. */
++		ath5k_hw_set_associd(ah, ah->bssid, 0);
++	}
 +	mutex_unlock(&sc->lock);
 +
 +	return ath_reset(hw);
@@ -13200,7 +13349,7 @@
 +{
 +	unsigned int m, i;
 +
-+	for (m = 0; m < NUM_IEEE80211_MODES; m++) {
++	for (m = 0; m < NUM_DRIVER_MODES; m++) {
 +		printk(KERN_DEBUG "Mode %u: channels %d, rates %d\n", m,
 +				modes[m].num_channels, modes[m].num_rates);
 +		printk(KERN_DEBUG " channels:\n");
@@ -13223,71 +13372,92 @@
 +static inline void ath_dump_modes(struct ieee80211_hw_mode *modes) {}
 +#endif
 +
++static inline int ath5k_register_mode(struct ieee80211_hw *hw, u8 m)
++{
++	struct ath_softc *sc = hw->priv;
++	struct ieee80211_hw_mode *modes = sc->modes;
++	int i, ret;
++
++	for (i = 0; i < NUM_DRIVER_MODES; i++) {
++		if (modes[i].mode != m || !modes[i].num_channels)
++			continue;
++		ret = ieee80211_register_hwmode(hw, &modes[i]);
++		if (ret) {
++			printk(KERN_ERR "can't register hwmode %u\n", m);
++			return ret;
++		}
++		return 0;
++	}
++	return 1;
++}
++
++/* Only tries to register modes our EEPROM says it can support */
++#define REGISTER_MODE(m) do { \
++	if (test_bit(m, ah->ah_capabilities.cap_mode)) { \
++		ret = ath5k_register_mode(hw, m); \
++		if (ret) \
++			return ret; \
++	} \
++} while (0) \
++
 +static int ath_getchannels(struct ieee80211_hw *hw)
 +{
 +	struct ath_softc *sc = hw->priv;
 +	struct ath_hw *ah = sc->ah;
 +	struct ieee80211_hw_mode *modes = sc->modes;
-+	unsigned int i, max;
++	unsigned int i, max_r, max_c;
 +	int ret;
-+	enum {
-+		A = MODE_IEEE80211A,
-+		B = MODE_IEEE80211G, /* this is not a typo, but workaround */
-+		G = MODE_IEEE80211B, /* to prefer g over b */
-+		T = MODE_ATHEROS_TURBO,
-+		TG = MODE_ATHEROS_TURBOG,
-+	};
 +
 +	BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3);
 +
 +	ah->ah_country_code = countrycode;
 +
-+	modes[A].mode = MODE_IEEE80211A;
-+	modes[B].mode = MODE_IEEE80211B;
-+	modes[G].mode = MODE_IEEE80211G;
-+
-+	max = ARRAY_SIZE(sc->rates);
-+	modes[A].rates = sc->rates;
-+	max -= modes[A].num_rates = ath_copy_rates(modes[A].rates,
-+			ath5k_hw_get_rate_table(ah, MODE_IEEE80211A), max);
-+	modes[B].rates = &modes[A].rates[modes[A].num_rates];
-+	max -= modes[B].num_rates = ath_copy_rates(modes[B].rates,
-+			ath5k_hw_get_rate_table(ah, MODE_IEEE80211B), max);
-+	modes[G].rates = &modes[B].rates[modes[B].num_rates];
-+	max -= modes[G].num_rates = ath_copy_rates(modes[G].rates,
-+			ath5k_hw_get_rate_table(ah, MODE_IEEE80211G), max);
-+
-+	if (!max)
-+		printk(KERN_WARNING "yet another rates found, but there is not "
-+				"sufficient space to store them\n");
-+
-+	max = ARRAY_SIZE(sc->channels);
-+	modes[A].channels = sc->channels;
-+	max -= modes[A].num_channels = ath_copy_channels(ah, modes[A].channels,
-+			MODE_IEEE80211A, max);
-+	modes[B].channels = &modes[A].channels[modes[A].num_channels];
-+	max -= modes[B].num_channels = ath_copy_channels(ah, modes[B].channels,
-+			MODE_IEEE80211B, max);
-+	modes[G].channels = &modes[B].channels[modes[B].num_channels];
-+	max -= modes[G].num_channels = ath_copy_channels(ah, modes[G].channels,
-+			MODE_IEEE80211G, max);
-+
-+	if (!max)
-+		printk(KERN_WARNING "yet another modes found, but there is not "
-+				"sufficient space to store them\n");
-+
-+	for (i = 0; i < ARRAY_SIZE(sc->modes); i++)
-+		if (modes[i].num_channels) {
-+			ret = ieee80211_register_hwmode(hw, &modes[i]);
-+			if (ret) {
-+				printk(KERN_ERR "can't register hwmode %u\n",i);
-+				goto err;
-+			}
-+		}
++	/* The order here does not matter */
++	modes[0].mode = MODE_IEEE80211G;
++	modes[1].mode = MODE_IEEE80211B;
++	modes[2].mode = MODE_IEEE80211A;
++
++	max_r = ARRAY_SIZE(sc->rates);
++	max_c = ARRAY_SIZE(sc->channels);
++
++	for (i = 0; i < NUM_DRIVER_MODES; i++) {
++		struct ieee80211_hw_mode *mode = &modes[i];
++		const struct ath5k_rate_table *hw_rates;
++
++		if (i == 0) {
++			modes[0].rates	= sc->rates;
++			modes->channels	= sc->channels;
++		} else {
++			struct ieee80211_hw_mode *prev_mode = &modes[i-1];
++			int prev_num_r	= prev_mode->num_rates;
++			int prev_num_c	= prev_mode->num_channels;
++			mode->rates	= &prev_mode->rates[prev_num_r];
++			mode->channels	= &prev_mode->channels[prev_num_c];
++		}
++
++		hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
++		mode->num_rates    = ath_copy_rates(mode->rates, hw_rates,
++			max_r);
++		mode->num_channels = ath_copy_channels(ah, mode->channels,
++			mode->mode, max_c);
++		max_r -= mode->num_rates;
++		max_c -= mode->num_channels;
++	}
++
++	/* We try to register all modes this driver supports. We don't bother
++	 * with MODE_IEEE80211B for AR5212 as MODE_IEEE80211G already accounts
++	 * for that as per mac80211. Then, REGISTER_MODE() will will actually
++	 * check the eeprom reading for more reliable capability information.
++	 * Order matters here as per mac80211's latest preference. This will
++	 * all hopefullly soon go away. */
++
++	REGISTER_MODE(MODE_IEEE80211G);
++	if (ah->ah_version != AR5K_AR5212)
++		REGISTER_MODE(MODE_IEEE80211B);
++	REGISTER_MODE(MODE_IEEE80211A);
++
 +	ath_dump_modes(modes);
 +
-+	return 0;
-+err:
 +	return ret;
 +}
 +
@@ -13548,10 +13718,9 @@
 +
 +	ath5k_hw_get_lladdr(ah, mac);
 +	SET_IEEE80211_PERM_ADDR(hw, mac);
-+	if (ath5k_hw_hasbssidmask(ah)) {
-+		memset(sc->bssidmask, 0xff, ETH_ALEN);
-+		ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
-+	}
++	/* All MAC address bits matter for ACKs */
++	memset(sc->bssidmask, 0xff, ETH_ALEN);
++	ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
 +
 +	ret = ieee80211_register_hw(hw);
 +	if (ret) {
@@ -13922,10 +14091,10 @@
 +MODULE_SUPPORTED_DEVICE("Atheros WLAN cards");
 +MODULE_LICENSE("Dual BSD/GPL");
 +MODULE_VERSION(ATH_PCI_VERSION " (EXPERIMENTAL)");
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/base.h
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/base.h	2007-09-27 19:26:44.000000000 -0400
-@@ -0,0 +1,204 @@
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/base.h
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/base.h	2007-10-15 21:24:43.000000000 -0400
+@@ -0,0 +1,203 @@
 +/*-
 + * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
 + * All rights reserved.
@@ -13961,7 +14130,6 @@
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 + * THE POSSIBILITY OF SUCH DAMAGES.
 + *
-+ * $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.20 2005/01/24 20:31:24 sam Exp $
 + */
 +
 +/*
@@ -14052,9 +14220,9 @@
 +	struct ieee80211_tx_queue_stats tx_stats;
 +	struct ieee80211_low_level_stats ll_stats;
 +	struct ieee80211_hw	*hw;		/* IEEE 802.11 common */
-+	struct ieee80211_hw_mode modes[NUM_IEEE80211_MODES];
++	struct ieee80211_hw_mode modes[NUM_DRIVER_MODES];
 +	struct ieee80211_channel channels[ATH_CHAN_MAX];
-+	struct ieee80211_rate	rates[AR5K_MAX_RATES * NUM_IEEE80211_MODES];
++	struct ieee80211_rate	rates[AR5K_MAX_RATES * NUM_DRIVER_MODES];
 +	enum ieee80211_if_types	opmode;
 +	struct ath_hw		*ah;		/* Atheros HW */
 +
@@ -14130,9 +14298,9 @@
 +	(ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
 +
 +#endif
-diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/regdom.c
---- /dev/null	2007-09-27 08:31:24.563724082 -0400
-+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/regdom.c	2007-09-27 19:26:44.000000000 -0400
+diff -up /dev/null linux-2.6.23.noarch/drivers/net/wireless/ath5k/regdom.c
+--- /dev/null	2007-10-15 19:30:01.791299883 -0400
++++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/regdom.c	2007-10-15 21:21:48.000000000 -0400
 @@ -0,0 +1,121 @@
 +/*
 + * Copyright (c) 2004, 2005 Reyk Floeter <reyk at vantronix.net>




More information about the fedora-extras-commits mailing list