[kernel] r9502 - in dists/trunk/linux-2.6/debian/patches: features/all series

Maximilian Attems maks at alioth.debian.org
Wed Sep 12 09:44:03 UTC 2007


Author: maks
Date: Wed Sep 12 09:44:03 2007
New Revision: 9502

Log:
update iwlwifi
submitted to linux-wireless in
Message-Id: <1189582835.24707.118.camel at debian.sh.intel.com>
should carry improvements of version 0.1.15


Added:
   dists/trunk/linux-2.6/debian/patches/features/all/v7-iwlwifi-add-iwlwifi-wireless-drivers.patch
      - copied, changed from r9500, /dists/trunk/linux-2.6/debian/patches/features/all/v6-Add-iwlwifi-wireless-drivers.patch
Removed:
   dists/trunk/linux-2.6/debian/patches/features/all/iwlwifi-rmmod-fix.patch
   dists/trunk/linux-2.6/debian/patches/features/all/v6-Add-iwlwifi-wireless-drivers.patch
Modified:
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.1

Copied: dists/trunk/linux-2.6/debian/patches/features/all/v7-iwlwifi-add-iwlwifi-wireless-drivers.patch (from r9500, /dists/trunk/linux-2.6/debian/patches/features/all/v6-Add-iwlwifi-wireless-drivers.patch)
==============================================================================
--- /dists/trunk/linux-2.6/debian/patches/features/all/v6-Add-iwlwifi-wireless-drivers.patch	(original)
+++ dists/trunk/linux-2.6/debian/patches/features/all/v7-iwlwifi-add-iwlwifi-wireless-drivers.patch	Wed Sep 12 09:44:03 2007
@@ -1,29 +1,69 @@
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 48ca8b4..8a4ace8 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -2057,6 +2057,16 @@ L:	http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
- W:	http://ipw2200.sourceforge.net
- S:	Supported
- 
-+INTEL WIRELESS WIFI LINK (iwlwifi)
-+P:	Zhu Yi
-+M:	yi.zhu at intel.com
-+L:	linux-wireless at vger.kernel.org
-+L:	ipw3945-devel at lists.sourceforge.net
-+L:	http://lists.sourceforge.net/mailman/listinfo/ipw3945-devel
-+W:	http://intellinuxwireless.org
-+T:	git git://intellinuxwireless.org/repos/iwlwifi
-+S:	Supported
-+
- IOC3 ETHERNET DRIVER
- P:	Ralf Baechle
- M:	ralf at linux-mips.org
+From a366327d9490e963b695fbdcf3ac1c5994dbeac4 Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu at intel.com>
+Date: Wed, 12 Sep 2007 15:34:11 +0800
+Subject: [PATCH] [PATCH V4] iwlwifi: add iwlwifi wireless drivers
+
+This patch adds the mac80211 based wireless drivers for the Intel
+PRO/Wireless 3945ABG/BG Network Connection and Intel Wireless WiFi
+Link AGN (4965) adapters.
+
+Signed-off-by: Zhu Yi <yi.zhu at intel.com>
+---
+ drivers/net/wireless/Kconfig        |  129 +
+ drivers/net/wireless/Makefile       |   12 +
+ drivers/net/wireless/iwl-3945-hw.h  |  118 +
+ drivers/net/wireless/iwl-3945-rs.c  |  979 ++++
+ drivers/net/wireless/iwl-3945-rs.h  |  191 +
+ drivers/net/wireless/iwl-3945.c     | 2290 +++++++++
+ drivers/net/wireless/iwl-3945.h     |   41 +
+ drivers/net/wireless/iwl-4965-hw.h  |  581 +++
+ drivers/net/wireless/iwl-4965-rs.c  | 2118 ++++++++
+ drivers/net/wireless/iwl-4965-rs.h  |  266 +
+ drivers/net/wireless/iwl-4965.c     | 4719 ++++++++++++++++++
+ drivers/net/wireless/iwl-4965.h     |  341 ++
+ drivers/net/wireless/iwl-channel.h  |  161 +
+ drivers/net/wireless/iwl-commands.h | 1734 +++++++
+ drivers/net/wireless/iwl-debug.h    |  149 +
+ drivers/net/wireless/iwl-eeprom.h   |  336 ++
+ drivers/net/wireless/iwl-helpers.h  |  255 +
+ drivers/net/wireless/iwl-hw.h       |  537 ++
+ drivers/net/wireless/iwl-io.h       |  470 ++
+ drivers/net/wireless/iwl-priv.h     |  308 ++
+ drivers/net/wireless/iwl-prph.h     |  229 +
+ drivers/net/wireless/iwl-spectrum.h |   91 +
+ drivers/net/wireless/iwl3945-base.c | 8732 ++++++++++++++++++++++++++++++++
+ drivers/net/wireless/iwl4965-base.c | 9323 +++++++++++++++++++++++++++++++++++
+ drivers/net/wireless/iwlwifi.h      |  713 +++
+ 25 files changed, 34823 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/net/wireless/iwl-3945-hw.h
+ create mode 100644 drivers/net/wireless/iwl-3945-rs.c
+ create mode 100644 drivers/net/wireless/iwl-3945-rs.h
+ create mode 100644 drivers/net/wireless/iwl-3945.c
+ create mode 100644 drivers/net/wireless/iwl-3945.h
+ create mode 100644 drivers/net/wireless/iwl-4965-hw.h
+ create mode 100644 drivers/net/wireless/iwl-4965-rs.c
+ create mode 100644 drivers/net/wireless/iwl-4965-rs.h
+ create mode 100644 drivers/net/wireless/iwl-4965.c
+ create mode 100644 drivers/net/wireless/iwl-4965.h
+ create mode 100644 drivers/net/wireless/iwl-channel.h
+ create mode 100644 drivers/net/wireless/iwl-commands.h
+ create mode 100644 drivers/net/wireless/iwl-debug.h
+ create mode 100644 drivers/net/wireless/iwl-eeprom.h
+ create mode 100644 drivers/net/wireless/iwl-helpers.h
+ create mode 100644 drivers/net/wireless/iwl-hw.h
+ create mode 100644 drivers/net/wireless/iwl-io.h
+ create mode 100644 drivers/net/wireless/iwl-priv.h
+ create mode 100644 drivers/net/wireless/iwl-prph.h
+ create mode 100644 drivers/net/wireless/iwl-spectrum.h
+ create mode 100644 drivers/net/wireless/iwl3945-base.c
+ create mode 100644 drivers/net/wireless/iwl4965-base.c
+ create mode 100644 drivers/net/wireless/iwlwifi.h
+
 diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
-index ae27af0..4b7c656 100644
+index d3613ef..5438d4f 100644
 --- a/drivers/net/wireless/Kconfig
 +++ b/drivers/net/wireless/Kconfig
-@@ -558,6 +558,135 @@ config RTL8187
+@@ -550,6 +550,135 @@ config RTL8187
  
  	  Thanks to Realtek for their support!
  
@@ -160,38 +200,25 @@
  source "drivers/net/wireless/bcm43xx/Kconfig"
  source "drivers/net/wireless/zd1211rw/Kconfig"
 diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
-index ef35bc6..59740e2 100644
+index aa1ba9d..0d884e8 100644
 --- a/drivers/net/wireless/Makefile
 +++ b/drivers/net/wireless/Makefile
-@@ -47,3 +47,28 @@ obj-$(CONFIG_LIBERTAS_USB)     += libertas/
+@@ -47,3 +47,15 @@ obj-$(CONFIG_LIBERTAS)      += libertas/
  
  rtl8187-objs		:= rtl8187_dev.o rtl8187_rtl8225.o
  obj-$(CONFIG_RTL8187)	+= rtl8187.o
 +
-+# NOTE: iwl-base-XXXX.o has -D"KBUILD_MODNAME=KBUILD_STR(...)" in order to
-+# prevent the following kbuild error:
-+# 	include/linux/pci.h:603: error: `KBUILD_MODNAME' undeclared (first \
-+#		use in this function)
-+#
-+# -jpk
-+
 +obj-$(CONFIG_IWL3945)	+= iwl3945.o
-+iwl3945-objs		= iwl-base-3945.o iwl-3945.o iwl-3945-rs.o
++iwl3945-objs		= iwl3945-base.o iwl-3945.o iwl-3945-rs.o
++CFLAGS_iwl3945-base.o	= -DIWL=3945
 +CFLAGS_iwl-3945.o	= -DIWL=3945
 +CFLAGS_iwl-3945-rs.o	= -DIWL=3945
-+CFLAGS_iwl-base-3945.o	= -DIWL=3945 -D"KBUILD_MODNAME=KBUILD_STR(iwl3945)"
-+$(obj)/iwl-base-3945.o: $(src)/iwl3945-base.c FORCE
-+	$(call cmd,force_checksrc)
-+	$(call if_changed_rule,cc_o_c)
 +
 +obj-$(CONFIG_IWL4965)	+= iwl4965.o
-+iwl4965-objs		= iwl-base-4965.o iwl-4965.o iwl-4965-rs.o
++iwl4965-objs		= iwl4965-base.o iwl-4965.o iwl-4965-rs.o
++CFLAGS_iwl4965-base.o	= -DIWL=4965
 +CFLAGS_iwl-4965.o	= -DIWL=4965
 +CFLAGS_iwl-4965-rs.o	= -DIWL=4965
-+CFLAGS_iwl-base-4965.o	= -DIWL=4965 -D"KBUILD_MODNAME=KBUILD_STR(iwl4965)"
-+$(obj)/iwl-base-4965.o: $(src)/iwl4965-base.c FORCE
-+	$(call cmd,force_checksrc)
-+	$(call if_changed_rule,cc_o_c)
 diff --git a/drivers/net/wireless/iwl-3945-hw.h b/drivers/net/wireless/iwl-3945-hw.h
 new file mode 100644
 index 0000000..fb5f064
@@ -318,10 +345,10 @@
 +#endif
 diff --git a/drivers/net/wireless/iwl-3945-rs.c b/drivers/net/wireless/iwl-3945-rs.c
 new file mode 100644
