[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