-index 0000000..f394fd4
+index 0000000..a4f4c87
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-3945-rs.c
-@@ -0,0 +1,968 @@
+@@ -0,0 +1,979 @@
 +/******************************************************************************
 + *
 + * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
@@ -384,11 +411,11 @@
 +	s32 *expected_tpt;
 +	unsigned long last_partial_flush;
 +	unsigned long last_flush;
-+	u8 flush_pending;
 +	u32 flush_time;
 +	u32 last_tx_packets;
-+	u8 tgg;
 +	u32 tx_packets;
++	u8 tgg;
++	u8 flush_pending;
 +	u8 start_rate;
 +	u8 ibss_sta_added;
 +	struct timer_list rate_scale_flush;
@@ -683,6 +710,17 @@
 +	return local->hw.priv;
 +}
 +
++/* rate scale requires free function to be implmented */
++static void rs_free(void *priv)
++{
++	return;
++}
++static void rs_clear(void *priv)
++{
++	return;
++}
++
++
 +static void *rs_alloc_sta(void *priv, gfp_t gfp)
 +{
 +	struct iwl_rate_scale_priv *rs_priv;
@@ -1128,9 +1166,9 @@
 +	.tx_status = rs_tx_status,
 +	.get_rate = rs_get_rate,
 +	.rate_init = rs_rate_init,
-+	.clear = NULL,
++	.clear = rs_clear,
 +	.alloc = rs_alloc,
-+	.free = NULL,
++	.free = rs_free,
 +	.alloc_sta = rs_alloc_sta,
 +	.free_sta = rs_free_sta,
 +};
@@ -1489,10 +1527,10 @@
 +#endif
 diff --git a/drivers/net/wireless/iwl-3945.c b/drivers/net/wireless/iwl-3945.c
 new file mode 100644
-index 0000000..2ed217c
+index 0000000..26f03a0
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-3945.c
-@@ -0,0 +1,2287 @@
+@@ -0,0 +1,2290 @@
 +/******************************************************************************
 + *
 + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
@@ -1793,7 +1831,7 @@
 +	u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg);
 +	u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
 +	struct ieee80211_rx_status stats = {
-+		.mactime = le32_to_cpu(rx_end->beacon_timestamp),
++		.mactime = le64_to_cpu(rx_end->timestamp),
 +		.freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)),
 +		.channel = le16_to_cpu(rx_hdr->channel),
 +		.phymode = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
@@ -2053,30 +2091,30 @@
 +	return 0;
 +}
 +
-+u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *bssid)
++u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr)
 +{
 +	int i;
 +	int ret = IWL_INVALID_STATION;
 +	unsigned long flags;
 +
 +	spin_lock_irqsave(&priv->sta_lock, flags);
-+	for (i = IWL_STA_ID; i < (IWL_STA_ID + priv->num_stations); i++)
++	for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
 +		if ((priv->stations[i].used) &&
 +		    (!compare_ether_addr
-+		     (priv->stations[i].sta.sta.addr, bssid))) {
++		     (priv->stations[i].sta.sta.addr, addr))) {
 +			ret = i;
 +			goto out;
 +		}
 +
 +	IWL_DEBUG_INFO("can not find STA " MAC_FMT " (total %d)\n",
-+		       MAC_ARG(bssid), priv->num_stations);
++		       MAC_ARG(addr), priv->num_stations);
 + out:
 +	spin_unlock_irqrestore(&priv->sta_lock, flags);
 +	return ret;
 +}
 +
 +/**
-+ * iwl_hw_build_tx_cmd_rate - Add rate portion to TX_CMD
++ * iwl_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
 + *
 +*/
 +void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
@@ -2105,7 +2143,8 @@
 +	priv->stations[sta_id].current_rate.rate_n_flags = rate;
 +
 +	if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
-+	    (sta_id != IWL_BROADCAST_ID) && (sta_id != IWL_MULTICAST_ID))
++	    (sta_id != IWL3945_BROADCAST_ID) &&
++		(sta_id != IWL_MULTICAST_ID))
 +		priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate;
 +
 +	spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -3704,6 +3743,8 @@
 +	priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
 +	priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
 +	priv->hw_setting.cck_flag = 0;
++	priv->hw_setting.max_stations = IWL3945_STATION_COUNT;
++	priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID;
 +	return 0;
 +}
 +
@@ -3716,7 +3757,7 @@
 +	tx_beacon_cmd = (struct iwl_tx_beacon_cmd *)&frame->u;
 +	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
 +
-+	tx_beacon_cmd->tx.sta_id = IWL_BROADCAST_ID;
++	tx_beacon_cmd->tx.sta_id = IWL3945_BROADCAST_ID;
 +	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 +
 +	frame_size = iwl_fill_beacon_frame(priv,
@@ -3829,7 +3870,7 @@
 +#endif
 diff --git a/drivers/net/wireless/iwl-4965-hw.h b/drivers/net/wireless/iwl-4965-hw.h
 new file mode 100644
-index 0000000..810e969
+index 0000000..99a19ef
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-4965-hw.h
 @@ -0,0 +1,581 @@
@@ -4231,7 +4272,7 @@
 +#define FH_RSCSR_CHNL0_RBDCB_WPTR_MASK		(0x00000FFF)	/* bits 0-11 */
 +
 +#define SCD_WIN_SIZE				64
-+#define SCD_FRAME_LIMIT				10
++#define SCD_FRAME_LIMIT				64
 +
 +/* memory mapped registers */
 +#define SCD_START_OFFSET		0xa02c00
@@ -4416,10 +4457,10 @@
 +#endif /* __iwl_4965_hw_h__ */
 diff --git a/drivers/net/wireless/iwl-4965-rs.c b/drivers/net/wireless/iwl-4965-rs.c
 new file mode 100644
-index 0000000..9e0ba5f
+index 0000000..f363860
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-4965-rs.c
-@@ -0,0 +1,2115 @@
+@@ -0,0 +1,2118 @@
 +/******************************************************************************
 + *
 + * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
@@ -4509,8 +4550,8 @@
 +	u8 is_SGI;
 +	u8 is_fat;
 +	u8 is_dup;
-+	s32 *expected_tpt;
 +	u8 action;
++	s32 *expected_tpt;
 +	struct iwl_rate current_rate;
 +	struct iwl_rate_scale_data win[IWL_RATE_COUNT];
 +};
@@ -4527,8 +4568,8 @@
 +	u32 table_count;
 +	u32 total_failed;
 +	u32 total_success;
-+	u8 action_counter;
 +	u32 flush_timer;
++	u8 action_counter;
 +	u8 antenna;
 +	u8 valid_antenna;
 +	u8 is_green;
@@ -5467,7 +5508,7 @@
 +			lq_data->search_better_tbl = 1;
 +			goto out;
 +
-+		case IWL_LECACY_SWITCH_SISO:
++		case IWL_LEGACY_SWITCH_SISO:
 +			IWL_DEBUG_HT("LQ: Legacy switch to SISO\n");
 +			memcpy(search_tbl, tbl, sz);
 +			search_tbl->lq_type = LQ_SISO;
@@ -6047,8 +6088,6 @@
 +	else
 +		sta->txrate = i;
 +
-+	sta->antenna_sel_tx = tbl->lq_type;
-+
 +	return;
 +}
 +
@@ -6389,6 +6428,11 @@
 +{
 +	return local->hw.priv;
 +}
++/* rate scale requires free function to be implemented */
++static void rs_free(void *priv_rate)
++{
++	return;
++}
 +
 +static void rs_clear(void *priv_rate)
 +{
@@ -6425,7 +6469,7 @@
 +	.rate_init = rs_rate_init,
 +	.clear = rs_clear,
 +	.alloc = rs_alloc,
-+	.free = NULL,
++	.free = rs_free,
 +	.alloc_sta = rs_alloc_sta,
 +	.free_sta = rs_free_sta,
 +};
@@ -6537,7 +6581,7 @@
 +
 diff --git a/drivers/net/wireless/iwl-4965-rs.h b/drivers/net/wireless/iwl-4965-rs.h
 new file mode 100644
-index 0000000..35d2044
+index 0000000..c6325f7
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-4965-rs.h
 @@ -0,0 +1,266 @@
@@ -6714,7 +6758,7 @@
 +#define IWL_MAX_RSSI_VAL                    0
 +
 +#define IWL_LEGACY_SWITCH_ANTENNA	0
-+#define IWL_LECACY_SWITCH_SISO		1
++#define IWL_LEGACY_SWITCH_SISO		1
 +#define IWL_LEGACY_SWITCH_MIMO	        2
 +
 +#define IWL_RS_GOOD_RATIO		12800
@@ -6809,10 +6853,10 @@
 +#endif
 diff --git a/drivers/net/wireless/iwl-4965.c b/drivers/net/wireless/iwl-4965.c
 new file mode 100644
-index 0000000..68b6d52
+index 0000000..ba35b3a
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-4965.c
-@@ -0,0 +1,4731 @@
+@@ -0,0 +1,4719 @@
 +/******************************************************************************
 + *
 + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
@@ -6973,7 +7017,7 @@
 +	return 0;
 +}
 +
-+u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *bssid)
++u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr)
 +{
 +	int i;
 +	int start = 0;
@@ -6984,20 +7028,20 @@
 +	    (priv->iw_mode == IEEE80211_IF_TYPE_AP))
 +		start = IWL_STA_ID;
 +
-+	if (is_broadcast_ether_addr(bssid))
-+		return IWL_BROADCAST_ID;
++	if (is_broadcast_ether_addr(addr))
++		return IWL4965_BROADCAST_ID;
 +
 +	spin_lock_irqsave(&priv->sta_lock, flags);
-+	for (i = start; i < (start + priv->num_stations); i++)
++	for (i = start; i < priv->hw_setting.max_stations; i++)
 +		if ((priv->stations[i].used) &&
 +		    (!compare_ether_addr
-+		     (priv->stations[i].sta.sta.addr, bssid))) {
++		     (priv->stations[i].sta.sta.addr, addr))) {
 +			ret = i;
 +			goto out;
 +		}
 +
 +	IWL_DEBUG_ASSOC("can not find STA " MAC_FMT " total %d\n",
-+			MAC_ARG(bssid), priv->num_stations);
++			MAC_ARG(addr), priv->num_stations);
 +
 + out:
 +	spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -8426,13 +8470,16 @@
 +		       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 +}
 +
-+static const u16 default_ac_to_tx_fifo[] = {
-+	IWL_TX_QUEUE_AC1, IWL_TX_QUEUE_AC0,
-+	IWL_TX_QUEUE_AC2, IWL_TX_QUEUE_AC3,
-+	IWL_TX_QUEUE_HCCA_1, IWL_TX_QUEUE_HCCA_2
++static const u16 default_queue_to_tx_fifo[] = {
++	IWL_TX_FIFO_AC3,
++	IWL_TX_FIFO_AC2,
++	IWL_TX_FIFO_AC1,
++	IWL_TX_FIFO_AC0,
++	IWL_CMD_FIFO_NUM,
++	IWL_TX_FIFO_HCCA_1,
++	IWL_TX_FIFO_HCCA_2
 +};
 +
-+
 +static inline void iwl4965_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
 +{
 +	set_bit(txq_id, &priv->txq_ctx_active_msk);
@@ -8505,14 +8552,11 @@
 +				 SCD_TXFACT_REG_TXFIFO_MASK(0, 7));
 +
 +	iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
-+	iwl4965_txq_ctx_activate(priv, IWL_CMD_QUEUE_NUM);
-+	iwl4965_tx_queue_set_status(priv, &priv->txq[IWL_CMD_QUEUE_NUM],
-+				    IWL_CMD_FIFO_NUM, 0);
 +	/* map qos queues to fifos one-to-one */
-+	for (i = 0; i < ARRAY_SIZE(default_ac_to_tx_fifo); i++) {
-+		int ac = default_ac_to_tx_fifo[i];
-+		iwl4965_txq_ctx_activate(priv, ac);
-+		iwl4965_tx_queue_set_status(priv, &priv->txq[ac], ac, 0);
++	for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
++		int ac = default_queue_to_tx_fifo[i];
++		iwl4965_txq_ctx_activate(priv, i);
++		iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
 +	}
 +
 +	iwl_release_restricted_access(priv);
@@ -8541,6 +8585,8 @@
 +	priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
 +	priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
 +
++	priv->hw_setting.max_stations = IWL4965_STATION_COUNT;
++	priv->hw_setting.bcast_sta_id = IWL4965_BROADCAST_ID;
 +	return 0;
 +}
 +
@@ -9474,7 +9520,7 @@
 +	tx_beacon_cmd = &frame->u.beacon;
 +	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
 +
-+	tx_beacon_cmd->tx.sta_id = IWL_BROADCAST_ID;
++	tx_beacon_cmd->tx.sta_id = IWL4965_BROADCAST_ID;
 +	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 +
 +	frame_size = iwl_fill_beacon_frame(priv,
@@ -10075,7 +10121,7 @@
 +}
 +
 +/**
-+ * iwl4965_sign_extend - Sign extend a value using specified bit as sign-bit
++ * sign_extend - Sign extend a value using specified bit as sign-bit
 + *
 + * Example: sign_extend(9, 3) would return -7 as bit3 of 1001b is 1
 + * and bit0..2 is 001b which when sign extended to 1111111111111001b is -7.
@@ -10083,25 +10129,11 @@
 + * @param oper value to sign extend
 + * @param index 0 based bit index (0<=index<32) to sign bit
 + */
-+static s32 iwl4965_sign_extend(u32 oper, int index)
++static s32 sign_extend(u32 oper, int index)
 +{
-+	u32 bit;
-+	u32 mask;
++	u8 shift = 31 - index;
 +
-+	/* If the index is the MSB or higher then just return the
-+	 * operand cast to a signed value */
-+	if (index > 30)
-+		return oper;
-+
-+	bit = 1 << index;
-+	mask = ~(bit - 1);
-+
-+	/* negative -- sign extend */
-+	if (oper & bit)
-+		return oper |= mask;
-+
-+	/* positive -- sign clear */
-+	return oper &= ~mask;
++	return (s32)(oper << shift) >> shift;
 +}
 +
 +/**
@@ -10139,9 +10171,9 @@
 +	 * with an updated temperature, use R4 provided to us in the
 +	 * ALIVE response. */
 +	if (!test_bit(STATUS_TEMPERATURE, &priv->status))
-+		vt = iwl4965_sign_extend(R4, 23);
++		vt = sign_extend(R4, 23);
 +	else
-+		vt = iwl4965_sign_extend(
++		vt = sign_extend(
 +			le32_to_cpu(priv->statistics.general.temperature), 23);
 +
 +	IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n",
@@ -10553,7 +10585,7 @@
 +	struct ieee80211_hdr *header;
 +	u16 fc;
 +	struct ieee80211_rx_status stats = {
-+		.mactime = le32_to_cpu(rx_start->beacon_time_stamp),
++		.mactime = le64_to_cpu(rx_start->timestamp),
 +		.channel = le16_to_cpu(rx_start->channel),
 +		.phymode =
 +			(rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
@@ -11149,7 +11181,7 @@
 +	link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000);
 +
 +	/* Update the rate scaling for control frame Tx to AP */
-+	link_cmd.sta_id = is_ap ? IWL_AP_ID : IWL_BROADCAST_ID;
++	link_cmd.sta_id = is_ap ? IWL_AP_ID : IWL4965_BROADCAST_ID;
 +
 +	iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd),
 +			 &link_cmd);
@@ -11325,24 +11357,24 @@
 +	iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
 +}
 +
-+static const u16 default_tid_to_ac[] = {
-+	IWL_TX_QUEUE_AC0,
-+	IWL_TX_QUEUE_AC1,
-+	IWL_TX_QUEUE_AC1,
-+	IWL_TX_QUEUE_AC0,
-+	IWL_TX_QUEUE_AC2,
-+	IWL_TX_QUEUE_AC2,
-+	IWL_TX_QUEUE_AC3,
-+	IWL_TX_QUEUE_AC3,
-+	IWL_TX_QUEUE_NONE,
-+	IWL_TX_QUEUE_NONE,
-+	IWL_TX_QUEUE_NONE,
-+	IWL_TX_QUEUE_NONE,
-+	IWL_TX_QUEUE_NONE,
-+	IWL_TX_QUEUE_NONE,
-+	IWL_TX_QUEUE_NONE,
-+	IWL_TX_QUEUE_NONE,
-+	IWL_TX_QUEUE_AC3
++static const u16 default_tid_to_tx_fifo[] = {
++	IWL_TX_FIFO_AC1,
++	IWL_TX_FIFO_AC0,
++	IWL_TX_FIFO_AC0,
++	IWL_TX_FIFO_AC1,
++	IWL_TX_FIFO_AC2,
++	IWL_TX_FIFO_AC2,
++	IWL_TX_FIFO_AC3,
++	IWL_TX_FIFO_AC3,
++	IWL_TX_FIFO_NONE,
++	IWL_TX_FIFO_NONE,
++	IWL_TX_FIFO_NONE,
++	IWL_TX_FIFO_NONE,
++	IWL_TX_FIFO_NONE,
++	IWL_TX_FIFO_NONE,
++	IWL_TX_FIFO_NONE,
++	IWL_TX_FIFO_NONE,
++	IWL_TX_FIFO_AC3
 +};
 +
 +static int iwl_txq_ctx_activate_free(struct iwl_priv *priv)
@@ -11367,8 +11399,8 @@
 +	unsigned long flags;
 +	struct iwl_tid_data *tid_data;
 +
-+	if (likely(tid < ARRAY_SIZE(default_tid_to_ac)))
-+		tx_fifo = default_tid_to_ac[tid];
++	if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
++		tx_fifo = default_tid_to_tx_fifo[tid];
 +	else
 +		return -EINVAL;
 +
@@ -11409,8 +11441,8 @@
 +		return -EINVAL;
 +	}
 +
-+	if (likely(tid < ARRAY_SIZE(default_tid_to_ac)))
-+		tx_fifo_id = default_tid_to_ac[tid];
++	if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
++		tx_fifo_id = default_tid_to_tx_fifo[tid];
 +	else
 +		return -EINVAL;
 +
@@ -11546,10 +11578,10 @@
 +MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
 diff --git a/drivers/net/wireless/iwl-4965.h b/drivers/net/wireless/iwl-4965.h
 new file mode 100644
-index 0000000..4c63b3b
+index 0000000..4c70081
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-4965.h
-@@ -0,0 +1,358 @@
+@@ -0,0 +1,341 @@
 +/******************************************************************************
 + *
 + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
@@ -11686,23 +11718,6 @@
 +#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9)
 +#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5)
 +
-+#define IWL4965_LEGACY_SWITCH_ANTENNA	0
-+#define IWL4965_LECACY_SWITCH_SISO		1
-+#define IWL4965_LEGACY_SWITCH_MIMO	        2
-+
-+#define IWL4965_GOOD_RATIO			12800
-+
-+#define IWL_ACTION_LIMIT		3
-+#define IWL4965_LEGACY_FAILURE_LIMIT	160
-+#define IWL4965_LEGACY_SUCCESS_LIMIT	480
-+#define IWL4965_LEGACY_TABLE_COUNT		160
-+
-+#define IWL4965_NONE_LEGACY_FAILURE_LIMIT	400
-+#define IWL4965_NONE_LEGACY_SUCCESS_LIMIT	4500
-+#define IWL4965_NONE_LEGACY_TABLE_COUNT	1500
-+
-+#define IWL4965_RATE_SCALE_SWITCH  (10880)
-+
 +struct iwl_traffic_load {
 +	unsigned long time_stamp;
 +	u32 packet_count[TID_QUEUE_MAX_SIZE];
@@ -12077,10 +12092,10 @@
 +#endif
 diff --git a/drivers/net/wireless/iwl-commands.h b/drivers/net/wireless/iwl-commands.h
 new file mode 100644
-index 0000000..b686d16
+index 0000000..9de8d7f
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-commands.h
-@@ -0,0 +1,1737 @@
+@@ -0,0 +1,1734 @@
 +/******************************************************************************
 + *
 + * This file is provided under a dual BSD/GPLv2 license.  When using or
@@ -12533,25 +12548,18 @@
 +/*
 + * Multi station support
 + */
-+#if IWL == 3945
-+enum {
-+	IWL_AP_ID = 0,
-+	IWL_MULTICAST_ID,
-+	IWL_STA_ID,
-+	IWL_BROADCAST_ID = 24,
-+	IWL_STATION_COUNT = 25,
-+	IWL_INVALID_STATION
-+};
-+#elif IWL == 4965
-+enum {
-+	IWL_AP_ID = 0,
-+	IWL_MULTICAST_ID,
-+	IWL_STA_ID,
-+	IWL_BROADCAST_ID = 31,
-+	IWL_STATION_COUNT = 32,
-+	IWL_INVALID_STATION
-+};
-+#endif
++#define	IWL_AP_ID		0
++#define IWL_MULTICAST_ID	1
++#define	IWL_STA_ID		2
++
++#define	IWL3945_BROADCAST_ID	24
++#define IWL3945_STATION_COUNT	25
++
++#define IWL4965_BROADCAST_ID	31
++#define	IWL4965_STATION_COUNT	32
++
++#define	IWL_STATION_COUNT	32 	/* MAX(3945,4965)*/
++#define	IWL_INVALID_STATION 	255
 +
 +#if IWL == 3945
 +#define STA_FLG_TX_RATE_MSK		__constant_cpu_to_le32(1<<2);
@@ -12787,8 +12795,12 @@
 +/*
 + * TX command security control
 + */
-+#define TX_CMD_SEC_CCM  	0x2
-+#define TX_CMD_SEC_TKIP		0x3
++#define TX_CMD_SEC_WEP  	0x01
++#define TX_CMD_SEC_CCM  	0x02
++#define TX_CMD_SEC_TKIP		0x03
++#define TX_CMD_SEC_MSK		0x03
++#define TX_CMD_SEC_SHIFT	6
++#define TX_CMD_SEC_KEY128	0x08
 +
 +/*
 + * TX command Frame life time
@@ -13820,7 +13832,7 @@
 +#endif				/* __iwl_commands_h__ */
 diff --git a/drivers/net/wireless/iwl-debug.h b/drivers/net/wireless/iwl-debug.h
 new file mode 100644
-index 0000000..0ebc4f7
+index 0000000..abd344c
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-debug.h
 @@ -0,0 +1,149 @@
@@ -13892,11 +13904,11 @@
 + *
 + * To add your debug level to the list of levels seen when you perform
 + *
-+ * % cat /proc/net/ipw/debug_level
++ * % cat /proc/net/iwl/debug_level
 + *
 + * you simply need to add your entry to the iwl_debug_levels array.
 + *
-+ * If you do not see debug_level in /proc/net/ipw then you do not have
++ * If you do not see debug_level in /proc/net/iwl then you do not have
 + * CONFIG_IWLWIFI_DEBUG defined in your kernel configuration
 + *
 + */
@@ -14578,10 +14590,10 @@
 +#endif				/* __iwl_helpers_h__ */
 diff --git a/drivers/net/wireless/iwl-hw.h b/drivers/net/wireless/iwl-hw.h
 new file mode 100644
-index 0000000..b5ac994
+index 0000000..1aa6fcd
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-hw.h
-@@ -0,0 +1,576 @@
+@@ -0,0 +1,537 @@
 +/******************************************************************************
 + *
 + * This file is provided under a dual BSD/GPLv2 license.  When using or
@@ -14987,8 +14999,6 @@
 +
 +#define IWL_MAX_CMD_SIZE 1024
 +
-+/* LEDs mode */
-+
 +#define IWL_DEFAULT_TX_RETRY  15
 +#define IWL_MAX_TX_RETRY      16
 +
@@ -15001,33 +15011,6 @@
 +#define RX_QUEUE_MASK                         255
 +#define RX_QUEUE_SIZE_LOG                     8
 +
-+/*
-+ * TX Queue Flag Definitions
-+ */
-+
-+/* abort attempt if mgmt frame is rx'd */
-+
-+/* require CTS */
-+
-+/* use short preamble */
-+#define DCT_FLAG_LONG_PREAMBLE             0x00
-+#define DCT_FLAG_SHORT_PREAMBLE            0x04
-+
-+/* RTS/CTS first */
-+
-+/* don't calculate duration field */
-+
-+/* even if MAC WEP set (allows pre-encrypt) */
-+#define IWL_
-+/* overwrite TSF field */
-+
-+/* ACK rx is expected to follow */
-+#define DCT_FLAG_ACK_REQD                  0x80
-+
-+#define IWL_MB_DISASSOCIATE_THRESHOLD_DEFAULT           24
-+#define IWL_MB_ROAMING_THRESHOLD_DEFAULT                8
-+#define IWL_REAL_RATE_RX_PACKET_THRESHOLD               300
-+
 +/* QoS  definitions */
 +
 +#define CW_MIN_OFDM          15
@@ -15123,18 +15106,8 @@
 +#define CTRL_QOS_NO_ACK               (0x0020)
 +#define DCT_FLAG_EXT_QOS_ENABLED      (0x10)
 +
-+#define IWL_TX_QUEUE_AC0        0
-+#define IWL_TX_QUEUE_AC1        1
-+#define IWL_TX_QUEUE_AC2        2
-+#define IWL_TX_QUEUE_AC3        3
-+#define IWL_TX_QUEUE_HCCA_1     5
-+#define IWL_TX_QUEUE_HCCA_2     6
-+
 +#define U32_PAD(n)		((4-(n))&0x3)
 +
-+#define AC_BE_TID_MASK 0x9	/* TID 0 and 3 */
-+#define AC_BK_TID_MASK 0x6	/* TID 1 and 2 */
-+
 +/*
 + * Generic queue structure
 + *
@@ -15160,7 +15133,7 @@
 +#endif				/* __iwlwifi_hw_h__ */
 diff --git a/drivers/net/wireless/iwl-io.h b/drivers/net/wireless/iwl-io.h
 new file mode 100644
-index 0000000..1ab5f54
+index 0000000..8a8b96f
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-io.h
 @@ -0,0 +1,470 @@
@@ -15226,29 +15199,29 @@
 + *
 + */
 +
-+#define _iwl_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
++#define _iwl_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs))
 +#ifdef CONFIG_IWLWIFI_DEBUG
-+static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *ipw,
++static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *iwl,
 +				 u32 ofs, u32 val)
 +{
 +	IWL_DEBUG_IO("write_direct32(0x%08X, 0x%08X) - %s %d\n",
 +		     (u32) (ofs), (u32) (val), f, l);
-+	_iwl_write32(ipw, ofs, val);
++	_iwl_write32(iwl, ofs, val);
 +}
-+#define iwl_write32(ipw, ofs, val) \
-+	__iwl_write32(__FILE__, __LINE__, ipw, ofs, val)
++#define iwl_write32(iwl, ofs, val) \
++	__iwl_write32(__FILE__, __LINE__, iwl, ofs, val)
 +#else
-+#define iwl_write32(ipw, ofs, val) _iwl_write32(ipw, ofs, val)
++#define iwl_write32(iwl, ofs, val) _iwl_write32(iwl, ofs, val)
 +#endif
 +
-+#define _iwl_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
++#define _iwl_read32(iwl, ofs) readl((iwl)->hw_base + (ofs))
 +#ifdef CONFIG_IWLWIFI_DEBUG
-+static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *ipw, u32 ofs)
++static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *iwl, u32 ofs)
 +{
 +	IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
-+	return _iwl_read32(ipw, ofs);
++	return _iwl_read32(iwl, ofs);
 +}
-+#define iwl_read32(ipw, ofs) __iwl_read32(__FILE__, __LINE__, ipw, ofs)
++#define iwl_read32(iwl, ofs) __iwl_read32(__FILE__, __LINE__, iwl, ofs)
 +#else
 +#define iwl_read32(p, o) _iwl_read32(p, o)
 +#endif
@@ -15283,8 +15256,8 @@
 +		     addr, bits, mask, rc, f, l);
 +	return rc;
 +}
-+#define iwl_poll_bit(ipw, addr, bits, mask, timeout) \
-+	__iwl_poll_bit(__FILE__, __LINE__, ipw, addr, bits, mask, timeout)
++#define iwl_poll_bit(iwl, addr, bits, mask, timeout) \
++	__iwl_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout)
 +#else
 +#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t)
 +#endif
@@ -15490,8 +15463,8 @@
 +			     "- %s %d\n", addr, mask, rc, f, l);
 +	return rc;
 +}
-+#define iwl_poll_restricted_bit(ipw, addr, mask, timeout) \
-+	__iwl_poll_restricted_bit(__FILE__, __LINE__, ipw, addr, mask, timeout)
++#define iwl_poll_restricted_bit(iwl, addr, mask, timeout) \
++	__iwl_poll_restricted_bit(__FILE__, __LINE__, iwl, addr, mask, timeout)
 +#else
 +#define iwl_poll_restricted_bit _iwl_poll_restricted_bit
 +#endif
@@ -15636,7 +15609,7 @@
 +#endif
 diff --git a/drivers/net/wireless/iwl-priv.h b/drivers/net/wireless/iwl-priv.h
 new file mode 100644
-index 0000000..ffd3d79
+index 0000000..6b490d0
 --- /dev/null
 +++ b/drivers/net/wireless/iwl-priv.h
 @@ -0,0 +1,308 @@
@@ -15847,7 +15820,7 @@
 +
 +	/*station table variables */
 +	spinlock_t sta_lock;
-+	u8 num_stations;
++	int num_stations;
 +	struct iwl_station_entry stations[IWL_STATION_COUNT];
 +
 +	/* Indication if ieee80211_ops->open has been called */
@@ -16282,10 +16255,10 @@
 +#endif
 diff --git a/drivers/net/wireless/iwl3945-base.c b/drivers/net/wireless/iwl3945-base.c
 new file mode 100644
-index 0000000..c2c20f4
+index 0000000..6a064a6
 --- /dev/null
 +++ b/drivers/net/wireless/iwl3945-base.c
-@@ -0,0 +1,8758 @@
+@@ -0,0 +1,8732 @@
 +/******************************************************************************
 + *
 + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
@@ -16389,7 +16362,7 @@
 +#define VS
 +#endif
 +
-+#define IWLWIFI_VERSION "0.1.13k" VD VS
++#define IWLWIFI_VERSION "0.1.15k" VD VS
 +#define DRV_COPYRIGHT	"Copyright(c) 2003-2007 Intel Corporation"
 +#define DRV_VERSION     IWLWIFI_VERSION
 +
@@ -16493,11 +16466,6 @@
 + * The IPW operates with six queues, one receive queue in the device's
 + * sram, one transmit queue for sending commands to the device firmware,
 + * and four transmit queues for data.
-+ *
-+ * The four transmit queues allow for performing quality of service (qos)
-+ * transmissions as per the 802.11 protocol.  Currently Linux does not
-+ * provide a mechanism to the user for utilizing prioritized queues, so
-+ * we only utilize the first data transmit queue (queue1).
 + ***************************************************/
 +
 +static int iwl_queue_space(const struct iwl_queue *q)
@@ -16698,8 +16666,7 @@
 + */
 +
 +/**************************************************************/
-+
-+static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *bssid, int is_ap)
++static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
 +{
 +	int index = IWL_INVALID_STATION;
 +	int i;
@@ -16707,30 +16674,30 @@
 +
 +	spin_lock_irqsave(&priv->sta_lock, flags);
 +
-+	if (is_ap) {
++	if (is_ap)
 +		index = IWL_AP_ID;
-+		if ((priv->stations[index].used))
-+			priv->stations[index].used = 0;
-+	} else if (is_broadcast_ether_addr(bssid)) {
-+		index = IWL_BROADCAST_ID;
-+		if ((priv->stations[index].used))
-+			priv->stations[index].used = 0;
-+	} else {
-+		for (i = IWL_STA_ID; i < priv->num_stations + IWL_STA_ID; i++) {
++	else if (is_broadcast_ether_addr(addr))
++		index = priv->hw_setting.bcast_sta_id;
++	else
++		for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
 +			if (priv->stations[i].used &&
 +			    !compare_ether_addr(priv->stations[i].sta.sta.addr,
-+						bssid)) {
++						addr)) {
 +				index = i;
-+				priv->stations[index].used = 0;
 +				break;
 +			}
-+		}
-+	}
-+	if (index != IWL_INVALID_STATION) {
-+		if (priv->num_stations > 0)
-+			priv->num_stations--;
++
++	if (unlikely(index == IWL_INVALID_STATION))
++		goto out;
++
++	if (priv->stations[index].used) {
++		priv->stations[index].used = 0;
++		priv->num_stations--;
 +	}
 +
++	BUG_ON(priv->num_stations < 0);
++
++out:
 +	spin_unlock_irqrestore(&priv->sta_lock, flags);
 +	return 0;
 +}
@@ -16747,77 +16714,60 @@
 +	spin_unlock_irqrestore(&priv->sta_lock, flags);
 +}
 +
-+u8 iwl_add_station(struct iwl_priv *priv, const u8 *bssid, int is_ap, u8 flags)
++
++u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
 +{
-+	int i = IWL_STATION_COUNT;
++	int i;
 +	int index = IWL_INVALID_STATION;
 +	struct iwl_station_entry *station;
 +	unsigned long flags_spin;
-+	u8 rate;
 +
 +	spin_lock_irqsave(&priv->sta_lock, flags_spin);
-+	if (is_ap) {
++	if (is_ap)
 +		index = IWL_AP_ID;
-+		if (priv->stations[index].used &&
-+		    !compare_ether_addr(priv->stations[index].sta.sta.addr,
-+					bssid))
-+			goto done;
-+	} else if (is_broadcast_ether_addr(bssid)) {
-+		index = IWL_BROADCAST_ID;
-+		if (priv->stations[index].used &&
-+		    !compare_ether_addr(priv->stations[index].sta.sta.addr,
-+					bssid))
-+			goto done;
-+	} else {
-+		for (i = IWL_STA_ID; i < priv->num_stations + IWL_STA_ID; i++) {
-+			if (priv->stations[i].used &&
-+			    !compare_ether_addr(priv->stations[i].sta.sta.addr,
-+						bssid))
-+				goto done;
++	else if (is_broadcast_ether_addr(addr))
++		index = priv->hw_setting.bcast_sta_id;
++	else
++		for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) {
++			if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
++						addr)) {
++				index = i;
++				break;
++			}
 +
 +			if (!priv->stations[i].used &&
 +			    index == IWL_INVALID_STATION)
 +				index = i;
 +		}
-+	}
-+
-+	if (index != IWL_INVALID_STATION)
-+		i = index;
 +
-+	if (i == IWL_STATION_COUNT) {
-+		index = IWL_INVALID_STATION;
-+		goto done;
++	/* These twh conditions has the same outcome but keep them separate
++	  since they have different meaning */
++	if (unlikely(index == IWL_INVALID_STATION)) {
++		spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
++		return index;
 +	}
 +
-+	IWL_DEBUG_ASSOC("Adding STA ID %d: " MAC_FMT "\n", i, MAC_ARG(bssid));
-+	station = &priv->stations[i];
++	if (priv->stations[index].used &&
++	   !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) {
++		spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
++		return index;
++	}
 +
++	IWL_DEBUG_ASSOC("Add STA ID %d: " MAC_FMT "\n", index, MAC_ARG(addr));
++	station = &priv->stations[index];
 +	station->used = 1;
++	priv->num_stations++;
++
 +	memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
-+	memcpy(station->sta.sta.addr, bssid, ETH_ALEN);
++	memcpy(station->sta.sta.addr, addr, ETH_ALEN);
 +	station->sta.mode = 0;
-+	station->sta.sta.sta_id = i;
++	station->sta.sta.sta_id = index;
 +	station->sta.station_flags = 0;
-+	rate = (priv->phymode == MODE_IEEE80211A) ? IWL_RATE_6M_PLCP :
-+			IWL_RATE_1M_PLCP | priv->hw_setting.cck_flag;
-+
-+	/* Turn on both antennas for the station... */
-+	station->sta.rate_n_flags =
-+			iwl_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
-+
-+	station->sta.station_flags |= STA_FLG_TX_RATE_MSK;
 +
-+	station->current_rate.rate_n_flags =
-+		le16_to_cpu(station->sta.rate_n_flags);
-+
-+	priv->num_stations++;
 +	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 +	iwl_send_add_station(priv, &station->sta, flags);
-+	return i;
-+
-+ done:
-+	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 +	return index;
++
 +}
 +
 +/*************** DRIVER STATUS FUNCTIONS   *****/
@@ -17409,9 +17359,6 @@
 +		return 0;
 +	}
 +
-+	/* station table will be cleared */
-+	priv->assoc_station_added = 0;
-+
 +	/* If we are currently associated and the new config requires
 +	 * an RXON_ASSOC and the new config wants the associated mask enabled,
 +	 * we must clear the associated from the active configuration
@@ -17482,14 +17429,12 @@
 +	/* If we have set the ASSOC_MSK and we are in BSS mode then
 +	 * add the IWL_AP_ID to the station rate table */
 +	if (iwl_is_associated(priv) &&
-+	    (priv->iw_mode == IEEE80211_IF_TYPE_STA)) {
++	    (priv->iw_mode == IEEE80211_IF_TYPE_STA))
 +		if (iwl_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1)
 +		    == IWL_INVALID_STATION) {
 +			IWL_ERROR("Error adding AP address for transmit.\n");
 +			return -EIO;
 +		}
-+		priv->assoc_station_added = 1;
-+	}
 +
 +	/* Init the hardware's rate fallback order based on the
 +	 * phymode */
@@ -17703,6 +17648,23 @@
 +	return 0;
 +}
 +
++static int iwl_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&priv->sta_lock, flags);
++	memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
++	memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl_keyinfo));
++	priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
++	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
++	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
++	spin_unlock_irqrestore(&priv->sta_lock, flags);
++
++	IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
++	iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0);
++	return 0;
++}
++
 +static void iwl_clear_free_frames(struct iwl_priv *priv)
 +{
 +	struct list_head *element;
@@ -18861,17 +18823,10 @@
 +	switch (keyinfo->alg) {
 +	case ALG_CCMP:
 +		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
-+
-+		cmd->cmd.tx.hdr[0].frame_control |=
-+		    cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-+		/* XXX: ACK flag must be set for CCMP even if it
-+		 * is a multicast/broadcast packet, because CCMP
-+		 * group communication encrypted by GTK is
-+		 * actually done by the AP. */
-+		cmd->cmd.tx.tx_flags |= TX_CMD_FLG_ACK_MSK;
 +		memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
-+		IWL_DEBUG_TX("tx_cmd with aes  hwcrypto\n");
++		IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
 +		break;
++
 +	case ALG_TKIP:
 +#if 0
 +		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP;
@@ -18881,42 +18836,30 @@
 +			       8);
 +		else
 +			memset(cmd->cmd.tx.tkip_mic.byte, 0, 8);
-+
-+		cmd->cmd.tx.hdr[0].frame_control |=
-+		    cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-+		/* XXX: ACK flag must be set for CCMP even if it
-+		 * is a multicast/broadcast packet, because CCMP
-+		 * group communication encrypted by GTK is
-+		 * actually done by the AP. */
-+		cmd->cmd.tx.tx_flags |= TX_CMD_FLG_ACK_MSK;
 +#endif
 +		break;
++
 +	case ALG_WEP:
-+		cmd->cmd.tx.sec_ctl = 1 |	/* WEP */
-+		    (ctl->key_idx & 0x3) << 6;
++		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
++		    (ctl->key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
 +
 +		if (keyinfo->keylen == 13)
-+			cmd->cmd.tx.sec_ctl |= (1 << 3);	/* 128-bit */
++			cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
 +
 +		memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
 +
-+		cmd->cmd.tx.hdr[0].frame_control |=
-+		    cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-+
 +		IWL_DEBUG_TX("Configuring packet for WEP encryption "
 +			     "with key %d\n", ctl->key_idx);
 +		break;
 +
 +	case ALG_NONE:
-+		IWL_DEBUG_TX("Tx packet in the clear "
-+			     "(encrypt requested).\n");
++		IWL_DEBUG_TX("Tx packet in the clear (encrypt requested).\n");
 +		break;
 +
 +	default:
 +		printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg);
 +		break;
 +	}
-+
 +}
 +
 +/*
@@ -18993,7 +18936,7 @@
 +	 * station id */
 +	if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
 +	    is_multicast_ether_addr(hdr->addr1))
-+		return IWL_BROADCAST_ID;
++		return priv->hw_setting.bcast_sta_id;
 +
 +	switch (priv->iw_mode) {
 +
@@ -19007,7 +18950,7 @@
 +		sta_id = iwl_hw_find_station(priv, hdr->addr1);
 +		if (sta_id != IWL_INVALID_STATION)
 +			return sta_id;
-+		return IWL_BROADCAST_ID;
++		return priv->hw_setting.bcast_sta_id;
 +
 +	/* If this frame is part of a IBSS network, then we use the
 +	 * target specific station id */
@@ -19025,11 +18968,11 @@
 +			       "Defaulting to broadcast...\n",
 +			       MAC_ARG(hdr->addr1));
 +		iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
-+		return IWL_BROADCAST_ID;
++		return priv->hw_setting.bcast_sta_id;
 +
 +	default:
 +		IWL_WARNING("Unkown mode of operation: %d", priv->iw_mode);
-+		return IWL_BROADCAST_ID;
++		return priv->hw_setting.bcast_sta_id;
 +	}
 +}
 +
@@ -19291,8 +19234,7 @@
 +{
 +	unsigned long flags;
 +
-+	if (disable_radio ? 1 : 0 ==
-+	    test_bit(STATUS_RF_KILL_SW, &priv->status) ? 1 : 0)
++	if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))
 +		return;
 +
 +	IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",
@@ -20207,17 +20149,17 @@
 + * resets the Rx queue buffers with new memory.
 + *
 + * The management in the driver is as follows:
-+ * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free.  When
-+ *   ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
-+ *   to replensish the ipw->rxq->rx_free.
++ * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free.  When
++ *   iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
++ *   to replensish the iwl->rxq->rx_free.
 + * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the
-+ *   ipw->rxq is replenished and the READ INDEX is updated (updating the
++ *   iwl->rxq is replenished and the READ INDEX is updated (updating the
 + *   'processed' and 'read' driver indexes as well)
 + * + A received packet is processed and handed to the kernel network stack,
-+ *   detached from the ipw->rxq.  The driver 'processed' index is updated.
-+ * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free
-+ *   list. If there are no allocated buffers in ipw->rxq->rx_free, the READ
-+ *   INDEX is not incremented and ipw->status(RX_STALLED) is set.  If there
++ *   detached from the iwl->rxq.  The driver 'processed' index is updated.
++ * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free
++ *   list. If there are no allocated buffers in iwl->rxq->rx_free, the READ
++ *   INDEX is not incremented and iwl->status(RX_STALLED) is set.  If there
 + *   were enough free buffers and RX_STALLED is set it is cleared.
 + *
 + *
@@ -22939,7 +22881,7 @@
 +		iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
 +			IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
 +	scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-+	scan->tx_cmd.sta_id = IWL_BROADCAST_ID;
++	scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
 +	scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 +
 +	/* flags + rate selection */
@@ -23048,6 +22990,12 @@
 +	int rc = 0;
 +	struct ieee80211_conf *conf = NULL;
 +
++	if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
++		IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
++		return;
++	}
++
++
 +	IWL_DEBUG_ASSOC("Associated as %d to: " MAC_FMT "\n",
 +			priv->assoc_id, MAC_ARG(priv->active_rxon.bssid_addr));
 +
@@ -23115,23 +23063,13 @@
 +
 +		break;
 +
-+	case IEEE80211_IF_TYPE_AP:
-+
-+		/* clear out the station table */
-+		iwl_clear_stations_table(priv);
-+
-+		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-+		iwl_send_beacon_cmd(priv);
-+
++	default:
++		 IWL_ERROR("%s Should not be called in %d mode\n",
++				__FUNCTION__, priv->iw_mode);
 +		break;
 +	}
 +
-+	/* FIXME: not sure why this doesn't work in AP mode */
-+	if (priv->iw_mode != IEEE80211_IF_TYPE_AP)
-+		iwl_sequence_reset(priv);
-+
-+	if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
-+		priv->assoc_station_added = 1;
++	iwl_sequence_reset(priv);
 +
 +#ifdef CONFIG_IWLWIFI_QOS
 +	iwl_activate_qos(priv, 0);
@@ -23378,10 +23316,6 @@
 +			IWL_WARNING("REPLY_RXON_TIMING failed - "
 +					"Attempting to continue.\n");
 +
-+#ifdef CONFIG_IWL_QOS
-+		iwl_reset_qos(priv);
-+#endif /* CONFIG_IWL_QOS */
-+
 +		/* FIXME: what should be the assoc_id for AP? */
 +		priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
 +		if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -23588,8 +23522,9 @@
 +	return rc;
 +}
 +
-+static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, u8 *addr,
-+			   struct ieee80211_key_conf *key, int aid)
++static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd,
++			   const u8 *local_addr, const u8 *addr,
++			   struct ieee80211_key_conf *key)
 +{
 +	struct iwl_priv *priv = hw->priv;
 +	int rc = 0;
@@ -23602,6 +23537,10 @@
 +		return -EOPNOTSUPP;
 +	}
 +
++	if (is_zero_ether_addr(addr))
++		/* only support pairwise keys */
++		return -EOPNOTSUPP;
++
 +	sta_id = iwl_hw_find_station(priv, addr);
 +	if (sta_id == IWL_INVALID_STATION) {
 +		IWL_DEBUG_MAC80211("leave - " MAC_FMT " not in station map.\n",
@@ -23611,17 +23550,26 @@
 +
 +	mutex_lock(&priv->mutex);
 +
-+	if (cmd == SET_KEY)
++	switch (cmd) {
++	case  SET_KEY:
 +		rc = iwl_update_sta_key_info(priv, key, sta_id);
-+	else
++		if (!rc) {
++			iwl_set_rxon_hwcrypto(priv, 1);
++			iwl_commit_rxon(priv);
++			key->hw_key_idx = sta_id;
++			IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
++		}
++		break;
++	case DISABLE_KEY:
++		rc = iwl_clear_sta_key_info(priv, sta_id);
++		if (!rc) {
++			iwl_set_rxon_hwcrypto(priv, 0);
++			iwl_commit_rxon(priv);
++			IWL_DEBUG_MAC80211("disable hwcrypto key\n");
++		}
++		break;
++	default:
 +		rc = -EINVAL;
-+
-+	if (!rc) {
-+		iwl_set_rxon_hwcrypto(priv, 1);
-+		iwl_commit_rxon(priv);
-+		key->flags &= ~IEEE80211_KEY_FORCE_SW_ENCRYPT;
-+		key->hw_key_idx = sta_id;
-+		IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
 +	}
 +
 +	IWL_DEBUG_MAC80211("leave\n");
@@ -23755,7 +23703,6 @@
 +	priv->assoc_id = 0;
 +	priv->assoc_capability = 0;
 +	priv->call_post_assoc_from_beacon = 0;
-+	priv->assoc_station_added = 0;
 +
 +	/* new association get rid of ibss beacon skb */
 +	if (priv->ibss_beacon)
@@ -23848,10 +23795,10 @@
 +
 +/*
 + * The following adds a new attribute to the sysfs representation
-+ * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
++ * of this device driver (i.e. a new file in /sys/bus/pci/drivers/iwl/)
 + * used for controlling the debug level.
 + *
-+ * See the level definitions in ipw for details.
++ * See the level definitions in iwl for details.
 + */
 +
 +static ssize_t show_debug_level(struct device_driver *d, char *buf)
@@ -25046,10 +24993,10 @@
 +module_init(iwl_init);
 diff --git a/drivers/net/wireless/iwl4965-base.c b/drivers/net/wireless/iwl4965-base.c
 new file mode 100644
-index 0000000..47e2fdf
+index 0000000..a880414
 --- /dev/null
 +++ b/drivers/net/wireless/iwl4965-base.c
-@@ -0,0 +1,9326 @@
+@@ -0,0 +1,9323 @@
 +/******************************************************************************
 + *
 + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
@@ -25152,7 +25099,7 @@
 +#define VS
 +#endif
 +
-+#define IWLWIFI_VERSION "0.1.14k" VD VS
++#define IWLWIFI_VERSION "0.1.15k" VD VS
 +#define DRV_COPYRIGHT	"Copyright(c) 2003-2007 Intel Corporation"
 +#define DRV_VERSION     IWLWIFI_VERSION
 +
@@ -25256,11 +25203,6 @@
 + * The IPW operates with six queues, one receive queue in the device's
 + * sram, one transmit queue for sending commands to the device firmware,
 + * and four transmit queues for data.
-+ *
-+ * The four transmit queues allow for performing quality of service (qos)
-+ * transmissions as per the 802.11 protocol.  Currently Linux does not
-+ * provide a mechanism to the user for utilizing prioritized queues, so
-+ * we only utilize the first data transmit queue (queue1).
 + ***************************************************/
 +
 +static int iwl_queue_space(const struct iwl_queue *q)
@@ -25462,7 +25404,7 @@
 +
 +/**************************************************************/
 +
-+static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *bssid, int is_ap)
++static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
 +{
 +	int index = IWL_INVALID_STATION;
 +	int i;
@@ -25470,30 +25412,30 @@
 +
 +	spin_lock_irqsave(&priv->sta_lock, flags);
 +
-+	if (is_ap) {
++	if (is_ap)
 +		index = IWL_AP_ID;
-+		if ((priv->stations[index].used))
-+			priv->stations[index].used = 0;
-+	} else if (is_broadcast_ether_addr(bssid)) {
-+		index = IWL_BROADCAST_ID;
-+		if ((priv->stations[index].used))
-+			priv->stations[index].used = 0;
-+	} else {
-+		for (i = IWL_STA_ID; i < priv->num_stations + IWL_STA_ID; i++) {
++	else if (is_broadcast_ether_addr(addr))
++		index = priv->hw_setting.bcast_sta_id;
++	else
++		for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
 +			if (priv->stations[i].used &&
 +			    !compare_ether_addr(priv->stations[i].sta.sta.addr,
-+						bssid)) {
++						addr)) {
 +				index = i;
-+				priv->stations[index].used = 0;
 +				break;
 +			}
-+		}
-+	}
-+	if (index != IWL_INVALID_STATION) {
-+		if (priv->num_stations > 0)
-+			priv->num_stations--;
++
++	if (unlikely(index == IWL_INVALID_STATION))
++		goto out;
++
++	if (priv->stations[index].used) {
++		priv->stations[index].used = 0;
++		priv->num_stations--;
 +	}
 +
++	BUG_ON(priv->num_stations < 0);
++
++out:
 +	spin_unlock_irqrestore(&priv->sta_lock, flags);
 +	return 0;
 +}
@@ -25510,72 +25452,68 @@
 +	spin_unlock_irqrestore(&priv->sta_lock, flags);
 +}
 +
-+u8 iwl_add_station(struct iwl_priv *priv, const u8 *bssid, int is_ap, u8 flags)
++u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
 +{
-+	int i = IWL_STATION_COUNT;
++	int i;
 +	int index = IWL_INVALID_STATION;
 +	struct iwl_station_entry *station;
 +	unsigned long flags_spin;
 +
 +	spin_lock_irqsave(&priv->sta_lock, flags_spin);
-+	if (is_ap) {
++	if (is_ap)
 +		index = IWL_AP_ID;
-+		if (priv->stations[index].used &&
-+		    !compare_ether_addr(priv->stations[index].sta.sta.addr,
-+					bssid))
-+			goto done;
-+	} else if (is_broadcast_ether_addr(bssid)) {
-+		index = IWL_BROADCAST_ID;
-+		if (priv->stations[index].used &&
-+		    !compare_ether_addr(priv->stations[index].sta.sta.addr,
-+					bssid))
-+			goto done;
-+	} else {
-+		for (i = IWL_STA_ID; i < priv->num_stations + IWL_STA_ID; i++) {
-+			if (priv->stations[i].used &&
-+			    !compare_ether_addr(priv->stations[i].sta.sta.addr,
-+						bssid))
-+				goto done;
++	else if (is_broadcast_ether_addr(addr))
++		index = priv->hw_setting.bcast_sta_id;
++	else
++		for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) {
++			if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
++						addr)) {
++				index = i;
++				break;
++			}
 +
 +			if (!priv->stations[i].used &&
 +			    index == IWL_INVALID_STATION)
 +				index = i;
 +		}
-+	}
 +
-+	if (index != IWL_INVALID_STATION)
-+		i = index;
 +
-+	if (i == IWL_STATION_COUNT) {
-+		index = IWL_INVALID_STATION;
-+		goto done;
++	/* These twh conditions has the same outcome but keep them separate
++	  since they have different meaning */
++	if (unlikely(index == IWL_INVALID_STATION)) {
++		spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
++		return index;
++	}
++
++	if (priv->stations[index].used &&
++	    !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) {
++		spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
++		return index;
 +	}
 +
-+	IWL_DEBUG_ASSOC("Adding STA ID %d: " MAC_FMT "\n", i, MAC_ARG(bssid));
-+	station = &priv->stations[i];
 +
++	IWL_DEBUG_ASSOC("Add STA ID %d: " MAC_FMT "\n", index, MAC_ARG(addr));
++	station = &priv->stations[index];
 +	station->used = 1;
++	priv->num_stations++;
++
 +	memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
-+	memcpy(station->sta.sta.addr, bssid, ETH_ALEN);
++	memcpy(station->sta.sta.addr, addr, ETH_ALEN);
 +	station->sta.mode = 0;
-+	station->sta.sta.sta_id = i;
++	station->sta.sta.sta_id = index;
 +	station->sta.station_flags = 0;
 +
 +#ifdef CONFIG_IWLWIFI_HT
-+	if (is_ap) {
-+		iwl4965_set_ht_add_station(priv, i);
-+		iwl4965_set_rxon_chain(priv);
-+	}
++	/* BCAST station and IBSS stations do not work in HT mode */
++	if (index != priv->hw_setting.bcast_sta_id &&
++	    priv->iw_mode != IEEE80211_IF_TYPE_IBSS)
++		iwl4965_set_ht_add_station(priv, index);
 +#endif /*CONFIG_IWLWIFI_HT*/
 +
-+	priv->num_stations++;
 +	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 +	iwl_send_add_station(priv, &station->sta, flags);
-+	return i;
-+
-+ done:
-+	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 +	return index;
++
 +}
 +
 +/*************** DRIVER STATUS FUNCTIONS   *****/
@@ -26476,6 +26414,23 @@
 +	return 0;
 +}
 +
++static int iwl_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&priv->sta_lock, flags);
++	memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
++	memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl_keyinfo));
++	priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
++	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
++	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
++	spin_unlock_irqrestore(&priv->sta_lock, flags);
++
++	IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
++	iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0);
++	return 0;
++}
++
 +static void iwl_clear_free_frames(struct iwl_priv *priv)
 +{
 +	struct list_head *element;
@@ -27684,17 +27639,10 @@
 +	switch (keyinfo->alg) {
 +	case ALG_CCMP:
 +		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
-+
-+		cmd->cmd.tx.hdr[0].frame_control |=
-+		    cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-+		/* XXX: ACK flag must be set for CCMP even if it
-+		 * is a multicast/broadcast packet, because CCMP
-+		 * group communication encrypted by GTK is
-+		 * actually done by the AP. */
-+		cmd->cmd.tx.tx_flags |= TX_CMD_FLG_ACK_MSK;
 +		memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
-+		IWL_DEBUG_TX("tx_cmd with aes  hwcrypto\n");
++		IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
 +		break;
++
 +	case ALG_TKIP:
 +#if 0
 +		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP;
@@ -27704,42 +27652,30 @@
 +			       8);
 +		else
 +			memset(cmd->cmd.tx.tkip_mic.byte, 0, 8);
-+
-+		cmd->cmd.tx.hdr[0].frame_control |=
-+		    cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-+		/* XXX: ACK flag must be set for CCMP even if it
-+		 * is a multicast/broadcast packet, because CCMP
-+		 * group communication encrypted by GTK is
-+		 * actually done by the AP. */
-+		cmd->cmd.tx.tx_flags |= TX_CMD_FLG_ACK_MSK;
 +#endif
 +		break;
++
 +	case ALG_WEP:
-+		cmd->cmd.tx.sec_ctl = 1 |	/* WEP */
-+		    (ctl->key_idx & 0x3) << 6;
++		cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
++			(ctl->key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
 +
 +		if (keyinfo->keylen == 13)
-+			cmd->cmd.tx.sec_ctl |= (1 << 3);	/* 128-bit */
++			cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
 +
 +		memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
 +
-+		cmd->cmd.tx.hdr[0].frame_control |=
-+		    cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-+
 +		IWL_DEBUG_TX("Configuring packet for WEP encryption "
 +			     "with key %d\n", ctl->key_idx);
 +		break;
 +
 +	case ALG_NONE:
-+		IWL_DEBUG_TX("Tx packet in the clear "
-+			     "(encrypt requested).\n");
++		IWL_DEBUG_TX("Tx packet in the clear (encrypt requested).\n");
 +		break;
 +
 +	default:
 +		printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg);
 +		break;
 +	}
-+
 +}
 +
 +/*
@@ -27816,7 +27752,7 @@
 +	 * station id */
 +	if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
 +	    is_multicast_ether_addr(hdr->addr1))
-+		return IWL_BROADCAST_ID;
++		return priv->hw_setting.bcast_sta_id;
 +
 +	switch (priv->iw_mode) {
 +
@@ -27830,7 +27766,7 @@
 +		sta_id = iwl_hw_find_station(priv, hdr->addr1);
 +		if (sta_id != IWL_INVALID_STATION)
 +			return sta_id;
-+		return IWL_BROADCAST_ID;
++		return priv->hw_setting.bcast_sta_id;
 +
 +	/* If this frame is part of a IBSS network, then we use the
 +	 * target specific station id */
@@ -27848,11 +27784,11 @@
 +			       "Defaulting to broadcast...\n",
 +			       MAC_ARG(hdr->addr1));
 +		iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
-+		return IWL_BROADCAST_ID;
++		return priv->hw_setting.bcast_sta_id;
 +
 +	default:
 +		IWL_WARNING("Unkown mode of operation: %d", priv->iw_mode);
-+		return IWL_BROADCAST_ID;
++		return priv->hw_setting.bcast_sta_id;
 +	}
 +}
 +
@@ -28119,8 +28055,7 @@
 +{
 +	unsigned long flags;
 +
-+	if (disable_radio ? 1 : 0 ==
-+	    test_bit(STATUS_RF_KILL_SW, &priv->status) ? 1 : 0)
++	if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))
 +		return;
 +
 +	IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",
@@ -29267,17 +29202,17 @@
 + * resets the Rx queue buffers with new memory.
 + *
 + * The management in the driver is as follows:
-+ * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free.  When
-+ *   ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
-+ *   to replensish the ipw->rxq->rx_free.
++ * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free.  When
++ *   iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
++ *   to replensish the iwl->rxq->rx_free.
 + * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the
-+ *   ipw->rxq is replenished and the READ INDEX is updated (updating the
++ *   iwl->rxq is replenished and the READ INDEX is updated (updating the
 + *   'processed' and 'read' driver indexes as well)
 + * + A received packet is processed and handed to the kernel network stack,
-+ *   detached from the ipw->rxq.  The driver 'processed' index is updated.
-+ * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free
-+ *   list. If there are no allocated buffers in ipw->rxq->rx_free, the READ
-+ *   INDEX is not incremented and ipw->status(RX_STALLED) is set.  If there
++ *   detached from the iwl->rxq.  The driver 'processed' index is updated.
++ * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free
++ *   list. If there are no allocated buffers in iwl->rxq->rx_free, the READ
++ *   INDEX is not incremented and iwl->status(RX_STALLED) is set.  If there
 + *   were enough free buffers and RX_STALLED is set it is cleared.
 + *
 + *
@@ -32038,7 +31973,7 @@
 +		iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
 +			IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
 +	scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-+	scan->tx_cmd.sta_id = IWL_BROADCAST_ID;
++	scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
 +	scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 +
 +	/* flags + rate selection */
@@ -32161,9 +32096,15 @@
 +	int rc = 0;
 +	struct ieee80211_conf *conf = NULL;
 +
++	if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
++		IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
++		return;
++	}
++
 +	IWL_DEBUG_ASSOC("Associated as %d to: " MAC_FMT "\n",
 +			priv->assoc_id, MAC_ARG(priv->active_rxon.bssid_addr));
 +
++
 +	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 +		return;
 +
@@ -32234,20 +32175,13 @@
 +
 +		break;
 +
-+	case IEEE80211_IF_TYPE_AP:
-+
-+		/* clear out the station table */
-+		iwl_clear_stations_table(priv);
-+
-+		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-+		iwl_send_beacon_cmd(priv);
-+
++	default:
++		IWL_ERROR("%s Should not be called in %d mode\n",
++				__FUNCTION__, priv->iw_mode);
 +		break;
 +	}
 +
-+	/* FIXME: not sure why this doesn't work in AP mode */
-+	if (priv->iw_mode != IEEE80211_IF_TYPE_AP)
-+		iwl_sequence_reset(priv);
++	iwl_sequence_reset(priv);
 +
 +#ifdef CONFIG_IWLWIFI_SENSITIVITY
 +	/* Enable Rx differential gain and sensitivity calibrations */
@@ -32516,9 +32450,6 @@
 +					"Attempting to continue.\n");
 +
 +		iwl4965_set_rxon_chain(priv);
-+#ifdef CONFIG_IWL_QOS
-+		iwl_reset_qos(priv);
-+#endif /* CONFIG_IWL_QOS */
 +
 +		/* FIXME: what should be the assoc_id for AP? */
 +		priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
@@ -32545,6 +32476,9 @@
 +		/* restore RXON assoc */
 +		priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 +		iwl_commit_rxon(priv);
++#ifdef CONFIG_IWLWIFI_QOS
++		iwl_activate_qos(priv, 1);
++#endif
 +		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
 +		iwl_send_beacon_cmd(priv);
 +	} else
@@ -32726,8 +32660,9 @@
 +	return rc;
 +}
 +
-+static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, u8 *addr,
-+			   struct ieee80211_key_conf *key, int aid)
++static int iwl_mac_set_key(struct ieee80211_hw *hw, set_key_cmd cmd,
++			   const u8 *local_addr, const u8 *addr,
++			   struct ieee80211_key_conf *key)
 +{
 +	struct iwl_priv *priv = hw->priv;
 +	int rc = 0;
@@ -32740,6 +32675,10 @@
 +		return -EOPNOTSUPP;
 +	}
 +
++	if (is_zero_ether_addr(addr))
++		/* only support pairwise keys */
++		return -EOPNOTSUPP;
++
 +	sta_id = iwl_hw_find_station(priv, addr);
 +	if (sta_id == IWL_INVALID_STATION) {
 +		IWL_DEBUG_MAC80211("leave - " MAC_FMT " not in station map.\n",
@@ -32749,17 +32688,26 @@
 +
 +	mutex_lock(&priv->mutex);
 +
-+	if (cmd == SET_KEY)
++	switch (cmd) {
++	case  SET_KEY:
 +		rc = iwl_update_sta_key_info(priv, key, sta_id);
-+	else
++		if (!rc) {
++			iwl_set_rxon_hwcrypto(priv, 1);
++			iwl_commit_rxon(priv);
++			key->hw_key_idx = sta_id;
++			IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
++		}
++		break;
++	case DISABLE_KEY:
++		rc = iwl_clear_sta_key_info(priv, sta_id);
++		if (!rc) {
++			iwl_set_rxon_hwcrypto(priv, 0);
++			iwl_commit_rxon(priv);
++			IWL_DEBUG_MAC80211("disable hwcrypto key\n");
++		}
++		break;
++	default:
 +		rc = -EINVAL;
-+
-+	if (!rc) {
-+		iwl_set_rxon_hwcrypto(priv, 1);
-+		iwl_commit_rxon(priv);
-+		key->flags &= ~IEEE80211_KEY_FORCE_SW_ENCRYPT;
-+		key->hw_key_idx = sta_id;
-+		IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
 +	}
 +
 +	IWL_DEBUG_MAC80211("leave\n");
@@ -33200,10 +33148,10 @@
 +
 +/*
 + * The following adds a new attribute to the sysfs representation
-+ * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
++ * of this device driver (i.e. a new file in /sys/bus/pci/drivers/iwl/)
 + * used for controlling the debug level.
 + *
-+ * See the level definitions in ipw for details.
++ * See the level definitions in iwl for details.
 + */
 +
 +static ssize_t show_debug_level(struct device_driver *d, char *buf)
@@ -33916,7 +33864,6 @@
 +static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 +{
 +	int err = 0;
-+	u32 pci_id;
 +	struct iwl_priv *priv;
 +	struct ieee80211_hw *hw;
 +	int i;
@@ -34038,9 +33985,6 @@
 +
 +	priv->iw_mode = IEEE80211_IF_TYPE_STA;
 +
-+	pci_id =
-+	    (priv->pci_dev->device << 16) | priv->pci_dev->subsystem_device;
-+
 +	priv->ps_mode = 0;
 +	priv->use_ant_b_for_management_frame = 1; /* start with ant B */
 +	priv->is_ht_enabled = 1;
@@ -34378,10 +34322,10 @@
 +module_init(iwl_init);
 diff --git a/drivers/net/wireless/iwlwifi.h b/drivers/net/wireless/iwlwifi.h
 new file mode 100644
-index 0000000..f4f42f5
+index 0000000..00c79e2
 --- /dev/null
 +++ b/drivers/net/wireless/iwlwifi.h
-@@ -0,0 +1,712 @@
+@@ -0,0 +1,713 @@
 +/******************************************************************************
 + *
 + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
@@ -34577,13 +34521,15 @@
 +#include "iwl-4965-rs.h"
 +#endif
 +
-+#define IWL_TX_QUEUE_AC0	0
-+#define IWL_TX_QUEUE_AC1	1
-+#define IWL_TX_QUEUE_AC2	2
-+#define IWL_TX_QUEUE_AC3	3
-+#define IWL_TX_QUEUE_HCCA_1	5
-+#define IWL_TX_QUEUE_HCCA_2	6
-+#define IWL_TX_QUEUE_NONE	7
++#define IWL_TX_FIFO_AC0	0
++#define IWL_TX_FIFO_AC1	1
++#define IWL_TX_FIFO_AC2	2
++#define IWL_TX_FIFO_AC3	3
++#define IWL_TX_FIFO_HCCA_1	5
++#define IWL_TX_FIFO_HCCA_2	6
++#define IWL_TX_FIFO_NONE	7
++
++/* Minimum number of queues. MAX_NUM is defined in hw specific files */
 +#define IWL_MIN_NUM_QUEUES	4
 +
 +/* Power management (not Tx power) structures */
@@ -34761,9 +34707,6 @@
 +#define STATUS_POWER_PMI	15
 +#define STATUS_FW_ERROR		16
 +
-+/*TODO need to support adding adhoc station MAX_STATION should be 25 */
-+#define IWL_INVALID_STATION     (0xff)
-+
 +#define MAX_TID_COUNT        9
 +
 +#define IWL_INVALID_RATE     0xFF
@@ -34922,6 +34865,8 @@
 +	u16 max_rxq_size;
 +	u16 max_rxq_log;
 +	u32 cck_flag;
++	u8  max_stations;
++	u8  bcast_sta_id;
 +	void *shared_virt;
 +	dma_addr_t shared_phys;
 +};
@@ -35022,7 +34967,7 @@
 +extern const u8 BROADCAST_ADDR[ETH_ALEN];
 +
 +/*
-+ * Currently used by ipw-3945-rs... look at restructuring so that it doesn't
++ * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
 + * call this... todo... fix that.
 +*/
 +extern u8 iwl_sync_station(struct iwl_priv *priv, int sta_id,
@@ -35094,3 +35039,5 @@
 +extern int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel);
 +extern int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
 +#endif
+
+

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	Wed Sep 12 09:44:03 2007
@@ -39,6 +39,5 @@
 + bugfix/arm/disable-netxen_nic.patch
 + bugfix/arm/disable-chelsio_t3.patch
 + bugfix/arm/disable-video_bt848.patch
-+ features/all/v6-Add-iwlwifi-wireless-drivers.patch
 + bugfix/all/git-ieee1394.patch
-+ features/all/iwlwifi-rmmod-fix.patch
++ features/all/v7-Add-iwlwifi-wireless-drivers.patch



More information about the Kernel-svn-changes mailing list