aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-02-03 12:41:58 -0800
committerDavid S. Miller <davem@davemloft.net>2009-02-03 12:41:58 -0800
commit1725d409caba16ea5fc694bd50e95e79e8ced11a (patch)
tree688fe26dd4ceda5364692f0ce307aadb6f04f331 /drivers/net/wireless/iwlwifi
parentb3ff29d2ccfe3af065a9b393699a8fbf2abd1b15 (diff)
parentb8abde45d7d6ab9e8ceced9b5990eeb1149d0b97 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig53
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-100.c70
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-commands.h1702
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debug.h167
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-fh.h188
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h221
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-io.h404
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c109
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c93
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h206
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c1038
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h759
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c64
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h (renamed from drivers/net/wireless/iwlwifi/iwl-3945-core.h)59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c130
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c106
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h55
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c538
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h505
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c169
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h55
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h172
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h135
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c61
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c233
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c4242
54 files changed, 4089 insertions, 7955 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 47bee0ee0a7..7b3bad1796c 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,25 +1,26 @@
config IWLWIFI
- tristate
+ bool "Intel Wireless Wifi"
+ depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ default y
config IWLCORE
tristate "Intel Wireless Wifi Core"
- depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ depends on IWLWIFI
select LIB80211
- select IWLWIFI
select MAC80211_LEDS if IWLWIFI_LEDS
select LEDS_CLASS if IWLWIFI_LEDS
select RFKILL if IWLWIFI_RFKILL
config IWLWIFI_LEDS
- bool
- default n
+ bool "Enable LED support in iwlagn driver"
+ depends on IWLCORE
config IWLWIFI_RFKILL
- boolean "Iwlwifi RF kill support"
+ bool "Enable RF kill support in iwlagn driver"
depends on IWLCORE
config IWLWIFI_DEBUG
- bool "Enable full debugging output in iwlagn driver"
+ bool "Enable full debugging output in iwlagn and iwl3945 drivers"
depends on IWLCORE
---help---
This option will enable debug tracing output for the iwlwifi drivers
@@ -51,7 +52,7 @@ config IWLWIFI_DEBUGFS
config IWLAGN
tristate "Intel Wireless WiFi Next Gen AGN"
- depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ depends on IWLWIFI
select FW_LOADER
select IWLCORE
---help---
@@ -104,13 +105,12 @@ config IWL5000
config IWL3945
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
- depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ depends on IWLWIFI
select FW_LOADER
select LIB80211
- select IWLWIFI
select MAC80211_LEDS if IWL3945_LEDS
select LEDS_CLASS if IWL3945_LEDS
- select RFKILL if IWL3945_RFKILL
+ select RFKILL if IWLWIFI_RFKILL
---help---
Select to build the driver supporting the:
@@ -133,10 +133,6 @@ config IWL3945
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945.ko.
-config IWL3945_RFKILL
- bool "Enable RF kill support in iwl3945 drivers"
- depends on IWL3945
-
config IWL3945_SPECTRUM_MEASUREMENT
bool "Enable Spectrum Measurement in iwl3945 drivers"
depends on IWL3945
@@ -148,30 +144,3 @@ config IWL3945_LEDS
depends on IWL3945
---help---
This option enables LEDS for the iwl3945 driver.
-
-config IWL3945_DEBUG
- bool "Enable full debugging output in iwl3945 driver"
- depends on IWL3945
- ---help---
- This option will enable debug tracing output for the iwl3945
- driver.
-
- This will result in the kernel module being ~100k larger. You can
- control which debug output is sent to the kernel log by setting the
- value in
-
- /sys/bus/pci/drivers/${DRIVER}/debug_level
-
- This entry will only exist if this option is enabled.
-
- To set a value, simply echo an 8-byte hex value to the same file:
-
- % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
-
- You can find the list of debug mask values in:
- drivers/net/wireless/iwlwifi/iwl-3945-debug.h
-
- If this is your first time using this driver, you should say Y here
- as the debug information can assist others in helping you resolve
- any problems you may encounter.
-
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 0be9e6b66aa..fec2fbf8dc0 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -12,6 +12,8 @@ iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-hcmd-check.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
+iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
+iwlagn-$(CONFIG_IWL5000) += iwl-100.o
obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-100.c b/drivers/net/wireless/iwlwifi/iwl-100.c
new file mode 100644
index 00000000000..dbadaf44f57
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-100.c
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+/* Highest firmware API version supported */
+#define IWL100_UCODE_API_MAX 1
+
+/* Lowest firmware API version supported */
+#define IWL100_UCODE_API_MIN 1
+
+#define IWL100_FW_PRE "iwlwifi-100-"
+#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
+#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api)
+
+struct iwl_cfg iwl100_bgn_cfg = {
+ .name = "100 Series BGN",
+ .fw_name_pre = IWL100_FW_PRE,
+ .ucode_api_max = IWL100_UCODE_API_MAX,
+ .ucode_api_min = IWL100_UCODE_API_MIN,
+ .sku = IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+};
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
deleted file mode 100644
index c6f4eb54a2b..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
+++ /dev/null
@@ -1,1702 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-/*
- * Please use this file (iwl-3945-commands.h) only for uCode API definitions.
- * Please use iwl-3945-hw.h for hardware-related definitions.
- * Please use iwl-3945.h for driver implementation definitions.
- */
-
-#ifndef __iwl_3945_commands_h__
-#define __iwl_3945_commands_h__
-
-/* uCode version contains 4 values: Major/Minor/API/Serial */
-#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
-#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
-#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
-#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
-
-enum {
- REPLY_ALIVE = 0x1,
- REPLY_ERROR = 0x2,
-
- /* RXON and QOS commands */
- REPLY_RXON = 0x10,
- REPLY_RXON_ASSOC = 0x11,
- REPLY_QOS_PARAM = 0x13,
- REPLY_RXON_TIMING = 0x14,
-
- /* Multi-Station support */
- REPLY_ADD_STA = 0x18,
- REPLY_REMOVE_STA = 0x19, /* not used */
- REPLY_REMOVE_ALL_STA = 0x1a, /* not used */
-
- /* RX, TX, LEDs */
- REPLY_3945_RX = 0x1b, /* 3945 only */
- REPLY_TX = 0x1c,
- REPLY_RATE_SCALE = 0x47, /* 3945 only */
- REPLY_LEDS_CMD = 0x48,
- REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
-
- /* 802.11h related */
- RADAR_NOTIFICATION = 0x70, /* not used */
- REPLY_QUIET_CMD = 0x71, /* not used */
- REPLY_CHANNEL_SWITCH = 0x72,
- CHANNEL_SWITCH_NOTIFICATION = 0x73,
- REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74,
- SPECTRUM_MEASURE_NOTIFICATION = 0x75,
-
- /* Power Management */
- POWER_TABLE_CMD = 0x77,
- PM_SLEEP_NOTIFICATION = 0x7A,
- PM_DEBUG_STATISTIC_NOTIFIC = 0x7B,
-
- /* Scan commands and notifications */
- REPLY_SCAN_CMD = 0x80,
- REPLY_SCAN_ABORT_CMD = 0x81,
- SCAN_START_NOTIFICATION = 0x82,
- SCAN_RESULTS_NOTIFICATION = 0x83,
- SCAN_COMPLETE_NOTIFICATION = 0x84,
-
- /* IBSS/AP commands */
- BEACON_NOTIFICATION = 0x90,
- REPLY_TX_BEACON = 0x91,
- WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */
-
- /* Miscellaneous commands */
- QUIET_NOTIFICATION = 0x96, /* not used */
- REPLY_TX_PWR_TABLE_CMD = 0x97,
- MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */
-
- /* Bluetooth device coexistence config command */
- REPLY_BT_CONFIG = 0x9b,
-
- /* Statistics */
- REPLY_STATISTICS_CMD = 0x9c,
- STATISTICS_NOTIFICATION = 0x9d,
-
- /* RF-KILL commands and notifications */
- REPLY_CARD_STATE_CMD = 0xa0,
- CARD_STATE_NOTIFICATION = 0xa1,
-
- /* Missed beacons notification */
- MISSED_BEACONS_NOTIFICATION = 0xa2,
-
- REPLY_MAX = 0xff
-};
-
-/******************************************************************************
- * (0)
- * Commonly used structures and definitions:
- * Command header, txpower
- *
- *****************************************************************************/
-
-/* iwl3945_cmd_header flags value */
-#define IWL_CMD_FAILED_MSK 0x40
-
-/**
- * struct iwl3945_cmd_header
- *
- * This header format appears in the beginning of each command sent from the
- * driver, and each response/notification received from uCode.
- */
-struct iwl3945_cmd_header {
- u8 cmd; /* Command ID: REPLY_RXON, etc. */
- u8 flags; /* IWL_CMD_* */
- /*
- * The driver sets up the sequence number to values of its choosing.
- * uCode does not use this value, but passes it back to the driver
- * when sending the response to each driver-originated command, so
- * the driver can match the response to the command. Since the values
- * don't get used by uCode, the driver may set up an arbitrary format.
- *
- * There is one exception: uCode sets bit 15 when it originates
- * the response/notification, i.e. when the response/notification
- * is not a direct response to a command sent by the driver. For
- * example, uCode issues REPLY_3945_RX when it sends a received frame
- * to the driver; it is not a direct response to any driver command.
- *
- * The Linux driver uses the following format:
- *
- * 0:7 index/position within Tx queue
- * 8:13 Tx queue selection
- * 14:14 driver sets this to indicate command is in the 'huge'
- * storage at the end of the command buffers, i.e. scan cmd
- * 15:15 uCode sets this in uCode-originated response/notification
- */
- __le16 sequence;
-
- /* command or response/notification data follows immediately */
- u8 data[0];
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_tx_power
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
- *
- * Each entry contains two values:
- * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained
- * linear value that multiplies the output of the digital signal processor,
- * before being sent to the analog radio.
- * 2) Radio gain. This sets the analog gain of the radio Tx path.
- * It is a coarser setting, and behaves in a logarithmic (dB) fashion.
- *
- * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
- */
-struct iwl3945_tx_power {
- u8 tx_gain; /* gain for analog radio */
- u8 dsp_atten; /* gain for DSP */
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_power_per_rate
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- */
-struct iwl3945_power_per_rate {
- u8 rate; /* plcp */
- struct iwl3945_tx_power tpc;
- u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (0a)
- * Alive and Error Commands & Responses:
- *
- *****************************************************************************/
-
-#define UCODE_VALID_OK cpu_to_le32(0x1)
-#define INITIALIZE_SUBTYPE (9)
-
-/*
- * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "initialize alive" notification once the initialization
- * uCode image has completed its work, and is ready to load the runtime image.
- * This is the *first* "alive" notification that the driver will receive after
- * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- */
-struct iwl3945_init_alive_resp {
- u8 ucode_minor;
- u8 ucode_major;
- __le16 reserved1;
- u8 sw_rev[8];
- u8 ver_type;
- u8 ver_subtype; /* "9" for initialize alive */
- __le16 reserved2;
- __le32 log_event_table_ptr;
- __le32 error_event_table_ptr;
- __le32 timestamp;
- __le32 is_valid;
-} __attribute__ ((packed));
-
-
-/**
- * REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "alive" notification once the runtime image is ready
- * to receive commands from the driver. This is the *second* "alive"
- * notification that the driver will receive after rebooting uCode;
- * this "alive" is indicated by subtype field != 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- *
- * This response includes two pointers to structures within the device's
- * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging:
- *
- * 1) log_event_table_ptr indicates base of the event log. This traces
- * a 256-entry history of uCode execution within a circular buffer.
- *
- * 2) error_event_table_ptr indicates base of the error log. This contains
- * information about any uCode error that occurs.
- *
- * The Linux driver can print both logs to the system log when a uCode error
- * occurs.
- */
-struct iwl3945_alive_resp {
- u8 ucode_minor;
- u8 ucode_major;
- __le16 reserved1;
- u8 sw_rev[8];
- u8 ver_type;
- u8 ver_subtype; /* not "9" for runtime alive */
- __le16 reserved2;
- __le32 log_event_table_ptr; /* SRAM address for event log */
- __le32 error_event_table_ptr; /* SRAM address for error log */
- __le32 timestamp;
- __le32 is_valid;
-} __attribute__ ((packed));
-
-union tsf {
- u8 byte[8];
- __le16 word[4];
- __le32 dw[2];
-};
-
-/*
- * REPLY_ERROR = 0x2 (response only, not a command)
- */
-struct iwl3945_error_resp {
- __le32 error_type;
- u8 cmd_id;
- u8 reserved1;
- __le16 bad_cmd_seq_num;
- __le16 reserved2;
- __le32 error_info;
- union tsf timestamp;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (1)
- * RXON Commands & Responses:
- *
- *****************************************************************************/
-
-/*
- * Rx config defines & structure
- */
-/* rx_config device types */
-enum {
- RXON_DEV_TYPE_AP = 1,
- RXON_DEV_TYPE_ESS = 3,
- RXON_DEV_TYPE_IBSS = 4,
- RXON_DEV_TYPE_SNIFFER = 6,
-};
-
-/* rx_config flags */
-/* band & modulation selection */
-#define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0)
-#define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1)
-/* auto detection enable */
-#define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2)
-/* TGg protection when tx */
-#define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3)
-/* cck short slot & preamble */
-#define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4)
-#define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5)
-/* antenna selection */
-#define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7)
-#define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00)
-#define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
-#define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
-/* radar detection enable */
-#define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12)
-#define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13)
-/* rx response to host with 8-byte TSF
-* (according to ON_AIR deassertion) */
-#define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15)
-
-/* rx_config filter flags */
-/* accept all data frames */
-#define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0)
-/* pass control & management to host */
-#define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1)
-/* accept multi-cast */
-#define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2)
-/* don't decrypt uni-cast frames */
-#define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3)
-/* don't decrypt multi-cast frames */
-#define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4)
-/* STA is associated */
-#define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5)
-/* transfer to host non bssid beacons in associated state */
-#define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6)
-
-/**
- * REPLY_RXON = 0x10 (command, has simple generic response)
- *
- * RXON tunes the radio tuner to a service channel, and sets up a number
- * of parameters that are used primarily for Rx, but also for Tx operations.
- *
- * NOTE: When tuning to a new channel, driver must set the
- * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent
- * info within the device, including the station tables, tx retry
- * rate tables, and txpower tables. Driver must build a new station
- * table and txpower table before transmitting anything on the RXON
- * channel.
- *
- * NOTE: All RXONs wipe clean the internal txpower table. Driver must
- * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
- * regardless of whether RXON_FILTER_ASSOC_MSK is set.
- */
-struct iwl3945_rxon_cmd {
- u8 node_addr[6];
- __le16 reserved1;
- u8 bssid_addr[6];
- __le16 reserved2;
- u8 wlap_bssid_addr[6];
- __le16 reserved3;
- u8 dev_type;
- u8 air_propagation;
- __le16 reserved4;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 assoc_id;
- __le32 flags;
- __le32 filter_flags;
- __le16 channel;
- __le16 reserved5;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl3945_rxon_assoc_cmd {
- __le32 flags;
- __le32 filter_flags;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
- */
-struct iwl3945_rxon_time_cmd {
- union tsf timestamp;
- __le16 beacon_interval;
- __le16 atim_window;
- __le32 beacon_init_val;
- __le16 listen_interval;
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
- */
-struct iwl3945_channel_switch_cmd {
- u8 band;
- u8 expect_beacon;
- __le16 channel;
- __le32 rxon_flags;
- __le32 rxon_filter_flags;
- __le32 switch_time;
- struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-/*
- * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
- */
-struct iwl3945_csa_notification {
- __le16 band;
- __le16 channel;
- __le32 status; /* 0 - OK, 1 - fail */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (2)
- * Quality-of-Service (QOS) Commands & Responses:
- *
- *****************************************************************************/
-
-/**
- * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM
- * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd
- *
- * @cw_min: Contention window, start value in numbers of slots.
- * Should be a power-of-2, minus 1. Device's default is 0x0f.
- * @cw_max: Contention window, max value in numbers of slots.
- * Should be a power-of-2, minus 1. Device's default is 0x3f.
- * @aifsn: Number of slots in Arbitration Interframe Space (before
- * performing random backoff timing prior to Tx). Device default 1.
- * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0.
- *
- * Device will automatically increase contention window by (2*CW) + 1 for each
- * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW
- * value, to cap the CW value.
- */
-struct iwl3945_ac_qos {
- __le16 cw_min;
- __le16 cw_max;
- u8 aifsn;
- u8 reserved1;
- __le16 edca_txop;
-} __attribute__ ((packed));
-
-/* QoS flags defines */
-#define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01)
-#define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02)
-#define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10)
-
-/* Number of Access Categories (AC) (EDCA), queues 0..3 */
-#define AC_NUM 4
-
-/*
- * REPLY_QOS_PARAM = 0x13 (command, has simple generic response)
- *
- * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs
- * 0: Background, 1: Best Effort, 2: Video, 3: Voice.
- */
-struct iwl3945_qosparam_cmd {
- __le32 qos_flags;
- struct iwl3945_ac_qos ac[AC_NUM];
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (3)
- * Add/Modify Stations Commands & Responses:
- *
- *****************************************************************************/
-/*
- * Multi station support
- */
-
-/* Special, dedicated locations within device's station table */
-#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 IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
-#define IWL_INVALID_STATION 255
-
-#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2);
-#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
-
-/* Use in mode field. 1: modify existing entry, 0: add new station entry */
-#define STA_CONTROL_MODIFY_MSK 0x01
-
-/* key flags __le16*/
-#define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007)
-#define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000)
-#define STA_KEY_FLG_WEP cpu_to_le16(0x0001)
-#define STA_KEY_FLG_CCMP cpu_to_le16(0x0002)
-#define STA_KEY_FLG_TKIP cpu_to_le16(0x0003)
-
-#define STA_KEY_FLG_KEYID_POS 8
-#define STA_KEY_FLG_INVALID cpu_to_le16(0x0800)
-/* wep key is either from global key (0) or from station info array (1) */
-#define STA_KEY_FLG_WEP_KEY_MAP_MSK cpu_to_le16(0x0008)
-
-/* wep key in STA: 5-bytes (0) or 13-bytes (1) */
-#define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000)
-#define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000)
-
-/* Flags indicate whether to modify vs. don't change various station params */
-#define STA_MODIFY_KEY_MASK 0x01
-#define STA_MODIFY_TID_DISABLE_TX 0x02
-#define STA_MODIFY_TX_RATE_MSK 0x04
-
-/*
- * Antenna masks:
- * bit14:15 01 B inactive, A active
- * 10 B active, A inactive
- * 11 Both active
- */
-#define RATE_MCS_ANT_A_POS 14
-#define RATE_MCS_ANT_B_POS 15
-#define RATE_MCS_ANT_A_MSK 0x4000
-#define RATE_MCS_ANT_B_MSK 0x8000
-#define RATE_MCS_ANT_AB_MSK 0xc000
-
-struct iwl3945_keyinfo {
- __le16 key_flags;
- u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
- u8 reserved1;
- __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
- u8 key_offset;
- u8 reserved2;
- u8 key[16]; /* 16-byte unicast decryption key */
-} __attribute__ ((packed));
-
-/**
- * struct sta_id_modify
- * @addr[ETH_ALEN]: station's MAC address
- * @sta_id: index of station in uCode's station table
- * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change
- *
- * Driver selects unused table index when adding new station,
- * or the index to a pre-existing station entry when modifying that station.
- * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP).
- *
- * modify_mask flags select which parameters to modify vs. leave alone.
- */
-struct sta_id_modify {
- u8 addr[ETH_ALEN];
- __le16 reserved1;
- u8 sta_id;
- u8 modify_mask;
- __le16 reserved2;
-} __attribute__ ((packed));
-
-/*
- * REPLY_ADD_STA = 0x18 (command)
- *
- * The device contains an internal table of per-station information,
- * with info on security keys, aggregation parameters, and Tx rates for
- * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD,
- * 3945 uses REPLY_RATE_SCALE to set up rate tables).
- *
- * REPLY_ADD_STA sets up the table entry for one station, either creating
- * a new entry, or modifying a pre-existing one.
- *
- * NOTE: RXON command (without "associated" bit set) wipes the station table
- * clean. Moving into RF_KILL state does this also. Driver must set up
- * new station table before transmitting anything on the RXON channel
- * (except active scans or active measurements; those commands carry
- * their own txpower/rate setup data).
- *
- * When getting started on a new channel, driver must set up the
- * IWL_BROADCAST_ID entry (last entry in the table). For a client
- * station in a BSS, once an AP is selected, driver sets up the AP STA
- * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP
- * are all that are needed for a BSS client station. If the device is
- * used as AP, or in an IBSS network, driver must set up station table
- * entries for all STAs in network, starting with index IWL_STA_ID.
- */
-struct iwl3945_addsta_cmd {
- u8 mode; /* 1: modify existing, 0: add new station */
- u8 reserved[3];
- struct sta_id_modify sta;
- struct iwl3945_keyinfo key;
- __le32 station_flags; /* STA_FLG_* */
- __le32 station_flags_msk; /* STA_FLG_* */
-
- /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
- * corresponding to bit (e.g. bit 5 controls TID 5).
- * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
- __le16 tid_disable_tx;
-
- __le16 rate_n_flags;
-
- /* TID for which to add block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- u8 add_immediate_ba_tid;
-
- /* TID for which to remove block-ack support.
- * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
- u8 remove_immediate_ba_tid;
-
- /* Starting Sequence Number for added block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- __le16 add_immediate_ba_ssn;
-} __attribute__ ((packed));
-
-#define ADD_STA_SUCCESS_MSK 0x1
-#define ADD_STA_NO_ROOM_IN_TABLE 0x2
-#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4
-/*
- * REPLY_ADD_STA = 0x18 (response)
- */
-struct iwl3945_add_sta_resp {
- u8 status; /* ADD_STA_* */
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (4)
- * Rx Responses:
- *
- *****************************************************************************/
-
-struct iwl3945_rx_frame_stats {
- u8 phy_count;
- u8 id;
- u8 rssi;
- u8 agc;
- __le16 sig_avg;
- __le16 noise_diff;
- u8 payload[0];
-} __attribute__ ((packed));
-
-struct iwl3945_rx_frame_hdr {
- __le16 channel;
- __le16 phy_flags;
- u8 reserved1;
- u8 rate;
- __le16 len;
- u8 payload[0];
-} __attribute__ ((packed));
-
-#define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0)
-#define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1)
-
-#define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0)
-#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
-#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
-#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
-#define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0)
-
-#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
-#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
-#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8)
-#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8)
-#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8)
-
-#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11)
-#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11)
-#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11)
-#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11)
-#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11)
-
-struct iwl3945_rx_frame_end {
- __le32 status;
- __le64 timestamp;
- __le32 beacon_timestamp;
-} __attribute__ ((packed));
-
-/*
- * REPLY_3945_RX = 0x1b (response only, not a command)
- *
- * NOTE: DO NOT dereference from casts to this structure
- * It is provided only for calculating minimum data set size.
- * The actual offsets of the hdr and end are dynamic based on
- * stats.phy_count
- */
-struct iwl3945_rx_frame {
- struct iwl3945_rx_frame_stats stats;
- struct iwl3945_rx_frame_hdr hdr;
- struct iwl3945_rx_frame_end end;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (5)
- * Tx Commands & Responses:
- *
- * Driver must place each REPLY_TX command into one of the prioritized Tx
- * queues in host DRAM, shared between driver and device. When the device's
- * Tx scheduler and uCode are preparing to transmit, the device pulls the
- * Tx command over the PCI bus via one of the device's Tx DMA channels,
- * to fill an internal FIFO from which data will be transmitted.
- *
- * uCode handles all timing and protocol related to control frames
- * (RTS/CTS/ACK), based on flags in the Tx command.
- *
- * uCode handles retrying Tx when an ACK is expected but not received.
- * This includes trying lower data rates than the one requested in the Tx
- * command, as set up by the REPLY_RATE_SCALE (for 3945) or
- * REPLY_TX_LINK_QUALITY_CMD (4965).
- *
- * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
- * This command must be executed after every RXON command, before Tx can occur.
- *****************************************************************************/
-
-/* REPLY_TX Tx flags field */
-
-/* 1: Use Request-To-Send protocol before this frame.
- * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
-#define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1)
-
-/* 1: Transmit Clear-To-Send to self before this frame.
- * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames.
- * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */
-#define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2)
-
-/* 1: Expect ACK from receiving station
- * 0: Don't expect ACK (MAC header's duration field s/b 0)
- * Set this for unicast frames, but not broadcast/multicast. */
-#define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3)
-
-/* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
- * Tx command's initial_rate_index indicates first rate to try;
- * uCode walks through table for additional Tx attempts.
- * 0: Use Tx rate/MCS from Tx command's rate_n_flags field.
- * This rate will be used for all Tx attempts; it will not be scaled. */
-#define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4)
-
-/* 1: Expect immediate block-ack.
- * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */
-#define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6)
-
-/* 1: Frame requires full Tx-Op protection.
- * Set this if either RTS or CTS Tx Flag gets set. */
-#define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7)
-
-/* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
- * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
-#define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00)
-#define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
-#define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
-
-/* 1: Ignore Bluetooth priority for this frame.
- * 0: Delay Tx until Bluetooth device is done (normal usage). */
-#define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12)
-
-/* 1: uCode overrides sequence control field in MAC header.
- * 0: Driver provides sequence control field in MAC header.
- * Set this for management frames, non-QOS data frames, non-unicast frames,
- * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */
-#define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13)
-
-/* 1: This frame is non-last MPDU; more fragments are coming.
- * 0: Last fragment, or not using fragmentation. */
-#define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14)
-
-/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame.
- * 0: No TSF required in outgoing frame.
- * Set this for transmitting beacons and probe responses. */
-#define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16)
-
-/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword
- * alignment of frame's payload data field.
- * 0: No pad
- * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4
- * field (but not both). Driver must align frame data (i.e. data following
- * MAC header) to DWORD boundary. */
-#define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20)
-
-/* HCCA-AP - disable duration overwriting. */
-#define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25)
-
-/*
- * TX command security control
- */
-#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
-
-/*
- * REPLY_TX = 0x1c (command)
- */
-struct iwl3945_tx_cmd {
- /*
- * MPDU byte count:
- * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
- * + 8 byte IV for CCM or TKIP (not used for WEP)
- * + Data payload
- * + 8-byte MIC (not used for CCM/WEP)
- * NOTE: Does not include Tx command bytes, post-MAC pad bytes,
- * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
- * Range: 14-2342 bytes.
- */
- __le16 len;
-
- /*
- * MPDU or MSDU byte count for next frame.
- * Used for fragmentation and bursting, but not 11n aggregation.
- * Same as "len", but for next frame. Set to 0 if not applicable.
- */
- __le16 next_frame_len;
-
- __le32 tx_flags; /* TX_CMD_FLG_* */
-
- u8 rate;
-
- /* Index of recipient station in uCode's station table */
- u8 sta_id;
- u8 tid_tspec;
- u8 sec_ctl;
- u8 key[16];
- union {
- u8 byte[8];
- __le16 word[4];
- __le32 dw[2];
- } tkip_mic;
- __le32 next_frame_info;
- union {
- __le32 life_time;
- __le32 attempt;
- } stop_time;
- u8 supp_rates[2];
- u8 rts_retry_limit; /*byte 50 */
- u8 data_retry_limit; /*byte 51 */
- union {
- __le16 pm_frame_timeout;
- __le16 attempt_duration;
- } timeout;
-
- /*
- * Duration of EDCA burst Tx Opportunity, in 32-usec units.
- * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
- */
- __le16 driver_txop;
-
- /*
- * MAC header goes here, followed by 2 bytes padding if MAC header
- * length is 26 or 30 bytes, followed by payload data
- */
- u8 payload[0];
- struct ieee80211_hdr hdr[0];
-} __attribute__ ((packed));
-
-/* TX command response is sent after *all* transmission attempts.
- *
- * NOTES:
- *
- * TX_STATUS_FAIL_NEXT_FRAG
- *
- * If the fragment flag in the MAC header for the frame being transmitted
- * is set and there is insufficient time to transmit the next frame, the
- * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
- *
- * TX_STATUS_FIFO_UNDERRUN
- *
- * Indicates the host did not provide bytes to the FIFO fast enough while
- * a TX was in progress.
- *
- * TX_STATUS_FAIL_MGMNT_ABORT
- *
- * This status is only possible if the ABORT ON MGMT RX parameter was
- * set to true with the TX command.
- *
- * If the MSB of the status parameter is set then an abort sequence is
- * required. This sequence consists of the host activating the TX Abort
- * control line, and then waiting for the TX Abort command response. This
- * indicates that a the device is no longer in a transmit state, and that the
- * command FIFO has been cleared. The host must then deactivate the TX Abort
- * control line. Receiving is still allowed in this case.
- */
-enum {
- TX_STATUS_SUCCESS = 0x01,
- TX_STATUS_DIRECT_DONE = 0x02,
- TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
- TX_STATUS_FAIL_LONG_LIMIT = 0x83,
- TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
- TX_STATUS_FAIL_MGMNT_ABORT = 0x85,
- TX_STATUS_FAIL_NEXT_FRAG = 0x86,
- TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
- TX_STATUS_FAIL_DEST_PS = 0x88,
- TX_STATUS_FAIL_ABORTED = 0x89,
- TX_STATUS_FAIL_BT_RETRY = 0x8a,
- TX_STATUS_FAIL_STA_INVALID = 0x8b,
- TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
- TX_STATUS_FAIL_TID_DISABLE = 0x8d,
- TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
- TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
- TX_STATUS_FAIL_TX_LOCKED = 0x90,
- TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
-};
-
-#define TX_PACKET_MODE_REGULAR 0x0000
-#define TX_PACKET_MODE_BURST_SEQ 0x0100
-#define TX_PACKET_MODE_BURST_FIRST 0x0200
-
-enum {
- TX_POWER_PA_NOT_ACTIVE = 0x0,
-};
-
-enum {
- TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */
- TX_STATUS_DELAY_MSK = 0x00000040,
- TX_STATUS_ABORT_MSK = 0x00000080,
- TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */
- TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */
- TX_RESERVED = 0x00780000, /* bits 19:22 */
- TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */
- TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */
-};
-
-/*
- * REPLY_TX = 0x1c (response)
- */
-struct iwl3945_tx_resp {
- u8 failure_rts;
- u8 failure_frame;
- u8 bt_kill_count;
- u8 rate;
- __le32 wireless_media_time;
- __le32 status; /* TX status */
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
- */
-struct iwl3945_txpowertable_cmd {
- u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
- u8 reserved;
- __le16 channel;
- struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-struct iwl3945_rate_scaling_info {
- __le16 rate_n_flags;
- u8 try_cnt;
- u8 next_rate_index;
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
- *
- * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
- *
- * NOTE: The table of rates passed to the uCode via the
- * RATE_SCALE command sets up the corresponding order of
- * rates used for all related commands, including rate
- * masks, etc.
- *
- * For example, if you set 9MB (PLCP 0x0f) as the first
- * rate in the rate table, the bit mask for that rate
- * when passed through ofdm_basic_rates on the REPLY_RXON
- * command would be bit 0 (1 << 0)
- */
-struct iwl3945_rate_scaling_cmd {
- u8 table_id;
- u8 reserved[3];
- struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-/*
- * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
- *
- * 3945 and 4965 support hardware handshake with Bluetooth device on
- * same platform. Bluetooth device alerts wireless device when it will Tx;
- * wireless device can delay or kill its own Tx to accommodate.
- */
-struct iwl3945_bt_cmd {
- u8 flags;
- u8 lead_time;
- u8 max_kill;
- u8 reserved;
- __le32 kill_ack_mask;
- __le32 kill_cts_mask;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (6)
- * Spectrum Management (802.11h) Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/*
- * Spectrum Management
- */
-#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \
- RXON_FILTER_CTL2HOST_MSK | \
- RXON_FILTER_ACCEPT_GRP_MSK | \
- RXON_FILTER_DIS_DECRYPT_MSK | \
- RXON_FILTER_DIS_GRP_DECRYPT_MSK | \
- RXON_FILTER_ASSOC_MSK | \
- RXON_FILTER_BCON_AWARE_MSK)
-
-struct iwl3945_measure_channel {
- __le32 duration; /* measurement duration in extended beacon
- * format */
- u8 channel; /* channel to measure */
- u8 type; /* see enum iwl3945_measure_type */
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
- */
-struct iwl3945_spectrum_cmd {
- __le16 len; /* number of bytes starting from token */
- u8 token; /* token id */
- u8 id; /* measurement id -- 0 or 1 */
- u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */
- u8 periodic; /* 1 = periodic */
- __le16 path_loss_timeout;
- __le32 start_time; /* start time in extended beacon format */
- __le32 reserved2;
- __le32 flags; /* rxon flags */
- __le32 filter_flags; /* rxon filter flags */
- __le16 channel_count; /* minimum 1, maximum 10 */
- __le16 reserved3;
- struct iwl3945_measure_channel channels[10];
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
- */
-struct iwl3945_spectrum_resp {
- u8 token;
- u8 id; /* id of the prior command replaced, or 0xff */
- __le16 status; /* 0 - command will be handled
- * 1 - cannot handle (conflicts with another
- * measurement) */
-} __attribute__ ((packed));
-
-enum iwl3945_measurement_state {
- IWL_MEASUREMENT_START = 0,
- IWL_MEASUREMENT_STOP = 1,
-};
-
-enum iwl3945_measurement_status {
- IWL_MEASUREMENT_OK = 0,
- IWL_MEASUREMENT_CONCURRENT = 1,
- IWL_MEASUREMENT_CSA_CONFLICT = 2,
- IWL_MEASUREMENT_TGH_CONFLICT = 3,
- /* 4-5 reserved */
- IWL_MEASUREMENT_STOPPED = 6,
- IWL_MEASUREMENT_TIMEOUT = 7,
- IWL_MEASUREMENT_PERIODIC_FAILED = 8,
-};
-
-#define NUM_ELEMENTS_IN_HISTOGRAM 8
-
-struct iwl3945_measurement_histogram {
- __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */
- __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */
-} __attribute__ ((packed));
-
-/* clear channel availability counters */
-struct iwl3945_measurement_cca_counters {
- __le32 ofdm;
- __le32 cck;
-} __attribute__ ((packed));
-
-enum iwl3945_measure_type {
- IWL_MEASURE_BASIC = (1 << 0),
- IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
- IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
- IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3),
- IWL_MEASURE_FRAME = (1 << 4),
- /* bits 5:6 are reserved */
- IWL_MEASURE_IDLE = (1 << 7),
-};
-
-/*
- * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
- */
-struct iwl3945_spectrum_notification {
- u8 id; /* measurement id -- 0 or 1 */
- u8 token;
- u8 channel_index; /* index in measurement channel list */
- u8 state; /* 0 - start, 1 - stop */
- __le32 start_time; /* lower 32-bits of TSF */
- u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */
- u8 channel;
- u8 type; /* see enum iwl3945_measurement_type */
- u8 reserved1;
- /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only
- * valid if applicable for measurement type requested. */
- __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */
- __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */
- __le32 cca_time; /* channel load time in usecs */
- u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 -
- * unidentified */
- u8 reserved2[3];
- struct iwl3945_measurement_histogram histogram;
- __le32 stop_time; /* lower 32-bits of TSF */
- __le32 status; /* see iwl3945_measurement_status */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (7)
- * Power Management Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl3945_powertable_cmd - Power Table Command
- * @flags: See below:
- *
- * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
- *
- * PM allow:
- * bit 0 - '0' Driver not allow power management
- * '1' Driver allow PM (use rest of parameters)
- * uCode send sleep notifications:
- * bit 1 - '0' Don't send sleep notification
- * '1' send sleep notification (SEND_PM_NOTIFICATION)
- * Sleep over DTIM
- * bit 2 - '0' PM have to walk up every DTIM
- * '1' PM could sleep over DTIM till listen Interval.
- * PCI power managed
- * bit 3 - '0' (PCI_LINK_CTRL & 0x1)
- * '1' !(PCI_LINK_CTRL & 0x1)
- * Force sleep Modes
- * bit 31/30- '00' use both mac/xtal sleeps
- * '01' force Mac sleep
- * '10' force xtal sleep
- * '11' Illegal set
- *
- * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then
- * ucode assume sleep over DTIM is allowed and we don't need to wakeup
- * for every DTIM.
- */
-#define IWL_POWER_VEC_SIZE 5
-
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le32(1 << 0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le32(1 << 2)
-#define IWL_POWER_PCI_PM_MSK cpu_to_le32(1 << 3)
-struct iwl3945_powertable_cmd {
- __le32 flags;
- __le32 rx_data_timeout;
- __le32 tx_data_timeout;
- __le32 sleep_interval[IWL_POWER_VEC_SIZE];
-} __attribute__((packed));
-
-/*
- * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
- * 3945 and 4965 identical.
- */
-struct iwl3945_sleep_notification {
- u8 pm_sleep_mode;
- u8 pm_wakeup_src;
- __le16 reserved;
- __le32 sleep_time;
- __le32 tsf_low;
- __le32 bcon_timer;
-} __attribute__ ((packed));
-
-/* Sleep states. 3945 and 4965 identical. */
-enum {
- IWL_PM_NO_SLEEP = 0,
- IWL_PM_SLP_MAC = 1,
- IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2,
- IWL_PM_SLP_FULL_MAC_CARD_STATE = 3,
- IWL_PM_SLP_PHY = 4,
- IWL_PM_SLP_REPENT = 5,
- IWL_PM_WAKEUP_BY_TIMER = 6,
- IWL_PM_WAKEUP_BY_DRIVER = 7,
- IWL_PM_WAKEUP_BY_RFKILL = 8,
- /* 3 reserved */
- IWL_PM_NUM_OF_MODES = 12,
-};
-
-/*
- * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response)
- */
-#define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */
-#define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */
-#define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */
-struct iwl3945_card_state_cmd {
- __le32 status; /* CARD_STATE_CMD_* request new power state */
-} __attribute__ ((packed));
-
-/*
- * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
- */
-struct iwl3945_card_state_notif {
- __le32 flags;
-} __attribute__ ((packed));
-
-#define HW_CARD_DISABLED 0x01
-#define SW_CARD_DISABLED 0x02
-#define RF_CARD_DISABLED 0x04
-#define RXON_CARD_DISABLED 0x10
-
-struct iwl3945_ct_kill_config {
- __le32 reserved;
- __le32 critical_temperature_M;
- __le32 critical_temperature_R;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (8)
- * Scan Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl3945_scan_channel - entry in REPLY_SCAN_CMD channel table
- *
- * One for each channel in the scan list.
- * Each channel can independently select:
- * 1) SSID for directed active scans
- * 2) Txpower setting (for rate specified within Tx command)
- * 3) How long to stay on-channel (behavior may be modified by quiet_time,
- * quiet_plcp_th, good_CRC_th)
- *
- * To avoid uCode errors, make sure the following are true (see comments
- * under struct iwl3945_scan_cmd about max_out_time and quiet_time):
- * 1) If using passive_dwell (i.e. passive_dwell != 0):
- * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
- * 2) quiet_time <= active_dwell
- * 3) If restricting off-channel time (i.e. max_out_time !=0):
- * passive_dwell < max_out_time
- * active_dwell < max_out_time
- */
-struct iwl3945_scan_channel {
- /*
- * type is defined as:
- * 0:0 1 = active, 0 = passive
- * 1:4 SSID direct bit map; if a bit is set, then corresponding
- * SSID IE is transmitted in probe request.
- * 5:7 reserved
- */
- u8 type;
- u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */
- struct iwl3945_tx_power tpc;
- __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
- __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_ssid_ie - directed scan network information element
- *
- * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
- * in struct iwl3945_scan_channel; each channel may select different ssids from
- * among the 4 entries. SSID IEs get transmitted in reverse order of entry.
- */
-struct iwl3945_ssid_ie {
- u8 id;
- u8 len;
- u8 ssid[32];
-} __attribute__ ((packed));
-
-#define PROBE_OPTION_MAX 0x4
-#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH cpu_to_le16(1)
-#define IWL_MAX_SCAN_SIZE 1024
-
-/*
- * REPLY_SCAN_CMD = 0x80 (command)
- *
- * The hardware scan command is very powerful; the driver can set it up to
- * maintain (relatively) normal network traffic while doing a scan in the
- * background. The max_out_time and suspend_time control the ratio of how
- * long the device stays on an associated network channel ("service channel")
- * vs. how long it's away from the service channel, tuned to other channels
- * for scanning.
- *
- * max_out_time is the max time off-channel (in usec), and suspend_time
- * is how long (in "extended beacon" format) that the scan is "suspended"
- * after returning to the service channel. That is, suspend_time is the
- * time that we stay on the service channel, doing normal work, between
- * scan segments. The driver may set these parameters differently to support
- * scanning when associated vs. not associated, and light vs. heavy traffic
- * loads when associated.
- *
- * After receiving this command, the device's scan engine does the following;
- *
- * 1) Sends SCAN_START notification to driver
- * 2) Checks to see if it has time to do scan for one channel
- * 3) Sends NULL packet, with power-save (PS) bit set to 1,
- * to tell AP that we're going off-channel
- * 4) Tunes to first channel in scan list, does active or passive scan
- * 5) Sends SCAN_RESULT notification to driver
- * 6) Checks to see if it has time to do scan on *next* channel in list
- * 7) Repeats 4-6 until it no longer has time to scan the next channel
- * before max_out_time expires
- * 8) Returns to service channel
- * 9) Sends NULL packet with PS=0 to tell AP that we're back
- * 10) Stays on service channel until suspend_time expires
- * 11) Repeats entire process 2-10 until list is complete
- * 12) Sends SCAN_COMPLETE notification
- *
- * For fast, efficient scans, the scan command also has support for staying on
- * a channel for just a short time, if doing active scanning and getting no
- * responses to the transmitted probe request. This time is controlled by
- * quiet_time, and the number of received packets below which a channel is
- * considered "quiet" is controlled by quiet_plcp_threshold.
- *
- * For active scanning on channels that have regulatory restrictions against
- * blindly transmitting, the scan can listen before transmitting, to make sure
- * that there is already legitimate activity on the channel. If enough
- * packets are cleanly received on the channel (controlled by good_CRC_th,
- * typical value 1), the scan engine starts transmitting probe requests.
- *
- * Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
- *
- * To avoid uCode errors, see timing restrictions described under
- * struct iwl3945_scan_channel.
- */
-struct iwl3945_scan_cmd {
- __le16 len;
- u8 reserved0;
- u8 channel_count; /* # channels in channel list */
- __le16 quiet_time; /* dwell only this # millisecs on quiet channel
- * (only for active scan) */
- __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */
- __le16 good_CRC_th; /* passive -> active promotion threshold */
- __le16 reserved1;
- __le32 max_out_time; /* max usec to be away from associated (service)
- * channel */
- __le32 suspend_time; /* pause scan this long (in "extended beacon
- * format") when returning to service channel:
- * 3945; 31:24 # beacons, 19:0 additional usec,
- * 4965; 31:22 # beacons, 21:0 additional usec.
- */
- __le32 flags; /* RXON_FLG_* */
- __le32 filter_flags; /* RXON_FILTER_* */
-
- /* For active scans (set to all-0s for passive scans).
- * Does not include payload. Must specify Tx rate; no rate scaling. */
- struct iwl3945_tx_cmd tx_cmd;
-
- /* For directed active scans (set to all-0s otherwise) */
- struct iwl3945_ssid_ie direct_scan[PROBE_OPTION_MAX];
-
- /*
- * Probe request frame, followed by channel list.
- *
- * Size of probe request frame is specified by byte count in tx_cmd.
- * Channel list follows immediately after probe request frame.
- * Number of channels in list is specified by channel_count.
- * Each channel in list is of type:
- *
- * struct iwl3945_scan_channel channels[0];
- *
- * NOTE: Only one band of channels can be scanned per pass. You
- * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
- * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
- * before requesting another scan.
- */
- u8 data[0];
-} __attribute__ ((packed));
-
-/* Can abort will notify by complete notification with abort status. */
-#define CAN_ABORT_STATUS cpu_to_le32(0x1)
-/* complete notification statuses */
-#define ABORT_STATUS 0x2
-
-/*
- * REPLY_SCAN_CMD = 0x80 (response)
- */
-struct iwl3945_scanreq_notification {
- __le32 status; /* 1: okay, 2: cannot fulfill request */
-} __attribute__ ((packed));
-
-/*
- * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
- */
-struct iwl3945_scanstart_notification {
- __le32 tsf_low;
- __le32 tsf_high;
- __le32 beacon_timer;
- u8 channel;
- u8 band;
- u8 reserved[2];
- __le32 status;
-} __attribute__ ((packed));
-
-#define SCAN_OWNER_STATUS 0x1;
-#define MEASURE_OWNER_STATUS 0x2;
-
-#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */
-/*
- * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
- */
-struct iwl3945_scanresults_notification {
- u8 channel;
- u8 band;
- u8 reserved[2];
- __le32 tsf_low;
- __le32 tsf_high;
- __le32 statistics[NUMBER_OF_STATISTICS];
-} __attribute__ ((packed));
-
-/*
- * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
- */
-struct iwl3945_scancomplete_notification {
- u8 scanned_channels;
- u8 status;
- u8 reserved;
- u8 last_channel;
- __le32 tsf_low;
- __le32 tsf_high;
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (9)
- * IBSS/AP Commands and Notifications:
- *
- *****************************************************************************/
-
-/*
- * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
- */
-struct iwl3945_beacon_notif {
- struct iwl3945_tx_resp beacon_notify_hdr;
- __le32 low_tsf;
- __le32 high_tsf;
- __le32 ibss_mgr_status;
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
- */
-struct iwl3945_tx_beacon_cmd {
- struct iwl3945_tx_cmd tx;
- __le16 tim_idx;
- u8 tim_size;
- u8 reserved1;
- struct ieee80211_hdr frame[0]; /* beacon frame */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (10)
- * Statistics Commands and Notifications:
- *
- *****************************************************************************/
-
-#define IWL_TEMP_CONVERT 260
-
-#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
-#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
-#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
-
-/* Used for passing to driver number of successes and failures per rate */
-struct rate_histogram {
- union {
- __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
- __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
- __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
- } success;
- union {
- __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
- __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
- __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
- } failed;
-} __attribute__ ((packed));
-
-/* statistics command response */
-
-struct statistics_rx_phy {
- __le32 ina_cnt;
- __le32 fina_cnt;
- __le32 plcp_err;
- __le32 crc32_err;
- __le32 overrun_err;
- __le32 early_overrun_err;
- __le32 crc32_good;
- __le32 false_alarm_cnt;
- __le32 fina_sync_err_cnt;
- __le32 sfd_timeout;
- __le32 fina_timeout;
- __le32 unresponded_rts;
- __le32 rxe_frame_limit_overrun;
- __le32 sent_ack_cnt;
- __le32 sent_cts_cnt;
-} __attribute__ ((packed));
-
-struct statistics_rx_non_phy {
- __le32 bogus_cts; /* CTS received when not expecting CTS */
- __le32 bogus_ack; /* ACK received when not expecting ACK */
- __le32 non_bssid_frames; /* number of frames with BSSID that
- * doesn't belong to the STA BSSID */
- __le32 filtered_frames; /* count frames that were dumped in the
- * filtering process */
- __le32 non_channel_beacons; /* beacons with our bss id but not on
- * our serving channel */
-} __attribute__ ((packed));
-
-struct statistics_rx {
- struct statistics_rx_phy ofdm;
- struct statistics_rx_phy cck;
- struct statistics_rx_non_phy general;
-} __attribute__ ((packed));
-
-struct statistics_tx {
- __le32 preamble_cnt;
- __le32 rx_detected_cnt;
- __le32 bt_prio_defer_cnt;
- __le32 bt_prio_kill_cnt;
- __le32 few_bytes_cnt;
- __le32 cts_timeout;
- __le32 ack_timeout;
- __le32 expected_ack_cnt;
- __le32 actual_ack_cnt;
-} __attribute__ ((packed));
-
-struct statistics_dbg {
- __le32 burst_check;
- __le32 burst_count;
- __le32 reserved[4];
-} __attribute__ ((packed));
-
-struct statistics_div {
- __le32 tx_on_a;
- __le32 tx_on_b;
- __le32 exec_time;
- __le32 probe_time;
-} __attribute__ ((packed));
-
-struct statistics_general {
- __le32 temperature;
- struct statistics_dbg dbg;
- __le32 sleep_time;
- __le32 slots_out;
- __le32 slots_idle;
- __le32 ttl_timestamp;
- struct statistics_div div;
-} __attribute__ ((packed));
-
-/*
- * REPLY_STATISTICS_CMD = 0x9c,
- * 3945 and 4965 identical.
- *
- * This command triggers an immediate response containing uCode statistics.
- * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
- *
- * If the CLEAR_STATS configuration flag is set, uCode will clear its
- * internal copy of the statistics (counters) after issuing the response.
- * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below).
- *
- * If the DISABLE_NOTIF configuration flag is set, uCode will not issue
- * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag
- * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself.
- */
-#define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */
-#define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */
-struct iwl3945_statistics_cmd {
- __le32 configuration_flags; /* IWL_STATS_CONF_* */
-} __attribute__ ((packed));
-
-/*
- * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
- *
- * By default, uCode issues this notification after receiving a beacon
- * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
- * REPLY_STATISTICS_CMD 0x9c, above.
- *
- * Statistics counters continue to increment beacon after beacon, but are
- * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
- * 0x9c with CLEAR_STATS bit set (see above).
- *
- * uCode also issues this notification during scans. uCode clears statistics
- * appropriately so that each notification contains statistics for only the
- * one channel that has just been scanned.
- */
-#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
-#define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8)
-struct iwl3945_notif_statistics {
- __le32 flag;
- struct statistics_rx rx;
- struct statistics_tx tx;
- struct statistics_general general;
-} __attribute__ ((packed));
-
-
-/*
- * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
- */
-/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
- * then this notification will be sent. */
-#define CONSECUTIVE_MISSED_BCONS_TH 20
-
-struct iwl3945_missed_beacon_notif {
- __le32 consequtive_missed_beacons;
- __le32 total_missed_becons;
- __le32 num_expected_beacons;
- __le32 num_recvd_beacons;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (11)
- * Rx Calibration Commands:
- *
- *****************************************************************************/
-
-#define PHY_CALIBRATE_DIFF_GAIN_CMD (7)
-#define HD_TABLE_SIZE (11)
-
-struct iwl3945_sensitivity_cmd {
- __le16 control;
- __le16 table[HD_TABLE_SIZE];
-} __attribute__ ((packed));
-
-struct iwl3945_calibration_cmd {
- u8 opCode;
- u8 flags;
- __le16 reserved;
- s8 diff_gain_a;
- s8 diff_gain_b;
- s8 diff_gain_c;
- u8 reserved1;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (12)
- * Miscellaneous Commands:
- *
- *****************************************************************************/
-
-/*
- * LEDs Command & Response
- * REPLY_LEDS_CMD = 0x48 (command, has simple generic response)
- *
- * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
- * this command turns it on or off, or sets up a periodic blinking cycle.
- */
-struct iwl3945_led_cmd {
- __le32 interval; /* "interval" in uSec */
- u8 id; /* 1: Activity, 2: Link, 3: Tech */
- u8 off; /* # intervals off while blinking;
- * "0", with >0 "on" value, turns LED on */
- u8 on; /* # intervals on while blinking;
- * "0", regardless of "off", turns LED off */
- u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (13)
- * Union of all expected notifications/responses:
- *
- *****************************************************************************/
-
-struct iwl3945_rx_packet {
- __le32 len;
- struct iwl3945_cmd_header hdr;
- union {
- struct iwl3945_alive_resp alive_frame;
- struct iwl3945_rx_frame rx_frame;
- struct iwl3945_tx_resp tx_resp;
- struct iwl3945_spectrum_notification spectrum_notif;
- struct iwl3945_csa_notification csa_notif;
- struct iwl3945_error_resp err_resp;
- struct iwl3945_card_state_notif card_state_notif;
- struct iwl3945_beacon_notif beacon_status;
- struct iwl3945_add_sta_resp add_sta;
- struct iwl3945_sleep_notification sleep_notif;
- struct iwl3945_spectrum_resp spectrum;
- struct iwl3945_notif_statistics stats;
- __le32 status;
- u8 raw[0];
- } u;
-} __attribute__ ((packed));
-
-#define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
-
-#endif /* __iwl3945_3945_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
deleted file mode 100644
index 85eb778f9df..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl3945_debug_h__
-#define __iwl3945_debug_h__
-
-#ifdef CONFIG_IWL3945_DEBUG
-extern u32 iwl3945_debug_level;
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (iwl3945_debug_level & (level)) \
- printk(KERN_ERR DRV_NAME": %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \
- printk(KERN_ERR DRV_NAME": %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-
-static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
- if (!(iwl3945_debug_level & level))
- return;
-
- print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
- p, len, 1);
-}
-#else
-static inline void IWL_DEBUG(int level, const char *fmt, ...)
-{
-}
-static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
-{
-}
-static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
-}
-#endif /* CONFIG_IWL3945_DEBUG */
-
-
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IWL_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry. xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IWL_xxxx_DEBUG() macro definition for your
- * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/iwl/debug_level
- *
- * you simply need to add your entry to the iwl3945_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/iwl then you do not have
- * CONFIG_IWL3945_DEBUG defined in your kernel configuration
- *
- */
-
-#define IWL_DL_INFO (1 << 0)
-#define IWL_DL_MAC80211 (1 << 1)
-#define IWL_DL_HOST_COMMAND (1 << 2)
-#define IWL_DL_STATE (1 << 3)
-
-#define IWL_DL_RADIO (1 << 7)
-#define IWL_DL_POWER (1 << 8)
-#define IWL_DL_TEMP (1 << 9)
-
-#define IWL_DL_NOTIF (1 << 10)
-#define IWL_DL_SCAN (1 << 11)
-#define IWL_DL_ASSOC (1 << 12)
-#define IWL_DL_DROP (1 << 13)
-
-#define IWL_DL_TXPOWER (1 << 14)
-
-#define IWL_DL_AP (1 << 15)
-
-#define IWL_DL_FW (1 << 16)
-#define IWL_DL_RF_KILL (1 << 17)
-#define IWL_DL_FW_ERRORS (1 << 18)
-
-#define IWL_DL_LED (1 << 19)
-
-#define IWL_DL_RATE (1 << 20)
-
-#define IWL_DL_CALIB (1 << 21)
-#define IWL_DL_WEP (1 << 22)
-#define IWL_DL_TX (1 << 23)
-#define IWL_DL_RX (1 << 24)
-#define IWL_DL_ISR (1 << 25)
-#define IWL_DL_HT (1 << 26)
-#define IWL_DL_IO (1 << 27)
-#define IWL_DL_11H (1 << 28)
-
-#define IWL_DL_STATS (1 << 29)
-#define IWL_DL_TX_REPLY (1 << 30)
-#define IWL_DL_QOS (1 << 31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a)
-
-#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a)
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
new file mode 100644
index 00000000000..08ce259a0e6
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __iwl_3945_fh_h__
+#define __iwl_3945_fh_h__
+
+/************************************/
+/* iwl3945 Flow Handler Definitions */
+/************************************/
+
+/**
+ * This I/O area is directly read/writable by driver (e.g. Linux uses writel())
+ * Addresses are offsets from device's PCI hardware base address.
+ */
+#define FH39_MEM_LOWER_BOUND (0x0800)
+#define FH39_MEM_UPPER_BOUND (0x1000)
+
+#define FH39_CBCC_TABLE (FH39_MEM_LOWER_BOUND + 0x140)
+#define FH39_TFDB_TABLE (FH39_MEM_LOWER_BOUND + 0x180)
+#define FH39_RCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x400)
+#define FH39_RSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x4c0)
+#define FH39_TCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x500)
+#define FH39_TSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x680)
+
+/* TFDB (Transmit Frame Buffer Descriptor) */
+#define FH39_TFDB(_ch, buf) (FH39_TFDB_TABLE + \
+ ((_ch) * 2 + (buf)) * 0x28)
+#define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch) (FH39_TFDB_TABLE + 0x50 * (_ch))
+
+/* CBCC channel is [0,2] */
+#define FH39_CBCC(_ch) (FH39_CBCC_TABLE + (_ch) * 0x8)
+#define FH39_CBCC_CTRL(_ch) (FH39_CBCC(_ch) + 0x00)
+#define FH39_CBCC_BASE(_ch) (FH39_CBCC(_ch) + 0x04)
+
+/* RCSR channel is [0,2] */
+#define FH39_RCSR(_ch) (FH39_RCSR_TABLE + (_ch) * 0x40)
+#define FH39_RCSR_CONFIG(_ch) (FH39_RCSR(_ch) + 0x00)
+#define FH39_RCSR_RBD_BASE(_ch) (FH39_RCSR(_ch) + 0x04)
+#define FH39_RCSR_WPTR(_ch) (FH39_RCSR(_ch) + 0x20)
+#define FH39_RCSR_RPTR_ADDR(_ch) (FH39_RCSR(_ch) + 0x24)
+
+#define FH39_RSCSR_CHNL0_WPTR (FH39_RCSR_WPTR(0))
+
+/* RSSR */
+#define FH39_RSSR_CTRL (FH39_RSSR_TABLE + 0x000)
+#define FH39_RSSR_STATUS (FH39_RSSR_TABLE + 0x004)
+
+/* TCSR */
+#define FH39_TCSR(_ch) (FH39_TCSR_TABLE + (_ch) * 0x20)
+#define FH39_TCSR_CONFIG(_ch) (FH39_TCSR(_ch) + 0x00)
+#define FH39_TCSR_CREDIT(_ch) (FH39_TCSR(_ch) + 0x04)
+#define FH39_TCSR_BUFF_STTS(_ch) (FH39_TCSR(_ch) + 0x08)
+
+/* TSSR */
+#define FH39_TSSR_CBB_BASE (FH39_TSSR_TABLE + 0x000)
+#define FH39_TSSR_MSG_CONFIG (FH39_TSSR_TABLE + 0x008)
+#define FH39_TSSR_TX_STATUS (FH39_TSSR_TABLE + 0x010)
+
+
+/* DBM */
+
+#define FH39_SRVC_CHNL (6)
+
+#define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20)
+#define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4)
+
+#define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000)
+
+#define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000)
+
+#define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005)
+
+#define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) (BIT(_ch) << 24)
+#define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch) (BIT(_ch) << 16)
+
+#define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \
+ (FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \
+ FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch))
+
+#define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
+
+struct iwl3945_tfd_tb {
+ __le32 addr;
+ __le32 len;
+} __attribute__ ((packed));
+
+struct iwl3945_tfd {
+ __le32 control_flags;
+ struct iwl3945_tfd_tb tbs[4];
+ u8 __pad[28];
+} __attribute__ ((packed));
+
+
+#endif /* __iwl_3945_fh_h__ */
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 94ea0e60c41..1327b2ac1c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,77 +69,26 @@
#ifndef __iwl_3945_hw__
#define __iwl_3945_hw__
+#include "iwl-eeprom.h"
+
/*
* uCode queue management definitions ...
* Queue #4 is the command queue for 3945 and 4965.
*/
-#define IWL_CMD_QUEUE_NUM 4
-
-/* Tx rates */
-#define IWL_CCK_RATES 4
-#define IWL_OFDM_RATES 8
-#define IWL_HT_RATES 0
-#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
+#define IWL_CMD_QUEUE_NUM 4
/* Time constants */
#define SHORT_SLOT_TIME 9
#define LONG_SLOT_TIME 20
/* RSSI to dBm */
-#define IWL_RSSI_OFFSET 95
+#define IWL39_RSSI_OFFSET 95
/*
* EEPROM related constants, enums, and structures.
*/
-
-/*
- * EEPROM access time values:
- *
- * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
- * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
- * CSR_EEPROM_REG_BIT_CMD (0x2).
- * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
- * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
- * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
- */
-#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
-
-/*
- * Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags.
- *
- * IBSS and/or AP operation is allowed *only* on those channels with
- * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because
- * RADAR detection is not supported by the 3945 driver, but is a
- * requirement for establishing a new network for legal operation on channels
- * requiring RADAR detection or restricting ACTIVE scanning.
- *
- * NOTE: "WIDE" flag indicates that 20 MHz channel is supported;
- * 3945 does not support FAT 40 MHz-wide channels.
- *
- * NOTE: Using a channel inappropriately will result in a uCode error!
- */
-enum {
- EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */
- EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */
- /* Bit 2 Reserved */
- EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */
- EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */
- EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */
- /* Bit 6 Reserved (was Narrow Channel) */
- EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */
-};
-
-/* SKU Capabilities */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7)
-/* *regulatory* channel data from eeprom, one for each channel */
-struct iwl3945_eeprom_channel {
- u8 flags; /* flags copied from EEPROM */
- s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
-} __attribute__ ((packed));
-
/*
* Mapping of a Tx power level, at factory calibration temperature,
* to a radio/DSP gain table index.
@@ -233,7 +182,7 @@ struct iwl3945_eeprom {
* 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
*/
u16 band_1_count; /* abs.ofs: 196 */
- struct iwl3945_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */
+ struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */
/*
* 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
@@ -241,28 +190,28 @@ struct iwl3945_eeprom {
* (4915-5080MHz) (none of these is ever supported)
*/
u16 band_2_count; /* abs.ofs: 226 */
- struct iwl3945_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
+ struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
/*
* 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
* (5170-5320MHz)
*/
u16 band_3_count; /* abs.ofs: 254 */
- struct iwl3945_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
+ struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
/*
* 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
* (5500-5700MHz)
*/
u16 band_4_count; /* abs.ofs: 280 */
- struct iwl3945_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
+ struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
/*
* 5.7 GHz channels 145, 149, 153, 157, 161, 165
* (5725-5825MHz)
*/
u16 band_5_count; /* abs.ofs: 304 */
- struct iwl3945_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
+ struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
u8 reserved9[194];
@@ -276,125 +225,21 @@ struct iwl3945_eeprom {
u8 reserved16[172]; /* fill out to full 1024 byte block */
} __attribute__ ((packed));
-#define IWL_EEPROM_IMAGE_SIZE 1024
+#define IWL3945_EEPROM_IMG_SIZE 1024
/* End of EEPROM */
-#include "iwl-3945-commands.h"
-
#define PCI_LINK_CTRL 0x0F0
#define PCI_POWER_SOURCE 0x0C8
#define PCI_REG_WUM8 0x0E8
#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
-/*=== FH (data Flow Handler) ===*/
-#define FH_BASE (0x800)
-
-#define FH_CBCC_TABLE (FH_BASE+0x140)
-#define FH_TFDB_TABLE (FH_BASE+0x180)
-#define FH_RCSR_TABLE (FH_BASE+0x400)
-#define FH_RSSR_TABLE (FH_BASE+0x4c0)
-#define FH_TCSR_TABLE (FH_BASE+0x500)
-#define FH_TSSR_TABLE (FH_BASE+0x680)
-
-/* TFDB (Transmit Frame Buffer Descriptor) */
-#define FH_TFDB(_channel, buf) \
- (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28)
-#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \
- (FH_TFDB_TABLE + 0x50 * _channel)
-/* CBCC _channel is [0,2] */
-#define FH_CBCC(_channel) (FH_CBCC_TABLE+(_channel)*0x8)
-#define FH_CBCC_CTRL(_channel) (FH_CBCC(_channel)+0x00)
-#define FH_CBCC_BASE(_channel) (FH_CBCC(_channel)+0x04)
-
-/* RCSR _channel is [0,2] */
-#define FH_RCSR(_channel) (FH_RCSR_TABLE+(_channel)*0x40)
-#define FH_RCSR_CONFIG(_channel) (FH_RCSR(_channel)+0x00)
-#define FH_RCSR_RBD_BASE(_channel) (FH_RCSR(_channel)+0x04)
-#define FH_RCSR_WPTR(_channel) (FH_RCSR(_channel)+0x20)
-#define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24)
-
-#define FH_RSCSR_CHNL0_WPTR (FH_RCSR_WPTR(0))
-
-/* RSSR */
-#define FH_RSSR_CTRL (FH_RSSR_TABLE+0x000)
-#define FH_RSSR_STATUS (FH_RSSR_TABLE+0x004)
-#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
-/* TCSR */
-#define FH_TCSR(_channel) (FH_TCSR_TABLE+(_channel)*0x20)
-#define FH_TCSR_CONFIG(_channel) (FH_TCSR(_channel)+0x00)
-#define FH_TCSR_CREDIT(_channel) (FH_TCSR(_channel)+0x04)
-#define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08)
-/* TSSR */
-#define FH_TSSR_CBB_BASE (FH_TSSR_TABLE+0x000)
-#define FH_TSSR_MSG_CONFIG (FH_TSSR_TABLE+0x008)
-#define FH_TSSR_TX_STATUS (FH_TSSR_TABLE+0x010)
-
-
-/* DBM */
-
-#define ALM_FH_SRVC_CHNL (6)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20)
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005)
-
-#define ALM_TB_MAX_BYTES_COUNT (0xFFF0)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \
- ((1LU << _channel) << 24)
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \
- ((1LU << _channel) << 16)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \
- (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \
- ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel))
#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */
#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */
#define TFD_QUEUE_MIN 0
#define TFD_QUEUE_MAX 6
-#define TFD_QUEUE_SIZE_MAX (256)
#define IWL_NUM_SCAN_RATES (2)
@@ -416,12 +261,6 @@ struct iwl3945_eeprom {
#define TFD_CTL_PAD_SET(n) (n << 28)
#define TFD_CTL_PAD_GET(ctl) (ctl >> 28)
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
- sizeof(struct iwl3945_cmd_meta))
-
/*
* RX related structures and functions
*/
@@ -430,45 +269,35 @@ struct iwl3945_eeprom {
/* Sizes and addresses for instruction and data memory (SRAM) in
* 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */
-#define RTC_INST_LOWER_BOUND (0x000000)
-#define ALM_RTC_INST_UPPER_BOUND (0x014000)
+#define IWL39_RTC_INST_LOWER_BOUND (0x000000)
+#define IWL39_RTC_INST_UPPER_BOUND (0x014000)
-#define RTC_DATA_LOWER_BOUND (0x800000)
-#define ALM_RTC_DATA_UPPER_BOUND (0x808000)
+#define IWL39_RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL39_RTC_DATA_UPPER_BOUND (0x808000)
-#define ALM_RTC_INST_SIZE (ALM_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define ALM_RTC_DATA_SIZE (ALM_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \
+ IWL39_RTC_INST_LOWER_BOUND)
+#define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \
+ IWL39_RTC_DATA_LOWER_BOUND)
-#define IWL_MAX_INST_SIZE ALM_RTC_INST_SIZE
-#define IWL_MAX_DATA_SIZE ALM_RTC_DATA_SIZE
+#define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE
+#define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE
/* Size of uCode instruction memory in bootstrap state machine */
-#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE
+#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE
#define IWL39_MAX_NUM_QUEUES 8
static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
- (addr < ALM_RTC_DATA_UPPER_BOUND);
+ return (addr >= IWL39_RTC_DATA_LOWER_BOUND) &&
+ (addr < IWL39_RTC_DATA_UPPER_BOUND);
}
/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE
* and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */
struct iwl3945_shared {
__le32 tx_base_ptr[8];
- __le32 rx_read_ptr[3];
-} __attribute__ ((packed));
-
-struct iwl3945_tfd_frame_data {
- __le32 addr;
- __le32 len;
-} __attribute__ ((packed));
-
-struct iwl3945_tfd_frame {
- __le32 control_flags;
- struct iwl3945_tfd_frame_data pa[4];
- u8 reserved[28];
} __attribute__ ((packed));
static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
deleted file mode 100644
index 2440fd664dd..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl3945_io_h__
-#define __iwl3945_io_h__
-
-#include <linux/io.h>
-
-#include "iwl-3945-debug.h"
-
-/*
- * IO, register, and NIC memory access functions
- *
- * NOTE on naming convention and macro usage for these
- *
- * A single _ prefix before a an access function means that no state
- * check or debug information is printed when that function is called.
- *
- * A double __ prefix before an access function means that state is checked
- * and the current line number is printed in addition to any other debug output.
- *
- * The non-prefixed name is the #define that maps the caller into a
- * #define that provides the caller's __LINE__ to the double prefix version.
- *
- * If you wish to call the function without any debug or state checking,
- * you should use the single _ prefix version (as is used by dependent IO
- * routines, for example _iwl3945_read_direct32 calls the non-check version of
- * _iwl3945_read32.)
- *
- * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguration of the hardware I/O. In combination with
- * git-bisect and the IO debug level you can quickly determine the specific
- * commit which breaks the IO sequence to the hardware.
- *
- */
-
-#define _iwl3945_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv,
- u32 ofs, u32 val)
-{
- IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
- _iwl3945_write32(priv, ofs, val);
-}
-#define iwl3945_write32(priv, ofs, val) \
- __iwl3945_write32(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val)
-#endif
-
-#define _iwl3945_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs)
-{
- IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
- return _iwl3945_read32(priv, ofs);
-}
-#define iwl3945_read32(priv, ofs)__iwl3945_read32(__FILE__, __LINE__, priv, ofs)
-#else
-#define iwl3945_read32(p, o) _iwl3945_read32(p, o)
-#endif
-
-static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int i = 0;
-
- do {
- if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask))
- return i;
- udelay(10);
- i += 10;
- } while (i < timeout);
-
- return -ETIMEDOUT;
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_poll_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout);
- IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
- addr, bits, mask,
- unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
- return ret;
-}
-#define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \
- __iwl3945_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
-#else
-#define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t)
-#endif
-
-static inline void _iwl3945_set_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) | mask);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read32(priv, reg) | mask;
- IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl3945_write32(priv, reg, val);
-}
-#define iwl3945_set_bit(p, r, m) __iwl3945_set_bit(__FILE__, __LINE__, p, r, m)
-#else
-#define iwl3945_set_bit(p, r, m) _iwl3945_set_bit(p, r, m)
-#endif
-
-static inline void _iwl3945_clear_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) & ~mask);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_clear_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read32(priv, reg) & ~mask;
- IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl3945_write32(priv, reg, val);
-}
-#define iwl3945_clear_bit(p, r, m) __iwl3945_clear_bit(__FILE__, __LINE__, p, r, m)
-#else
-#define iwl3945_clear_bit(p, r, m) _iwl3945_clear_bit(p, r, m)
-#endif
-
-static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv)
-{
- int ret;
-#ifdef CONFIG_IWL3945_DEBUG
- if (atomic_read(&priv->restrict_refcnt))
- return 0;
-#endif
- /* this bit wakes up the NIC */
- _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
- (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
- CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
- if (ret < 0) {
- IWL_ERROR("MAC is in deep sleep!\n");
- return -EIO;
- }
-
-#ifdef CONFIG_IWL3945_DEBUG
- atomic_inc(&priv->restrict_refcnt);
-#endif
- return 0;
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_grab_nic_access(const char *f, u32 l,
- struct iwl3945_priv *priv)
-{
- if (atomic_read(&priv->restrict_refcnt))
- IWL_DEBUG_INFO("Grabbing access while already held at "
- "line %d.\n", l);
-
- IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
- return _iwl3945_grab_nic_access(priv);
-}
-#define iwl3945_grab_nic_access(priv) \
- __iwl3945_grab_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl3945_grab_nic_access(priv) \
- _iwl3945_grab_nic_access(priv)
-#endif
-
-static inline void _iwl3945_release_nic_access(struct iwl3945_priv *priv)
-{
-#ifdef CONFIG_IWL3945_DEBUG
- if (atomic_dec_and_test(&priv->restrict_refcnt))
-#endif
- _iwl3945_clear_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_release_nic_access(const char *f, u32 l,
- struct iwl3945_priv *priv)
-{
- if (atomic_read(&priv->restrict_refcnt) <= 0)
- IWL_ERROR("Release unheld nic access at line %d.\n", l);
-
- IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
- _iwl3945_release_nic_access(priv);
-}
-#define iwl3945_release_nic_access(priv) \
- __iwl3945_release_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl3945_release_nic_access(priv) \
- _iwl3945_release_nic_access(priv)
-#endif
-
-static inline u32 _iwl3945_read_direct32(struct iwl3945_priv *priv, u32 reg)
-{
- return _iwl3945_read32(priv, reg);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read_direct32(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg)
-{
- u32 value = _iwl3945_read_direct32(priv, reg);
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s %d\n", f, l);
- IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
- f, l);
- return value;
-}
-#define iwl3945_read_direct32(priv, reg) \
- __iwl3945_read_direct32(__FILE__, __LINE__, priv, reg)
-#else
-#define iwl3945_read_direct32 _iwl3945_read_direct32
-#endif
-
-static inline void _iwl3945_write_direct32(struct iwl3945_priv *priv,
- u32 reg, u32 value)
-{
- _iwl3945_write32(priv, reg, value);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static void __iwl3945_write_direct32(u32 line,
- struct iwl3945_priv *priv, u32 reg, u32 value)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- _iwl3945_write_direct32(priv, reg, value);
-}
-#define iwl3945_write_direct32(priv, reg, value) \
- __iwl3945_write_direct32(__LINE__, priv, reg, value)
-#else
-#define iwl3945_write_direct32 _iwl3945_write_direct32
-#endif
-
-static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv,
- u32 reg, u32 len, u32 *values)
-{
- u32 count = sizeof(u32);
-
- if ((priv != NULL) && (values != NULL)) {
- for (; 0 < len; len -= count, reg += count, values++)
- _iwl3945_write_direct32(priv, reg, *values);
- }
-}
-
-static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv,
- u32 addr, u32 mask, int timeout)
-{
- return _iwl3945_poll_bit(priv, addr, mask, mask, timeout);
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_poll_direct_bit(const char *f, u32 l,
- struct iwl3945_priv *priv,
- u32 addr, u32 mask, int timeout)
-{
- int ret = _iwl3945_poll_direct_bit(priv, addr, mask, timeout);
-
- if (unlikely(ret == -ETIMEDOUT))
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
- "timedout - %s %d\n", addr, mask, f, l);
- else
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
- "- %s %d\n", addr, mask, ret, f, l);
- return ret;
-}
-#define iwl3945_poll_direct_bit(priv, addr, mask, timeout) \
- __iwl3945_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
-#else
-#define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit
-#endif
-
-static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg)
-{
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
- rmb();
- return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read_prph(u32 line, struct iwl3945_priv *priv, u32 reg)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- return _iwl3945_read_prph(priv, reg);
-}
-
-#define iwl3945_read_prph(priv, reg) \
- __iwl3945_read_prph(__LINE__, priv, reg)
-#else
-#define iwl3945_read_prph _iwl3945_read_prph
-#endif
-
-static inline void _iwl3945_write_prph(struct iwl3945_priv *priv,
- u32 addr, u32 val)
-{
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
- ((addr & 0x0000FFFF) | (3 << 24)));
- wmb();
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_write_prph(u32 line, struct iwl3945_priv *priv,
- u32 addr, u32 val)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access from line %d\n", line);
- _iwl3945_write_prph(priv, addr, val);
-}
-
-#define iwl3945_write_prph(priv, addr, val) \
- __iwl3945_write_prph(__LINE__, priv, addr, val);
-#else
-#define iwl3945_write_prph _iwl3945_write_prph
-#endif
-
-#define _iwl3945_set_bits_prph(priv, reg, mask) \
- _iwl3945_write_prph(priv, reg, (_iwl3945_read_prph(priv, reg) | mask))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bits_prph(u32 line, struct iwl3945_priv *priv,
- u32 reg, u32 mask)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
-
- _iwl3945_set_bits_prph(priv, reg, mask);
-}
-#define iwl3945_set_bits_prph(priv, reg, mask) \
- __iwl3945_set_bits_prph(__LINE__, priv, reg, mask)
-#else
-#define iwl3945_set_bits_prph _iwl3945_set_bits_prph
-#endif
-
-#define _iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
- _iwl3945_write_prph(priv, reg, ((_iwl3945_read_prph(priv, reg) & mask) | bits))
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bits_mask_prph(u32 line,
- struct iwl3945_priv *priv, u32 reg, u32 bits, u32 mask)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- _iwl3945_set_bits_mask_prph(priv, reg, bits, mask);
-}
-#define iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
- __iwl3945_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
-#else
-#define iwl3945_set_bits_mask_prph _iwl3945_set_bits_mask_prph
-#endif
-
-static inline void iwl3945_clear_bits_prph(struct iwl3945_priv
- *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read_prph(priv, reg);
- _iwl3945_write_prph(priv, reg, (val & ~mask));
-}
-
-static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
- rmb();
- return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
-}
-
-static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
-}
-
-static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 addr,
- u32 len, u32 *values)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- for (; 0 < len; len -= sizeof(u32), values++)
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
-}
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 4c638909a7d..fab13736500 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -38,8 +38,10 @@
#include <linux/etherdevice.h>
#include <asm/unaligned.h>
+#include "iwl-commands.h"
#include "iwl-3945.h"
-#include "iwl-helpers.h"
+#include "iwl-core.h"
+#include "iwl-dev.h"
static const struct {
@@ -67,8 +69,8 @@ static const struct {
#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/
#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
-static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+static int iwl3945_led_cmd_callback(struct iwl_priv *priv,
+ struct iwl_cmd *cmd,
struct sk_buff *skb)
{
return 1;
@@ -80,27 +82,27 @@ static inline int iwl3945_brightness_to_idx(enum led_brightness brightness)
}
/* Send led command */
-static int iwl_send_led_cmd(struct iwl3945_priv *priv,
- struct iwl3945_led_cmd *led_cmd)
+static int iwl_send_led_cmd(struct iwl_priv *priv,
+ struct iwl_led_cmd *led_cmd)
{
- struct iwl3945_host_cmd cmd = {
+ struct iwl_host_cmd cmd = {
.id = REPLY_LEDS_CMD,
- .len = sizeof(struct iwl3945_led_cmd),
+ .len = sizeof(struct iwl_led_cmd),
.data = led_cmd,
.meta.flags = CMD_ASYNC,
.meta.u.callback = iwl3945_led_cmd_callback,
};
- return iwl3945_send_cmd(priv, &cmd);
+ return iwl_send_cmd(priv, &cmd);
}
/* Set led on command */
-static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
+static int iwl3945_led_pattern(struct iwl_priv *priv, int led_id,
unsigned int idx)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.interval = IWL_DEF_LED_INTRVL
};
@@ -114,11 +116,10 @@ static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
}
-#if 1
/* Set led on command */
-static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_on(struct iwl_priv *priv, int led_id)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.on = IWL_LED_SOLID,
.off = 0,
@@ -128,9 +129,9 @@ static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
}
/* Set led off command */
-static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_off(struct iwl_priv *priv, int led_id)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.on = 0,
.off = 0,
@@ -139,13 +140,11 @@ static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id)
IWL_DEBUG_LED("led off %d\n", led_id);
return iwl_send_led_cmd(priv, &led_cmd);
}
-#endif
-
/*
* brightness call back function for Tx/Rx LED
*/
-static int iwl3945_led_associated(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_associated(struct iwl_priv *priv, int led_id)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
!test_bit(STATUS_READY, &priv->status))
@@ -166,7 +165,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
{
struct iwl3945_led *led = container_of(led_cdev,
struct iwl3945_led, led_dev);
- struct iwl3945_priv *priv = led->priv;
+ struct iwl_priv *priv = led->priv;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -202,7 +201,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
/*
* Register led class with the system
*/
-static int iwl3945_led_register_led(struct iwl3945_priv *priv,
+static int iwl3945_led_register_led(struct iwl_priv *priv,
struct iwl3945_led *led,
enum led_type type, u8 set_led,
char *trigger)
@@ -219,7 +218,7 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv,
ret = led_classdev_register(device, &led->led_dev);
if (ret) {
- IWL_ERROR("Error: failed to register led handler.\n");
+ IWL_ERR(priv, "Error: failed to register led handler.\n");
return ret;
}
@@ -234,7 +233,7 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv,
/*
* calculate blink rate according to last 2 sec Tx/Rx activities
*/
-static inline u8 get_blink_rate(struct iwl3945_priv *priv)
+static inline u8 get_blink_rate(struct iwl_priv *priv)
{
int index;
u64 current_tpt = priv->rxtxpackets;
@@ -253,7 +252,7 @@ static inline u8 get_blink_rate(struct iwl3945_priv *priv)
return index;
}
-static inline int is_rf_kill(struct iwl3945_priv *priv)
+static inline int is_rf_kill(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
test_bit(STATUS_RF_KILL_SW, &priv->status);
@@ -264,7 +263,7 @@ static inline int is_rf_kill(struct iwl3945_priv *priv)
* happen very frequent we postpone led command to be called from
* REPLY handler so we know ucode is up
*/
-void iwl3945_led_background(struct iwl3945_priv *priv)
+void iwl3945_led_background(struct iwl_priv *priv)
{
u8 blink_idx;
@@ -304,7 +303,7 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
/* Register all led handler */
-int iwl3945_led_register(struct iwl3945_priv *priv)
+int iwl3945_led_register(struct iwl_priv *priv)
{
char *trigger;
int ret;
@@ -316,66 +315,66 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
priv->allow_blinking = 0;
trigger = ieee80211_get_radio_led_name(priv->hw);
- snprintf(priv->led[IWL_LED_TRG_RADIO].name,
- sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
+ snprintf(priv->led39[IWL_LED_TRG_RADIO].name,
+ sizeof(priv->led39[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
wiphy_name(priv->hw->wiphy));
- priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
- priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
- priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
+ priv->led39[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
+ priv->led39[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
+ priv->led39[IWL_LED_TRG_RADIO].led_pattern = NULL;
ret = iwl3945_led_register_led(priv,
- &priv->led[IWL_LED_TRG_RADIO],
+ &priv->led39[IWL_LED_TRG_RADIO],
IWL_LED_TRG_RADIO, 1, trigger);
if (ret)
goto exit_fail;
trigger = ieee80211_get_assoc_led_name(priv->hw);
- snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
- sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
+ snprintf(priv->led39[IWL_LED_TRG_ASSOC].name,
+ sizeof(priv->led39[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
- &priv->led[IWL_LED_TRG_ASSOC],
+ &priv->led39[IWL_LED_TRG_ASSOC],
IWL_LED_TRG_ASSOC, 0, trigger);
/* for assoc always turn led on */
- priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
- priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
- priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
+ priv->led39[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
+ priv->led39[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
+ priv->led39[IWL_LED_TRG_ASSOC].led_pattern = NULL;
if (ret)
goto exit_fail;
trigger = ieee80211_get_rx_led_name(priv->hw);
- snprintf(priv->led[IWL_LED_TRG_RX].name,
- sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
+ snprintf(priv->led39[IWL_LED_TRG_RX].name,
+ sizeof(priv->led39[IWL_LED_TRG_RX].name), "iwl-%s:RX",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
- &priv->led[IWL_LED_TRG_RX],
+ &priv->led39[IWL_LED_TRG_RX],
IWL_LED_TRG_RX, 0, trigger);
- priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
- priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
- priv->led[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern;
+ priv->led39[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
+ priv->led39[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
+ priv->led39[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern;
if (ret)
goto exit_fail;
trigger = ieee80211_get_tx_led_name(priv->hw);
- snprintf(priv->led[IWL_LED_TRG_TX].name,
- sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
+ snprintf(priv->led39[IWL_LED_TRG_TX].name,
+ sizeof(priv->led39[IWL_LED_TRG_TX].name), "iwl-%s:TX",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
- &priv->led[IWL_LED_TRG_TX],
+ &priv->led39[IWL_LED_TRG_TX],
IWL_LED_TRG_TX, 0, trigger);
- priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
- priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
- priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
+ priv->led39[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
+ priv->led39[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
+ priv->led39[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
if (ret)
goto exit_fail;
@@ -402,11 +401,11 @@ static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
}
/* Unregister all led handlers */
-void iwl3945_led_unregister(struct iwl3945_priv *priv)
+void iwl3945_led_unregister(struct iwl_priv *priv)
{
- iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
- iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
- iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_TX], 0);
- iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
+ iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_ASSOC], 0);
+ iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_RX], 0);
+ iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_TX], 0);
+ iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_RADIO], 1);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 749ac035fd6..88185a6ccd6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -27,48 +27,34 @@
#ifndef IWL3945_LEDS_H
#define IWL3945_LEDS_H
-struct iwl3945_priv;
+struct iwl_priv;
#ifdef CONFIG_IWL3945_LEDS
-#define IWL_LED_SOLID 11
-#define IWL_LED_NAME_LEN 31
-#define IWL_DEF_LED_INTRVL __constant_cpu_to_le32(1000)
-#define IWL_LED_ACTIVITY (0<<1)
-#define IWL_LED_LINK (1<<1)
-
-enum led_type {
- IWL_LED_TRG_TX,
- IWL_LED_TRG_RX,
- IWL_LED_TRG_ASSOC,
- IWL_LED_TRG_RADIO,
- IWL_LED_TRG_MAX,
-};
-
-#include <linux/leds.h>
+#include "iwl-led.h"
struct iwl3945_led {
- struct iwl3945_priv *priv;
+ struct iwl_priv *priv;
struct led_classdev led_dev;
char name[32];
- int (*led_on) (struct iwl3945_priv *priv, int led_id);
- int (*led_off) (struct iwl3945_priv *priv, int led_id);
- int (*led_pattern) (struct iwl3945_priv *priv, int led_id,
+ int (*led_on) (struct iwl_priv *priv, int led_id);
+ int (*led_off) (struct iwl_priv *priv, int led_id);
+ int (*led_pattern) (struct iwl_priv *priv, int led_id,
unsigned int idx);
enum led_type type;
unsigned int registered;
};
-extern int iwl3945_led_register(struct iwl3945_priv *priv);
-extern void iwl3945_led_unregister(struct iwl3945_priv *priv);
-extern void iwl3945_led_background(struct iwl3945_priv *priv);
+extern int iwl3945_led_register(struct iwl_priv *priv);
+extern void iwl3945_led_unregister(struct iwl_priv *priv);
+extern void iwl3945_led_background(struct iwl_priv *priv);
#else
-static inline int iwl3945_led_register(struct iwl3945_priv *priv) { return 0; }
-static inline void iwl3945_led_unregister(struct iwl3945_priv *priv) {}
-static inline void iwl3945_led_background(struct iwl3945_priv *priv) {}
+static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; }
+static inline void iwl3945_led_unregister(struct iwl_priv *priv) {}
+static inline void iwl3945_led_background(struct iwl_priv *priv) {}
#endif /* CONFIG_IWL3945_LEDS */
#endif /* IWL3945_LEDS_H */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 21c841847d8..044abf734eb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -36,6 +36,7 @@
#include <linux/workqueue.h>
+#include "iwl-commands.h"
#include "iwl-3945.h"
#define RS_NAME "iwl-3945-rs"
@@ -51,6 +52,7 @@ struct iwl3945_rate_scale_data {
struct iwl3945_rs_sta {
spinlock_t lock;
+ struct iwl_priv *priv;
s32 *expected_tpt;
unsigned long last_partial_flush;
unsigned long last_flush;
@@ -62,7 +64,7 @@ struct iwl3945_rs_sta {
u8 start_rate;
u8 ibss_sta_added;
struct timer_list rate_scale_flush;
- struct iwl3945_rate_scale_data win[IWL_RATE_COUNT];
+ struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_stats_table_file;
#endif
@@ -71,19 +73,19 @@ struct iwl3945_rs_sta {
int last_txrate_idx;
};
-static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
};
-static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
};
-static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = {
0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
};
-static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
};
@@ -119,7 +121,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
#define IWL_RATE_MAX_WINDOW 62
#define IWL_RATE_FLUSH (3*HZ)
#define IWL_RATE_WIN_FLUSH (HZ/2)
-#define IWL_RATE_HIGH_TH 11520
+#define IWL39_RATE_HIGH_TH 11520
#define IWL_SUCCESS_UP_TH 8960
#define IWL_SUCCESS_DOWN_TH 10880
#define IWL_RATE_MIN_FAILURE_TH 8
@@ -165,7 +167,7 @@ static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window)
window->success_counter = 0;
window->success_ratio = -1;
window->counter = 0;
- window->average_tpt = IWL_INV_TPT;
+ window->average_tpt = IWL_INVALID_VALUE;
window->stamp = 0;
}
@@ -181,13 +183,14 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta)
int unflushed = 0;
int i;
unsigned long flags;
+ struct iwl_priv *priv = rs_sta->priv;
/*
* For each rate, if we have collected data on that rate
* and it has been more than IWL_RATE_WIN_FLUSH
* since we flushed, clear out the gathered statistics
*/
- for (i = 0; i < IWL_RATE_COUNT; i++) {
+ for (i = 0; i < IWL_RATE_COUNT_3945; i++) {
if (!rs_sta->win[i].counter)
continue;
@@ -213,6 +216,7 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta)
static void iwl3945_bg_rate_scale_flush(unsigned long data)
{
struct iwl3945_rs_sta *rs_sta = (void *)data;
+ struct iwl_priv *priv = rs_sta->priv;
int unflushed = 0;
unsigned long flags;
u32 packet_count, duration, pps;
@@ -286,6 +290,7 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
{
unsigned long flags;
s32 fail_count;
+ struct iwl_priv *priv = rs_sta->priv;
if (!retries) {
IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n");
@@ -329,7 +334,7 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
window->average_tpt = ((window->success_ratio *
rs_sta->expected_tpt[index] + 64) / 128);
else
- window->average_tpt = IWL_INV_TPT;
+ window->average_tpt = IWL_INVALID_VALUE;
spin_unlock_irqrestore(&rs_sta->lock, flags);
@@ -339,7 +344,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
struct iwl3945_rs_sta *rs_sta = priv_sta;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
int i;
IWL_DEBUG_RATE("enter\n");
@@ -379,10 +384,11 @@ static void rs_free(void *priv)
return;
}
-static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
+static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
{
struct iwl3945_rs_sta *rs_sta;
struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
+ struct iwl_priv *priv = iwl_priv;
int i;
/*
@@ -402,6 +408,8 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
spin_lock_init(&rs_sta->lock);
+ rs_sta->priv = priv;
+
rs_sta->start_rate = IWL_RATE_INVALID;
/* default to just 802.11b */
@@ -417,7 +425,7 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush;
- for (i = 0; i < IWL_RATE_COUNT; i++)
+ for (i = 0; i < IWL_RATE_COUNT_3945; i++)
iwl3945_clear_window(&rs_sta->win[i]);
IWL_DEBUG_RATE("leave\n");
@@ -425,11 +433,12 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
return rs_sta;
}
-static void rs_free_sta(void *priv, struct ieee80211_sta *sta,
+static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
void *priv_sta)
{
struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
struct iwl3945_rs_sta *rs_sta = priv_sta;
+ struct iwl_priv *priv = rs_sta->priv;
psta->rs_sta = NULL;
@@ -443,7 +452,7 @@ static void rs_free_sta(void *priv, struct ieee80211_sta *sta,
/**
* rs_tx_status - Update rate control values based on Tx results
*
- * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
+ * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by
* the hardware for each rate.
*/
static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
@@ -453,7 +462,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
s8 retries = 0, current_count;
int scale_rate_index, first_index, last_index;
unsigned long flags;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct iwl3945_rs_sta *rs_sta = priv_sta;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -462,7 +471,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
retries = info->status.rates[0].count;
first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
- if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
+ if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) {
IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
return;
}
@@ -547,6 +556,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
{
u8 high = IWL_RATE_INVALID;
u8 low = IWL_RATE_INVALID;
+ struct iwl_priv *priv = rs_sta->priv;
/* 802.11A walks to the next literal adjacent rate in
* the rate table */
@@ -565,7 +575,8 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
/* Find the next rate that is in the rate mask */
i = index + 1;
- for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
+ for (mask = (1 << i); i < IWL_RATE_COUNT_3945;
+ i++, mask <<= 1) {
if (rate_mask & mask) {
high = i;
break;
@@ -631,16 +642,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
int index;
struct iwl3945_rs_sta *rs_sta = priv_sta;
struct iwl3945_rate_scale_data *window = NULL;
- int current_tpt = IWL_INV_TPT;
- int low_tpt = IWL_INV_TPT;
- int high_tpt = IWL_INV_TPT;
+ int current_tpt = IWL_INVALID_VALUE;
+ int low_tpt = IWL_INVALID_VALUE;
+ int high_tpt = IWL_INVALID_VALUE;
u32 fail_count;
s8 scale_action = 0;
unsigned long flags;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
u16 fc;
u16 rate_mask = 0;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
+ s8 max_rate_idx = -1;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
IWL_DEBUG_RATE("enter\n");
@@ -664,7 +676,14 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
return;
}
- index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
+ /* get user max rate if set */
+ max_rate_idx = txrc->max_rate_idx;
+ if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1))
+ max_rate_idx += IWL_FIRST_OFDM_RATE;
+ if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT))
+ max_rate_idx = -1;
+
+ index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1);
if (sband->band == IEEE80211_BAND_5GHZ)
rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
@@ -695,6 +714,12 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
rs_sta->start_rate = IWL_RATE_INVALID;
}
+ /* force user max rate if set by user */
+ if ((max_rate_idx != -1) && (max_rate_idx < index)) {
+ if (rate_mask & (1 << max_rate_idx))
+ index = max_rate_idx;
+ }
+
window = &(rs_sta->win[index]);
fail_count = window->counter - window->success_counter;
@@ -721,6 +746,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
+ /* If user set max rate, dont allow higher than user constrain */
+ if ((max_rate_idx != -1) && (max_rate_idx < high))
+ high = IWL_RATE_INVALID;
+
if (low != IWL_RATE_INVALID)
low_tpt = rs_sta->win[low].average_tpt;
@@ -734,16 +763,18 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
scale_action = -1;
- } else if ((low_tpt == IWL_INV_TPT) && (high_tpt == IWL_INV_TPT))
+ } else if ((low_tpt == IWL_INVALID_VALUE) &&
+ (high_tpt == IWL_INVALID_VALUE))
scale_action = 1;
- else if ((low_tpt != IWL_INV_TPT) && (high_tpt != IWL_INV_TPT) &&
+ else if ((low_tpt != IWL_INVALID_VALUE) &&
+ (high_tpt != IWL_INVALID_VALUE) &&
(low_tpt < current_tpt) && (high_tpt < current_tpt)) {
IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < "
"current_tpt [%d]\n",
low_tpt, high_tpt, current_tpt);
scale_action = 0;
} else {
- if (high_tpt != IWL_INV_TPT) {
+ if (high_tpt != IWL_INVALID_VALUE) {
if (high_tpt > current_tpt)
scale_action = 1;
else {
@@ -751,7 +782,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
("decrease rate because of high tpt\n");
scale_action = -1;
}
- } else if (low_tpt != IWL_INV_TPT) {
+ } else if (low_tpt != IWL_INVALID_VALUE) {
if (low_tpt > current_tpt) {
IWL_DEBUG_RATE
("decrease rate because of low tpt\n");
@@ -825,7 +856,7 @@ static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file,
lq_sta->tx_packets,
lq_sta->last_txrate_idx,
lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time));
- for (j = 0; j < IWL_RATE_COUNT; j++) {
+ for (j = 0; j < IWL_RATE_COUNT_3945; j++) {
desc += sprintf(buff+desc,
"counter=%d success=%d %%=%d\n",
lq_sta->win[j].counter,
@@ -877,7 +908,7 @@ static struct rate_control_ops rs_ops = {
void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
s32 rssi = 0;
unsigned long flags;
struct iwl3945_rs_sta *rs_sta;
@@ -888,7 +919,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
rcu_read_lock();
- sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
+ sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr);
if (!sta) {
rcu_read_unlock();
return;
@@ -903,7 +934,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
switch (priv->band) {
case IEEE80211_BAND_2GHZ:
/* TODO: this always does G, not a regression */
- if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) {
+ if (priv->active39_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) {
rs_sta->tgg = 1;
rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot;
} else
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
deleted file mode 100644
index b5a66135ded..00000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_3945_rs_h__
-#define __iwl_3945_rs_h__
-
-struct iwl3945_rate_info {
- u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
- u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
- u8 prev_ieee; /* previous rate in IEEE speeds */
- u8 next_ieee; /* next rate in IEEE speeds */
- u8 prev_rs; /* previous rate used in rs algo */
- u8 next_rs; /* next rate used in rs algo */
- u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
- u8 next_rs_tgg; /* next rate used in TGG rs algo */
- u8 table_rs_index; /* index in rate scale table cmd */
- u8 prev_table_rs; /* prev in rate table cmd */
-};
-
-/*
- * These serve as indexes into
- * struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
- */
-enum {
- IWL_RATE_1M_INDEX = 0,
- IWL_RATE_2M_INDEX,
- IWL_RATE_5M_INDEX,
- IWL_RATE_11M_INDEX,
- IWL_RATE_6M_INDEX,
- IWL_RATE_9M_INDEX,
- IWL_RATE_12M_INDEX,
- IWL_RATE_18M_INDEX,
- IWL_RATE_24M_INDEX,
- IWL_RATE_36M_INDEX,
- IWL_RATE_48M_INDEX,
- IWL_RATE_54M_INDEX,
- IWL_RATE_COUNT,
- IWL_RATE_INVM_INDEX,
- IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
-};
-
-enum {
- IWL_RATE_6M_INDEX_TABLE = 0,
- IWL_RATE_9M_INDEX_TABLE,
- IWL_RATE_12M_INDEX_TABLE,
- IWL_RATE_18M_INDEX_TABLE,
- IWL_RATE_24M_INDEX_TABLE,
- IWL_RATE_36M_INDEX_TABLE,
- IWL_RATE_48M_INDEX_TABLE,
- IWL_RATE_54M_INDEX_TABLE,
- IWL_RATE_1M_INDEX_TABLE,
- IWL_RATE_2M_INDEX_TABLE,
- IWL_RATE_5M_INDEX_TABLE,
- IWL_RATE_11M_INDEX_TABLE,
- IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX,
-};
-
-enum {
- IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
- IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
- IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
- IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
-};
-
-/* #define vs. enum to keep from defaulting to 'large integer' */
-#define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX)
-#define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX)
-#define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX)
-#define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX)
-#define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX)
-#define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX)
-#define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX)
-#define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX)
-#define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX)
-#define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX)
-#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
-#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
-
-/* 3945 uCode API values for (legacy) bit rates, both OFDM and CCK */
-enum {
- IWL_RATE_6M_PLCP = 13,
- IWL_RATE_9M_PLCP = 15,
- IWL_RATE_12M_PLCP = 5,
- IWL_RATE_18M_PLCP = 7,
- IWL_RATE_24M_PLCP = 9,
- IWL_RATE_36M_PLCP = 11,
- IWL_RATE_48M_PLCP = 1,
- IWL_RATE_54M_PLCP = 3,
- IWL_RATE_1M_PLCP = 10,
- IWL_RATE_2M_PLCP = 20,
- IWL_RATE_5M_PLCP = 55,
- IWL_RATE_11M_PLCP = 110,
-};
-
-/* MAC header values for bit rates */
-enum {
- IWL_RATE_6M_IEEE = 12,
- IWL_RATE_9M_IEEE = 18,
- IWL_RATE_12M_IEEE = 24,
- IWL_RATE_18M_IEEE = 36,
- IWL_RATE_24M_IEEE = 48,
- IWL_RATE_36M_IEEE = 72,
- IWL_RATE_48M_IEEE = 96,
- IWL_RATE_54M_IEEE = 108,
- IWL_RATE_1M_IEEE = 2,
- IWL_RATE_2M_IEEE = 4,
- IWL_RATE_5M_IEEE = 11,
- IWL_RATE_11M_IEEE = 22,
-};
-
-#define IWL_CCK_BASIC_RATES_MASK \
- (IWL_RATE_1M_MASK | \
- IWL_RATE_2M_MASK)
-
-#define IWL_CCK_RATES_MASK \
- (IWL_BASIC_RATES_MASK | \
- IWL_RATE_5M_MASK | \
- IWL_RATE_11M_MASK)
-
-#define IWL_OFDM_BASIC_RATES_MASK \
- (IWL_RATE_6M_MASK | \
- IWL_RATE_12M_MASK | \
- IWL_RATE_24M_MASK)
-
-#define IWL_OFDM_RATES_MASK \
- (IWL_OFDM_BASIC_RATES_MASK | \
- IWL_RATE_9M_MASK | \
- IWL_RATE_18M_MASK | \
- IWL_RATE_36M_MASK | \
- IWL_RATE_48M_MASK | \
- IWL_RATE_54M_MASK)
-
-#define IWL_BASIC_RATES_MASK \
- (IWL_OFDM_BASIC_RATES_MASK | \
- IWL_CCK_BASIC_RATES_MASK)
-
-#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
-
-#define IWL_INV_TPT -1
-
-#define IWL_MIN_RSSI_VAL -100
-#define IWL_MAX_RSSI_VAL 0
-
-extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
-
-static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
-{
- u8 rate = iwl3945_rates[rate_index].prev_ieee;
-
- if (rate == IWL_RATE_INVALID)
- rate = rate_index;
- return rate;
-}
-
-/**
- * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
- *
- * The specific throughput table used is based on the type of network
- * the associated with, including A, B, G, and G w/ TGG protection
- */
-extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
-
-/**
- * iwl3945_rate_control_register - Register the rate control algorithm callbacks
- *
- * Since the rate control algorithm is hardware specific, there is no need
- * or reason to place it as a stand alone module. The driver can call
- * iwl3945_rate_control_register in order to register the rate control callbacks
- * with the mac80211 subsystem. This should be performed prior to calling
- * ieee80211_register_hw
- *
- */
-extern int iwl3945_rate_control_register(void);
-
-/**
- * iwl3945_rate_control_unregister - Unregister the rate control callbacks
- *
- * This should be called after calling ieee80211_unregister_hw, but before
- * the driver is unloaded.
- */
-extern void iwl3945_rate_control_unregister(void);
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 45cfa1cf194..12f93b6207d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -38,10 +38,15 @@
#include <asm/unaligned.h>
#include <net/mac80211.h>
-#include "iwl-3945-core.h"
+#include "iwl-fh.h"
+#include "iwl-3945-fh.h"
+#include "iwl-commands.h"
+#include "iwl-sta.h"
#include "iwl-3945.h"
+#include "iwl-eeprom.h"
#include "iwl-helpers.h"
-#include "iwl-3945-rs.h"
+#include "iwl-core.h"
+#include "iwl-agn-rs.h"
#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -63,7 +68,7 @@
* maps to IWL_RATE_INVALID
*
*/
-const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
+const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */
IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */
IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */
@@ -91,7 +96,7 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
* Use for only special debugging. This function is just a placeholder as-is,
* you'll need to provide the special bits! ...
* ... and set IWL_EVT_DISABLE to 1. */
-void iwl3945_disable_events(struct iwl3945_priv *priv)
+void iwl3945_disable_events(struct iwl_priv *priv)
{
int ret;
int i;
@@ -150,30 +155,30 @@ void iwl3945_disable_events(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
- ret = iwl3945_grab_nic_access(priv);
+ ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
- disable_ptr = iwl3945_read_targ_mem(priv, base + (4 * sizeof(u32)));
- array_size = iwl3945_read_targ_mem(priv, base + (5 * sizeof(u32)));
- iwl3945_release_nic_access(priv);
+ disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32)));
+ array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32)));
+ iwl_release_nic_access(priv);
if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
IWL_DEBUG_INFO("Disabling selected uCode log events at 0x%x\n",
disable_ptr);
- ret = iwl3945_grab_nic_access(priv);
+ ret = iwl_grab_nic_access(priv);
for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
- iwl3945_write_targ_mem(priv,
+ iwl_write_targ_mem(priv,
disable_ptr + (i * sizeof(u32)),
evt_disable[i]);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
} else {
IWL_DEBUG_INFO("Selected uCode log events may be disabled\n");
IWL_DEBUG_INFO(" by writing \"1\"s into disable bitmap\n");
@@ -193,40 +198,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
return -1;
}
-/**
- * iwl3945_get_antenna_flags - Get antenna flags for RXON command
- * @priv: eeprom and antenna fields are used to determine antenna flags
- *
- * priv->eeprom is used to determine if antenna AUX/MAIN are reversed
- * priv->antenna specifies the antenna diversity mode:
- *
- * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
- * IWL_ANTENNA_MAIN - Force MAIN antenna
- * IWL_ANTENNA_AUX - Force AUX antenna
- */
-__le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
-{
- switch (priv->antenna) {
- case IWL_ANTENNA_DIVERSITY:
- return 0;
-
- case IWL_ANTENNA_MAIN:
- if (priv->eeprom.antenna_switch_type)
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
-
- case IWL_ANTENNA_AUX:
- if (priv->eeprom.antenna_switch_type)
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
- }
-
- /* bad antenna selector value */
- IWL_ERROR("Bad antenna selector value (0x%x)\n", priv->antenna);
- return 0; /* "diversity" is default if error */
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
static const char *iwl3945_get_tx_fail_reason(u32 status)
@@ -266,7 +238,7 @@ static inline const char *iwl3945_get_tx_fail_reason(u32 status)
* for A and B mode we need to overright prev
* value
*/
-int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
+int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
{
int next_rate = iwl3945_get_prev_ieee_rate(rate);
@@ -300,12 +272,12 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
* need to be reclaimed. As result, some free space forms. If there is
* enough free space (> low mark), wake the stack that feeds us.
*/
-static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
+static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
int txq_id, int index)
{
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
- struct iwl3945_queue *q = &txq->q;
- struct iwl3945_tx_info *tx_info;
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+ struct iwl_tx_info *tx_info;
BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
@@ -315,10 +287,10 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
tx_info = &txq->txb[txq->q.read_ptr];
ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
tx_info->skb[0] = NULL;
- iwl3945_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
}
- if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
+ if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
(txq_id != IWL_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
ieee80211_wake_queue(priv->hw, txq_id);
@@ -327,22 +299,22 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
/**
* iwl3945_rx_reply_tx - Handle Tx response
*/
-static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int index = SEQ_TO_INDEX(sequence);
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info;
struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->status);
int rate_idx;
int fail;
- if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -374,7 +346,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
iwl3945_tx_queue_reclaim(priv, txq_id, index);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
@@ -387,14 +359,14 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
*
*****************************************************************************/
-void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
+void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
(int)sizeof(struct iwl3945_notif_statistics),
le32_to_cpu(pkt->len));
- memcpy(&priv->statistics, pkt->u.raw, sizeof(priv->statistics));
+ memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
iwl3945_led_background(priv);
@@ -406,7 +378,7 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b
* Misc. internal state and helper functions
*
******************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
/**
* iwl3945_report_frame - dump frame to syslog during debug sessions
@@ -415,8 +387,8 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b
* including selective frame dumps.
* group100 parameter selects whether to show 1 out of 100 good frames.
*/
-static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
- struct iwl3945_rx_packet *pkt,
+static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
struct ieee80211_hdr *header, int group100)
{
u32 to_us;
@@ -540,18 +512,27 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
}
}
if (print_dump)
- iwl3945_print_hex_dump(IWL_DL_RX, data, length);
+ iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
+}
+
+static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
+ struct ieee80211_hdr *header, int group100)
+{
+ if (priv->debug_level & IWL_DL_RX)
+ _iwl3945_dbg_report_frame(priv, pkt, header, group100);
}
+
#else
-static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
- struct iwl3945_rx_packet *pkt,
+static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
struct ieee80211_hdr *header, int group100)
{
}
#endif
/* This is necessary only for a number of statistics, see the caller. */
-static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
+static int iwl3945_is_network_packet(struct iwl_priv *priv,
struct ieee80211_hdr *header)
{
/* Filter incoming packets to determine if they are targeted toward
@@ -568,11 +549,11 @@ static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
}
}
-static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb,
+static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb,
struct ieee80211_rx_status *stats)
{
- struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
#ifdef CONFIG_IWL3945_LEDS
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
#endif
@@ -581,7 +562,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
short len = le16_to_cpu(rx_hdr->len);
/* We received data from the HW, so stop the watchdog */
- if (unlikely((len + IWL_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
+ if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
IWL_DEBUG_DROP("Corruption detected!\n");
return;
}
@@ -597,7 +578,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
/* Set the size of the skb to the size of the frame */
skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
- if (iwl3945_param_hwcrypto)
+ if (!iwl3945_mod_params.sw_crypto)
iwl3945_set_decrypted_flag(priv, rxb->skb,
le32_to_cpu(rx_end->status), stats);
@@ -611,12 +592,12 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct ieee80211_hdr *header;
struct ieee80211_rx_status rx_status;
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
@@ -659,7 +640,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
/* Convert 3945's rssi indicator to dBm */
- rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
+ rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET;
/* Set default noise value to -127 */
if (priv->last_rx_noise == 0)
@@ -705,11 +686,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
rx_status.signal, rx_status.signal,
rx_status.noise, rx_status.rate_idx);
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_RX))
- /* Set "1" to report good data frames in groups of 100 */
- iwl3945_dbg_report_frame(priv, pkt, header, 1);
-#endif
+ /* Set "1" to report good data frames in groups of 100 */
+ iwl3945_dbg_report_frame(priv, pkt, header, 1);
if (network_packet) {
priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
@@ -721,24 +699,31 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
}
-int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
- dma_addr_t addr, u16 len)
+int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len, u8 reset, u8 pad)
{
int count;
- u32 pad;
- struct iwl3945_tfd_frame *tfd = (struct iwl3945_tfd_frame *)ptr;
+ struct iwl_queue *q;
+ struct iwl3945_tfd *tfd, *tfd_tmp;
+
+ q = &txq->q;
+ tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+ tfd = &tfd_tmp[q->write_ptr];
+
+ if (reset)
+ memset(tfd, 0, sizeof(*tfd));
count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
- pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags));
if ((count >= NUM_TFD_CHUNKS) || (count < 0)) {
- IWL_ERROR("Error can not send more than %d chunks\n",
+ IWL_ERR(priv, "Error can not send more than %d chunks\n",
NUM_TFD_CHUNKS);
return -EINVAL;
}
- tfd->pa[count].addr = cpu_to_le32(addr);
- tfd->pa[count].len = cpu_to_le32(len);
+ tfd->tbs[count].addr = cpu_to_le32(addr);
+ tfd->tbs[count].len = cpu_to_le32(len);
count++;
@@ -753,10 +738,10 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
*
* Does NOT advance any indexes
*/
-int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
+void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
- struct iwl3945_tfd_frame *bd_tmp = (struct iwl3945_tfd_frame *)&txq->bd[0];
- struct iwl3945_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
+ struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+ struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr];
struct pci_dev *dev = priv->pci_dev;
int i;
int counter;
@@ -764,21 +749,21 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *
/* classify bd */
if (txq->q.id == IWL_CMD_QUEUE_NUM)
/* nothing to cleanup after for host commands */
- return 0;
+ return;
/* sanity check */
- counter = TFD_CTL_COUNT_GET(le32_to_cpu(bd->control_flags));
+ counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
if (counter > NUM_TFD_CHUNKS) {
- IWL_ERROR("Too many chunks: %i\n", counter);
+ IWL_ERR(priv, "Too many chunks: %i\n", counter);
/* @todo issue fatal error, it is quite serious situation */
- return 0;
+ return;
}
/* unmap chunks if any */
for (i = 1; i < counter; i++) {
- pci_unmap_single(dev, le32_to_cpu(bd->pa[i].addr),
- le32_to_cpu(bd->pa[i].len), PCI_DMA_TODEVICE);
+ pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr),
+ le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE);
if (txq->txb[txq->q.read_ptr].skb[0]) {
struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0];
if (txq->txb[txq->q.read_ptr].skb[0]) {
@@ -788,10 +773,10 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *
}
}
}
- return 0;
+ return ;
}
-u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
+u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
{
int i, start = IWL_AP_ID;
int ret = IWL_INVALID_STATION;
@@ -802,13 +787,13 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
start = IWL_STA_ID;
if (is_broadcast_ether_addr(addr))
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
spin_lock_irqsave(&priv->sta_lock, flags);
- for (i = start; i < priv->hw_setting.max_stations; i++)
- if ((priv->stations[i].used) &&
+ for (i = start; i < priv->hw_params.max_stations; i++)
+ if ((priv->stations_39[i].used) &&
(!compare_ether_addr
- (priv->stations[i].sta.sta.addr, addr))) {
+ (priv->stations_39[i].sta.sta.addr, addr))) {
ret = i;
goto out;
}
@@ -824,12 +809,10 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
* iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
*
*/
-void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr, int sta_id, int tx_id)
{
- unsigned long flags;
u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
u16 rate_mask;
@@ -838,25 +821,15 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
u8 data_retry_limit;
__le32 tx_flags;
__le16 fc = hdr->frame_control;
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
rate = iwl3945_rates[rate_index].plcp;
- tx_flags = cmd->cmd.tx.tx_flags;
+ tx_flags = tx->tx_flags;
/* We need to figure out how to get the sta->supp_rates while
* in this running context */
rate_mask = IWL_RATES_MASK;
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- priv->stations[sta_id].current_rate.rate_n_flags = rate;
-
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
- (sta_id != priv->hw_setting.bcast_sta_id) &&
- (sta_id != IWL_MULTICAST_ID))
- priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate;
-
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
if (tx_id >= IWL_CMD_QUEUE_NUM)
rts_retry_limit = 3;
else
@@ -888,25 +861,25 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
}
}
- cmd->cmd.tx.rts_retry_limit = rts_retry_limit;
- cmd->cmd.tx.data_retry_limit = data_retry_limit;
- cmd->cmd.tx.rate = rate;
- cmd->cmd.tx.tx_flags = tx_flags;
+ tx->rts_retry_limit = rts_retry_limit;
+ tx->data_retry_limit = data_retry_limit;
+ tx->rate = rate;
+ tx->tx_flags = tx_flags;
/* OFDM */
- cmd->cmd.tx.supp_rates[0] =
+ tx->supp_rates[0] =
((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
/* CCK */
- cmd->cmd.tx.supp_rates[1] = (rate_mask & 0xF);
+ tx->supp_rates[1] = (rate_mask & 0xF);
IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
"cck/ofdm mask: 0x%x/0x%x\n", sta_id,
- cmd->cmd.tx.rate, le32_to_cpu(cmd->cmd.tx.tx_flags),
- cmd->cmd.tx.supp_rates[1], cmd->cmd.tx.supp_rates[0]);
+ tx->rate, le32_to_cpu(tx->tx_flags),
+ tx->supp_rates[1], tx->supp_rates[0]);
}
-u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags)
+u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
{
unsigned long flags_spin;
struct iwl3945_station_entry *station;
@@ -915,56 +888,56 @@ u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags
return IWL_INVALID_STATION;
spin_lock_irqsave(&priv->sta_lock, flags_spin);
- station = &priv->stations[sta_id];
+ station = &priv->stations_39[sta_id];
station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
station->sta.rate_n_flags = cpu_to_le16(tx_rate);
- station->current_rate.rate_n_flags = tx_rate;
station->sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- iwl3945_send_add_station(priv, &station->sta, flags);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&station->sta, flags);
IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n",
sta_id, tx_rate);
return sta_id;
}
-static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max)
+static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- if (!pwr_max) {
+ if (src == IWL_PWR_SRC_VAUX) {
u32 val;
rc = pci_read_config_dword(priv->pci_dev,
PCI_POWER_SOURCE, &val);
if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
- iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
~APMG_PS_CTRL_MSK_PWR_SRC);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
- iwl3945_poll_bit(priv, CSR_GPIO_IN,
+ iwl_poll_bit(priv, CSR_GPIO_IN,
CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
CSR_GPIO_IN_BIT_AUX_POWER, 5000);
} else
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
} else {
- iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~APMG_PS_CTRL_MSK_PWR_SRC);
- iwl3945_release_nic_access(priv);
- iwl3945_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
+ iwl_release_nic_access(priv);
+ iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -972,81 +945,79 @@ static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max)
return rc;
}
-static int iwl3945_rx_init(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
+static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr);
- iwl3945_write_direct32(priv, FH_RCSR_RPTR_ADDR(0),
- priv->hw_setting.shared_phys +
- offsetof(struct iwl3945_shared, rx_read_ptr[0]));
- iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), 0);
- iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0),
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
- ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
- (RX_QUEUE_SIZE_LOG << ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
- (1 << ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
+ iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr);
+ iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
+ iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
+ iwl_write_direct32(priv, FH39_RCSR_CONFIG(0),
+ FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
+ FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
+ FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
+ FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
+ (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
+ FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
+ (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
+ FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
/* fake read to flush all prev I/O */
- iwl3945_read_direct32(priv, FH_RSSR_CTRL);
+ iwl_read_direct32(priv, FH39_RSSR_CTRL);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-static int iwl3945_tx_reset(struct iwl3945_priv *priv)
+static int iwl3945_tx_reset(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
/* bypass mode */
- iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
+ iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
/* RA 0 is active */
- iwl3945_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
+ iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
/* all 6 fifo are active */
- iwl3945_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
-
- iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
- iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
- iwl3945_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
- iwl3945_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
-
- iwl3945_write_direct32(priv, FH_TSSR_CBB_BASE,
- priv->hw_setting.shared_phys);
-
- iwl3945_write_direct32(priv, FH_TSSR_MSG_CONFIG,
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
-
- iwl3945_release_nic_access(priv);
+ iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
+
+ iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
+ iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
+ iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
+ iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
+
+ iwl_write_direct32(priv, FH39_TSSR_CBB_BASE,
+ priv->shared_phys);
+
+ iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
+
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
@@ -1057,7 +1028,7 @@ static int iwl3945_tx_reset(struct iwl3945_priv *priv)
*
* Destroys all DMA structures and initialize them again
*/
-static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
+static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
{
int rc;
int txq_id, slots_num;
@@ -1073,10 +1044,10 @@ static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
- txq_id);
+ rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
+ txq_id);
if (rc) {
- IWL_ERROR("Tx %d queue init failed\n", txq_id);
+ IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
goto error;
}
}
@@ -1088,111 +1059,140 @@ static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
return rc;
}
-int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
+static int iwl3945_apm_init(struct iwl_priv *priv)
{
- u8 rev_id;
- int rc;
- unsigned long flags;
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ int ret = 0;
iwl3945_power_init_handle(priv);
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL);
- iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- rc = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+ /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+
+ /* set "initialization complete" bit to move adapter
+ * D0U* --> D0A* state */
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+ iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ if (ret < 0) {
IWL_DEBUG_INFO("Failed to init the card\n");
- return rc;
+ goto out;
}
- rc = iwl3945_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
- iwl3945_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT |
- APMG_CLK_VAL_BSM_CLK_RQT);
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ goto out;
+
+ /* enable DMA */
+ iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
+ APMG_CLK_VAL_BSM_CLK_RQT);
+
udelay(20);
- iwl3945_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
- APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwl3945_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
- /* Determine HW type */
- rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
- if (rc)
- return rc;
- IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id);
+ /* disable L1-Active */
+ iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
+ APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+ iwl_release_nic_access(priv);
+out:
+ return ret;
+}
+
+static void iwl3945_nic_config(struct iwl_priv *priv)
+{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ unsigned long flags;
+ u8 rev_id = 0;
- iwl3945_nic_set_pwr_src(priv, 1);
spin_lock_irqsave(&priv->lock, flags);
if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
IWL_DEBUG_INFO("RTP type \n");
else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
IWL_DEBUG_INFO("3945 RADIO-MB type\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_3945_MB);
} else {
IWL_DEBUG_INFO("3945 RADIO-MM type\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);
}
- if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) {
+ if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) {
IWL_DEBUG_INFO("SKU OP mode is mrc\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);
} else
IWL_DEBUG_INFO("SKU OP mode is basic\n");
- if ((priv->eeprom.board_revision & 0xF0) == 0xD0) {
+ if ((eeprom->board_revision & 0xF0) == 0xD0) {
IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
- priv->eeprom.board_revision);
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ eeprom->board_revision);
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
} else {
IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
- priv->eeprom.board_revision);
- iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+ eeprom->board_revision);
+ iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
}
- if (priv->eeprom.almgor_m_version <= 1) {
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ if (eeprom->almgor_m_version <= 1) {
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
IWL_DEBUG_INFO("Card M type A version is 0x%X\n",
- priv->eeprom.almgor_m_version);
+ eeprom->almgor_m_version);
} else {
IWL_DEBUG_INFO("Card M type B version is 0x%X\n",
- priv->eeprom.almgor_m_version);
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ eeprom->almgor_m_version);
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
}
spin_unlock_irqrestore(&priv->lock, flags);
- if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
+ if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n");
- if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
+ if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n");
+}
+
+int iwl3945_hw_nic_init(struct iwl_priv *priv)
+{
+ u8 rev_id;
+ int rc;
+ unsigned long flags;
+ struct iwl_rx_queue *rxq = &priv->rxq;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->cfg->ops->lib->apm_ops.init(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* Determine HW type */
+ rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+ if (rc)
+ return rc;
+ IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id);
+
+ rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
+ if(rc)
+ return rc;
+
+ priv->cfg->ops->lib->apm_ops.config(priv);
/* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) {
- rc = iwl3945_rx_queue_alloc(priv);
+ rc = iwl_rx_queue_alloc(priv);
if (rc) {
- IWL_ERROR("Unable to initialize Rx queue\n");
+ IWL_ERR(priv, "Unable to initialize Rx queue\n");
return -ENOMEM;
}
} else
- iwl3945_rx_queue_reset(priv, rxq);
+ iwl_rx_queue_reset(priv, rxq);
iwl3945_rx_replenish(priv);
@@ -1202,16 +1202,16 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
/* Look at using this instead:
rxq->need_update = 1;
- iwl3945_rx_queue_update_write_ptr(priv, rxq);
+ iwl_rx_queue_update_write_ptr(priv, rxq);
*/
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), rxq->write & ~7);
- iwl3945_release_nic_access(priv);
+ iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1229,116 +1229,121 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
*
* Destroy all TX DMA queues and structures
*/
-void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv)
+void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
{
int txq_id;
/* Tx queues */
for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
- iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
+ iwl_tx_queue_free(priv, txq_id);
}
-void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv)
+void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
{
- int queue;
+ int txq_id;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- if (iwl3945_grab_nic_access(priv)) {
+ if (iwl_grab_nic_access(priv)) {
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_free(priv);
return;
}
/* stop SCD */
- iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0);
+ iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
/* reset TFD queues */
- for (queue = TFD_QUEUE_MIN; queue < TFD_QUEUE_MAX; queue++) {
- iwl3945_write_direct32(priv, FH_TCSR_CONFIG(queue), 0x0);
- iwl3945_poll_direct_bit(priv, FH_TSSR_TX_STATUS,
- ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(queue),
+ for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
+ iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
+ iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
+ FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1000);
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_free(priv);
}
-int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv)
+static int iwl3945_apm_stop_master(struct iwl_priv *priv)
{
- int rc = 0;
- u32 reg_val;
+ int ret = 0;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
/* set stop master bit */
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
- reg_val = iwl3945_read32(priv, CSR_GP_CNTRL);
+ iwl_poll_direct_bit(priv, CSR_RESET,
+ CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE ==
- (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE))
- IWL_DEBUG_INFO("Card in power save, master is already "
- "stopped\n");
- else {
- rc = iwl3945_poll_direct_bit(priv, CSR_RESET,
- CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
- }
+ if (ret < 0)
+ goto out;
+out:
spin_unlock_irqrestore(&priv->lock, flags);
IWL_DEBUG_INFO("stop master\n");
- return rc;
+ return ret;
+}
+
+static void iwl3945_apm_stop(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ iwl3945_apm_stop_master(priv);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+ udelay(10);
+ /* clear "init complete" move adapter D0A* --> D0U state */
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
-int iwl3945_hw_nic_reset(struct iwl3945_priv *priv)
+static int iwl3945_apm_reset(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
- iwl3945_hw_nic_stop_master(priv);
+ iwl3945_apm_stop_master(priv);
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+ udelay(10);
- iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+ iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (!rc) {
- iwl3945_write_prph(priv, APMG_CLK_CTRL_REG,
+ iwl_write_prph(priv, APMG_CLK_CTRL_REG,
APMG_CLK_VAL_BSM_CLK_RQT);
- udelay(10);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
- iwl3945_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
- iwl3945_write_prph(priv, APMG_RTC_INT_STT_REG,
+ iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
+ iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
0xFFFFFFFF);
/* enable DMA */
- iwl3945_write_prph(priv, APMG_CLK_EN_REG,
+ iwl_write_prph(priv, APMG_CLK_EN_REG,
APMG_CLK_VAL_DMA_CLK_RQT |
APMG_CLK_VAL_BSM_CLK_RQT);
udelay(10);
- iwl3945_set_bits_prph(priv, APMG_PS_CTRL_REG,
+ iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ);
udelay(5);
- iwl3945_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+ iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
/* Clear the 'host command active' bit... */
@@ -1367,17 +1372,18 @@ static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
}
-int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
+int iwl3945_hw_get_temperature(struct iwl_priv *priv)
{
- return iwl3945_read32(priv, CSR_UCODE_DRV_GP2);
+ return iwl_read32(priv, CSR_UCODE_DRV_GP2);
}
/**
* iwl3945_hw_reg_txpower_get_temperature
* get the current temperature by reading from NIC
*/
-static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
+static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int temperature;
temperature = iwl3945_hw_get_temperature(priv);
@@ -1388,12 +1394,12 @@ static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
/* handle insane temp reading */
if (iwl3945_hw_reg_temp_out_of_range(temperature)) {
- IWL_ERROR("Error bad temperature value %d\n", temperature);
+ IWL_ERR(priv, "Error bad temperature value %d\n", temperature);
/* if really really hot(?),
* substitute the 3rd band/group's temp measured at factory */
if (priv->last_temperature > 100)
- temperature = priv->eeprom.groups[2].temperature;
+ temperature = eeprom->groups[2].temperature;
else /* else use most recent "sane" value from driver */
temperature = priv->last_temperature;
}
@@ -1412,7 +1418,7 @@ static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
* records new temperature in tx_mgr->temperature.
* replaces tx_mgr->last_temperature *only* if calib needed
* (assumes caller will actually do the calibration!). */
-static int is_temp_calib_needed(struct iwl3945_priv *priv)
+static int is_temp_calib_needed(struct iwl_priv *priv)
{
int temp_diff;
@@ -1627,9 +1633,9 @@ static inline u8 iwl3945_hw_reg_fix_power_index(int index)
* Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK)
* or 6 Mbit (OFDM) rates.
*/
-static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tbl_index,
+static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
s32 rate_index, const s8 *clip_pwrs,
- struct iwl3945_channel_info *ch_info,
+ struct iwl_channel_info *ch_info,
int band_index)
{
struct iwl3945_scan_power_info *scan_power_info;
@@ -1646,7 +1652,7 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tb
/* further limit to user's max power preference.
* FIXME: Other spectrum management power limitations do not
* seem to apply?? */
- power = min(power, priv->user_txpower_limit);
+ power = min(power, priv->tx_power_user_lmt);
scan_power_info->requested_power = power;
/* find difference between new scan *power* and current "normal"
@@ -1678,27 +1684,27 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tb
}
/**
- * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings
+ * iwl3945_send_tx_power - fill in Tx Power command with gain settings
*
* Configures power settings for all rates for the current channel,
* using values from channel info struct, and send to NIC
*/
-int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
+int iwl3945_send_tx_power(struct iwl_priv *priv)
{
int rate_idx, i;
- const struct iwl3945_channel_info *ch_info = NULL;
+ const struct iwl_channel_info *ch_info = NULL;
struct iwl3945_txpowertable_cmd txpower = {
- .channel = priv->active_rxon.channel,
+ .channel = priv->active39_rxon.channel,
};
txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
- ch_info = iwl3945_get_channel_info(priv,
+ ch_info = iwl_get_channel_info(priv,
priv->band,
- le16_to_cpu(priv->active_rxon.channel));
+ le16_to_cpu(priv->active39_rxon.channel));
if (!ch_info) {
- IWL_ERROR
- ("Failed to get channel info for channel %d [%d]\n",
- le16_to_cpu(priv->active_rxon.channel), priv->band);
+ IWL_ERR(priv,
+ "Failed to get channel info for channel %d [%d]\n",
+ le16_to_cpu(priv->active39_rxon.channel), priv->band);
return -EINVAL;
}
@@ -1711,7 +1717,7 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
/* fill cmd with power settings for all rates for current channel */
/* Fill OFDM rate */
for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0;
- rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) {
+ rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) {
txpower.power[i].tpc = ch_info->power_info[i].tpc;
txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
@@ -1737,8 +1743,9 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
txpower.power[i].rate);
}
- return iwl3945_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
- sizeof(struct iwl3945_txpowertable_cmd), &txpower);
+ return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
+ sizeof(struct iwl3945_txpowertable_cmd),
+ &txpower);
}
@@ -1758,8 +1765,8 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
* properly fill out the scan powers, and actual h/w gain settings,
* and send changes to NIC
*/
-static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
- struct iwl3945_channel_info *ch_info)
+static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv,
+ struct iwl_channel_info *ch_info)
{
struct iwl3945_channel_power_info *power_info;
int power_changed = 0;
@@ -1768,7 +1775,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
int power;
/* Get this chnlgrp's rate-to-max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* Get this channel's rate-to-current-power settings table */
power_info = ch_info->power_info;
@@ -1821,7 +1828,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
* based strictly on regulatory (eeprom and spectrum mgt) limitations
* (no consideration for h/w clipping limitations).
*/
-static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_info)
+static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
{
s8 max_power;
@@ -1849,9 +1856,10 @@ static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_i
*
* If RxOn is "associated", this sends the new Txpower to NIC!
*/
-static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
+static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
{
- struct iwl3945_channel_info *ch_info = NULL;
+ struct iwl_channel_info *ch_info = NULL;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int delta_index;
const s8 *clip_pwrs; /* array of h/w max power levels for each rate */
u8 a_band;
@@ -1867,7 +1875,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
a_band = is_channel_a_band(ch_info);
/* Get this chnlgrp's factory calibration temperature */
- ref_temp = (s16)priv->eeprom.groups[ch_info->group_index].
+ ref_temp = (s16)eeprom->groups[ch_info->group_index].
temperature;
/* get power index adjustment based on current and factory
@@ -1893,7 +1901,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
}
/* Get this chnlgrp's rate-to-max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */
for (scan_tbl_index = 0;
@@ -1907,24 +1915,24 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
}
/* send Txpower command for current channel to ucode */
- return iwl3945_hw_reg_send_txpower(priv);
+ return priv->cfg->ops->lib->send_tx_power(priv);
}
-int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
+int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
{
- struct iwl3945_channel_info *ch_info;
+ struct iwl_channel_info *ch_info;
s8 max_power;
u8 a_band;
u8 i;
- if (priv->user_txpower_limit == power) {
+ if (priv->tx_power_user_lmt == power) {
IWL_DEBUG_POWER("Requested Tx power same as current "
"limit: %ddBm.\n", power);
return 0;
}
IWL_DEBUG_POWER("Setting upper limit clamp to %ddBm.\n", power);
- priv->user_txpower_limit = power;
+ priv->tx_power_user_lmt = power;
/* set up new Tx powers for each and every channel, 2.4 and 5.x */
@@ -1953,7 +1961,7 @@ int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
}
/* will add 3945 channel switch cmd handling later */
-int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
+int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
{
return 0;
}
@@ -1968,7 +1976,7 @@ int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
* -- send new set of gain settings to NIC
* NOTE: This should continue working, even when we're not associated,
* so we can keep our internal table of scan powers current. */
-void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
+void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
{
/* This will kick in the "brute force"
* iwl3945_hw_reg_comp_txpower_temp() below */
@@ -1987,7 +1995,7 @@ void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv,
+ struct iwl_priv *priv = container_of(work, struct iwl_priv,
thermal_periodic.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -2009,10 +2017,11 @@ static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
* on A-band, EEPROM's "group frequency" entries represent the top
* channel in each group 1-4. Group 5 All B/G channels are in group 0.
*/
-static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
- const struct iwl3945_channel_info *ch_info)
+static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
+ const struct iwl_channel_info *ch_info)
{
- struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0];
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0];
u8 group;
u16 group_index = 0; /* based on factory calib frequencies */
u8 grp_channel;
@@ -2043,11 +2052,12 @@ static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
* Interpolate to get nominal (i.e. at factory calibration temperature) index
* into radio/DSP gain settings table for requested power.
*/
-static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
+static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv,
s8 requested_power,
s32 setting_index, s32 *new_index)
{
const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
s32 index0, index1;
s32 power = 2 * requested_power;
s32 i;
@@ -2056,7 +2066,7 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
s32 res;
s32 denominator;
- chnl_grp = &priv->eeprom.groups[setting_index];
+ chnl_grp = &eeprom->groups[setting_index];
samples = chnl_grp->samples;
for (i = 0; i < 5; i++) {
if (power == samples[i].power) {
@@ -2091,10 +2101,11 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
return 0;
}
-static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
+static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
{
u32 i;
s32 rate_index;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
const struct iwl3945_eeprom_txpower_group *group;
IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n");
@@ -2102,11 +2113,11 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) {
s8 *clip_pwrs; /* table of power levels for each rate */
s8 satur_pwr; /* saturation power for each chnl group */
- group = &priv->eeprom.groups[i];
+ group = &eeprom->groups[i];
/* sanity check on factory saturation power value */
if (group->saturation_power < 40) {
- IWL_WARNING("Error: saturation power is %d, "
+ IWL_WARN(priv, "Error: saturation power is %d, "
"less than minimum expected 40\n",
group->saturation_power);
return;
@@ -2121,7 +2132,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
* power peaks, without too much distortion (clipping).
*/
/* we'll fill in this array with h/w max power levels */
- clip_pwrs = (s8 *) priv->clip_groups[i].clip_powers;
+ clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers;
/* divide factory saturation power by 2 to find -3dB level */
satur_pwr = (s8) (group->saturation_power >> 1);
@@ -2171,10 +2182,11 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
*
* This does *not* write values to NIC, just sets up our internal table.
*/
-int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
+int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
{
- struct iwl3945_channel_info *ch_info = NULL;
+ struct iwl_channel_info *ch_info = NULL;
struct iwl3945_channel_power_info *pwr_info;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int delta_index;
u8 rate_index;
u8 scan_tbl_index;
@@ -2204,12 +2216,12 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
/* Get this chnlgrp's rate->max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* calculate power index *adjustment* value according to
* diff between current temperature and factory temperature */
delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
- priv->eeprom.groups[ch_info->group_index].
+ eeprom->groups[ch_info->group_index].
temperature);
IWL_DEBUG_POWER("Delta index for channel %d: %d [%d]\n",
@@ -2235,7 +2247,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
ch_info->group_index,
&power_idx);
if (rc) {
- IWL_ERROR("Invalid power index\n");
+ IWL_ERR(priv, "Invalid power index\n");
return rc;
}
pwr_info->base_power_index = (u8) power_idx;
@@ -2295,75 +2307,88 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
return 0;
}
-int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv)
+int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0);
- rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS,
- FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
+ iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
+ rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
+ FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
if (rc < 0)
- IWL_ERROR("Can't stop Rx DMA.\n");
+ IWL_ERR(priv, "Can't stop Rx DMA.\n");
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
+int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
int rc;
unsigned long flags;
int txq_id = txq->q.id;
- struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
+ struct iwl3945_shared *shared_data = priv->shared_virt;
shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_CBCC_CTRL(txq_id), 0);
- iwl3945_write_direct32(priv, FH_CBCC_BASE(txq_id), 0);
+ iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
+ iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
- iwl3945_write_direct32(priv, FH_TCSR_CONFIG(txq_id),
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
- iwl3945_release_nic_access(priv);
+ iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id),
+ FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
+ FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
+ FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
+ FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
+ FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
+ iwl_release_nic_access(priv);
/* fake read to flush all prev. writes */
- iwl3945_read32(priv, FH_TSSR_CBB_BASE);
+ iwl_read32(priv, FH39_TSSR_CBB_BASE);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv)
+/*
+ * HCMD utils
+ */
+static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
{
- struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
+ switch (cmd_id) {
+ case REPLY_RXON:
+ return (u16) sizeof(struct iwl3945_rxon_cmd);
+ default:
+ return len;
+ }
+}
- return le32_to_cpu(shared_data->rx_read_ptr[0]);
+static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+{
+ u16 size = (u16)sizeof(struct iwl3945_addsta_cmd);
+ memcpy(data, cmd, size);
+ return size;
}
/**
* iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
*/
-int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
+int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
{
int rc, i, index, prev_index;
struct iwl3945_rate_scaling_cmd rate_cmd = {
@@ -2428,47 +2453,48 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
/* Update the rate scaling for control frame Tx */
rate_cmd.table_id = 0;
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+ rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
&rate_cmd);
if (rc)
return rc;
/* Update the rate scaling for data frame Tx */
rate_cmd.table_id = 1;
- return iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+ return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
&rate_cmd);
}
/* Called when initializing driver */
-int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv)
+int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
{
- memset((void *)&priv->hw_setting, 0,
- sizeof(struct iwl3945_driver_hw_info));
+ memset((void *)&priv->hw_params, 0,
+ sizeof(struct iwl_hw_params));
- priv->hw_setting.shared_virt =
+ priv->shared_virt =
pci_alloc_consistent(priv->pci_dev,
sizeof(struct iwl3945_shared),
- &priv->hw_setting.shared_phys);
+ &priv->shared_phys);
- if (!priv->hw_setting.shared_virt) {
- IWL_ERROR("failed to allocate pci memory\n");
+ if (!priv->shared_virt) {
+ IWL_ERR(priv, "failed to allocate pci memory\n");
mutex_unlock(&priv->mutex);
return -ENOMEM;
}
- priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE;
- priv->hw_setting.max_pkt_size = 2342;
- priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd);
- priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
- priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
- priv->hw_setting.max_stations = IWL3945_STATION_COUNT;
- priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID;
+ priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
+ priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
+ priv->hw_params.max_pkt_size = 2342;
+ priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
+ priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
+ priv->hw_params.max_stations = IWL3945_STATION_COUNT;
+ priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID;
+
+ priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
- priv->hw_setting.tx_ant_num = 2;
return 0;
}
-unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl3945_frame *frame, u8 rate)
{
struct iwl3945_tx_beacon_cmd *tx_beacon_cmd;
@@ -2477,7 +2503,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
- tx_beacon_cmd->tx.sta_id = priv->hw_setting.bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl3945_fill_beacon_frame(priv,
@@ -2501,37 +2527,261 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
}
-void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
+void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv)
{
priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
}
-void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv)
+void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv)
{
INIT_DELAYED_WORK(&priv->thermal_periodic,
iwl3945_bg_reg_txpower_periodic);
}
-void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv)
+void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv)
{
cancel_delayed_work(&priv->thermal_periodic);
}
-static struct iwl_3945_cfg iwl3945_bg_cfg = {
+/* check contents of special bootstrap uCode SRAM */
+static int iwl3945_verify_bsm(struct iwl_priv *priv)
+ {
+ __le32 *image = priv->ucode_boot.v_addr;
+ u32 len = priv->ucode_boot.len;
+ u32 reg;
+ u32 val;
+
+ IWL_DEBUG_INFO("Begin verify bsm\n");
+
+ /* verify BSM SRAM contents */
+ val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
+ for (reg = BSM_SRAM_LOWER_BOUND;
+ reg < BSM_SRAM_LOWER_BOUND + len;
+ reg += sizeof(u32), image++) {
+ val = iwl_read_prph(priv, reg);
+ if (val != le32_to_cpu(*image)) {
+ IWL_ERR(priv, "BSM uCode verification failed at "
+ "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
+ BSM_SRAM_LOWER_BOUND,
+ reg - BSM_SRAM_LOWER_BOUND, len,
+ val, le32_to_cpu(*image));
+ return -EIO;
+ }
+ }
+
+ IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
+
+ return 0;
+}
+
+
+/******************************************************************************
+ *
+ * EEPROM related functions
+ *
+ ******************************************************************************/
+
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism. Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+ _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+ return 0;
+}
+
+
+static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+ return;
+}
+
+ /**
+ * iwl3945_load_bsm - Load bootstrap instructions
+ *
+ * BSM operation:
+ *
+ * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
+ * in special SRAM that does not power down during RFKILL. When powering back
+ * up after power-saving sleeps (or during initial uCode load), the BSM loads
+ * the bootstrap program into the on-board processor, and starts it.
+ *
+ * The bootstrap program loads (via DMA) instructions and data for a new
+ * program from host DRAM locations indicated by the host driver in the
+ * BSM_DRAM_* registers. Once the new program is loaded, it starts
+ * automatically.
+ *
+ * When initializing the NIC, the host driver points the BSM to the
+ * "initialize" uCode image. This uCode sets up some internal data, then
+ * notifies host via "initialize alive" that it is complete.
+ *
+ * The host then replaces the BSM_DRAM_* pointer values to point to the
+ * normal runtime uCode instructions and a backup uCode data cache buffer
+ * (filled initially with starting data values for the on-board processor),
+ * then triggers the "initialize" uCode to load and launch the runtime uCode,
+ * which begins normal operation.
+ *
+ * When doing a power-save shutdown, runtime uCode saves data SRAM into
+ * the backup data cache in DRAM before SRAM is powered down.
+ *
+ * When powering back up, the BSM loads the bootstrap program. This reloads
+ * the runtime uCode instructions and the backup data cache into SRAM,
+ * and re-launches the runtime uCode from where it left off.
+ */
+static int iwl3945_load_bsm(struct iwl_priv *priv)
+{
+ __le32 *image = priv->ucode_boot.v_addr;
+ u32 len = priv->ucode_boot.len;
+ dma_addr_t pinst;
+ dma_addr_t pdata;
+ u32 inst_len;
+ u32 data_len;
+ int rc;
+ int i;
+ u32 done;
+ u32 reg_offset;
+
+ IWL_DEBUG_INFO("Begin load bsm\n");
+
+ /* make sure bootstrap program is no larger than BSM's SRAM size */
+ if (len > IWL39_MAX_BSM_SIZE)
+ return -EINVAL;
+
+ /* Tell bootstrap uCode where to find the "Initialize" uCode
+ * in host DRAM ... host DRAM physical address bits 31:0 for 3945.
+ * NOTE: iwl3945_initialize_alive_start() will replace these values,
+ * after the "initialize" uCode has run, to point to
+ * runtime/protocol instructions and backup data cache. */
+ pinst = priv->ucode_init.p_addr;
+ pdata = priv->ucode_init_data.p_addr;
+ inst_len = priv->ucode_init.len;
+ data_len = priv->ucode_init_data.len;
+
+ rc = iwl_grab_nic_access(priv);
+ if (rc)
+ return rc;
+
+ iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+ iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+ iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
+ iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
+
+ /* Fill BSM memory with bootstrap instructions */
+ for (reg_offset = BSM_SRAM_LOWER_BOUND;
+ reg_offset < BSM_SRAM_LOWER_BOUND + len;
+ reg_offset += sizeof(u32), image++)
+ _iwl_write_prph(priv, reg_offset,
+ le32_to_cpu(*image));
+
+ rc = iwl3945_verify_bsm(priv);
+ if (rc) {
+ iwl_release_nic_access(priv);
+ return rc;
+ }
+
+ /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
+ iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
+ iwl_write_prph(priv, BSM_WR_MEM_DST_REG,
+ IWL39_RTC_INST_LOWER_BOUND);
+ iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
+
+ /* Load bootstrap code into instruction SRAM now,
+ * to prepare to load "initialize" uCode */
+ iwl_write_prph(priv, BSM_WR_CTRL_REG,
+ BSM_WR_CTRL_REG_BIT_START);
+
+ /* Wait for load of bootstrap uCode to finish */
+ for (i = 0; i < 100; i++) {
+ done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
+ if (!(done & BSM_WR_CTRL_REG_BIT_START))
+ break;
+ udelay(10);
+ }
+ if (i < 100)
+ IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
+ else {
+ IWL_ERR(priv, "BSM write did not complete!\n");
+ return -EIO;
+ }
+
+ /* Enable future boot loads whenever power management unit triggers it
+ * (e.g. when powering back up after power-save shutdown) */
+ iwl_write_prph(priv, BSM_WR_CTRL_REG,
+ BSM_WR_CTRL_REG_BIT_START_EN);
+
+ iwl_release_nic_access(priv);
+
+ return 0;
+}
+
+static struct iwl_lib_ops iwl3945_lib = {
+ .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl3945_hw_txq_free_tfd,
+ .txq_init = iwl3945_hw_tx_queue_init,
+ .load_ucode = iwl3945_load_bsm,
+ .apm_ops = {
+ .init = iwl3945_apm_init,
+ .reset = iwl3945_apm_reset,
+ .stop = iwl3945_apm_stop,
+ .config = iwl3945_nic_config,
+ .set_pwr_src = iwl3945_set_pwr_src,
+ },
+ .eeprom_ops = {
+ .regulatory_bands = {
+ EEPROM_REGULATORY_BAND_1_CHANNELS,
+ EEPROM_REGULATORY_BAND_2_CHANNELS,
+ EEPROM_REGULATORY_BAND_3_CHANNELS,
+ EEPROM_REGULATORY_BAND_4_CHANNELS,
+ EEPROM_REGULATORY_BAND_5_CHANNELS,
+ IWL3945_EEPROM_IMG_SIZE,
+ IWL3945_EEPROM_IMG_SIZE,
+ },
+ .verify_signature = iwlcore_eeprom_verify_signature,
+ .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
+ .release_semaphore = iwl3945_eeprom_release_semaphore,
+ .query_addr = iwlcore_eeprom_query_addr,
+ },
+ .send_tx_power = iwl3945_send_tx_power,
+};
+
+static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
+ .get_hcmd_size = iwl3945_get_hcmd_size,
+ .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
+};
+
+static struct iwl_ops iwl3945_ops = {
+ .lib = &iwl3945_lib,
+ .utils = &iwl3945_hcmd_utils,
+};
+
+static struct iwl_cfg iwl3945_bg_cfg = {
.name = "3945BG",
.fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_G,
+ .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+ .ops = &iwl3945_ops,
+ .mod_params = &iwl3945_mod_params
};
-static struct iwl_3945_cfg iwl3945_abg_cfg = {
+static struct iwl_cfg iwl3945_abg_cfg = {
.name = "3945ABG",
.fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
+ .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+ .ops = &iwl3945_ops,
+ .mod_params = &iwl3945_mod_params
};
struct pci_device_id iwl3945_hw_card_ids[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 2c0ddc5110c..fef54e9cf8a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -43,11 +43,13 @@
/* Hardware specific file defines the PCI IDs table for that hardware module */
extern struct pci_device_id iwl3945_hw_card_ids[];
-#define DRV_NAME "iwl3945"
#include "iwl-csr.h"
#include "iwl-prph.h"
+#include "iwl-fh.h"
#include "iwl-3945-hw.h"
-#include "iwl-3945-debug.h"
+#include "iwl-debug.h"
+#include "iwl-power.h"
+#include "iwl-dev.h"
#include "iwl-3945-led.h"
/* Highest firmware API version supported */
@@ -74,8 +76,7 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
/* Module parameters accessible from iwl-*.c */
-extern int iwl3945_param_hwcrypto;
-extern int iwl3945_param_queues_num;
+extern struct iwl_mod_params iwl3945_mod_params;
struct iwl3945_sta_priv {
struct iwl3945_rs_sta *rs_sta;
@@ -95,7 +96,6 @@ enum iwl3945_antenna {
* else RTS for data/management frames where MPDU is larger
* than RTS value.
*/
-#define IWL_RX_BUF_SIZE 3000U
#define DEFAULT_RTS_THRESHOLD 2347U
#define MIN_RTS_THRESHOLD 0U
#define MAX_RTS_THRESHOLD 2347U
@@ -105,136 +105,7 @@ enum iwl3945_antenna {
#define DEFAULT_SHORT_RETRY_LIMIT 7U
#define DEFAULT_LONG_RETRY_LIMIT 4U
-struct iwl3945_rx_mem_buffer {
- dma_addr_t dma_addr;
- struct sk_buff *skb;
- struct list_head list;
-};
-
-/*
- * Generic queue structure
- *
- * Contains common data for Rx and Tx queues
- */
-struct iwl3945_queue {
- int n_bd; /* number of BDs in this queue */
- int write_ptr; /* 1-st empty entry (index) host_w*/
- int read_ptr; /* last used entry (index) host_r*/
- dma_addr_t dma_addr; /* physical addr for BD's */
- int n_window; /* safe queue window */
- u32 id;
- int low_mark; /* low watermark, resume queue if free
- * space more than this */
- int high_mark; /* high watermark, stop queue if free
- * space less than this */
-} __attribute__ ((packed));
-
-int iwl3945_queue_space(const struct iwl3945_queue *q);
-int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i);
-
-#define MAX_NUM_OF_TBS (20)
-
-/* One for each TFD */
-struct iwl3945_tx_info {
- struct sk_buff *skb[MAX_NUM_OF_TBS];
-};
-
-/**
- * struct iwl3945_tx_queue - Tx Queue for DMA
- * @q: generic Rx/Tx queue descriptor
- * @bd: base of circular buffer of TFDs
- * @cmd: array of command/Tx buffers
- * @dma_addr_cmd: physical address of cmd/tx buffer array
- * @txb: array of per-TFD driver data
- * @need_update: indicates need to update read/write index
- *
- * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
- * descriptors) and required locking structures.
- */
-struct iwl3945_tx_queue {
- struct iwl3945_queue q;
- struct iwl3945_tfd_frame *bd;
- struct iwl3945_cmd *cmd;
- dma_addr_t dma_addr_cmd;
- struct iwl3945_tx_info *txb;
- int need_update;
- int active;
-};
-
-#define IWL_NUM_SCAN_RATES (2)
-
-struct iwl3945_channel_tgd_info {
- u8 type;
- s8 max_power;
-};
-
-struct iwl3945_channel_tgh_info {
- s64 last_radar_time;
-};
-
-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl3945_channel_power_info {
- struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 base_power_index; /* gain index for power at factory temp. */
- s8 requested_power; /* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl3945_scan_power_info {
- struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
-};
-
-/*
- * One for each channel, holds all channel setup data
- * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
- * with one another!
- */
-#define IWL4965_MAX_RATE (33)
-
-struct iwl3945_channel_info {
- struct iwl3945_channel_tgd_info tgd;
- struct iwl3945_channel_tgh_info tgh;
- struct iwl3945_eeprom_channel eeprom; /* EEPROM regulatory limit */
- struct iwl3945_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
- * FAT channel */
-
- u8 channel; /* channel number */
- u8 flags; /* flags copied from EEPROM */
- s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
- s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */
- s8 min_power; /* always 0 */
- s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */
-
- u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */
- u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */
- enum ieee80211_band band;
-
- /* Radio/DSP gain settings for each "normal" data Tx rate.
- * These include, in addition to RF and DSP gain, a few fields for
- * remembering/modifying gain settings (indexes). */
- struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
-
- /* Radio/DSP gain settings for each scan rate, for directed scans. */
- struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
-};
-
-struct iwl3945_clip_group {
- /* maximum power level to prevent clipping for each rate, derived by
- * us from this band's saturation power in EEPROM */
- const s8 clip_powers[IWL_MAX_RATES];
-};
-
-#include "iwl-3945-rs.h"
+#include "iwl-agn-rs.h"
#define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1
@@ -247,33 +118,6 @@ struct iwl3945_clip_group {
/* Minimum number of queues. MAX_NUM is defined in hw specific files */
#define IWL_MIN_NUM_QUEUES 4
-/* Power management (not Tx power) structures */
-
-struct iwl3945_power_vec_entry {
- struct iwl3945_powertable_cmd cmd;
- u8 no_dtim;
-};
-#define IWL_POWER_RANGE_0 (0)
-#define IWL_POWER_RANGE_1 (1)
-
-#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */
-#define IWL_POWER_INDEX_3 0x03
-#define IWL_POWER_INDEX_5 0x05
-#define IWL_POWER_AC 0x06
-#define IWL_POWER_BATTERY 0x07
-#define IWL_POWER_LIMIT 0x07
-#define IWL_POWER_MASK 0x0F
-#define IWL_POWER_ENABLED 0x10
-#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK)
-
-struct iwl3945_power_mgr {
- spinlock_t lock;
- struct iwl3945_power_vec_entry pwr_range_0[IWL_POWER_AC];
- struct iwl3945_power_vec_entry pwr_range_1[IWL_POWER_AC];
- u8 active_index;
- u32 dtim_val;
-};
-
#define IEEE80211_DATA_LEN 2304
#define IEEE80211_4ADDR_LEN 30
#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
@@ -289,81 +133,10 @@ struct iwl3945_frame {
struct list_head list;
};
-#define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf)
-#define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8)
-#define SEQ_TO_INDEX(x) ((u8)(x & 0xff))
-#define INDEX_TO_SEQ(x) ((u8)(x & 0xff))
-#define SEQ_HUGE_FRAME (0x4000)
-#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000)
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
-enum {
- /* CMD_SIZE_NORMAL = 0, */
- CMD_SIZE_HUGE = (1 << 0),
- /* CMD_SYNC = 0, */
- CMD_ASYNC = (1 << 1),
- /* CMD_NO_SKB = 0, */
- CMD_WANT_SKB = (1 << 2),
-};
-
-struct iwl3945_cmd;
-struct iwl3945_priv;
-
-struct iwl3945_cmd_meta {
- struct iwl3945_cmd_meta *source;
- union {
- struct sk_buff *skb;
- int (*callback)(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd, struct sk_buff *skb);
- } __attribute__ ((packed)) u;
-
- /* The CMD_SIZE_HUGE flag bit indicates that the command
- * structure is stored at the end of the shared queue memory. */
- u32 flags;
-
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_cmd
- *
- * For allocation of the command and tx queues, this establishes the overall
- * size of the largest command we send to uCode, except for a scan command
- * (which is relatively huge; space is allocated separately).
- */
-struct iwl3945_cmd {
- struct iwl3945_cmd_meta meta;
- struct iwl3945_cmd_header hdr;
- union {
- struct iwl3945_addsta_cmd addsta;
- struct iwl3945_led_cmd led;
- u32 flags;
- u8 val8;
- u16 val16;
- u32 val32;
- struct iwl3945_bt_cmd bt;
- struct iwl3945_rxon_time_cmd rxon_time;
- struct iwl3945_powertable_cmd powertable;
- struct iwl3945_qosparam_cmd qosparam;
- struct iwl3945_tx_cmd tx;
- struct iwl3945_tx_beacon_cmd tx_beacon;
- struct iwl3945_rxon_assoc_cmd rxon_assoc;
- u8 *indirect;
- u8 payload[360];
- } __attribute__ ((packed)) cmd;
-} __attribute__ ((packed));
-
-struct iwl3945_host_cmd {
- u8 id;
- u16 len;
- struct iwl3945_cmd_meta meta;
- const void *data;
-};
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
- sizeof(struct iwl3945_cmd_meta))
-
/*
* RX related structures and functions
*/
@@ -374,33 +147,6 @@ struct iwl3945_host_cmd {
#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
-/**
- * struct iwl3945_rx_queue - Rx queue
- * @processed: Internal index to last handled Rx packet
- * @read: Shared index to newest available Rx buffer
- * @write: Shared index to oldest written Rx packet
- * @free_count: Number of pre-allocated buffers in rx_free
- * @rx_free: list of free SKBs for use
- * @rx_used: List of Rx buffers with no SKB
- * @need_update: flag to indicate we need to update read/write index
- *
- * NOTE: rx_free and rx_used are used as a FIFO for iwl3945_rx_mem_buffers
- */
-struct iwl3945_rx_queue {
- __le32 *bd;
- dma_addr_t dma_addr;
- struct iwl3945_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
- struct iwl3945_rx_mem_buffer *queue[RX_QUEUE_SIZE];
- u32 processed;
- u32 read;
- u32 write;
- u32 free_count;
- struct list_head rx_free;
- struct list_head rx_used;
- int need_update;
- spinlock_t lock;
-};
-
#define IWL_SUPPORTED_RATES_IE_LEN 8
#define SCAN_INTERVAL 100
@@ -430,87 +176,9 @@ struct iwl3945_rx_queue {
#define IWL_INVALID_RATE 0xFF
#define IWL_INVALID_VALUE -1
-struct iwl3945_tid_data {
- u16 seq_number;
-};
-
-struct iwl3945_hw_key {
- enum ieee80211_key_alg alg;
- int keylen;
- u8 key[32];
-};
-
-union iwl3945_ht_rate_supp {
- u16 rates;
- struct {
- u8 siso_rate;
- u8 mimo_rate;
- };
-};
-
-union iwl3945_qos_capabity {
- struct {
- u8 edca_count:4; /* bit 0-3 */
- u8 q_ack:1; /* bit 4 */
- u8 queue_request:1; /* bit 5 */
- u8 txop_request:1; /* bit 6 */
- u8 reserved:1; /* bit 7 */
- } q_AP;
- struct {
- u8 acvo_APSD:1; /* bit 0 */
- u8 acvi_APSD:1; /* bit 1 */
- u8 ac_bk_APSD:1; /* bit 2 */
- u8 ac_be_APSD:1; /* bit 3 */
- u8 q_ack:1; /* bit 4 */
- u8 max_len:2; /* bit 5-6 */
- u8 more_data_ack:1; /* bit 7 */
- } q_STA;
- u8 val;
-};
-
-/* QoS structures */
-struct iwl3945_qos_info {
- int qos_active;
- union iwl3945_qos_capabity qos_cap;
- struct iwl3945_qosparam_cmd def_qos_parm;
-};
-
#define STA_PS_STATUS_WAKE 0
#define STA_PS_STATUS_SLEEP 1
-struct iwl3945_station_entry {
- struct iwl3945_addsta_cmd sta;
- struct iwl3945_tid_data tid[MAX_TID_COUNT];
- union {
- struct {
- u8 rate;
- u8 flags;
- } s;
- u16 rate_n_flags;
- } current_rate;
- u8 used;
- u8 ps_status;
- struct iwl3945_hw_key keyinfo;
-};
-
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_desc {
- void *v_addr; /* access by driver */
- dma_addr_t p_addr; /* access by card's busmaster DMA */
- u32 len; /* bytes */
-};
-
-/* uCode file layout */
-struct iwl3945_ucode {
- __le32 ver; /* major/minor/API/serial */
- __le32 inst_size; /* bytes of runtime instructions */
- __le32 data_size; /* bytes of runtime data */
- __le32 init_size; /* bytes of initialization instructions */
- __le32 init_data_size; /* bytes of initialization data */
- __le32 boot_size; /* bytes of bootstrap instructions */
- u8 data[0]; /* data in same order as "size" elements */
-};
-
struct iwl3945_ibss_seq {
u8 mac[ETH_ALEN];
u16 seq_num;
@@ -519,34 +187,6 @@ struct iwl3945_ibss_seq {
struct list_head list;
};
-/**
- * struct iwl3945_driver_hw_info
- * @max_txq_num: Max # Tx queues supported
- * @tx_cmd_len: Size of Tx command (but not including frame itself)
- * @tx_ant_num: Number of TX antennas
- * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
- * @rx_buf_size:
- * @max_pkt_size:
- * @max_rxq_log: Log-base-2 of max_rxq_size
- * @max_stations:
- * @bcast_sta_id:
- * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status
- * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status
- */
-struct iwl3945_driver_hw_info {
- u16 max_txq_num;
- u16 tx_cmd_len;
- u16 tx_ant_num;
- u16 max_rxq_size;
- u32 rx_buf_size;
- u32 max_pkt_size;
- u16 max_rxq_log;
- u8 max_stations;
- u8 bcast_sta_id;
- void *shared_virt;
- dma_addr_t shared_phys;
-};
-
#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\
x->u.rx_frame.stats.payload + \
x->u.rx_frame.stats.phy_count))
@@ -564,40 +204,33 @@ struct iwl3945_driver_hw_info {
*
*****************************************************************************/
struct iwl3945_addsta_cmd;
-extern int iwl3945_send_add_station(struct iwl3945_priv *priv,
+extern int iwl3945_send_add_station(struct iwl_priv *priv,
struct iwl3945_addsta_cmd *sta, u8 flags);
-extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid,
+extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
int is_ap, u8 flags);
-extern int iwl3945_power_init_handle(struct iwl3945_priv *priv);
-extern int iwl3945_eeprom_init(struct iwl3945_priv *priv);
-extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv);
-extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv,
- struct iwl3945_rx_queue *rxq);
+extern int iwl3945_power_init_handle(struct iwl_priv *priv);
+extern int iwl3945_eeprom_init(struct iwl_priv *priv);
extern int iwl3945_calc_db_from_ratio(int sig_ratio);
extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
-extern int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, int count, u32 id);
+extern int iwl3945_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq, int count, u32 id);
extern void iwl3945_rx_replenish(void *data);
-extern void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
-extern int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len,
+extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
const void *data);
-extern int __must_check iwl3945_send_cmd(struct iwl3945_priv *priv,
- struct iwl3945_host_cmd *cmd);
-extern unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv,
+ struct iwl_host_cmd *cmd);
+extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,int left);
-extern int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_rx_queue *q);
-extern int iwl3945_send_statistics_request(struct iwl3945_priv *priv);
-extern void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
+extern void iwl3945_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
u32 decrypt_res,
struct ieee80211_rx_status *stats);
-extern const u8 iwl3945_broadcast_addr[ETH_ALEN];
/*
* Currently used by iwl-3945-rs... look at restructuring so that it doesn't
* call this... todo... fix that.
*/
-extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id,
+extern u8 iwl3945_sync_station(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
/******************************************************************************
@@ -616,36 +249,37 @@ extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id,
* iwl3945_mac_ <-- mac80211 callback
*
****************************************************************************/
-extern void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv);
-extern void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv);
-extern void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv);
-extern int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv);
-extern int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_init(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv);
-extern void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv);
-extern void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_reset(struct iwl3945_priv *priv);
-extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *tfd,
- dma_addr_t addr, u16 len);
-extern int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
-extern int iwl3945_hw_get_temperature(struct iwl3945_priv *priv);
-extern int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq);
-extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv);
+extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv);
+extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv);
+extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv);
+extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_init(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv);
+extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv);
+extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_reset(struct iwl_priv *priv);
+extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len,
+ u8 reset, u8 pad);
+extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+extern int iwl3945_hw_get_temperature(struct iwl_priv *priv);
+extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl3945_frame *frame, u8 rate);
-extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv);
-extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr,
int sta_id, int tx_id);
-extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv);
-extern int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power);
-extern void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb);
-extern void iwl3945_disable_events(struct iwl3945_priv *priv);
-extern int iwl4965_get_temperature(const struct iwl3945_priv *priv);
+extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
+extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
+extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+extern void iwl3945_disable_events(struct iwl_priv *priv);
+extern int iwl4965_get_temperature(const struct iwl_priv *priv);
/**
* iwl3945_hw_find_station - Find station id for a given BSSID
@@ -655,302 +289,31 @@ extern int iwl4965_get_temperature(const struct iwl3945_priv *priv);
* not yet been merged into a single common layer for managing the
* station tables.
*/
-extern u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *bssid);
+extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
-extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
+extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel);
/*
* Forward declare iwl-3945.c functions for iwl-base.c
*/
-extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
-extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
-extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
-extern int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv);
-extern u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id,
+extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
+extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
+extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
+extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv);
+extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
-
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-
-enum {
- MEASUREMENT_READY = (1 << 0),
- MEASUREMENT_ACTIVE = (1 << 1),
-};
-
-#endif
-
-#ifdef CONFIG_IWL3945_RFKILL
-struct iwl3945_priv;
-
-void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv);
-void iwl3945_rfkill_unregister(struct iwl3945_priv *priv);
-int iwl3945_rfkill_init(struct iwl3945_priv *priv);
-#else
-static inline void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) {}
-static inline void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) {}
-static inline int iwl3945_rfkill_init(struct iwl3945_priv *priv) { return 0; }
-#endif
-
-#define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES
-
-struct iwl3945_priv {
-
- /* ieee device used by generic ieee processing code */
- struct ieee80211_hw *hw;
- struct ieee80211_channel *ieee_channels;
- struct ieee80211_rate *ieee_rates;
- struct iwl_3945_cfg *cfg; /* device configuration */
-
- /* temporary frame storage list */
- struct list_head free_frames;
- int frames_count;
-
- enum ieee80211_band band;
- int alloc_rxb_skb;
-
- void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb);
-
- struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
-
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
- /* spectrum measurement report caching */
- struct iwl3945_spectrum_notification measure_report;
- u8 measurement_status;
-#endif
- /* ucode beacon time */
- u32 ucode_beacon_time;
-
- /* we allocate array of iwl3945_channel_info for NIC's valid channels.
- * Access via channel # using indirect index array */
- struct iwl3945_channel_info *channel_info; /* channel info array */
- u8 channel_count; /* # of channels */
-
- /* each calibration channel group in the EEPROM has a derived
- * clip setting for each rate. */
- const struct iwl3945_clip_group clip_groups[5];
-
- /* thermal calibration */
- s32 temperature; /* degrees Kelvin */
- s32 last_temperature;
-
- /* Scan related variables */
- unsigned long last_scan_jiffies;
- unsigned long next_scan_jiffies;
- unsigned long scan_start;
- unsigned long scan_pass_start;
- unsigned long scan_start_tsf;
- int scan_bands;
- int one_direct_scan;
- u8 direct_ssid_len;
- u8 direct_ssid[IW_ESSID_MAX_SIZE];
- struct iwl3945_scan_cmd *scan;
-
- /* spinlock */
- spinlock_t lock; /* protect general shared data */
- spinlock_t hcmd_lock; /* protect hcmd */
- struct mutex mutex;
-
- /* basic pci-network driver stuff */
- struct pci_dev *pci_dev;
-
- /* pci hardware address support */
- void __iomem *hw_base;
-
- /* uCode images, save to reload in case of failure */
- u32 ucode_ver; /* ucode version, copy of
- iwl3945_ucode.ver */
- struct fw_desc ucode_code; /* runtime inst */
- struct fw_desc ucode_data; /* runtime data original */
- struct fw_desc ucode_data_backup; /* runtime data save/restore */
- struct fw_desc ucode_init; /* initialization inst */
- struct fw_desc ucode_init_data; /* initialization data */
- struct fw_desc ucode_boot; /* bootstrap inst */
-
-
- struct iwl3945_rxon_time_cmd rxon_timing;
-
- /* We declare this const so it can only be
- * changed via explicit cast within the
- * routines that actually update the physical
- * hardware */
- const struct iwl3945_rxon_cmd active_rxon;
- struct iwl3945_rxon_cmd staging_rxon;
-
- int error_recovering;
- struct iwl3945_rxon_cmd recovery_rxon;
-
- /* 1st responses from initialize and runtime uCode images.
- * 4965's initialize alive response contains some calibration data. */
- struct iwl3945_init_alive_resp card_alive_init;
- struct iwl3945_alive_resp card_alive;
-
-#ifdef CONFIG_IWL3945_RFKILL
- struct rfkill *rfkill;
-#endif
-
-#ifdef CONFIG_IWL3945_LEDS
- struct iwl3945_led led[IWL_LED_TRG_MAX];
- unsigned long last_blink_time;
- u8 last_blink_rate;
- u8 allow_blinking;
- unsigned int rxtxpackets;
- u64 led_tpt;
-#endif
-
-
- u16 active_rate;
- u16 active_rate_basic;
-
- u32 sta_supp_rates;
-
- u8 call_post_assoc_from_beacon;
- /* Rate scaling data */
- s8 data_retry_limit;
- u8 retry_rate;
-
- wait_queue_head_t wait_command_queue;
-
- int activity_timer_active;
-
- /* Rx and Tx DMA processing queues */
- struct iwl3945_rx_queue rxq;
- struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES];
-
- unsigned long status;
-
- int last_rx_rssi; /* From Rx packet statisitics */
- int last_rx_noise; /* From beacon statistics */
-
- struct iwl3945_power_mgr power_data;
-
- struct iwl3945_notif_statistics statistics;
- unsigned long last_statistics_time;
-
- /* context information */
- u16 rates_mask;
-
- u32 power_mode;
- u32 antenna;
- u8 bssid[ETH_ALEN];
- u16 rts_threshold;
- u8 mac_addr[ETH_ALEN];
-
- /*station table variables */
- spinlock_t sta_lock;
- int num_stations;
- struct iwl3945_station_entry stations[IWL_STATION_COUNT];
-
- /* Indication if ieee80211_ops->open has been called */
- u8 is_open;
-
- u8 mac80211_registered;
-
- /* Rx'd packet timing information */
- u32 last_beacon_time;
- u64 last_tsf;
-
- /* eeprom */
- struct iwl3945_eeprom eeprom;
-
- enum nl80211_iftype iw_mode;
-
- struct sk_buff *ibss_beacon;
-
- /* Last Rx'd beacon timestamp */
- u32 timestamp0;
- u32 timestamp1;
- u16 beacon_int;
- struct iwl3945_driver_hw_info hw_setting;
- struct ieee80211_vif *vif;
-
- /* Current association information needed to configure the
- * hardware */
- u16 assoc_id;
- u16 assoc_capability;
- u8 ps_mode;
-
- struct iwl3945_qos_info qos_data;
-
- struct workqueue_struct *workqueue;
-
- struct work_struct up;
- struct work_struct restart;
- struct work_struct calibrated_work;
- struct work_struct scan_completed;
- struct work_struct rx_replenish;
- struct work_struct rf_kill;
- struct work_struct abort_scan;
- struct work_struct update_link_led;
- struct work_struct auth_work;
- struct work_struct report_work;
- struct work_struct request_scan;
- struct work_struct beacon_update;
-
- struct tasklet_struct irq_tasklet;
-
- struct delayed_work init_alive_start;
- struct delayed_work alive_start;
- struct delayed_work activity_timer;
- struct delayed_work thermal_periodic;
- struct delayed_work gather_stats;
- struct delayed_work scan_check;
-
-#define IWL_DEFAULT_TX_POWER 0x0F
- s8 user_txpower_limit;
- s8 max_channel_txpower_limit;
-
-
-#ifdef CONFIG_IWL3945_DEBUG
- /* debugging info */
- u32 framecnt_to_us;
- atomic_t restrict_refcnt;
-#endif
-}; /*iwl3945_priv */
-
-static inline int iwl3945_is_associated(struct iwl3945_priv *priv)
-{
- return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
-}
-
-static inline int is_channel_valid(const struct iwl3945_channel_info *ch_info)
-{
- if (ch_info == NULL)
- return 0;
- return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
-}
-
-static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info)
-{
- return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
-}
-
-static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info)
-{
- return ch_info->band == IEEE80211_BAND_5GHZ;
-}
-
-static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info)
-{
- return ch_info->band == IEEE80211_BAND_2GHZ;
-}
-
-static inline int is_channel_passive(const struct iwl3945_channel_info *ch)
-{
- return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0;
-}
-
-static inline int is_channel_ibss(const struct iwl3945_channel_info *ch)
+static inline int iwl3945_is_associated(struct iwl_priv *priv)
{
- return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
+ return (priv->active39_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
}
-extern const struct iwl3945_channel_info *iwl3945_get_channel_info(
- const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel);
+extern const struct iwl_channel_info *iwl3945_get_channel_info(
+ const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
-extern int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate);
+extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
-/* Requires full declaration of iwl3945_priv before including */
-#include "iwl-3945-io.h"
+/* Requires full declaration of iwl_priv before including */
+#include "iwl-io.h"
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 6649f7b5565..af4c1bb0de1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -89,7 +89,7 @@
#define LONG_SLOT_TIME 20
/* RSSI to dBm */
-#define IWL_RSSI_OFFSET 44
+#define IWL49_RSSI_OFFSET 44
@@ -110,43 +110,29 @@
#define IWL_DEFAULT_TX_RETRY 15
-#define RX_QUEUE_SIZE 256
-#define RX_QUEUE_MASK 255
-#define RX_QUEUE_SIZE_LOG 8
-
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
-/* Size of one Rx buffer in host DRAM */
-#define IWL_RX_BUF_SIZE_4K (4 * 1024)
-#define IWL_RX_BUF_SIZE_8K (8 * 1024)
/* Sizes and addresses for instruction and data memory (SRAM) in
* 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */
-#define RTC_INST_LOWER_BOUND (0x000000)
+#define IWL49_RTC_INST_LOWER_BOUND (0x000000)
#define IWL49_RTC_INST_UPPER_BOUND (0x018000)
-#define RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL49_RTC_DATA_LOWER_BOUND (0x800000)
#define IWL49_RTC_DATA_UPPER_BOUND (0x80A000)
-#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - \
+ IWL49_RTC_INST_LOWER_BOUND)
+#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - \
+ IWL49_RTC_DATA_LOWER_BOUND)
-#define IWL_MAX_INST_SIZE IWL49_RTC_INST_SIZE
-#define IWL_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
+#define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE
+#define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
/* Size of uCode instruction memory in bootstrap state machine */
-#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE
+#define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE
static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
+ return (addr >= IWL49_RTC_DATA_LOWER_BOUND) &&
(addr < IWL49_RTC_DATA_UPPER_BOUND);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 5a72bc0377d..d7d956db19d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -85,7 +85,7 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv)
reg += sizeof(u32), image++) {
val = iwl_read_prph(priv, reg);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("BSM uCode verification failed at "
+ IWL_ERR(priv, "BSM uCode verification failed at "
"addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
BSM_SRAM_LOWER_BOUND,
reg - BSM_SRAM_LOWER_BOUND, len,
@@ -149,7 +149,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
priv->ucode_type = UCODE_RT;
/* make sure bootstrap program is no larger than BSM's SRAM size */
- if (len > IWL_MAX_BSM_SIZE)
+ if (len > IWL49_MAX_BSM_SIZE)
return -EINVAL;
/* Tell bootstrap uCode where to find the "Initialize" uCode
@@ -186,7 +186,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
- iwl_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND);
+ iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND);
iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
/* Load bootstrap code into instruction SRAM now,
@@ -203,7 +203,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
if (i < 100)
IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
else {
- IWL_ERROR("BSM write did not complete!\n");
+ IWL_ERR(priv, "BSM write did not complete!\n");
return -EIO;
}
@@ -523,7 +523,8 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
cmd.diff_gain_c = 0;
if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd))
- IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+ IWL_ERR(priv,
+ "Could not send REPLY_PHY_CALIBRATION_CMD\n");
data->state = IWL_CHAIN_NOISE_ACCUMULATE;
IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
}
@@ -804,8 +805,9 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
(priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
return -EINVAL;
}
@@ -813,6 +815,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
+ priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -820,6 +823,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ);
+ priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
priv->hw_params.tx_chains_num = 2;
priv->hw_params.rx_chains_num = 2;
priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
@@ -902,7 +907,6 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel)
channel <= CALIB_IWL_TX_ATTEN_GR4_LCH)
return CALIB_CH_GROUP_4;
- IWL_ERROR("Can't find txatten group for channel %d.\n", channel);
return -1;
}
@@ -956,7 +960,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
s = iwl4965_get_sub_band(priv, channel);
if (s >= EEPROM_TX_POWER_BANDS) {
- IWL_ERROR("Tx Power can not find channel %d\n", channel);
+ IWL_ERR(priv, "Tx Power can not find channel %d\n", channel);
return -1;
}
@@ -1303,7 +1307,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
s32 factory_actual_pwr[2];
s32 power_index;
- /* user_txpower_limit is in dBm, convert to half-dBm (half-dB units
+ /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units
* are used for indexing into txpower table) */
user_target_power = 2 * priv->tx_power_user_lmt;
@@ -1319,8 +1323,11 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* get txatten group, used to select 1) thermal txpower adjustment
* and 2) mimo txpower balance between Tx chains. */
txatten_grp = iwl4965_get_tx_atten_grp(channel);
- if (txatten_grp < 0)
+ if (txatten_grp < 0) {
+ IWL_ERR(priv, "Can't find txatten group for channel %d.\n",
+ channel);
return -EINVAL;
+ }
IWL_DEBUG_TXPOWER("channel %d belongs to txatten group %d\n",
channel, txatten_grp);
@@ -1483,12 +1490,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* stay within the table! */
if (power_index > 107) {
- IWL_WARNING("txpower index %d > 107\n",
+ IWL_WARN(priv, "txpower index %d > 107\n",
power_index);
power_index = 107;
}
if (power_index < 0) {
- IWL_WARNING("txpower index %d < 0\n",
+ IWL_WARN(priv, "txpower index %d < 0\n",
power_index);
power_index = 0;
}
@@ -1531,7 +1538,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
/* If this gets hit a lot, switch it to a BUG() and catch
* the stack trace to find out who is calling this during
* a scan. */
- IWL_WARNING("TX Power requested while scanning!\n");
+ IWL_WARN(priv, "TX Power requested while scanning!\n");
return -EAGAIN;
}
@@ -1725,7 +1732,7 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
if (R3 == R1) {
- IWL_ERROR("Calibration conflict R1 == R3\n");
+ IWL_ERR(priv, "Calibration conflict R1 == R3\n");
return -1;
}
@@ -1837,7 +1844,8 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL49_FIRST_AMPDU_QUEUE,
IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1908,7 +1916,8 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL49_FIRST_AMPDU_QUEUE,
IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -2067,10 +2076,10 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
sc = le16_to_cpu(hdr->seq_ctrl);
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
- IWL_ERROR("BUG_ON idx doesn't match seq control"
- " idx=%d, seq_idx=%d, seq=%d\n",
- idx, SEQ_TO_SN(sc),
- hdr->seq_ctrl);
+ IWL_ERR(priv,
+ "BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n",
+ idx, SEQ_TO_SN(sc), hdr->seq_ctrl);
return -1;
}
@@ -2129,7 +2138,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
u8 *qc = NULL;
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -2147,7 +2156,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
sta_id = iwl_get_ra_sta_id(priv, hdr);
if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
- IWL_ERROR("Station not known\n");
+ IWL_ERR(priv, "Station not known\n");
return;
}
@@ -2210,7 +2219,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
static int iwl4965_calc_rssi(struct iwl_priv *priv,
@@ -2244,7 +2253,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
- return max_rssi - agc - IWL_RSSI_OFFSET;
+ return max_rssi - agc - IWL49_RSSI_OFFSET;
}
@@ -2287,6 +2296,9 @@ static struct iwl_lib_ops iwl4965_lib = {
.txq_set_sched = iwl4965_txq_set_sched,
.txq_agg_enable = iwl4965_txq_agg_enable,
.txq_agg_disable = iwl4965_txq_agg_disable,
+ .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl_hw_txq_free_tfd,
+ .txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwl4965_rx_handler_setup,
.setup_deferred_work = iwl4965_setup_deferred_work,
.cancel_deferred_work = iwl4965_cancel_deferred_work,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 82c3859ce0f..15cac70e36e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -68,10 +68,16 @@
#ifndef __iwl_5000_hw_h__
#define __iwl_5000_hw_h__
+#define IWL50_RTC_INST_LOWER_BOUND (0x000000)
#define IWL50_RTC_INST_UPPER_BOUND (0x020000)
+
+#define IWL50_RTC_DATA_LOWER_BOUND (0x800000)
#define IWL50_RTC_DATA_UPPER_BOUND (0x80C000)
-#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+
+#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - \
+ IWL50_RTC_INST_LOWER_BOUND)
+#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - \
+ IWL50_RTC_DATA_LOWER_BOUND)
/* EEPROM */
#define IWL_5000_EEPROM_IMG_SIZE 2048
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 66d053d28a7..89d92a8ca15 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -289,7 +289,7 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
break;
default:
- IWL_ERROR("illegal indirect type: 0x%X\n",
+ IWL_ERR(priv, "illegal indirect type: 0x%X\n",
address & INDIRECT_TYPE_MSK);
break;
}
@@ -384,7 +384,8 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd);
if (ret)
- IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+ IWL_ERR(priv,
+ "Could not send REPLY_PHY_CALIBRATION_CMD\n");
data->state = IWL_CHAIN_NOISE_ACCUMULATE;
IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
}
@@ -507,7 +508,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
index = IWL_CALIB_BASE_BAND;
break;
default:
- IWL_ERROR("Unknown calibration notification %d\n",
+ IWL_ERR(priv, "Unknown calibration notification %d\n",
hdr->op_code);
return;
}
@@ -580,7 +581,8 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
{
int ret = 0;
- ret = iwl5000_load_section(priv, inst_image, RTC_INST_LOWER_BOUND);
+ ret = iwl5000_load_section(priv, inst_image,
+ IWL50_RTC_INST_LOWER_BOUND);
if (ret)
return ret;
@@ -588,19 +590,19 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
priv->ucode_write_complete, 5 * HZ);
if (ret == -ERESTARTSYS) {
- IWL_ERROR("Could not load the INST uCode section due "
+ IWL_ERR(priv, "Could not load the INST uCode section due "
"to interrupt\n");
return ret;
}
if (!ret) {
- IWL_ERROR("Could not load the INST uCode section\n");
+ IWL_ERR(priv, "Could not load the INST uCode section\n");
return -ETIMEDOUT;
}
priv->ucode_write_complete = 0;
ret = iwl5000_load_section(
- priv, data_image, RTC_DATA_LOWER_BOUND);
+ priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
if (ret)
return ret;
@@ -609,11 +611,11 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
priv->ucode_write_complete, 5 * HZ);
if (ret == -ERESTARTSYS) {
- IWL_ERROR("Could not load the INST uCode section due "
+ IWL_ERR(priv, "Could not load the INST uCode section due "
"to interrupt\n");
return ret;
} else if (!ret) {
- IWL_ERROR("Could not load the DATA uCode section\n");
+ IWL_ERR(priv, "Could not load the DATA uCode section\n");
return -ETIMEDOUT;
} else
ret = 0;
@@ -675,7 +677,8 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv)
iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
- IWL_WARNING("Could not complete ALIVE transition: %d\n", ret);
+ IWL_WARN(priv,
+ "Could not complete ALIVE transition: %d\n", ret);
goto restart;
}
@@ -824,8 +827,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
{
if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
(priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
return -EINVAL;
}
@@ -833,6 +837,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
+ priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
@@ -840,6 +845,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_bsm_size = 0;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
+ priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
priv->hw_params.sens = &iwl5000_sensitivity;
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
@@ -1011,7 +1018,8 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL50_FIRST_AMPDU_QUEUE,
IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1076,7 +1084,8 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL50_FIRST_AMPDU_QUEUE,
IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1197,8 +1206,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
sc = le16_to_cpu(hdr->seq_ctrl);
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
- IWL_ERROR("BUG_ON idx doesn't match seq control"
- " idx=%d, seq_idx=%d, seq=%d\n",
+ IWL_ERR(priv,
+ "BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n",
idx, SEQ_TO_SN(sc),
hdr->seq_ctrl);
return -1;
@@ -1254,7 +1264,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
int freed;
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -1328,7 +1338,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
/* Currently 5000 is the superset of everything */
@@ -1356,7 +1366,7 @@ static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
static int iwl5000_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
+ return (addr >= IWL50_RTC_DATA_LOWER_BOUND) &&
(addr < IWL50_RTC_DATA_UPPER_BOUND);
}
@@ -1460,7 +1470,7 @@ static int iwl5000_calc_rssi(struct iwl_priv *priv,
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
- return max_rssi - agc - IWL_RSSI_OFFSET;
+ return max_rssi - agc - IWL49_RSSI_OFFSET;
}
static struct iwl_hcmd_ops iwl5000_hcmd = {
@@ -1483,6 +1493,9 @@ static struct iwl_lib_ops iwl5000_lib = {
.txq_set_sched = iwl5000_txq_set_sched,
.txq_agg_enable = iwl5000_txq_agg_enable,
.txq_agg_disable = iwl5000_txq_agg_disable,
+ .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl_hw_txq_free_tfd,
+ .txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwl5000_rx_handler_setup,
.setup_deferred_work = iwl5000_setup_deferred_work,
.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
@@ -1517,13 +1530,13 @@ static struct iwl_lib_ops iwl5000_lib = {
},
};
-static struct iwl_ops iwl5000_ops = {
+struct iwl_ops iwl5000_ops = {
.lib = &iwl5000_lib,
.hcmd = &iwl5000_hcmd,
.utils = &iwl5000_hcmd_utils,
};
-static struct iwl_mod_params iwl50_mod_params = {
+struct iwl_mod_params iwl50_mod_params = {
.num_of_queues = IWL50_NUM_QUEUES,
.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
.amsdu_size_8K = 1,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-core.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 6f463555402..90185777d98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,47 +58,24 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
*****************************************************************************/
+/*
+ * Please use this file (iwl-6000-hw.h) only for hardware-related definitions.
+ * Use iwl-5000-commands.h for uCode API definitions.
+ */
-#ifndef __iwl_3945_dev_h__
-#define __iwl_3945_dev_h__
-
-#define IWL_PCI_DEVICE(dev, subdev, cfg) \
- .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
- .driver_data = (kernel_ulong_t)&(cfg)
+#ifndef __iwl_6000_hw_h__
+#define __iwl_6000_hw_h__
-#define IWL_SKU_G 0x1
-#define IWL_SKU_A 0x2
+#define IWL60_RTC_INST_LOWER_BOUND (0x000000)
+#define IWL60_RTC_INST_UPPER_BOUND (0x040000)
+#define IWL60_RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL60_RTC_DATA_UPPER_BOUND (0x814000)
+#define IWL60_RTC_INST_SIZE \
+ (IWL60_RTC_INST_UPPER_BOUND - IWL60_RTC_INST_LOWER_BOUND)
+#define IWL60_RTC_DATA_SIZE \
+ (IWL60_RTC_DATA_UPPER_BOUND - IWL60_RTC_DATA_LOWER_BOUND)
-/**
- * struct iwl_3945_cfg
- * @fw_name_pre: Firmware filename prefix. The api version and extension
- * (.ucode) will be added to filename before loading from disk. The
- * filename is constructed as fw_name_pre<api>.ucode.
- * @ucode_api_max: Highest version of uCode API supported by driver.
- * @ucode_api_min: Lowest version of uCode API supported by driver.
- *
- * We enable the driver to be backward compatible wrt API version. The
- * driver specifies which APIs it supports (with @ucode_api_max being the
- * highest and @ucode_api_min the lowest). Firmware will only be loaded if
- * it has a supported API version. The firmware's API version will be
- * stored in @iwl_priv, enabling the driver to make runtime changes based
- * on firmware version used.
- *
- * For example,
- * if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
- * Driver interacts with Firmware API version >= 2.
- * } else {
- * Driver interacts with Firmware API version 1.
- * }
- */
-struct iwl_3945_cfg {
- const char *name;
- const char *fw_name_pre;
- const unsigned int ucode_api_max;
- const unsigned int ucode_api_min;
- unsigned int sku;
-};
+#endif /* __iwl_6000_hw_h__ */
-#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
new file mode 100644
index 00000000000..4515a6053dd
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -0,0 +1,130 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+/* Highest firmware API version supported */
+#define IWL6000_UCODE_API_MAX 1
+#define IWL6050_UCODE_API_MAX 1
+
+/* Lowest firmware API version supported */
+#define IWL6000_UCODE_API_MIN 1
+#define IWL6050_UCODE_API_MIN 1
+
+#define IWL6000_FW_PRE "iwlwifi-6000-"
+#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
+#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
+
+#define IWL6050_FW_PRE "iwlwifi-6050-"
+#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
+#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
+
+struct iwl_cfg iwl6000_2ag_cfg = {
+ .name = "6000 Series 2x2 AG",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+};
+
+struct iwl_cfg iwl6000_2agn_cfg = {
+ .name = "6000 Series 2x2 AGN",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+};
+
+struct iwl_cfg iwl6050_2agn_cfg = {
+ .name = "6050 Series 2x2 AGN",
+ .fw_name_pre = IWL6050_FW_PRE,
+ .ucode_api_max = IWL6050_UCODE_API_MAX,
+ .ucode_api_min = IWL6050_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+};
+
+struct iwl_cfg iwl6000_3agn_cfg = {
+ .name = "6000 Series 3x3 AGN",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+};
+
+struct iwl_cfg iwl6050_3agn_cfg = {
+ .name = "6050 Series 3x3 AGN",
+ .fw_name_pre = IWL6050_FW_PRE,
+ .ucode_api_max = IWL6050_UCODE_API_MAX,
+ .ucode_api_min = IWL6050_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+};
+
+MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
index b8137eeae1d..1217a1da88f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -40,67 +40,68 @@
* be #ifdef'd out once the driver is stable and folks aren't actively
* making changes
*/
-int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
+int iwl_agn_check_rxon_cmd(struct iwl_priv *priv)
{
int error = 0;
int counter = 1;
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
error |= le32_to_cpu(rxon->flags &
(RXON_FLG_TGJ_NARROW_BAND_MSK |
RXON_FLG_RADAR_DETECT_MSK));
if (error)
- IWL_WARNING("check 24G fields %d | %d\n",
+ IWL_WARN(priv, "check 24G fields %d | %d\n",
counter++, error);
} else {
error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
if (error)
- IWL_WARNING("check 52 fields %d | %d\n",
+ IWL_WARN(priv, "check 52 fields %d | %d\n",
counter++, error);
error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
if (error)
- IWL_WARNING("check 52 CCK %d | %d\n",
+ IWL_WARN(priv, "check 52 CCK %d | %d\n",
counter++, error);
}
error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
if (error)
- IWL_WARNING("check mac addr %d | %d\n", counter++, error);
+ IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error);
/* make sure basic rates 6Mbps and 1Mbps are supported */
error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
if (error)
- IWL_WARNING("check basic rate %d | %d\n", counter++, error);
+ IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error);
error |= (le16_to_cpu(rxon->assoc_id) > 2007);
if (error)
- IWL_WARNING("check assoc id %d | %d\n", counter++, error);
+ IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error);
error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
if (error)
- IWL_WARNING("check CCK and short slot %d | %d\n",
+ IWL_WARN(priv, "check CCK and short slot %d | %d\n",
counter++, error);
error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
if (error)
- IWL_WARNING("check CCK & auto detect %d | %d\n",
+ IWL_WARN(priv, "check CCK & auto detect %d | %d\n",
counter++, error);
error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
if (error)
- IWL_WARNING("check TGG and auto detect %d | %d\n",
+ IWL_WARN(priv, "check TGG and auto detect %d | %d\n",
counter++, error);
if (error)
- IWL_WARNING("Tuning to channel %d\n",
+ IWL_WARN(priv, "Tuning to channel %d\n",
le16_to_cpu(rxon->channel));
if (error) {
- IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n");
+ IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n");
return -1;
}
return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 27f50471aed..13039a02447 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -49,6 +49,8 @@
#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
+/* max allowed rate miss before sync LQ cmd */
+#define IWL_MISSED_RATE_MAX 15
/* max time to accum history 2 seconds */
#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)
@@ -148,6 +150,8 @@ struct iwl_lq_sta {
u16 active_mimo2_rate;
u16 active_mimo3_rate;
u16 active_rate_basic;
+ s8 max_rate_idx; /* Max rate set by user */
+ u8 missed_rate_counter;
struct iwl_link_quality_cmd lq;
struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
@@ -463,8 +467,9 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
* Fill uCode API rate_n_flags field, based on "search" or "active" table.
*/
/* FIXME:RS:remove this function and put the flags statically in the table */
-static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
- int index, u8 use_green)
+static u32 rate_n_flags_from_tbl(struct iwl_priv *priv,
+ struct iwl_scale_tbl_info *tbl,
+ int index, u8 use_green)
{
u32 rate_n_flags = 0;
@@ -475,7 +480,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
} else if (is_Ht(tbl->lq_type)) {
if (index > IWL_LAST_OFDM_RATE) {
- IWL_ERROR("invalid HT rate index %d\n", index);
+ IWL_ERR(priv, "Invalid HT rate index %d\n", index);
index = IWL_LAST_OFDM_RATE;
}
rate_n_flags = RATE_MCS_HT_MSK;
@@ -487,7 +492,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
else
rate_n_flags |= iwl_rates[index].plcp_mimo3;
} else {
- IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type);
+ IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type);
}
rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
@@ -507,7 +512,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
rate_n_flags |= RATE_MCS_GF_MSK;
if (is_siso(tbl->lq_type) && tbl->is_SGI) {
rate_n_flags &= ~RATE_MCS_SGI_MSK;
- IWL_ERROR("GF was set with SGI:SISO\n");
+ IWL_ERR(priv, "GF was set with SGI:SISO\n");
}
}
}
@@ -758,7 +763,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
low = scale_index;
out:
- return rate_n_flags_from_tbl(tbl, low, is_green);
+ return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green);
}
/*
@@ -839,10 +844,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
/* the last LQ command could failed so the LQ in ucode not
* the same in driver sync up
*/
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
+ lq_sta->missed_rate_counter++;
+ if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
+ lq_sta->missed_rate_counter = 0;
+ iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
+ }
goto out;
}
+ lq_sta->missed_rate_counter = 0;
/* Update frame history window with "failure" for each Tx retry. */
while (retries) {
/* Look up the rate and other info used for each tx attempt.
@@ -1129,7 +1139,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
s32 rate;
s8 is_green = lq_sta->is_green;
- if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
+ if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
@@ -1176,7 +1186,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
rate, rate_mask);
return -1;
}
- tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
tbl->current_rate, is_green);
@@ -1196,7 +1206,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
u8 is_green = lq_sta->is_green;
s32 rate;
- if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
+ if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
IWL_DEBUG_RATE("LQ: try to switch to SISO\n");
@@ -1236,7 +1246,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
rate, rate_mask);
return -1;
}
- tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
tbl->current_rate, is_green);
return 0;
@@ -1430,7 +1440,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
if (!tbl->is_SGI)
break;
else
- IWL_ERROR("SGI was set in GF+SISO\n");
+ IWL_ERR(priv,
+ "SGI was set in GF+SISO\n");
}
search_tbl->is_SGI = !tbl->is_SGI;
rs_set_expected_tpt_table(lq_sta, search_tbl);
@@ -1439,8 +1450,9 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
if (tpt >= search_tbl->expected_tpt[index])
break;
}
- search_tbl->current_rate = rate_n_flags_from_tbl(
- search_tbl, index, is_green);
+ search_tbl->current_rate =
+ rate_n_flags_from_tbl(priv, search_tbl,
+ index, is_green);
goto out;
}
tbl->action++;
@@ -1551,8 +1563,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
if (tpt >= search_tbl->expected_tpt[index])
break;
}
- search_tbl->current_rate = rate_n_flags_from_tbl(
- search_tbl, index, is_green);
+ search_tbl->current_rate =
+ rate_n_flags_from_tbl(priv, search_tbl,
+ index, is_green);
goto out;
}
@@ -1745,16 +1758,25 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
rate_scale_index_msk = rate_mask;
if (!((1 << index) & rate_scale_index_msk)) {
- IWL_ERROR("Current Rate is not valid\n");
+ IWL_ERR(priv, "Current Rate is not valid\n");
return;
}
/* Get expected throughput table and history window for current rate */
if (!tbl->expected_tpt) {
- IWL_ERROR("tbl->expected_tpt is NULL\n");
+ IWL_ERR(priv, "tbl->expected_tpt is NULL\n");
return;
}
+ /* force user max rate if set by user */
+ if ((lq_sta->max_rate_idx != -1) &&
+ (lq_sta->max_rate_idx < index)) {
+ index = lq_sta->max_rate_idx;
+ update_lq = 1;
+ window = &(tbl->win[index]);
+ goto lq_update;
+ }
+
window = &(tbl->win[index]);
/*
@@ -1846,6 +1868,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
+ /* If user set max rate, dont allow higher than user constrain */
+ if ((lq_sta->max_rate_idx != -1) &&
+ (lq_sta->max_rate_idx < high))
+ high = IWL_RATE_INVALID;
+
sr = window->success_ratio;
/* Collect measured throughputs for current and adjacent rates */
@@ -1944,7 +1971,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
lq_update:
/* Replace uCode's rate table for the destination station. */
if (update_lq) {
- rate = rate_n_flags_from_tbl(tbl, index, is_green);
+ rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
rs_fill_link_cmd(priv, lq_sta, rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
}
@@ -1993,7 +2020,7 @@ lq_update:
* stay with best antenna legacy modulation for a while
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
- if (is_legacy(tbl1->lq_type) && !conf->ht.enabled &&
+ if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
lq_sta->action_counter >= 1) {
lq_sta->action_counter = 0;
IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
@@ -2028,7 +2055,7 @@ lq_update:
}
out:
- tbl->current_rate = rate_n_flags_from_tbl(tbl, index, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
i = index;
lq_sta->last_txrate_idx = i;
@@ -2081,7 +2108,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
rs_toggle_antenna(valid_tx_ant, &rate, tbl);
- rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green);
+ rate = rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green);
tbl->current_rate = rate;
rs_set_expected_tpt_table(lq_sta, tbl);
rs_fill_link_cmd(NULL, lq_sta, rate);
@@ -2106,6 +2133,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
+ /* Get max rate if user set max rate */
+ if (lq_sta) {
+ lq_sta->max_rate_idx = txrc->max_rate_idx;
+ if ((sband->band == IEEE80211_BAND_5GHZ) &&
+ (lq_sta->max_rate_idx != -1))
+ lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
+ if ((lq_sta->max_rate_idx < 0) ||
+ (lq_sta->max_rate_idx >= IWL_RATE_COUNT))
+ lq_sta->max_rate_idx = -1;
+ }
+
if (sta)
mask_bit = sta->supp_rates[sband->band];
@@ -2182,6 +2220,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_conf *conf = &priv->hw->conf;
struct iwl_lq_sta *lq_sta = priv_sta;
u16 mask_bit = 0;
+ int count;
+ int start_rate = 0;
lq_sta->flush_timer = 0;
lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2216,6 +2256,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
}
lq_sta->is_dup = 0;
+ lq_sta->max_rate_idx = -1;
+ lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
lq_sta->is_green = rs_use_green(priv, conf);
lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->active_rate_basic = priv->active_rate_basic;
@@ -2254,16 +2296,20 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->drv = priv;
/* Find highest tx rate supported by hardware and destination station */
- mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate;
- lq_sta->last_txrate_idx = 3;
- for (i = 0; i < sband->n_bitrates; i++)
+ mask_bit = sta->supp_rates[sband->band];
+ count = sband->n_bitrates;
+ if (sband->band == IEEE80211_BAND_5GHZ) {
+ count += IWL_FIRST_OFDM_RATE;
+ start_rate = IWL_FIRST_OFDM_RATE;
+ mask_bit <<= IWL_FIRST_OFDM_RATE;
+ }
+
+ mask_bit = mask_bit & lq_sta->active_legacy_rate;
+ lq_sta->last_txrate_idx = 4;
+ for (i = start_rate; i < count; i++)
if (mask_bit & BIT(i))
lq_sta->last_txrate_idx = i;
- /* For MODE_IEEE80211A, skip over cck rates in global rate table */
- if (sband->band == IEEE80211_BAND_5GHZ)
- lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
-
rs_initialize_lq(priv, conf, sta, lq_sta);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 78ee83adf74..345806dd887 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
#ifndef __iwl_agn_rs_h__
#define __iwl_agn_rs_h__
-#include "iwl-dev.h"
-
struct iwl_rate_info {
u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
@@ -43,6 +41,19 @@ struct iwl_rate_info {
u8 next_rs_tgg; /* next rate used in TGG rs algo */
};
+struct iwl3945_rate_info {
+ u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
+ u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
+ u8 prev_ieee; /* previous rate in IEEE speeds */
+ u8 next_ieee; /* next rate in IEEE speeds */
+ u8 prev_rs; /* previous rate used in rs algo */
+ u8 next_rs; /* next rate used in rs algo */
+ u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
+ u8 next_rs_tgg; /* next rate used in TGG rs algo */
+ u8 table_rs_index; /* index in rate scale table cmd */
+ u8 prev_table_rs; /* prev in rate table cmd */
+};
+
/*
* These serve as indexes into
* struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -62,12 +73,30 @@ enum {
IWL_RATE_54M_INDEX,
IWL_RATE_60M_INDEX,
IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
+ IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
IWL_RATE_INVALID = IWL_RATE_COUNT,
};
enum {
+ IWL_RATE_6M_INDEX_TABLE = 0,
+ IWL_RATE_9M_INDEX_TABLE,
+ IWL_RATE_12M_INDEX_TABLE,
+ IWL_RATE_18M_INDEX_TABLE,
+ IWL_RATE_24M_INDEX_TABLE,
+ IWL_RATE_36M_INDEX_TABLE,
+ IWL_RATE_48M_INDEX_TABLE,
+ IWL_RATE_54M_INDEX_TABLE,
+ IWL_RATE_1M_INDEX_TABLE,
+ IWL_RATE_2M_INDEX_TABLE,
+ IWL_RATE_5M_INDEX_TABLE,
+ IWL_RATE_11M_INDEX_TABLE,
+ IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1,
+};
+
+enum {
IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
+ IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
@@ -248,6 +277,7 @@ enum {
#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
+extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
enum iwl_table_type {
LQ_NONE,
@@ -303,6 +333,23 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
return rate;
}
+static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
+{
+ u8 rate = iwl3945_rates[rate_index].prev_ieee;
+
+ if (rate == IWL_RATE_INVALID)
+ rate = rate_index;
+ return rate;
+}
+
+/**
+ * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
+ *
+ * The specific throughput table used is based on the type of network
+ * the associated with, including A, B, G, and G w/ TGG protection
+ */
+extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
+
/**
* iwl_rate_control_register - Register the rate control algorithm callbacks
*
@@ -314,6 +361,7 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
*
*/
extern int iwlagn_rate_control_register(void);
+extern int iwl3945_rate_control_register(void);
/**
* iwl_rate_control_unregister - Unregister the rate control callbacks
@@ -322,5 +370,6 @@ extern int iwlagn_rate_control_register(void);
* the driver is unloaded.
*/
extern void iwlagn_rate_control_unregister(void);
+extern void iwl3945_rate_control_unregister(void);
#endif /* __iwl_agn__rs__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b35c8813bef..6b7120a41ab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -44,6 +44,8 @@
#include <asm/div64.h>
+#define DRV_NAME "iwlagn"
+
#include "iwl-eeprom.h"
#include "iwl-dev.h"
#include "iwl-core.h"
@@ -61,9 +63,7 @@
/*
* module name, copyright, version, etc.
- * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
*/
-
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -179,9 +179,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* 5000, but will not damage 4965 */
priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
- ret = iwl_agn_check_rxon_cmd(&priv->staging_rxon);
+ ret = iwl_agn_check_rxon_cmd(priv);
if (ret) {
- IWL_ERROR("Invalid RXON configuration. Not committing.\n");
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
}
@@ -191,7 +191,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
if (!iwl_full_rxon_required(priv)) {
ret = iwl_send_rxon_assoc(priv);
if (ret) {
- IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret);
+ IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
@@ -218,7 +218,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* active_rxon back to what it was previously */
if (ret) {
active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERROR("Error clearing ASSOC_MSK (%d)\n", ret);
+ IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
return ret;
}
}
@@ -242,7 +242,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
if (ret) {
- IWL_ERROR("Error setting new RXON (%d)\n", ret);
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
@@ -256,7 +256,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
/* Add the broadcast address so we can send broadcast frames */
if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
IWL_INVALID_STATION) {
- IWL_ERROR("Error adding BROADCAST address for transmit.\n");
+ IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
return -EIO;
}
@@ -267,13 +267,15 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_rxon_add_station(priv,
priv->active_rxon.bssid_addr, 1);
if (ret == IWL_INVALID_STATION) {
- IWL_ERROR("Error adding AP address for TX.\n");
+ IWL_ERR(priv,
+ "Error adding AP address for TX.\n");
return -EIO;
}
priv->assoc_station_added = 1;
if (priv->default_wep_key &&
iwl_send_static_wepkey_cmd(priv, 0))
- IWL_ERROR("Could not send WEP static key.\n");
+ IWL_ERR(priv,
+ "Could not send WEP static key.\n");
}
/* Apply the new configuration
@@ -282,7 +284,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
if (ret) {
- IWL_ERROR("Error setting new RXON (%d)\n", ret);
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
@@ -294,7 +296,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* send a new TXPOWER command or we won't be able to Tx any frames */
ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
if (ret) {
- IWL_ERROR("Error sending TX power (%d)\n", ret);
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
return ret;
}
@@ -308,20 +310,6 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
iwl_commit_rxon(priv);
}
-static int iwl_send_bt_config(struct iwl_priv *priv)
-{
- struct iwl_bt_cmd bt_cmd = {
- .flags = 3,
- .lead_time = 0xAA,
- .max_kill = 1,
- .kill_ack_mask = 0,
- .kill_cts_mask = 0,
- };
-
- return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(struct iwl_bt_cmd), &bt_cmd);
-}
-
static void iwl_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
@@ -337,7 +325,7 @@ static void iwl_clear_free_frames(struct iwl_priv *priv)
}
if (priv->frames_count) {
- IWL_WARNING("%d frames still in use. Did we lose one?\n",
+ IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
priv->frames_count);
priv->frames_count = 0;
}
@@ -350,7 +338,7 @@ static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
if (list_empty(&priv->free_frames)) {
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame) {
- IWL_ERROR("Could not allocate frame!\n");
+ IWL_ERR(priv, "Could not allocate frame!\n");
return NULL;
}
@@ -452,7 +440,7 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
frame = iwl_get_free_frame(priv);
if (!frame) {
- IWL_ERROR("Could not obtain free frame buffer for beacon "
+ IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
"command.\n");
return -ENOMEM;
}
@@ -469,6 +457,159 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
return rc;
}
+static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+ dma_addr_t addr = get_unaligned_le32(&tb->lo);
+ if (sizeof(dma_addr_t) > sizeof(u32))
+ addr |=
+ ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
+
+ return addr;
+}
+
+static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+ return le16_to_cpu(tb->hi_n_len) >> 4;
+}
+
+static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
+ dma_addr_t addr, u16 len)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+ u16 hi_n_len = len << 4;
+
+ put_unaligned_le32(addr, &tb->lo);
+ if (sizeof(dma_addr_t) > sizeof(u32))
+ hi_n_len |= ((addr >> 16) >> 16) & 0xF;
+
+ tb->hi_n_len = cpu_to_le16(hi_n_len);
+
+ tfd->num_tbs = idx + 1;
+}
+
+static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
+{
+ return tfd->num_tbs & 0x1f;
+}
+
+/**
+ * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
+ * @priv - driver private data
+ * @txq - tx queue
+ *
+ * Does NOT advance any TFD circular buffer read/write indexes
+ * Does NOT free the TFD itself (which is within circular buffer)
+ */
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+ struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds;
+ struct iwl_tfd *tfd;
+ struct pci_dev *dev = priv->pci_dev;
+ int index = txq->q.read_ptr;
+ int i;
+ int num_tbs;
+
+ tfd = &tfd_tmp[index];
+
+ /* Sanity check on number of chunks */
+ num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+ if (num_tbs >= IWL_NUM_OF_TBS) {
+ IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
+ /* @todo issue fatal error, it is quite serious situation */
+ return;
+ }
+
+ /* Unmap tx_cmd */
+ if (num_tbs)
+ pci_unmap_single(dev,
+ pci_unmap_addr(&txq->cmd[index]->meta, mapping),
+ pci_unmap_len(&txq->cmd[index]->meta, len),
+ PCI_DMA_TODEVICE);
+
+ /* Unmap chunks, if any. */
+ for (i = 1; i < num_tbs; i++) {
+ pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
+ iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
+
+ if (txq->txb) {
+ dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
+ txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
+ }
+ }
+}
+
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len,
+ u8 reset, u8 pad)
+{
+ struct iwl_queue *q;
+ struct iwl_tfd *tfd, *tfd_tmp;
+ u32 num_tbs;
+
+ q = &txq->q;
+ tfd_tmp = (struct iwl_tfd *)txq->tfds;
+ tfd = &tfd_tmp[q->write_ptr];
+
+ if (reset)
+ memset(tfd, 0, sizeof(*tfd));
+
+ num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+ /* Each TFD can point to a maximum 20 Tx buffers */
+ if (num_tbs >= IWL_NUM_OF_TBS) {
+ IWL_ERR(priv, "Error can not send more than %d chunks\n",
+ IWL_NUM_OF_TBS);
+ return -EINVAL;
+ }
+
+ BUG_ON(addr & ~DMA_BIT_MASK(36));
+ if (unlikely(addr & ~IWL_TX_DMA_MASK))
+ IWL_ERR(priv, "Unaligned address = %llx\n",
+ (unsigned long long)addr);
+
+ iwl_tfd_set_tb(tfd, num_tbs, addr, len);
+
+ return 0;
+}
+
+/*
+ * Tell nic where to find circular buffer of Tx Frame Descriptors for
+ * given Tx queue, and enable the DMA channel used for that queue.
+ *
+ * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * channels supported in hardware.
+ */
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
+{
+ int ret;
+ unsigned long flags;
+ int txq_id = txq->q.id;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ /* Circular buffer (TFD queue in DRAM) physical base address */
+ iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
+ txq->q.dma_addr >> 8);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+
/******************************************************************************
*
* Misc. internal state and helper functions
@@ -520,9 +661,9 @@ static void iwl_ht_conf(struct iwl_priv *priv,
*/
iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
- if (priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40MINUS)
+ if (conf_is_ht40_minus(&priv->hw->conf))
iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- else if(priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40PLUS)
+ else if (conf_is_ht40_plus(&priv->hw->conf))
iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
/* If no above or below channel supplied disable FAT channel */
@@ -686,7 +827,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
break;
default:
- IWL_ERROR("Unsupported interface type %d\n", mode);
+ IWL_ERR(priv, "Unsupported interface type %d\n", mode);
break;
}
@@ -745,7 +886,7 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
cancel_delayed_work(&priv->scan_check);
if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress after 100ms\n");
+ IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
return -EAGAIN;
}
@@ -763,7 +904,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
hw = iwl_get_hw_mode(priv, priv->band);
if (!hw) {
- IWL_ERROR("Failed to set rate: unable to get hw mode\n");
+ IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n");
return;
}
@@ -841,7 +982,7 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
queue_delayed_work(priv->workqueue, pwork,
msecs_to_jiffies(5));
else
- IWL_WARNING("uCode did not respond OK.\n");
+ IWL_WARN(priv, "uCode did not respond OK.\n");
}
static void iwl_rx_reply_error(struct iwl_priv *priv,
@@ -849,7 +990,7 @@ static void iwl_rx_reply_error(struct iwl_priv *priv,
{
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
+ IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
"seq 0x%04X ser 0x%08X\n",
le32_to_cpu(pkt->u.err_resp.error_type),
get_cmd_string(pkt->u.err_resp.cmd_id),
@@ -902,7 +1043,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
beacon = ieee80211_beacon_get(priv->hw, priv->vif);
if (!beacon) {
- IWL_ERROR("update beacon failed\n");
+ IWL_ERR(priv, "update beacon failed\n");
return;
}
@@ -1193,7 +1334,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
if (rxb && rxb->skb)
iwl_tx_cmd_complete(priv, rxb);
else
- IWL_WARNING("Claim null rxb?\n");
+ IWL_WARN(priv, "Claim null rxb?\n");
}
/* For now we just don't re-use anything. We can tweak this
@@ -1357,7 +1498,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Now service all interrupt bits discovered above. */
if (inta & CSR_INT_BIT_HW_ERR) {
- IWL_ERROR("Microcode HW error detected. Restarting.\n");
+ IWL_ERR(priv, "Microcode HW error detected. Restarting.\n");
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
@@ -1397,13 +1538,16 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
hw_rf_kill ? "disable radio" : "enable radio");
/* driver only loads ucode once setting the interface up.
- * the driver as well won't allow loading if RFKILL is set
- * therefore no need to restart the driver from this handler
+ * the driver allows loading the ucode even if the radio
+ * is killed. Hence update the killswitch state here. The
+ * rfkill handler will care about restarting if needed.
*/
- if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
- clear_bit(STATUS_RF_KILL_HW, &priv->status);
- if (priv->is_open && !iwl_is_rfkill(priv))
- queue_work(priv->workqueue, &priv->up);
+ if (!test_bit(STATUS_ALIVE, &priv->status)) {
+ if (hw_rf_kill)
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ queue_work(priv->workqueue, &priv->rf_kill);
}
handled |= CSR_INT_BIT_RF_KILL;
@@ -1411,14 +1555,14 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Chip got too hot and stopped itself */
if (inta & CSR_INT_BIT_CT_KILL) {
- IWL_ERROR("Microcode CT kill error detected.\n");
+ IWL_ERR(priv, "Microcode CT kill error detected.\n");
handled |= CSR_INT_BIT_CT_KILL;
}
/* Error detected by uCode */
if (inta & CSR_INT_BIT_SW_ERR) {
- IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n",
- inta);
+ IWL_ERR(priv, "Microcode SW error detected. "
+ " Restarting 0x%X.\n", inta);
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -1454,12 +1598,12 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
}
if (inta & ~handled)
- IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
if (inta & ~CSR_INI_SET_MASK) {
- IWL_WARNING("Disabled INTA bits 0x%08x were pending\n",
+ IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
inta & ~CSR_INI_SET_MASK);
- IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh);
+ IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
/* Re-enable all interrupts */
@@ -1511,7 +1655,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
/* Hardware disappeared. It might have already raised
* an interrupt */
- IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
+ IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
goto unplugged;
}
@@ -1584,7 +1728,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
sprintf(buf, "%s%d%s", name_pre, index, ".ucode");
ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
if (ret < 0) {
- IWL_ERROR("%s firmware file req failed: Reason %d\n",
+ IWL_ERR(priv, "%s firmware file req failed: %d\n",
buf, ret);
if (ret == -ENOENT)
continue;
@@ -1592,8 +1736,11 @@ static int iwl_read_ucode(struct iwl_priv *priv)
goto error;
} else {
if (index < api_max)
- IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+ IWL_ERR(priv, "Loaded firmware %s, "
+ "which is deprecated. "
+ "Please use API v%u instead.\n",
buf, api_max);
+
IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
buf, ucode_raw->size);
break;
@@ -1605,7 +1752,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Make sure that we got at least our header! */
if (ucode_raw->size < sizeof(*ucode)) {
- IWL_ERROR("File size way too small!\n");
+ IWL_ERR(priv, "File size way too small!\n");
ret = -EINVAL;
goto err_release;
}
@@ -1626,7 +1773,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
* on the API version read from firware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
- IWL_ERROR("Driver unable to support your firmware API. "
+ IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
api_max, api_ver);
priv->ucode_ver = 0;
@@ -1634,16 +1781,16 @@ static int iwl_read_ucode(struct iwl_priv *priv)
goto err_release;
}
if (api_ver != api_max)
- IWL_ERROR("Firmware has old API version. Expected v%u, "
+ IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
"got v%u. New firmware can be obtained "
"from http://www.intellinuxwireless.org.\n",
api_max, api_ver);
- printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
- IWL_UCODE_MAJOR(priv->ucode_ver),
- IWL_UCODE_MINOR(priv->ucode_ver),
- IWL_UCODE_API(priv->ucode_ver),
- IWL_UCODE_SERIAL(priv->ucode_ver));
+ IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
+ IWL_UCODE_MAJOR(priv->ucode_ver),
+ IWL_UCODE_MINOR(priv->ucode_ver),
+ IWL_UCODE_API(priv->ucode_ver),
+ IWL_UCODE_SERIAL(priv->ucode_ver));
IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
priv->ucode_ver);
@@ -1791,7 +1938,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
return 0;
err_pci_alloc:
- IWL_ERROR("failed to allocate pci memory\n");
+ IWL_ERR(priv, "failed to allocate pci memory\n");
ret = -ENOMEM;
iwl_dealloc_ucode_pci(priv);
@@ -1837,8 +1984,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
- IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n",
- ret);
+ IWL_WARN(priv,
+ "Could not complete ALIVE transition [ntf]: %d\n", ret);
goto restart;
}
@@ -2024,12 +2171,12 @@ static int __iwl_up(struct iwl_priv *priv)
int ret;
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_WARNING("Exit pending; will not bring the NIC up\n");
+ IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
}
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
- IWL_ERROR("ucode not available for device bringup\n");
+ IWL_ERR(priv, "ucode not available for device bringup\n");
return -EIO;
}
@@ -2041,7 +2188,7 @@ static int __iwl_up(struct iwl_priv *priv)
if (iwl_is_rfkill(priv)) {
iwl_enable_interrupts(priv);
- IWL_WARNING("Radio disabled by %s RF Kill switch\n",
+ IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
return 0;
}
@@ -2050,7 +2197,7 @@ static int __iwl_up(struct iwl_priv *priv)
ret = iwl_hw_nic_init(priv);
if (ret) {
- IWL_ERROR("Unable to init nic\n");
+ IWL_ERR(priv, "Unable to init nic\n");
return ret;
}
@@ -2083,7 +2230,8 @@ static int __iwl_up(struct iwl_priv *priv)
ret = priv->cfg->ops->lib->load_ucode(priv);
if (ret) {
- IWL_ERROR("Unable to set up bootstrap uCode: %d\n", ret);
+ IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
+ ret);
continue;
}
@@ -2104,7 +2252,7 @@ static int __iwl_up(struct iwl_priv *priv)
/* tried to restart and config the device for as long as our
* patience could withstand */
- IWL_ERROR("Unable to initialize device after %d attempts.\n", i);
+ IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
return -EIO;
}
@@ -2141,40 +2289,6 @@ static void iwl_bg_alive_start(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl_bg_rf_kill(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
-
- if (!iwl_is_rfkill(priv)) {
- IWL_DEBUG(IWL_DL_RF_KILL,
- "HW and/or SW RF Kill no longer active, restarting "
- "device\n");
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- queue_work(priv->workqueue, &priv->restart);
- } else {
- /* make sure mac80211 stop sending Tx frame */
- if (priv->mac80211_registered)
- ieee80211_stop_queues(priv->hw);
-
- if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by SW switch\n");
- else
- IWL_WARNING("Radio Frequency Kill Switch is On:\n"
- "Kill switch must be turned off for "
- "wireless networking to work.\n");
- }
- mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
-}
-
static void iwl_bg_run_time_calib_work(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -2244,7 +2358,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
unsigned long flags;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- IWL_ERROR("%s Should not be called in AP mode\n", __func__);
+ IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
@@ -2271,7 +2385,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -2317,7 +2431,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
break;
default:
- IWL_ERROR("%s Should not be called in %d mode\n",
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
__func__, priv->iw_mode);
break;
}
@@ -2353,31 +2467,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
- u16 pci_cmd;
IWL_DEBUG_MAC80211("enter\n");
- if (pci_enable_device(priv->pci_dev)) {
- IWL_ERROR("Fail to pci_enable_device\n");
- return -ENODEV;
- }
- pci_restore_state(priv->pci_dev);
- pci_enable_msi(priv->pci_dev);
-
- /* enable interrupts if needed: hw bug w/a */
- pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
- if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
- pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
- pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
- }
-
- ret = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
- DRV_NAME, priv);
- if (ret) {
- IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
- goto out_disable_msi;
- }
-
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
@@ -2388,9 +2480,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
if (!priv->ucode_code.len) {
ret = iwl_read_ucode(priv);
if (ret) {
- IWL_ERROR("Could not read microcode: %d\n", ret);
+ IWL_ERR(priv, "Could not read microcode: %d\n", ret);
mutex_unlock(&priv->mutex);
- goto out_release_irq;
+ return ret;
}
}
@@ -2401,7 +2493,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
iwl_rfkill_set_hw_state(priv);
if (ret)
- goto out_release_irq;
+ return ret;
if (iwl_is_rfkill(priv))
goto out;
@@ -2418,10 +2510,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
UCODE_READY_TIMEOUT);
if (!ret) {
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERROR("START_ALIVE timeout after %dms.\n",
+ IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
jiffies_to_msecs(UCODE_READY_TIMEOUT));
- ret = -ETIMEDOUT;
- goto out_release_irq;
+ return -ETIMEDOUT;
}
}
@@ -2429,15 +2520,6 @@ out:
priv->is_open = 1;
IWL_DEBUG_MAC80211("leave\n");
return 0;
-
-out_release_irq:
- free_irq(priv->pci_dev->irq, priv);
-out_disable_msi:
- pci_disable_msi(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
- priv->is_open = 0;
- IWL_DEBUG_MAC80211("leave - failed\n");
- return ret;
}
static void iwl_mac_stop(struct ieee80211_hw *hw)
@@ -2465,10 +2547,10 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
iwl_down(priv);
flush_workqueue(priv->workqueue);
- free_irq(priv->pci_dev->irq, priv);
- pci_disable_msi(priv->pci_dev);
- pci_save_state(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
+
+ /* enable interrupts again in order to receive rfkill changes */
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_enable_interrupts(priv);
IWL_DEBUG_MAC80211("leave\n");
}
@@ -2544,7 +2626,7 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
- priv->current_ht_config.is_ht = conf->ht.enabled;
+ priv->current_ht_config.is_ht = conf_is_ht(conf);
if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
@@ -2577,7 +2659,7 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
!is_channel_ibss(ch_info)) {
- IWL_ERROR("channel %d in band %d not IBSS channel\n",
+ IWL_ERR(priv, "channel %d in band %d not IBSS channel\n",
conf->channel->hw_value, conf->channel->band);
ret = -EINVAL;
goto out;
@@ -2639,6 +2721,9 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
iwl_set_rate(priv);
+ /* call to ensure that 4965 rx_chain is set properly in monitor mode */
+ iwl_set_rxon_chain(priv);
+
if (memcmp(&priv->active_rxon,
&priv->staging_rxon, sizeof(priv->staging_rxon)))
iwl_commit_rxon(priv);
@@ -2672,7 +2757,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
iwl_set_rxon_chain(priv);
@@ -2778,7 +2863,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
/* If there is currently a HW scan going on in the background
* then we need to cancel it else the RXON below will fail. */
if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress "
+ IWL_WARN(priv, "Aborted scan still in progress "
"after 100ms\n");
IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
mutex_unlock(&priv->mutex);
@@ -3019,13 +3104,15 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
}
static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
- int ret = 0;
- u8 sta_id = IWL_INVALID_STATION;
- u8 is_default_wep_key = 0;
+ const u8 *addr;
+ int ret;
+ u8 sta_id;
+ bool is_default_wep_key = false;
IWL_DEBUG_MAC80211("enter\n");
@@ -3033,11 +3120,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
-
- if (is_zero_ether_addr(addr))
- /* only support pairwise keys */
- return -EOPNOTSUPP;
-
+ addr = sta ? sta->addr : iwl_bcast_addr;
sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
@@ -3359,8 +3442,7 @@ static ssize_t store_debug_level(struct device *d,
ret = strict_strtoul(buf, 0, &val);
if (ret)
- printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
+ IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
else
priv->debug_level = val;
@@ -3439,8 +3521,7 @@ static ssize_t store_tx_power(struct device *d,
ret = strict_strtoul(buf, 10, &val);
if (ret)
- printk(KERN_INFO DRV_NAME
- ": %s is not in decimal form.\n", buf);
+ IWL_INFO(priv, "%s is not in decimal form.\n", buf);
else
iwl_set_tx_power(priv, val, false);
@@ -3473,7 +3554,7 @@ static ssize_t store_flags(struct device *d,
if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
@@ -3512,7 +3593,7 @@ static ssize_t store_filter_flags(struct device *d,
if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
IWL_DEBUG_INFO("Committing rxon.filter_flags = "
"0x%04X\n", filter_flags);
@@ -3529,31 +3610,6 @@ static ssize_t store_filter_flags(struct device *d,
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
store_filter_flags);
-static ssize_t store_retry_rate(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwl_priv *priv = dev_get_drvdata(d);
- long val;
- int ret = strict_strtol(buf, 10, &val);
- if (!ret)
- return ret;
-
- priv->retry_rate = (val > 0) ? val : 1;
-
- return count;
-}
-
-static ssize_t show_retry_rate(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl_priv *priv = dev_get_drvdata(d);
- return sprintf(buf, "%d", priv->retry_rate);
-}
-
-static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
- store_retry_rate);
-
static ssize_t store_power_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -3656,16 +3712,6 @@ static ssize_t show_statistics(struct device *d,
static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
-static ssize_t show_status(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- if (!iwl_is_alive(priv))
- return -EAGAIN;
- return sprintf(buf, "0x%08x\n", (int)priv->status);
-}
-
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
/*****************************************************************************
*
@@ -3719,9 +3765,7 @@ static struct attribute *iwl_sysfs_entries[] = {
&dev_attr_flags.attr,
&dev_attr_filter_flags.attr,
&dev_attr_power_level.attr,
- &dev_attr_retry_rate.attr,
&dev_attr_statistics.attr,
- &dev_attr_status.attr,
&dev_attr_temperature.attr,
&dev_attr_tx_power.attr,
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -3764,6 +3808,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
unsigned long flags;
+ u16 pci_cmd;
/************************
* 1. Allocating HW data
@@ -3816,8 +3861,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
/* both attempts failed: */
if (err) {
- printk(KERN_WARNING "%s: No suitable DMA available.\n",
- DRV_NAME);
+ IWL_WARN(priv, "No suitable DMA available.\n");
goto out_pci_disable_device;
}
}
@@ -3843,8 +3887,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
iwl_hw_detect(priv);
- printk(KERN_INFO DRV_NAME
- ": Detected Intel Wireless WiFi Link %s REV=0x%X\n",
+ IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
priv->cfg->name, priv->hw_rev);
/* We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -3863,7 +3906,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Read the EEPROM */
err = iwl_eeprom_init(priv);
if (err) {
- IWL_ERROR("Unable to init EEPROM\n");
+ IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_iounmap;
}
err = iwl_eeprom_check_version(priv);
@@ -3879,7 +3922,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 5. Setup HW constants
************************/
if (iwl_set_hw_params(priv)) {
- IWL_ERROR("failed to set hw parameters\n");
+ IWL_ERR(priv, "failed to set hw parameters\n");
goto out_free_eeprom;
}
@@ -3909,43 +3952,65 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
+ pci_enable_msi(priv->pci_dev);
+
+ err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
+ DRV_NAME, priv);
+ if (err) {
+ IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
+ goto out_disable_msi;
+ }
err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
if (err) {
- IWL_ERROR("failed to create sysfs device attributes\n");
+ IWL_ERR(priv, "failed to create sysfs device attributes\n");
goto out_uninit_drv;
}
-
iwl_setup_deferred_work(priv);
iwl_setup_rx_handlers(priv);
- /********************
- * 9. Conclude
- ********************/
- pci_save_state(pdev);
- pci_disable_device(pdev);
-
/**********************************
- * 10. Setup and register mac80211
+ * 9. Setup and register mac80211
**********************************/
+ /* enable interrupts if needed: hw bug w/a */
+ pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
+ if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
+ pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+ pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
+ }
+
+ iwl_enable_interrupts(priv);
+
err = iwl_setup_mac(priv);
if (err)
goto out_remove_sysfs;
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
- IWL_ERROR("failed to create debugfs files\n");
+ IWL_ERR(priv, "failed to create debugfs files\n");
+
+ /* If platform's RF_KILL switch is NOT set to KILL */
+ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
err = iwl_rfkill_init(priv);
if (err)
- IWL_ERROR("Unable to initialize RFKILL system. "
+ IWL_ERR(priv, "Unable to initialize RFKILL system. "
"Ignoring error: %d\n", err);
+ else
+ iwl_rfkill_set_hw_state(priv);
+
iwl_power_initialize(priv);
return 0;
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
+ out_disable_msi:
+ pci_disable_msi(priv->pci_dev);
+ pci_disable_device(priv->pci_dev);
out_uninit_drv:
iwl_uninit_drv(priv);
out_free_eeprom:
@@ -4017,6 +4082,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
+ free_irq(priv->pci_dev->irq, priv);
+ pci_disable_msi(priv->pci_dev);
pci_iounmap(pdev, priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -4042,6 +4109,8 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
priv->is_open = 1;
}
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
@@ -4052,6 +4121,9 @@ static int iwl_pci_resume(struct pci_dev *pdev)
struct iwl_priv *priv = pci_get_drvdata(pdev);
pci_set_power_state(pdev, PCI_D0);
+ pci_enable_device(pdev);
+ pci_restore_state(pdev);
+ iwl_enable_interrupts(priv);
if (priv->is_open)
iwl_mac_start(priv->hw);
@@ -4092,6 +4164,21 @@ static struct pci_device_id iwl_hw_card_ids[] = {
/* 5150 Wifi/WiMax */
{IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
{IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
+/* 6000/6050 Series */
+ {IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)},
+/* 100 Series WiFi */
+ {IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl100_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl100_bgn_cfg)},
#endif /* CONFIG_IWL5000 */
{0}
@@ -4118,13 +4205,14 @@ static int __init iwl_init(void)
ret = iwlagn_rate_control_register();
if (ret) {
- IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+ printk(KERN_ERR DRV_NAME
+ "Unable to register rate control algorithm: %d\n", ret);
return ret;
}
ret = pci_register_driver(&iwl_driver);
if (ret) {
- IWL_ERROR("Unable to initialize PCI module\n");
+ printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
goto error_register;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index f836ecc5575..8e5e6663be3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -102,7 +102,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
return 0;
err:
- IWL_ERROR("Error %d iteration %d\n", ret, i);
+ IWL_ERR(priv, "Error %d iteration %d\n", ret, i);
return ret;
}
EXPORT_SYMBOL(iwl_send_calib_results);
@@ -483,7 +483,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
ret = iwl_send_cmd(priv, &cmd_out);
if (ret)
- IWL_ERROR("SENSITIVITY_CMD failed\n");
+ IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index 1abe84bb74a..b6cef989a79 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index ba997204c8d..e49415c7fb2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,12 +69,20 @@
#ifndef __iwl_commands_h__
#define __iwl_commands_h__
+struct iwl_priv;
+
/* uCode version contains 4 values: Major/Minor/API/Serial */
#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
+
+/* Tx rates */
+#define IWL_CCK_RATES 4
+#define IWL_OFDM_RATES 8
+#define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES)
+
enum {
REPLY_ALIVE = 0x1,
REPLY_ERROR = 0x2,
@@ -219,6 +227,37 @@ struct iwl_cmd_header {
u8 data[0];
} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_tx_power
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
+ *
+ * Each entry contains two values:
+ * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained
+ * linear value that multiplies the output of the digital signal processor,
+ * before being sent to the analog radio.
+ * 2) Radio gain. This sets the analog gain of the radio Tx path.
+ * It is a coarser setting, and behaves in a logarithmic (dB) fashion.
+ *
+ * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
+ */
+struct iwl3945_tx_power {
+ u8 tx_gain; /* gain for analog radio */
+ u8 dsp_atten; /* gain for DSP */
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_power_per_rate
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
+ */
+struct iwl3945_power_per_rate {
+ u8 rate; /* plcp */
+ struct iwl3945_tx_power tpc;
+ u8 reserved;
+} __attribute__ ((packed));
+
/**
* iwlagn rate_n_flags bit fields
*
@@ -300,11 +339,12 @@ struct iwl_cmd_header {
* 5350 has 3 transmitters
* bit14:16
*/
-#define RATE_MCS_ANT_POS 14
-#define RATE_MCS_ANT_A_MSK 0x04000
-#define RATE_MCS_ANT_B_MSK 0x08000
-#define RATE_MCS_ANT_C_MSK 0x10000
-#define RATE_MCS_ANT_ABC_MSK 0x1C000
+#define RATE_MCS_ANT_POS 14
+#define RATE_MCS_ANT_A_MSK 0x04000
+#define RATE_MCS_ANT_B_MSK 0x08000
+#define RATE_MCS_ANT_C_MSK 0x10000
+#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | RATE_MCS_ANT_B_MSK)
+#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | RATE_MCS_ANT_C_MSK)
#define RATE_ANT_NUM 3
#define POWER_TABLE_NUM_ENTRIES 33
@@ -492,8 +532,6 @@ struct iwl_alive_resp {
__le32 is_valid;
} __attribute__ ((packed));
-
-
/*
* REPLY_ERROR = 0x2 (response only, not a command)
*/
@@ -525,6 +563,7 @@ enum {
#define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0)
+#define RXON_RX_CHAIN_DRIVER_FORCE_POS (0)
#define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1)
#define RXON_RX_CHAIN_VALID_POS (1)
#define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4)
@@ -611,6 +650,26 @@ enum {
* issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
* regardless of whether RXON_FILTER_ASSOC_MSK is set.
*/
+
+struct iwl3945_rxon_cmd {
+ u8 node_addr[6];
+ __le16 reserved1;
+ u8 bssid_addr[6];
+ __le16 reserved2;
+ u8 wlap_bssid_addr[6];
+ __le16 reserved3;
+ u8 dev_type;
+ u8 air_propagation;
+ __le16 reserved4;
+ u8 ofdm_basic_rates;
+ u8 cck_basic_rates;
+ __le16 assoc_id;
+ __le32 flags;
+ __le32 filter_flags;
+ __le16 channel;
+ __le16 reserved5;
+} __attribute__ ((packed));
+
struct iwl4965_rxon_cmd {
u8 node_addr[6];
__le16 reserved1;
@@ -656,33 +715,41 @@ struct iwl_rxon_cmd {
__le16 reserved6;
} __attribute__ ((packed));
-struct iwl5000_rxon_assoc_cmd {
+/*
+ * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
+ */
+struct iwl3945_rxon_assoc_cmd {
+ __le32 flags;
+ __le32 filter_flags;
+ u8 ofdm_basic_rates;
+ u8 cck_basic_rates;
+ __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwl4965_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
u8 cck_basic_rates;
- __le16 reserved1;
u8 ofdm_ht_single_stream_basic_rates;
u8 ofdm_ht_dual_stream_basic_rates;
- u8 ofdm_ht_triple_stream_basic_rates;
- u8 reserved2;
__le16 rx_chain_select_flags;
- __le16 acquisition_data;
- __le32 reserved3;
+ __le16 reserved;
} __attribute__ ((packed));
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl4965_rxon_assoc_cmd {
+struct iwl5000_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
u8 cck_basic_rates;
+ __le16 reserved1;
u8 ofdm_ht_single_stream_basic_rates;
u8 ofdm_ht_dual_stream_basic_rates;
+ u8 ofdm_ht_triple_stream_basic_rates;
+ u8 reserved2;
__le16 rx_chain_select_flags;
- __le16 reserved;
+ __le16 acquisition_data;
+ __le32 reserved3;
} __attribute__ ((packed));
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
@@ -702,6 +769,16 @@ struct iwl_rxon_time_cmd {
/*
* REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
*/
+struct iwl3945_channel_switch_cmd {
+ u8 band;
+ u8 expect_beacon;
+ __le16 channel;
+ __le32 rxon_flags;
+ __le32 rxon_filter_flags;
+ __le32 switch_time;
+ struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
struct iwl_channel_switch_cmd {
u8 band;
u8 expect_beacon;
@@ -783,6 +860,8 @@ struct iwl_qosparam_cmd {
#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 IWL5000_BROADCAST_ID 15
@@ -791,6 +870,8 @@ struct iwl_qosparam_cmd {
#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
#define IWL_INVALID_STATION 255
+#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2);
+#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
#define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17)
#define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18)
@@ -901,6 +982,35 @@ struct sta_id_modify {
* used as AP, or in an IBSS network, driver must set up station table
* entries for all STAs in network, starting with index IWL_STA_ID.
*/
+
+struct iwl3945_addsta_cmd {
+ u8 mode; /* 1: modify existing, 0: add new station */
+ u8 reserved[3];
+ struct sta_id_modify sta;
+ struct iwl4965_keyinfo key;
+ __le32 station_flags; /* STA_FLG_* */
+ __le32 station_flags_msk; /* STA_FLG_* */
+
+ /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
+ * corresponding to bit (e.g. bit 5 controls TID 5).
+ * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
+ __le16 tid_disable_tx;
+
+ __le16 rate_n_flags;
+
+ /* TID for which to add block-ack support.
+ * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+ u8 add_immediate_ba_tid;
+
+ /* TID for which to remove block-ack support.
+ * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
+ u8 remove_immediate_ba_tid;
+
+ /* Starting Sequence Number for added block-ack support.
+ * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+ __le16 add_immediate_ba_ssn;
+} __attribute__ ((packed));
+
struct iwl4965_addsta_cmd {
u8 mode; /* 1: modify existing, 0: add new station */
u8 reserved[3];
@@ -1054,6 +1164,48 @@ struct iwl_wep_cmd {
#define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7)
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
+
+struct iwl3945_rx_frame_stats {
+ u8 phy_count;
+ u8 id;
+ u8 rssi;
+ u8 agc;
+ __le16 sig_avg;
+ __le16 noise_diff;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_hdr {
+ __le16 channel;
+ __le16 phy_flags;
+ u8 reserved1;
+ u8 rate;
+ __le16 len;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_end {
+ __le32 status;
+ __le64 timestamp;
+ __le32 beacon_timestamp;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_3945_RX = 0x1b (response only, not a command)
+ *
+ * NOTE: DO NOT dereference from casts to this structure
+ * It is provided only for calculating minimum data set size.
+ * The actual offsets of the hdr and end are dynamic based on
+ * stats.phy_count
+ */
+struct iwl3945_rx_frame {
+ struct iwl3945_rx_frame_stats stats;
+ struct iwl3945_rx_frame_hdr hdr;
+ struct iwl3945_rx_frame_end end;
+} __attribute__ ((packed));
+
+#define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
+
/* Fixed (non-configurable) rx data from phy */
#define IWL49_RX_RES_PHY_CNT 14
@@ -1234,6 +1386,84 @@ struct iwl4965_rx_mpdu_res_start {
#define TKIP_ICV_LEN 4
/*
+ * REPLY_TX = 0x1c (command)
+ */
+
+struct iwl3945_tx_cmd {
+ /*
+ * MPDU byte count:
+ * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
+ * + 8 byte IV for CCM or TKIP (not used for WEP)
+ * + Data payload
+ * + 8-byte MIC (not used for CCM/WEP)
+ * NOTE: Does not include Tx command bytes, post-MAC pad bytes,
+ * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
+ * Range: 14-2342 bytes.
+ */
+ __le16 len;
+
+ /*
+ * MPDU or MSDU byte count for next frame.
+ * Used for fragmentation and bursting, but not 11n aggregation.
+ * Same as "len", but for next frame. Set to 0 if not applicable.
+ */
+ __le16 next_frame_len;
+
+ __le32 tx_flags; /* TX_CMD_FLG_* */
+
+ u8 rate;
+
+ /* Index of recipient station in uCode's station table */
+ u8 sta_id;
+ u8 tid_tspec;
+ u8 sec_ctl;
+ u8 key[16];
+ union {
+ u8 byte[8];
+ __le16 word[4];
+ __le32 dw[2];
+ } tkip_mic;
+ __le32 next_frame_info;
+ union {
+ __le32 life_time;
+ __le32 attempt;
+ } stop_time;
+ u8 supp_rates[2];
+ u8 rts_retry_limit; /*byte 50 */
+ u8 data_retry_limit; /*byte 51 */
+ union {
+ __le16 pm_frame_timeout;
+ __le16 attempt_duration;
+ } timeout;
+
+ /*
+ * Duration of EDCA burst Tx Opportunity, in 32-usec units.
+ * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
+ */
+ __le16 driver_txop;
+
+ /*
+ * MAC header goes here, followed by 2 bytes padding if MAC header
+ * length is 26 or 30 bytes, followed by payload data
+ */
+ u8 payload[0];
+ struct ieee80211_hdr hdr[0];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX = 0x1c (response)
+ */
+struct iwl3945_tx_resp {
+ u8 failure_rts;
+ u8 failure_frame;
+ u8 bt_kill_count;
+ u8 rate;
+ __le32 wireless_media_time;
+ __le32 status; /* TX status */
+} __attribute__ ((packed));
+
+
+/*
* 4965 uCode updates these Tx attempt count values in host DRAM.
* Used for managing Tx retries when expecting block-acks.
* Driver should set these fields to 0.
@@ -1244,9 +1474,6 @@ struct iwl_dram_scratch {
__le16 reserved;
} __attribute__ ((packed));
-/*
- * REPLY_TX = 0x1c (command)
- */
struct iwl_tx_cmd {
/*
* MPDU byte count:
@@ -1584,6 +1811,14 @@ struct iwl_compressed_ba_resp {
*
* See details under "TXPOWER" in iwl-4965-hw.h.
*/
+
+struct iwl3945_txpowertable_cmd {
+ u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
+ u8 reserved;
+ __le16 channel;
+ struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
struct iwl4965_txpowertable_cmd {
u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
u8 reserved;
@@ -1591,6 +1826,35 @@ struct iwl4965_txpowertable_cmd {
struct iwl4965_tx_power_db tx_power;
} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
+ *
+ * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
+ *
+ * NOTE: The table of rates passed to the uCode via the
+ * RATE_SCALE command sets up the corresponding order of
+ * rates used for all related commands, including rate
+ * masks, etc.
+ *
+ * For example, if you set 9MB (PLCP 0x0f) as the first
+ * rate in the rate table, the bit mask for that rate
+ * when passed through ofdm_basic_rates on the REPLY_RXON
+ * command would be bit 0 (1 << 0)
+ */
+struct iwl3945_rate_scaling_info {
+ __le16 rate_n_flags;
+ u8 try_cnt;
+ u8 next_rate_index;
+} __attribute__ ((packed));
+
+struct iwl3945_rate_scaling_cmd {
+ u8 table_id;
+ u8 reserved[3];
+ struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
+
/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0)
@@ -2044,15 +2308,23 @@ struct iwl_spectrum_notification {
*/
#define IWL_POWER_VEC_SIZE 5
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(1 << 0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(1 << 2)
-#define IWL_POWER_PCI_PM_MSK cpu_to_le16(1 << 3)
-#define IWL_POWER_FAST_PD cpu_to_le16(1 << 4)
+#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0))
+#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2))
+#define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3))
+#define IWL_POWER_FAST_PD cpu_to_le16(BIT(4))
+
+struct iwl3945_powertable_cmd {
+ __le16 flags;
+ u8 reserved[2];
+ __le32 rx_data_timeout;
+ __le32 tx_data_timeout;
+ __le32 sleep_interval[IWL_POWER_VEC_SIZE];
+} __attribute__ ((packed));
struct iwl_powertable_cmd {
__le16 flags;
- u8 keep_alive_seconds;
- u8 debug_flags;
+ u8 keep_alive_seconds; /* 3945 reserved */
+ u8 debug_flags; /* 3945 reserved */
__le32 rx_data_timeout;
__le32 tx_data_timeout;
__le32 sleep_interval[IWL_POWER_VEC_SIZE];
@@ -2143,6 +2415,26 @@ struct iwl_ct_kill_config {
* passive_dwell < max_out_time
* active_dwell < max_out_time
*/
+
+/* FIXME: rename to AP1, remove tpc */
+struct iwl3945_scan_channel {
+ /*
+ * type is defined as:
+ * 0:0 1 = active, 0 = passive
+ * 1:4 SSID direct bit map; if a bit is set, then corresponding
+ * SSID IE is transmitted in probe request.
+ * 5:7 reserved
+ */
+ u8 type;
+ u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */
+ struct iwl3945_tx_power tpc;
+ __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
+ __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
+} __attribute__ ((packed));
+
+/* set number of direct probes u8 type */
+#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
+
struct iwl_scan_channel {
/*
* type is defined as:
@@ -2159,6 +2451,9 @@ struct iwl_scan_channel {
__le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
} __attribute__ ((packed));
+/* set number of direct probes __le32 type */
+#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+
/**
* struct iwl_ssid_ie - directed scan network information element
*
@@ -2172,6 +2467,7 @@ struct iwl_ssid_ie {
u8 ssid[32];
} __attribute__ ((packed));
+#define PROBE_OPTION_MAX_API1 0x4
#define PROBE_OPTION_MAX 0x14
#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
#define IWL_GOOD_CRC_TH cpu_to_le16(1)
@@ -2229,6 +2525,51 @@ struct iwl_ssid_ie {
* To avoid uCode errors, see timing restrictions described under
* struct iwl_scan_channel.
*/
+
+struct iwl3945_scan_cmd {
+ __le16 len;
+ u8 reserved0;
+ u8 channel_count; /* # channels in channel list */
+ __le16 quiet_time; /* dwell only this # millisecs on quiet channel
+ * (only for active scan) */
+ __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */
+ __le16 good_CRC_th; /* passive -> active promotion threshold */
+ __le16 reserved1;
+ __le32 max_out_time; /* max usec to be away from associated (service)
+ * channel */
+ __le32 suspend_time; /* pause scan this long (in "extended beacon
+ * format") when returning to service channel:
+ * 3945; 31:24 # beacons, 19:0 additional usec,
+ * 4965; 31:22 # beacons, 21:0 additional usec.
+ */
+ __le32 flags; /* RXON_FLG_* */
+ __le32 filter_flags; /* RXON_FILTER_* */
+
+ /* For active scans (set to all-0s for passive scans).
+ * Does not include payload. Must specify Tx rate; no rate scaling. */
+ struct iwl3945_tx_cmd tx_cmd;
+
+ /* For directed active scans (set to all-0s otherwise) */
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1];
+
+ /*
+ * Probe request frame, followed by channel list.
+ *
+ * Size of probe request frame is specified by byte count in tx_cmd.
+ * Channel list follows immediately after probe request frame.
+ * Number of channels in list is specified by channel_count.
+ * Each channel in list is of type:
+ *
+ * struct iwl3945_scan_channel channels[0];
+ *
+ * NOTE: Only one band of channels can be scanned per pass. You
+ * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
+ * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
+ * before requesting another scan.
+ */
+ u8 data[0];
+} __attribute__ ((packed));
+
struct iwl_scan_cmd {
__le16 len;
u8 reserved0;
@@ -2336,6 +2677,14 @@ struct iwl_scancomplete_notification {
/*
* BEACON_NOTIFICATION = 0x90 (notification only, not a command)
*/
+
+struct iwl3945_beacon_notif {
+ struct iwl3945_tx_resp beacon_notify_hdr;
+ __le32 low_tsf;
+ __le32 high_tsf;
+ __le32 ibss_mgr_status;
+} __attribute__ ((packed));
+
struct iwl4965_beacon_notif {
struct iwl4965_tx_resp beacon_notify_hdr;
__le32 low_tsf;
@@ -2346,6 +2695,15 @@ struct iwl4965_beacon_notif {
/*
* REPLY_TX_BEACON = 0x91 (command, has simple generic response)
*/
+
+struct iwl3945_tx_beacon_cmd {
+ struct iwl3945_tx_cmd tx;
+ __le16 tim_idx;
+ u8 tim_size;
+ u8 reserved1;
+ struct ieee80211_hdr frame[0]; /* beacon frame */
+} __attribute__ ((packed));
+
struct iwl_tx_beacon_cmd {
struct iwl_tx_cmd tx;
__le16 tim_idx;
@@ -2382,6 +2740,76 @@ struct rate_histogram {
/* statistics command response */
+struct iwl39_statistics_rx_phy {
+ __le32 ina_cnt;
+ __le32 fina_cnt;
+ __le32 plcp_err;
+ __le32 crc32_err;
+ __le32 overrun_err;
+ __le32 early_overrun_err;
+ __le32 crc32_good;
+ __le32 false_alarm_cnt;
+ __le32 fina_sync_err_cnt;
+ __le32 sfd_timeout;
+ __le32 fina_timeout;
+ __le32 unresponded_rts;
+ __le32 rxe_frame_limit_overrun;
+ __le32 sent_ack_cnt;
+ __le32 sent_cts_cnt;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_rx_non_phy {
+ __le32 bogus_cts; /* CTS received when not expecting CTS */
+ __le32 bogus_ack; /* ACK received when not expecting ACK */
+ __le32 non_bssid_frames; /* number of frames with BSSID that
+ * doesn't belong to the STA BSSID */
+ __le32 filtered_frames; /* count frames that were dumped in the
+ * filtering process */
+ __le32 non_channel_beacons; /* beacons with our bss id but not on
+ * our serving channel */
+} __attribute__ ((packed));
+
+struct iwl39_statistics_rx {
+ struct iwl39_statistics_rx_phy ofdm;
+ struct iwl39_statistics_rx_phy cck;
+ struct iwl39_statistics_rx_non_phy general;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_tx {
+ __le32 preamble_cnt;
+ __le32 rx_detected_cnt;
+ __le32 bt_prio_defer_cnt;
+ __le32 bt_prio_kill_cnt;
+ __le32 few_bytes_cnt;
+ __le32 cts_timeout;
+ __le32 ack_timeout;
+ __le32 expected_ack_cnt;
+ __le32 actual_ack_cnt;
+} __attribute__ ((packed));
+
+struct statistics_dbg {
+ __le32 burst_check;
+ __le32 burst_count;
+ __le32 reserved[4];
+} __attribute__ ((packed));
+
+struct iwl39_statistics_div {
+ __le32 tx_on_a;
+ __le32 tx_on_b;
+ __le32 exec_time;
+ __le32 probe_time;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_general {
+ __le32 temperature;
+ struct statistics_dbg dbg;
+ __le32 sleep_time;
+ __le32 slots_out;
+ __le32 slots_idle;
+ __le32 ttl_timestamp;
+ struct iwl39_statistics_div div;
+} __attribute__ ((packed));
+
struct statistics_rx_phy {
__le32 ina_cnt;
__le32 fina_cnt;
@@ -2493,11 +2921,6 @@ struct statistics_tx {
struct statistics_tx_non_phy_agg agg;
} __attribute__ ((packed));
-struct statistics_dbg {
- __le32 burst_check;
- __le32 burst_count;
- __le32 reserved[4];
-} __attribute__ ((packed));
struct statistics_div {
__le32 tx_on_a;
@@ -2561,6 +2984,14 @@ struct iwl_statistics_cmd {
*/
#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
#define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8)
+
+struct iwl3945_notif_statistics {
+ __le32 flag;
+ struct iwl39_statistics_rx rx;
+ struct iwl39_statistics_tx tx;
+ struct iwl39_statistics_general general;
+} __attribute__ ((packed));
+
struct iwl_notif_statistics {
__le32 flag;
struct statistics_rx rx;
@@ -3012,6 +3443,10 @@ struct iwl_rx_packet {
__le32 len;
struct iwl_cmd_header hdr;
union {
+ struct iwl3945_rx_frame rx_frame;
+ struct iwl3945_tx_resp tx_resp;
+ struct iwl3945_beacon_notif beacon_status;
+
struct iwl_alive_resp alive_frame;
struct iwl_spectrum_notification spectrum_notif;
struct iwl_csa_notification csa_notif;
@@ -3029,6 +3464,6 @@ struct iwl_rx_packet {
} u;
} __attribute__ ((packed));
-int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon);
+int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
#endif /* __iwl_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 73d7973707e..21f386568c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -170,7 +170,8 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_hw *hw =
ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
if (hw == NULL) {
- IWL_ERROR("Can not allocate network device\n");
+ printk(KERN_ERR "%s: Can not allocate network device\n",
+ cfg->name);
goto out;
}
@@ -210,7 +211,7 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
if (!rxq->bd) {
ret = iwl_rx_queue_alloc(priv);
if (ret) {
- IWL_ERROR("Unable to initialize Rx queue\n");
+ IWL_ERR(priv, "Unable to initialize Rx queue\n");
return -ENOMEM;
}
} else
@@ -405,7 +406,7 @@ static void iwlcore_init_hw_rates(struct iwl_priv *priv,
/**
* iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
*/
-static int iwlcore_init_geos(struct iwl_priv *priv)
+int iwlcore_init_geos(struct iwl_priv *priv)
{
struct iwl_channel_info *ch;
struct ieee80211_supported_band *sband;
@@ -457,8 +458,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
priv->ieee_channels = channels;
priv->ieee_rates = rates;
- iwlcore_init_hw_rates(priv, rates);
-
for (i = 0; i < priv->channel_count; i++) {
ch = &priv->channel_info[i];
@@ -510,33 +509,33 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
priv->cfg->sku & IWL_SKU_A) {
- printk(KERN_INFO DRV_NAME
- ": Incorrectly detected BG card as ABG. Please send "
- "your PCI ID 0x%04X:0x%04X to maintainer.\n",
- priv->pci_dev->device, priv->pci_dev->subsystem_device);
+ IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
+ "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n",
+ priv->pci_dev->device,
+ priv->pci_dev->subsystem_device);
priv->cfg->sku &= ~IWL_SKU_A;
}
- printk(KERN_INFO DRV_NAME
- ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- priv->bands[IEEE80211_BAND_2GHZ].n_channels,
- priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
+ IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
+ priv->bands[IEEE80211_BAND_2GHZ].n_channels,
+ priv->bands[IEEE80211_BAND_5GHZ].n_channels);
set_bit(STATUS_GEO_CONFIGURED, &priv->status);
return 0;
}
+EXPORT_SYMBOL(iwlcore_init_geos);
/*
* iwlcore_free_geos - undo allocations in iwlcore_init_geos
*/
-static void iwlcore_free_geos(struct iwl_priv *priv)
+void iwlcore_free_geos(struct iwl_priv *priv)
{
kfree(priv->ieee_channels);
kfree(priv->ieee_rates);
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}
+EXPORT_SYMBOL(iwlcore_free_geos);
static bool is_single_rx_stream(struct iwl_priv *priv)
{
@@ -679,7 +678,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
break;
case WLAN_HT_CAP_SM_PS_INVALID:
default:
- IWL_ERROR("invalid mimo ps mode %d\n",
+ IWL_ERR(priv, "invalid mimo ps mode %d\n",
priv->current_ht_config.sm_ps);
WARN_ON(1);
idle_cnt = -1;
@@ -700,6 +699,18 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
}
/**
+ * iwl_is_monitor_mode - Determine if interface in monitor mode
+ *
+ * priv->iw_mode is set in add_interface, but add_interface is
+ * never called for monitor mode. The only way mac80211 informs us about
+ * monitor mode is through configuring filters (call to configure_filter).
+ */
+static bool iwl_is_monitor_mode(struct iwl_priv *priv)
+{
+ return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
+}
+
+/**
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
*
* Selects how many and which Rx receivers/antennas/chains to use.
@@ -742,6 +753,19 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
+ /* copied from 'iwl_bg_request_scan()' */
+ /* Force use of chains B and C (0x6) for Rx for 4965
+ * Avoid A (0x1) because of its off-channel reception on A-band.
+ * MIMO is not used here, but value is required */
+ if (iwl_is_monitor_mode(priv) &&
+ !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
+ ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
+ rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS;
+ rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+ }
+
priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
@@ -806,12 +830,13 @@ int iwl_setup_mac(struct iwl_priv *priv)
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM |
- IEEE80211_HW_AMPDU_AGGREGATION;
+ IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_SUPPORTS_PS;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->fw_handles_regulatory = true;
+ hw->wiphy->custom_regulatory = true;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
@@ -831,7 +856,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
ret = ieee80211_register_hw(priv->hw);
if (ret) {
- IWL_ERROR("Failed to register hw (error %d)\n", ret);
+ IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
return ret;
}
priv->mac80211_registered = 1;
@@ -863,7 +888,6 @@ int iwl_init_drv(struct iwl_priv *priv)
{
int ret;
- priv->retry_rate = 1;
priv->ibss_beacon = NULL;
spin_lock_init(&priv->lock);
@@ -903,15 +927,16 @@ int iwl_init_drv(struct iwl_priv *priv)
ret = iwl_init_channel_map(priv);
if (ret) {
- IWL_ERROR("initializing regulatory failed: %d\n", ret);
+ IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
goto err;
}
ret = iwlcore_init_geos(priv);
if (ret) {
- IWL_ERROR("initializing geos failed: %d\n", ret);
+ IWL_ERR(priv, "initializing geos failed: %d\n", ret);
goto err_free_channel_map;
}
+ iwlcore_init_hw_rates(priv, priv->ieee_rates);
return 0;
@@ -926,13 +951,13 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
int ret = 0;
if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) {
- IWL_WARNING("Requested user TXPOWER %d below limit.\n",
+ IWL_WARN(priv, "Requested user TXPOWER %d below limit.\n",
priv->tx_power_user_lmt);
return -EINVAL;
}
if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) {
- IWL_WARNING("Requested user TXPOWER %d above limit.\n",
+ IWL_WARN(priv, "Requested user TXPOWER %d above limit.\n",
priv->tx_power_user_lmt);
return -EINVAL;
}
@@ -982,6 +1007,21 @@ void iwl_enable_interrupts(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_enable_interrupts);
+int iwl_send_bt_config(struct iwl_priv *priv)
+{
+ struct iwl_bt_cmd bt_cmd = {
+ .flags = 3,
+ .lead_time = 0xAA,
+ .max_kill = 1,
+ .kill_ack_mask = 0,
+ .kill_cts_mask = 0,
+ };
+
+ return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+ sizeof(struct iwl_bt_cmd), &bt_cmd);
+}
+EXPORT_SYMBOL(iwl_send_bt_config);
+
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
{
u32 stat_flags = 0;
@@ -1018,7 +1058,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
- i + RTC_INST_LOWER_BOUND);
+ i + IWL49_RTC_INST_LOWER_BOUND);
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
ret = -EIO;
@@ -1051,7 +1091,8 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
if (ret)
return ret;
- iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ IWL49_RTC_INST_LOWER_BOUND);
errcnt = 0;
for (; len > 0; len -= sizeof(u32), image++) {
@@ -1060,7 +1101,7 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
* if IWL_DL_IO is set */
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
save_len - len, val, le32_to_cpu(*image));
ret = -EIO;
@@ -1116,7 +1157,7 @@ int iwl_verify_ucode(struct iwl_priv *priv)
return 0;
}
- IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
/* Since nothing seems to match, show first several data entries in
* instruction SRAM, so maybe visual inspection will give a clue.
@@ -1188,21 +1229,22 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
- IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
return;
}
ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
count = iwl_read_targ_mem(priv, base);
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
- IWL_ERROR("Start IWL Error Log Dump:\n");
- IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+ IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+ IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+ priv->status, count);
}
desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
@@ -1215,12 +1257,12 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
- IWL_ERROR("Desc Time "
+ IWL_ERR(priv, "Desc Time "
"data1 data2 line\n");
- IWL_ERROR("%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
+ IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
desc_lookup(desc), desc, time, data1, data2, line);
- IWL_ERROR("blink1 blink2 ilink1 ilink2\n");
- IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
+ IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n");
+ IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
ilink1, ilink2);
iwl_release_nic_access(priv);
@@ -1266,11 +1308,11 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
ptr += sizeof(u32);
if (mode == 0) {
/* data, ev */
- IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev);
+ IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
} else {
data = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n",
+ IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
time, data, ev);
}
}
@@ -1292,13 +1334,13 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
@@ -1312,12 +1354,12 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
/* bail out if nothing in log */
if (size == 0) {
- IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
+ IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
iwl_release_nic_access(priv);
return;
}
- IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+ IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
size, num_wraps);
/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -1349,7 +1391,7 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
sizeof(cmd), &cmd);
if (ret)
- IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
+ IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
else
IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "
"critical temperature is %d\n",
@@ -1368,7 +1410,7 @@ EXPORT_SYMBOL(iwl_rf_kill_ct_config);
* When in the 'halt' state, the card is shut down and must be fully
* restarted to come back on.
*/
-static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
{
struct iwl_host_cmd cmd = {
.id = REPLY_CARD_STATE_CMD,
@@ -1379,6 +1421,7 @@ static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
return iwl_send_cmd(priv, &cmd);
}
+EXPORT_SYMBOL(iwl_send_card_state);
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
{
@@ -1463,3 +1506,39 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
return 1;
}
EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);
+
+void iwl_bg_rf_kill(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
+
+ wake_up_interruptible(&priv->wait_command_queue);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ if (!iwl_is_rfkill(priv)) {
+ IWL_DEBUG(IWL_DL_RF_KILL,
+ "HW and/or SW RF Kill no longer active, restarting "
+ "device\n");
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
+ test_bit(STATUS_ALIVE, &priv->status))
+ queue_work(priv->workqueue, &priv->restart);
+ } else {
+ /* make sure mac80211 stop sending Tx frame */
+ if (priv->mac80211_registered)
+ ieee80211_stop_queues(priv->hw);
+
+ if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
+ IWL_DEBUG_RF_KILL("Can not turn radio back on - "
+ "disabled by SW switch\n");
+ else
+ IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n"
+ "Kill switch must be turned off for "
+ "wireless networking to work.\n");
+ }
+ mutex_unlock(&priv->mutex);
+ iwl_rfkill_set_hw_state(priv);
+}
+EXPORT_SYMBOL(iwl_bg_rf_kill);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7c3a20a986b..3c6a4b0c2c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ struct iwl_cmd;
#define IWLWIFI_VERSION "1.3.27k"
-#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -110,6 +110,14 @@ struct iwl_lib_ops {
void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
+ int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr,
+ u16 len, u8 reset, u8 pad);
+ void (*txq_free_tfd)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+ int (*txq_init)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
/* aggregations */
int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
int sta_id, int tid, u16 ssn_idx);
@@ -252,9 +260,18 @@ void iwl_rx_statistics(struct iwl_priv *priv,
* TX
******************************************************/
int iwl_txq_ctx_reset(struct iwl_priv *priv);
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len, u8 reset, u8 pad);
int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id);
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
@@ -267,7 +284,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
* RF -Kill - here and not in iwl-rfkill.h to be available when
* RF-kill subsystem is not compiled.
****************************************************/
-void iwl_rf_kill(struct iwl_priv *priv);
+void iwl_bg_rf_kill(struct work_struct *work);
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
@@ -306,8 +323,29 @@ void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_scan_initiate(struct iwl_priv *priv);
+u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band,
+ struct ieee80211_mgmt *frame, int left);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes);
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band);
+void iwl_bg_scan_check(struct work_struct *data);
+void iwl_bg_abort_scan(struct work_struct *work);
+void iwl_bg_scan_completed(struct work_struct *work);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+int iwl_send_scan_abort(struct iwl_priv *priv);
+
+/* For faster active scanning, scan will move to the next channel if fewer than
+ * PLCP_QUIET_THRESH packets are heard on this channel within
+ * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
+ * time if it's a quiet channel (nothing responded to our probe, and there's
+ * no other traffic).
+ * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
+#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
+#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
+
/*******************************************************************************
* Calibrations - implemented in iwl-calib.c
@@ -342,6 +380,9 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
+ u8 meta_flag);
+
/*****************************************************
* PCI *
*****************************************************/
@@ -354,6 +395,11 @@ void iwl_enable_interrupts(struct iwl_priv *priv);
void iwl_dump_nic_error_log(struct iwl_priv *priv);
void iwl_dump_nic_event_log(struct iwl_priv *priv);
+/*****************************************************
+* GEOS
+******************************************************/
+int iwlcore_init_geos(struct iwl_priv *priv);
+void iwlcore_free_geos(struct iwl_priv *priv);
/*************** DRIVER STATUS FUNCTIONS *****/
@@ -422,6 +468,7 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
}
extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
+extern int iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_verify_ucode(struct iwl_priv *priv);
extern int iwl_send_lq_cmd(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f34ede44ed1..74d3d43fa67 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 56c13b458de..7192d3249ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -29,16 +29,27 @@
#ifndef __iwl_debug_h__
#define __iwl_debug_h__
+struct iwl_priv;
+
+#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a)
+#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a)
+#define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a)
+#define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a)
+
#ifdef CONFIG_IWLWIFI_DEBUG
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (priv->debug_level & (level)) \
- dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+#define IWL_DEBUG(level, fmt, args...) \
+do { \
+ if (priv->debug_level & (level)) \
+ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
+ in_interrupt() ? 'I' : 'U', __func__ , ## args); \
+} while (0)
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((priv->debug_level & (level)) && net_ratelimit()) \
- dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+#define IWL_DEBUG_LIMIT(level, fmt, args...) \
+do { \
+ if ((priv->debug_level & (level)) && net_ratelimit()) \
+ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
+ in_interrupt() ? 'I' : 'U', __func__ , ## args); \
+} while (0)
#define iwl_print_hex_dump(priv, level, p, len) \
do { \
@@ -61,6 +72,7 @@ struct iwl_debugfs {
struct dentry *file_tx_statistics;
struct dentry *file_log_event;
struct dentry *file_channels;
+ struct dentry *file_status;
} dbgfs_data_files;
struct dir_rf_files {
struct dentry *file_disable_sensitivity;
@@ -117,84 +129,82 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
* when CONFIG_IWLWIFI_DEBUG=y.
*/
+/* 0x0000000F - 0x00000001 */
#define IWL_DL_INFO (1 << 0)
#define IWL_DL_MAC80211 (1 << 1)
#define IWL_DL_HCMD (1 << 2)
#define IWL_DL_STATE (1 << 3)
+/* 0x000000F0 - 0x00000010 */
#define IWL_DL_MACDUMP (1 << 4)
#define IWL_DL_HCMD_DUMP (1 << 5)
-#define IWL_DL_RADIO (1 << 7)
-#define IWL_DL_POWER (1 << 8)
-#define IWL_DL_TEMP (1 << 9)
-
-#define IWL_DL_NOTIF (1 << 10)
-#define IWL_DL_SCAN (1 << 11)
-#define IWL_DL_ASSOC (1 << 12)
-#define IWL_DL_DROP (1 << 13)
-
-#define IWL_DL_TXPOWER (1 << 14)
-
-#define IWL_DL_AP (1 << 15)
-
-#define IWL_DL_FW (1 << 16)
-#define IWL_DL_RF_KILL (1 << 17)
-#define IWL_DL_FW_ERRORS (1 << 18)
-
-#define IWL_DL_LED (1 << 19)
-
-#define IWL_DL_RATE (1 << 20)
-
-#define IWL_DL_CALIB (1 << 21)
-#define IWL_DL_WEP (1 << 22)
-#define IWL_DL_TX (1 << 23)
-#define IWL_DL_RX (1 << 24)
-#define IWL_DL_ISR (1 << 25)
-#define IWL_DL_HT (1 << 26)
-#define IWL_DL_IO (1 << 27)
-#define IWL_DL_11H (1 << 28)
-
-#define IWL_DL_STATS (1 << 29)
-#define IWL_DL_TX_REPLY (1 << 30)
-#define IWL_DL_QOS (1 << 31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a)
-
-#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_MACDUMP(f, a...) IWL_DEBUG(IWL_DL_MACDUMP, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HCMD, f, ## a)
-#define IWL_DEBUG_HC_DUMP(f, a...) IWL_DEBUG(IWL_DL_HCMD_DUMP, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DL_RADIO (1 << 7)
+/* 0x00000F00 - 0x00000100 */
+#define IWL_DL_POWER (1 << 8)
+#define IWL_DL_TEMP (1 << 9)
+#define IWL_DL_NOTIF (1 << 10)
+#define IWL_DL_SCAN (1 << 11)
+/* 0x0000F000 - 0x00001000 */
+#define IWL_DL_ASSOC (1 << 12)
+#define IWL_DL_DROP (1 << 13)
+#define IWL_DL_TXPOWER (1 << 14)
+#define IWL_DL_AP (1 << 15)
+/* 0x000F0000 - 0x00010000 */
+#define IWL_DL_FW (1 << 16)
+#define IWL_DL_RF_KILL (1 << 17)
+#define IWL_DL_FW_ERRORS (1 << 18)
+#define IWL_DL_LED (1 << 19)
+/* 0x00F00000 - 0x00100000 */
+#define IWL_DL_RATE (1 << 20)
+#define IWL_DL_CALIB (1 << 21)
+#define IWL_DL_WEP (1 << 22)
+#define IWL_DL_TX (1 << 23)
+/* 0x0F000000 - 0x01000000 */
+#define IWL_DL_RX (1 << 24)
+#define IWL_DL_ISR (1 << 25)
+#define IWL_DL_HT (1 << 26)
+#define IWL_DL_IO (1 << 27)
+/* 0xF0000000 - 0x10000000 */
+#define IWL_DL_11H (1 << 28)
+#define IWL_DL_STATS (1 << 29)
+#define IWL_DL_TX_REPLY (1 << 30)
+#define IWL_DL_QOS (1 << 31)
+
+#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
+#define IWL_DEBUG_MACDUMP(f, a...) IWL_DEBUG(IWL_DL_MACDUMP, f, ## a)
+#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a)
+#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a)
+#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a)
+#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a)
+#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a)
+#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
+#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a)
+#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HCMD, f, ## a)
+#define IWL_DEBUG_HC_DUMP(f, a...) IWL_DEBUG(IWL_DL_HCMD_DUMP, f, ## a)
+#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
+#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
+#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
+#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
+#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
+#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
+#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
+#define IWL_DEBUG_ASSOC(f, a...) \
+ IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
+ IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
+#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
#define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a)
+ IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
+#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
+#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a)
+#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a)
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index d5253a179de..36cfeccfafb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -63,6 +63,14 @@
goto err; \
} while (0)
+#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
+ dbgfs->dbgfs_##parent##_files.file_##name = \
+ debugfs_create_x32(#name, 0444, dbgfs->dir_##parent, ptr); \
+ if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
+ || !dbgfs->dbgfs_##parent##_files.file_##name) \
+ goto err; \
+} while (0)
+
#define DEBUGFS_REMOVE(name) do { \
debugfs_remove(name); \
name = NULL; \
@@ -164,9 +172,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
const size_t bufsz = sizeof(buf);
- printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n",
- priv->dbgfs->sram_offset, priv->dbgfs->sram_len);
-
iwl_grab_nic_access(priv);
for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
@@ -301,14 +306,14 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
buf_size = 4 * eeprom_len + 256;
if (eeprom_len % 16) {
- IWL_ERROR("EEPROM size is not multiple of 16.\n");
+ IWL_ERR(priv, "EEPROM size is not multiple of 16.\n");
return -ENODATA;
}
/* 4 characters for byte 0xYY */
buf = kzalloc(buf_size, GFP_KERNEL);
if (!buf) {
- IWL_ERROR("Can not allocate Buffer\n");
+ IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM;
}
@@ -365,7 +370,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) {
- IWL_ERROR("Can not allocate Buffer\n");
+ IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM;
}
@@ -420,7 +425,6 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
return ret;
}
-
DEBUGFS_READ_WRITE_FILE_OPS(sram);
DEBUGFS_WRITE_FILE_OPS(log_event);
DEBUGFS_READ_FILE_OPS(eeprom);
@@ -462,6 +466,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(rx_statistics, data);
DEBUGFS_ADD_FILE(tx_statistics, data);
DEBUGFS_ADD_FILE(channels, data);
+ DEBUGFS_ADD_X32(status, data, (u32 *)&priv->status);
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
@@ -469,7 +474,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
return 0;
err:
- IWL_ERROR("Can't open the debugfs directory\n");
+ IWL_ERR(priv, "Can't open the debugfs directory\n");
iwl_dbgfs_unregister(priv);
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0468fcc1ea9..437c05b9a33 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -36,13 +36,15 @@
#include <linux/kernel.h>
#include <net/ieee80211_radiotap.h>
-#define DRV_NAME "iwlagn"
-#include "iwl-rfkill.h"
#include "iwl-eeprom.h"
-#include "iwl-4965-hw.h"
#include "iwl-csr.h"
#include "iwl-prph.h"
+#include "iwl-fh.h"
#include "iwl-debug.h"
+#include "iwl-rfkill.h"
+#include "iwl-4965-hw.h"
+#include "iwl-3945-hw.h"
+#include "iwl-3945-led.h"
#include "iwl-led.h"
#include "iwl-power.h"
#include "iwl-agn-rs.h"
@@ -55,6 +57,16 @@ extern struct iwl_cfg iwl5350_agn_cfg;
extern struct iwl_cfg iwl5100_bg_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
+extern struct iwl_cfg iwl6000_2ag_cfg;
+extern struct iwl_cfg iwl6000_2agn_cfg;
+extern struct iwl_cfg iwl6000_3agn_cfg;
+extern struct iwl_cfg iwl6050_2agn_cfg;
+extern struct iwl_cfg iwl6050_3agn_cfg;
+extern struct iwl_cfg iwl100_bgn_cfg;
+
+/* shared structures from iwl-5000.c */
+extern struct iwl_mod_params iwl50_mod_params;
+extern struct iwl_ops iwl5000_ops;
/* CT-KILL constants */
#define CT_KILL_THRESHOLD 110 /* in Celsius */
@@ -132,9 +144,12 @@ struct iwl_tx_info {
* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
* descriptors) and required locking structures.
*/
+#define TFD_TX_CMD_SLOTS 256
+#define TFD_CMD_SLOTS 32
+
struct iwl_tx_queue {
struct iwl_queue q;
- struct iwl_tfd *tfds;
+ void *tfds;
struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
struct iwl_tx_info *txb;
u8 need_update;
@@ -154,6 +169,36 @@ struct iwl4965_channel_tgh_info {
s64 last_radar_time;
};
+#define IWL4965_MAX_RATE (33)
+
+struct iwl3945_clip_group {
+ /* maximum power level to prevent clipping for each rate, derived by
+ * us from this band's saturation power in EEPROM */
+ const s8 clip_powers[IWL_MAX_RATES];
+};
+
+/* current Tx power values to use, one for each rate for each channel.
+ * requested power is limited by:
+ * -- regulatory EEPROM limits for this channel
+ * -- hardware capabilities (clip-powers)
+ * -- spectrum management
+ * -- user preference (e.g. iwconfig)
+ * when requested power is set, base power index must also be set. */
+struct iwl3945_channel_power_info {
+ struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
+ s8 power_table_index; /* actual (compenst'd) index into gain table */
+ s8 base_power_index; /* gain index for power at factory temp. */
+ s8 requested_power; /* power (dBm) requested for this chnl/rate */
+};
+
+/* current scan Tx power values to use, one for each scan rate for each
+ * channel. */
+struct iwl3945_scan_power_info {
+ struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
+ s8 power_table_index; /* actual (compenst'd) index into gain table */
+ s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
+};
+
/*
* One for each channel, holds all channel setup data
* Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
@@ -184,8 +229,15 @@ struct iwl_channel_info {
s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */
u8 fat_flags; /* flags copied from EEPROM */
u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-};
+ /* Radio/DSP gain settings for each "normal" data Tx rate.
+ * These include, in addition to RF and DSP gain, a few fields for
+ * remembering/modifying gain settings (indexes). */
+ struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
+
+ /* Radio/DSP gain settings for each scan rate, for directed scans. */
+ struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
+};
#define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1
@@ -370,7 +422,7 @@ struct iwl_hw_key {
u8 key[32];
};
-union iwl4965_ht_rate_supp {
+union iwl_ht_rate_supp {
u16 rates;
struct {
u8 siso_rate;
@@ -430,6 +482,24 @@ struct iwl_qos_info {
#define STA_PS_STATUS_WAKE 0
#define STA_PS_STATUS_SLEEP 1
+struct iwl3945_tid_data {
+ u16 seq_number;
+};
+
+struct iwl3945_hw_key {
+ enum ieee80211_key_alg alg;
+ int keylen;
+ u8 key[32];
+};
+
+struct iwl3945_station_entry {
+ struct iwl3945_addsta_cmd sta;
+ struct iwl3945_tid_data tid[MAX_TID_COUNT];
+ u8 used;
+ u8 ps_status;
+ struct iwl3945_hw_key keyinfo;
+};
+
struct iwl_station_entry {
struct iwl_addsta_cmd sta;
struct iwl_tid_data tid[MAX_TID_COUNT];
@@ -497,11 +567,13 @@ struct iwl_sensitivity_ranges {
* @max_txq_num: Max # Tx queues supported
* @dma_chnl_num: Number of Tx DMA/FIFO channels
* @scd_bc_tbls_size: size of scheduler byte count tables
+ * @tfd_size: TFD size
* @tx/rx_chains_num: Number of TX/RX chains
* @valid_tx/rx_ant: usable antennas
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
* @max_rxq_log: Log-base-2 of max_rxq_size
* @rx_buf_size: Rx buffer size
+ * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
* @max_stations:
* @bcast_sta_id:
* @fat_channel: is 40MHz width possible in band 2.4
@@ -516,6 +588,7 @@ struct iwl_hw_params {
u8 max_txq_num;
u8 dma_chnl_num;
u16 scd_bc_tbls_size;
+ u32 tfd_size;
u8 tx_chains_num;
u8 rx_chains_num;
u8 valid_tx_ant;
@@ -523,6 +596,7 @@ struct iwl_hw_params {
u16 max_rxq_size;
u16 max_rxq_log;
u32 rx_buf_size;
+ u32 rx_wrt_ptr_reg;
u32 max_pkt_size;
u8 max_stations;
u8 bcast_sta_id;
@@ -755,7 +829,7 @@ struct iwl_priv {
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#if defined(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
/* spectrum measurement report caching */
struct iwl_spectrum_notification measure_report;
u8 measurement_status;
@@ -768,6 +842,10 @@ struct iwl_priv {
struct iwl_channel_info *channel_info; /* channel info array */
u8 channel_count; /* # of channels */
+ /* each calibration channel group in the EEPROM has a derived
+ * clip setting for each rate. 3945 only.*/
+ const struct iwl3945_clip_group clip39_groups[5];
+
/* thermal calibration */
s32 temperature; /* degrees Kelvin */
s32 last_temperature;
@@ -781,7 +859,7 @@ struct iwl_priv {
unsigned long scan_start;
unsigned long scan_pass_start;
unsigned long scan_start_tsf;
- struct iwl_scan_cmd *scan;
+ void *scan;
int scan_bands;
int one_direct_scan;
u8 direct_ssid_len;
@@ -832,18 +910,25 @@ struct iwl_priv {
* 4965's initialize alive response contains some calibration data. */
struct iwl_init_alive_resp card_alive_init;
struct iwl_alive_resp card_alive;
-#ifdef CONFIG_IWLWIFI_RFKILL
+#if defined(CONFIG_IWLWIFI_RFKILL) || defined(CONFIG_IWL3945_RFKILL)
struct rfkill *rfkill;
#endif
-#ifdef CONFIG_IWLWIFI_LEDS
- struct iwl_led led[IWL_LED_TRG_MAX];
+#if defined(CONFIG_IWLWIFI_LEDS) || defined(CONFIG_IWL3945_LEDS)
unsigned long last_blink_time;
u8 last_blink_rate;
u8 allow_blinking;
u64 led_tpt;
#endif
+#ifdef CONFIG_IWLWIFI_LEDS
+ struct iwl_led led[IWL_LED_TRG_MAX];
+#endif
+
+#ifdef CONFIG_IWL3945_LEDS
+ struct iwl3945_led led39[IWL_LED_TRG_MAX];
+ unsigned int rxtxpackets;
+#endif
u16 active_rate;
u16 active_rate_basic;
@@ -893,7 +978,6 @@ struct iwl_priv {
u16 rates_mask;
u32 power_mode;
- u32 antenna;
u8 bssid[ETH_ALEN];
u16 rts_threshold;
u8 mac_addr[ETH_ALEN];
@@ -929,6 +1013,10 @@ struct iwl_priv {
u16 beacon_int;
struct ieee80211_vif *vif;
+ /*Added for 3945 */
+ void *shared_virt;
+ dma_addr_t shared_phys;
+ /*End*/
struct iwl_hw_params hw_params;
@@ -960,6 +1048,11 @@ struct iwl_priv {
struct delayed_work init_alive_start;
struct delayed_work alive_start;
struct delayed_work scan_check;
+
+ /*For 3945 only*/
+ struct delayed_work thermal_periodic;
+ struct delayed_work rfkill_poll;
+
/* TX Power */
s8 tx_power_user_lmt;
s8 tx_power_channel_lmt;
@@ -982,6 +1075,22 @@ struct iwl_priv {
u32 disable_tx_power_cal;
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
+
+ /*For 3945*/
+#define IWL_DEFAULT_TX_POWER 0x0F
+ /* We declare this const so it can only be
+ * changed via explicit cast within the
+ * routines that actually update the physical
+ * hardware */
+ const struct iwl3945_rxon_cmd active39_rxon;
+ struct iwl3945_rxon_cmd staging39_rxon;
+ struct iwl3945_rxon_cmd recovery39_rxon;
+
+ struct iwl3945_notif_statistics statistics_39;
+
+ struct iwl3945_station_entry stations_39[IWL_STATION_COUNT];
+
+ u32 sta_supp_rates;
}; /*iwl_priv */
static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index ce2f47306ce..eaa658f9e54 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -145,7 +145,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
{
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+ IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
return -ENOENT;
}
return 0;
@@ -223,7 +223,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
if (ret < 0) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+ IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
ret = -ENOENT;
goto err;
}
@@ -231,7 +231,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
if (ret < 0) {
- IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
+ IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT;
goto err;
}
@@ -247,7 +247,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
CSR_EEPROM_REG_READ_VALID_MSK,
IWL_EEPROM_ACCESS_TIMEOUT);
if (ret < 0) {
- IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
+ IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
goto done;
}
r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
@@ -285,7 +285,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
return 0;
err:
- IWL_ERROR("Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+ IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
eeprom_ver, priv->cfg->eeprom_ver,
calib_ver, priv->cfg->eeprom_calib_ver);
return -EINVAL;
@@ -450,7 +450,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
priv->channel_count, GFP_KERNEL);
if (!priv->channel_info) {
- IWL_ERROR("Could not allocate channel_info\n");
+ IWL_ERR(priv, "Could not allocate channel_info\n");
priv->channel_count = 0;
return -ENOMEM;
}
@@ -520,7 +520,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
flags & EEPROM_CHANNEL_RADAR))
? "" : "not ");
- /* Set the user_txpower_limit to the highest power
+ /* Set the tx_power_user_lmt to the highest power
* supported by any channel */
if (eeprom_ch_info[ch].max_power_avg >
priv->tx_power_user_lmt)
@@ -531,6 +531,13 @@ int iwl_init_channel_map(struct iwl_priv *priv)
}
}
+ /* Check if we do have FAT channels */
+ if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] >=
+ priv->cfg->eeprom_size &&
+ priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] >=
+ priv->cfg->eeprom_size)
+ return 0;
+
/* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
for (band = 6; band <= 7; band++) {
enum ieee80211_band ieeeband;
@@ -582,6 +589,7 @@ void iwl_free_channel_map(struct iwl_priv *priv)
kfree(priv->channel_info);
priv->channel_count = 0;
}
+EXPORT_SYMBOL(iwl_free_channel_map);
/**
* iwl_get_channel_info - Find driver's private channel info
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 603c84bed63..17fed49f9d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -118,6 +118,9 @@ struct iwl_eeprom_channel {
s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
} __attribute__ ((packed));
+/* 3945 Specific */
+#define EEPROM_3945_EEPROM_VERSION (0x2f)
+
/* 4965 has two radio transmitters (and 3 radio receivers) */
#define EEPROM_TX_POWER_TX_CHAINS (2)
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index d7da1986455..65fa8a69fd5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -399,6 +399,21 @@
*/
#define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002)
+#define RX_QUEUE_SIZE 256
+#define RX_QUEUE_MASK 255
+#define RX_QUEUE_SIZE_LOG 8
+
+/*
+ * RX related structures and functions
+ */
+#define RX_FREE_BUFFERS 64
+#define RX_LOW_WATERMARK 8
+
+/* Size of one Rx buffer in host DRAM */
+#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */
+#define IWL_RX_BUF_SIZE_4K (4 * 1024)
+#define IWL_RX_BUF_SIZE_8K (8 * 1024)
+
/**
* struct iwl_rb_status - reseve buffer status
* host memory mapped FH registers
@@ -414,6 +429,7 @@ struct iwl_rb_status {
__le16 closed_fr_num;
__le16 finished_rb_num;
__le16 finished_fr_nam;
+ __le32 __unused; /* 3945 only */
} __attribute__ ((packed));
@@ -477,7 +493,6 @@ struct iwl_tfd {
__le32 __pad;
} __attribute__ ((packed));
-
/* Keep Warm Size */
#define IWL_KW_SIZE 0x1000 /* 4k */
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 4b35b30e493..65ae2af61c8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -109,14 +109,14 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = NULL;
if (!skb) {
- IWL_ERROR("Error: Response NULL in %s.\n",
+ IWL_ERR(priv, "Error: Response NULL in %s.\n",
get_cmd_string(cmd->hdr.cmd));
return 1;
}
pkt = (struct iwl_rx_packet *)skb->data;
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from %s (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
return 1;
}
@@ -156,7 +156,7 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
ret = iwl_enqueue_hcmd(priv, cmd);
if (ret < 0) {
- IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+ IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
return ret;
}
@@ -174,8 +174,9 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
BUG_ON(cmd->meta.u.callback != NULL);
if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: Already sending a host command\n",
- get_cmd_string(cmd->id));
+ IWL_ERR(priv,
+ "Error sending %s: Already sending a host command\n",
+ get_cmd_string(cmd->id));
ret = -EBUSY;
goto out;
}
@@ -188,7 +189,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
cmd_idx = iwl_enqueue_hcmd(priv, cmd);
if (cmd_idx < 0) {
ret = cmd_idx;
- IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+ IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
goto out;
}
@@ -198,9 +199,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
HOST_COMPLETE_TIMEOUT);
if (!ret) {
if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: time out after %dms.\n",
- get_cmd_string(cmd->id),
- jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
+ IWL_ERR(priv,
+ "Error sending %s: time out after %dms.\n",
+ get_cmd_string(cmd->id),
+ jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
ret = -ETIMEDOUT;
@@ -221,7 +223,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
goto fail;
}
if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
- IWL_ERROR("Error: Response NULL in '%s'\n",
+ IWL_ERR(priv, "Error: Response NULL in '%s'\n",
get_cmd_string(cmd->id));
ret = -EIO;
goto cancel;
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index ca4f638ab9d..fb64d297dd4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 0a92e7431ad..7341a2da843 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -165,9 +165,9 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
- CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
+ CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (ret < 0) {
- IWL_ERROR("MAC is in deep sleep!\n");
+ IWL_ERR(priv, "MAC is in deep sleep!\n");
return -EIO;
}
@@ -182,7 +182,7 @@ static inline int __iwl_grab_nic_access(const char *f, u32 l,
struct iwl_priv *priv)
{
if (atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Grabbing access while already held %s %d.\n", f, l);
+ IWL_ERR(priv, "Grabbing access while already held %s %d.\n", f, l);
IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
return _iwl_grab_nic_access(priv);
@@ -207,7 +207,7 @@ static inline void __iwl_release_nic_access(const char *f, u32 l,
struct iwl_priv *priv)
{
if (atomic_read(&priv->restrict_refcnt) <= 0)
- IWL_ERROR("Release unheld nic access at line %s %d.\n", f, l);
+ IWL_ERR(priv, "Release unheld nic access at line %s %d.\n", f, l);
IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
_iwl_release_nic_access(priv);
@@ -229,7 +229,7 @@ static inline u32 __iwl_read_direct32(const char *f, u32 l,
{
u32 value = _iwl_read_direct32(priv, reg);
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s %d\n", f, l);
+ IWL_ERR(priv, "Nic access not held from %s %d\n", f, l);
IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
f, l);
return value;
@@ -250,7 +250,7 @@ static void __iwl_write_direct32(const char *f , u32 line,
struct iwl_priv *priv, u32 reg, u32 value)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_write_direct32(priv, reg, value);
}
#define iwl_write_direct32(priv, reg, value) \
@@ -308,7 +308,7 @@ static inline u32 __iwl_read_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 reg)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
return _iwl_read_prph(priv, reg);
}
@@ -331,7 +331,7 @@ static inline void __iwl_write_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 addr, u32 val)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_write_prph(priv, addr, val);
}
@@ -349,7 +349,7 @@ static inline void __iwl_set_bits_prph(const char *f, u32 line,
u32 reg, u32 mask)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_set_bits_prph(priv, reg, mask);
}
@@ -367,7 +367,7 @@ static inline void __iwl_set_bits_mask_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_set_bits_mask_prph(priv, reg, bits, mask);
}
#define iwl_set_bits_mask_prph(priv, reg, bits, mask) \
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 11eccd7d268..501cffeff5f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -254,7 +254,7 @@ static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
ret = led_classdev_register(device, &led->led_dev);
if (ret) {
- IWL_ERROR("Error: failed to register led handler.\n");
+ IWL_ERR(priv, "Error: failed to register led handler.\n");
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 021e00bcd1b..1d798d08669 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
struct iwl_priv;
-#ifdef CONFIG_IWLWIFI_LEDS
+#if defined(CONFIG_IWLWIFI_LEDS) || defined(CONFIG_IWL3945_LEDS)
#include <linux/leds.h>
#define IWL_LED_SOLID 11
@@ -47,7 +47,9 @@ enum led_type {
IWL_LED_TRG_RADIO,
IWL_LED_TRG_MAX,
};
+#endif
+#ifdef CONFIG_IWLWIFI_LEDS
struct iwl_led {
struct iwl_priv *priv;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 75ca6a54217..a4634595c59 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -60,14 +60,6 @@
#define IWL_POWER_RANGE_1_MAX (10)
-#define NOSLP __constant_cpu_to_le16(0), 0, 0
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
-#define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
- __constant_cpu_to_le32(X1), \
- __constant_cpu_to_le32(X2), \
- __constant_cpu_to_le32(X3), \
- __constant_cpu_to_le32(X4)}
#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5
#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM
@@ -149,7 +141,7 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
}
/* initialize to default */
-static int iwl_power_init_handle(struct iwl_priv *priv)
+static void iwl_power_init_handle(struct iwl_priv *priv)
{
struct iwl_power_mgr *pow_data;
int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
@@ -159,7 +151,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
IWL_DEBUG_POWER("Initialize power \n");
- pow_data = &(priv->power_data);
+ pow_data = &priv->power_data;
memset(pow_data, 0, sizeof(*pow_data));
@@ -179,26 +171,25 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
else
cmd->flags |= IWL_POWER_PCI_PM_MSK;
}
- return 0;
}
/* adjust power command according to DTIM period and power level*/
-static int iwl_update_power_command(struct iwl_priv *priv,
- struct iwl_powertable_cmd *cmd,
- u16 mode)
+static int iwl_update_power_cmd(struct iwl_priv *priv,
+ struct iwl_powertable_cmd *cmd, u16 mode)
{
- int ret = 0, i;
- u8 skip;
- u32 max_sleep = 0;
struct iwl_power_vec_entry *range;
- u8 period = 0;
struct iwl_power_mgr *pow_data;
+ int i;
+ u32 max_sleep = 0;
+ u8 period;
+ bool skip;
if (mode > IWL_POWER_INDEX_5) {
IWL_DEBUG_POWER("Error invalid power mode \n");
- return -1;
+ return -EINVAL;
}
- pow_data = &(priv->power_data);
+
+ pow_data = &priv->power_data;
if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX)
range = &pow_data->pwr_range_0[0];
@@ -212,14 +203,12 @@ static int iwl_update_power_command(struct iwl_priv *priv,
if (period == 0) {
period = 1;
- skip = 0;
- } else
- skip = range[mode].no_dtim;
-
- if (skip == 0) {
- max_sleep = period;
- cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ skip = false;
} else {
+ skip = !!range[mode].no_dtim;
+ }
+
+ if (skip) {
__le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
max_sleep = le32_to_cpu(slp_itrvl);
if (max_sleep == 0xFF)
@@ -227,12 +216,14 @@ static int iwl_update_power_command(struct iwl_priv *priv,
else if (max_sleep > period)
max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ } else {
+ max_sleep = period;
+ cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
}
- for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
+ for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
- }
IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
@@ -244,7 +235,7 @@ static int iwl_update_power_command(struct iwl_priv *priv,
le32_to_cpu(cmd->sleep_interval[3]),
le32_to_cpu(cmd->sleep_interval[4]));
- return ret;
+ return 0;
}
@@ -295,7 +286,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
if (final_mode != IWL_POWER_MODE_CAM)
set_bit(STATUS_POWER_PMI, &priv->status);
- iwl_update_power_command(priv, &cmd, final_mode);
+ iwl_update_power_cmd(priv, &cmd, final_mode);
cmd.keep_alive_beacons = 0;
if (final_mode == IWL_POWER_INDEX_5)
@@ -392,13 +383,11 @@ EXPORT_SYMBOL(iwl_power_set_system_mode);
/* initialize to default */
void iwl_power_initialize(struct iwl_priv *priv)
{
-
iwl_power_init_handle(priv);
priv->power_data.user_power_setting = IWL_POWER_AUTO;
- priv->power_data.power_disabled = 0;
priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
- priv->power_data.is_battery_active = 0;
priv->power_data.power_disabled = 0;
+ priv->power_data.is_battery_active = 0;
priv->power_data.critical_power_setting = 0;
}
EXPORT_SYMBOL(iwl_power_initialize);
@@ -407,8 +396,8 @@ EXPORT_SYMBOL(iwl_power_initialize);
int iwl_power_temperature_change(struct iwl_priv *priv)
{
int ret = 0;
- u16 new_critical = priv->power_data.critical_power_setting;
s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
+ u16 new_critical = priv->power_data.critical_power_setting;
if (temperature > IWL_CT_KILL_TEMPERATURE)
return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index fa098d8975c..859b60b5335 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -42,7 +42,10 @@ enum {
IWL_POWER_INDEX_5,
IWL_POWER_AUTO,
IWL_POWER_MAX = IWL_POWER_AUTO,
+ IWL39_POWER_AC = IWL_POWER_AUTO, /* 0x06 */
IWL_POWER_AC,
+ IWL39_POWER_BATTERY = IWL_POWER_AC, /* 0x07 */
+ IWL39_POWER_LIMIT = IWL_POWER_AC,
IWL_POWER_BATTERY,
};
@@ -56,8 +59,21 @@ enum {
#define IWL_POWER_MASK 0x0F
#define IWL_POWER_ENABLED 0x10
+#define IWL_POWER_RANGE_0 (0)
+#define IWL_POWER_RANGE_1 (1)
+
+#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK)
+
/* Power management (not Tx power) structures */
+#define NOSLP __constant_cpu_to_le16(0), 0, 0
+#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
+#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
+ __constant_cpu_to_le32(X1), \
+ __constant_cpu_to_le32(X2), \
+ __constant_cpu_to_le32(X3), \
+ __constant_cpu_to_le32(X4)}
struct iwl_power_vec_entry {
struct iwl_powertable_cmd cmd;
u8 no_dtim;
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index b7a5f23351c..3b9cac3fd21 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index 4b69da30665..f67d7be1074 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -62,7 +62,8 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
iwl_radio_kill_sw_disable_radio(priv);
break;
default:
- IWL_WARNING("we received unexpected RFKILL state %d\n", state);
+ IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
+ state);
break;
}
out_unlock:
@@ -81,7 +82,7 @@ int iwl_rfkill_init(struct iwl_priv *priv)
IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!priv->rfkill) {
- IWL_ERROR("Unable to allocate RFKILL device.\n");
+ IWL_ERR(priv, "Unable to allocate RFKILL device.\n");
ret = -ENOMEM;
goto error;
}
@@ -97,7 +98,7 @@ int iwl_rfkill_init(struct iwl_priv *priv)
ret = rfkill_register(priv->rfkill);
if (ret) {
- IWL_ERROR("Unable to register RFKILL: %d\n", ret);
+ IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret);
goto free_rfkill;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
index 86dc055a2e9..633dafb4bf1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index c5f1aa0feac..33145207fc1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -125,9 +125,10 @@ EXPORT_SYMBOL(iwl_rx_queue_space);
*/
int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
{
- u32 reg = 0;
- int ret = 0;
unsigned long flags;
+ u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg;
+ u32 reg;
+ int ret = 0;
spin_lock_irqsave(&q->lock, flags);
@@ -149,15 +150,14 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
goto exit_unlock;
/* Device expects a multiple of 8 */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
- q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
iwl_release_nic_access(priv);
/* Else device is assumed to be awake */
- } else
+ } else {
/* Device expects a multiple of 8 */
- iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
-
+ iwl_write32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
+ }
q->need_update = 0;
@@ -262,8 +262,7 @@ void iwl_rx_allocate(struct iwl_priv *priv)
rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
GFP_KERNEL);
if (!rxb->skb) {
- printk(KERN_CRIT DRV_NAME
- "Can not allocate SKB buffers\n");
+ IWL_CRIT(priv, "Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
* call the restock method and if it still needs
* more buffers it will schedule replenish */
@@ -895,7 +894,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
if (!rx_start) {
- IWL_ERROR("MPDU frame without a PHY data\n");
+ IWL_ERR(priv, "MPDU frame without a PHY data\n");
return;
}
if (include_phy) {
@@ -1021,7 +1020,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
}
if (!rx_start) {
- IWL_ERROR("MPDU frame without a PHY data\n");
+ IWL_ERR(priv, "MPDU frame without a PHY data\n");
return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 3c803f6922e..c282d1d294e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -46,15 +46,6 @@
#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
-
/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
* Must be set longer than active dwell time.
* For the most reliable scan, set > AP beacon interval (typically 100msec). */
@@ -63,7 +54,6 @@
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5
-#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
/**
@@ -119,7 +109,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
}
EXPORT_SYMBOL(iwl_scan_cancel_timeout);
-static int iwl_send_scan_abort(struct iwl_priv *priv)
+int iwl_send_scan_abort(struct iwl_priv *priv)
{
int ret = 0;
struct iwl_rx_packet *res;
@@ -160,7 +150,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
return ret;
}
-
+EXPORT_SYMBOL(iwl_send_scan_abort);
/* Service response to REPLY_SCAN_CMD (0x80) */
static void iwl_rx_reply_scan(struct iwl_priv *priv,
@@ -296,9 +286,9 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_setup_rx_scan_handlers);
-static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band,
- u8 n_probes)
+inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes)
{
if (band == IEEE80211_BAND_5GHZ)
return IWL_ACTIVE_DWELL_TIME_52 +
@@ -307,9 +297,10 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
return IWL_ACTIVE_DWELL_TIME_24 +
IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
}
+EXPORT_SYMBOL(iwl_get_active_dwell_time);
-static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band)
{
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
@@ -327,6 +318,7 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
return passive;
}
+EXPORT_SYMBOL(iwl_get_passive_dwell_time);
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
@@ -450,7 +442,7 @@ EXPORT_SYMBOL(iwl_scan_initiate);
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-static void iwl_bg_scan_check(struct work_struct *data)
+void iwl_bg_scan_check(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, scan_check.work);
@@ -470,6 +462,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
}
mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_scan_check);
+
/**
* iwl_supported_rate_to_ie - fill in the supported rate in IE field
*
@@ -527,10 +521,10 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
* iwl_fill_probe_req - fill in all required fields and IE for probe request
*/
-static u16 iwl_fill_probe_req(struct iwl_priv *priv,
- enum ieee80211_band band,
- struct ieee80211_mgmt *frame,
- int left)
+u16 iwl_fill_probe_req(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ struct ieee80211_mgmt *frame,
+ int left)
{
int len = 0;
u8 *pos = NULL;
@@ -624,6 +618,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
return (u16)len;
}
+EXPORT_SYMBOL(iwl_fill_probe_req);
static void iwl_bg_request_scan(struct work_struct *data)
{
@@ -650,7 +645,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
mutex_lock(&priv->mutex);
if (!iwl_is_ready(priv)) {
- IWL_WARNING("request scan called when driver not ready.\n");
+ IWL_WARN(priv, "request scan called when driver not ready.\n");
goto done;
}
@@ -773,7 +768,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
rx_chain = 0x6;
} else {
- IWL_WARNING("Invalid scan band count\n");
+ IWL_WARN(priv, "Invalid scan band count\n");
goto done;
}
@@ -839,7 +834,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl_bg_abort_scan(struct work_struct *work)
+void iwl_bg_abort_scan(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
@@ -853,8 +848,9 @@ static void iwl_bg_abort_scan(struct work_struct *work)
mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_abort_scan);
-static void iwl_bg_scan_completed(struct work_struct *work)
+void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
@@ -872,7 +868,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
mutex_unlock(&priv->mutex);
}
-
+EXPORT_SYMBOL(iwl_bg_scan_completed);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
index 836c3c80b69..aba1ef22fc6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -146,7 +146,7 @@ static int iwl_get_measurement(struct iwl_priv *priv,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
rc = -EIO;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index b7d7943e476..a77c1e61906 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ieee80211 subsystem header files.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 412f66bac1a..9bba98e5e05 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -86,8 +86,10 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
spin_lock_irqsave(&priv->sta_lock, flags);
- if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
- IWL_ERROR("ACTIVATE a non DRIVER active station %d\n", sta_id);
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
+ !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
+ IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
+ sta_id);
priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
IWL_DEBUG_ASSOC("Added STA to Ucode: %pM\n",
@@ -105,13 +107,13 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
u8 sta_id = addsta->sta.sta_id;
if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
+ IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n");
return 1;
}
res = (struct iwl_rx_packet *)skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
res->hdr.flags);
return 1;
}
@@ -130,7 +132,7 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
return 1;
}
-static int iwl_send_add_sta(struct iwl_priv *priv,
+int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags)
{
struct iwl_rx_packet *res = NULL;
@@ -155,7 +157,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
res->hdr.flags);
ret = -EIO;
}
@@ -168,7 +170,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
break;
default:
ret = -EIO;
- IWL_WARNING("REPLY_ADD_STA failed\n");
+ IWL_WARN(priv, "REPLY_ADD_STA failed\n");
break;
}
}
@@ -178,6 +180,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
return ret;
}
+EXPORT_SYMBOL(iwl_send_add_sta);
static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
struct ieee80211_sta_ht_cap *sta_ht_inf)
@@ -204,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
case WLAN_HT_CAP_SM_PS_DISABLED:
break;
default:
- IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
+ IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
break;
}
@@ -307,7 +310,7 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
/* Ucode must be active and driver must be non active */
if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
- IWL_ERROR("removed non active STA %d\n", sta_id);
+ IWL_ERR(priv, "removed non active STA %d\n", sta_id);
priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
@@ -324,13 +327,13 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
const char *addr = rm_sta->addr;
if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_REMOVE_STA.\n");
+ IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n");
return 1;
}
res = (struct iwl_rx_packet *)skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
res->hdr.flags);
return 1;
}
@@ -340,7 +343,7 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
iwl_sta_ucode_deactivate(priv, addr);
break;
default:
- IWL_ERROR("REPLY_REMOVE_STA failed\n");
+ IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
break;
}
@@ -378,7 +381,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
res->hdr.flags);
ret = -EIO;
}
@@ -391,7 +394,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
break;
default:
ret = -EIO;
- IWL_ERROR("REPLY_REMOVE_STA failed\n");
+ IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
break;
}
}
@@ -433,13 +436,13 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
sta_id, addr);
if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
- IWL_ERROR("Removing %pM but non DRIVER active\n",
+ IWL_ERR(priv, "Removing %pM but non DRIVER active\n",
addr);
goto out;
}
if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
- IWL_ERROR("Removing %pM but non UCODE active\n",
+ IWL_ERR(priv, "Removing %pM but non UCODE active\n",
addr);
goto out;
}
@@ -475,7 +478,7 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
if (iwl_is_alive(priv) &&
!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL))
- IWL_ERROR("Couldn't clear the station table\n");
+ IWL_ERR(priv, "Couldn't clear the station table\n");
priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations));
@@ -548,7 +551,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
spin_lock_irqsave(&priv->sta_lock, flags);
if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))
- IWL_ERROR("index %d not used in uCode key table.\n",
+ IWL_ERR(priv, "index %d not used in uCode key table.\n",
keyconf->keyidx);
priv->default_wep_key--;
@@ -582,7 +585,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
priv->default_wep_key++;
if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table))
- IWL_ERROR("index %d already used in uCode key table.\n",
+ IWL_ERR(priv, "index %d already used in uCode key table.\n",
keyconf->keyidx);
priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
@@ -638,7 +641,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
@@ -686,7 +689,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
@@ -722,7 +725,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
/* This copy is acutally not needed: we get the key with each TX */
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
@@ -812,7 +815,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
}
if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
- IWL_WARNING("Removing wrong key %d 0x%x\n",
+ IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
keyconf->keyidx, key_flags);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return 0;
@@ -820,7 +823,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
&priv->ucode_key_table))
- IWL_ERROR("index %d not used in uCode key table.\n",
+ IWL_ERR(priv, "index %d not used in uCode key table.\n",
priv->stations[sta_id].sta.key.key_offset);
memset(&priv->stations[sta_id].keyinfo, 0,
sizeof(struct iwl_hw_key));
@@ -857,7 +860,8 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id);
break;
default:
- IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ IWL_ERR(priv,
+ "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
ret = -EINVAL;
}
@@ -1069,7 +1073,8 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
return priv->hw_params.bcast_sta_id;
default:
- IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
+ IWL_WARN(priv, "Unknown mode of operation: %d\n",
+ priv->iw_mode);
return priv->hw_params.bcast_sta_id;
}
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 9bb7cefc1f3..97f6169007f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -56,6 +56,8 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
void iwl_clear_stations_table(struct iwl_priv *priv);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
+int iwl_send_add_sta(struct iwl_priv *priv,
+ struct iwl_addsta_cmd *sta, u8 flags);
u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
int is_ap, u8 flags,
struct ieee80211_sta_ht_cap *ht_info);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index b0ee86c6268..7d2b6e11f73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -76,116 +76,6 @@ static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
memset(ptr, 0, sizeof(*ptr));
}
-static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
- dma_addr_t addr = get_unaligned_le32(&tb->lo);
- if (sizeof(dma_addr_t) > sizeof(u32))
- addr |=
- ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
-
- return addr;
-}
-
-static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
- return le16_to_cpu(tb->hi_n_len) >> 4;
-}
-
-static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
- dma_addr_t addr, u16 len)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
- u16 hi_n_len = len << 4;
-
- put_unaligned_le32(addr, &tb->lo);
- if (sizeof(dma_addr_t) > sizeof(u32))
- hi_n_len |= ((addr >> 16) >> 16) & 0xF;
-
- tb->hi_n_len = cpu_to_le16(hi_n_len);
-
- tfd->num_tbs = idx + 1;
-}
-
-static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
-{
- return tfd->num_tbs & 0x1f;
-}
-
-/**
- * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
- * @priv - driver private data
- * @txq - tx queue
- *
- * Does NOT advance any TFD circular buffer read/write indexes
- * Does NOT free the TFD itself (which is within circular buffer)
- */
-static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
-{
- struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)&txq->tfds[0];
- struct iwl_tfd *tfd;
- struct pci_dev *dev = priv->pci_dev;
- int index = txq->q.read_ptr;
- int i;
- int num_tbs;
-
- tfd = &tfd_tmp[index];
-
- /* Sanity check on number of chunks */
- num_tbs = iwl_tfd_get_num_tbs(tfd);
-
- if (num_tbs >= IWL_NUM_OF_TBS) {
- IWL_ERROR("Too many chunks: %i\n", num_tbs);
- /* @todo issue fatal error, it is quite serious situation */
- return;
- }
-
- /* Unmap tx_cmd */
- if (num_tbs)
- pci_unmap_single(dev,
- pci_unmap_addr(&txq->cmd[index]->meta, mapping),
- pci_unmap_len(&txq->cmd[index]->meta, len),
- PCI_DMA_TODEVICE);
-
- /* Unmap chunks, if any. */
- for (i = 1; i < num_tbs; i++) {
- pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
- iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
-
- if (txq->txb) {
- dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
- txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
- }
- }
-}
-
-static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
- struct iwl_tfd *tfd,
- dma_addr_t addr, u16 len)
-{
-
- u32 num_tbs = iwl_tfd_get_num_tbs(tfd);
-
- /* Each TFD can point to a maximum 20 Tx buffers */
- if (num_tbs >= IWL_NUM_OF_TBS) {
- IWL_ERROR("Error can not send more than %d chunks\n",
- IWL_NUM_OF_TBS);
- return -EINVAL;
- }
-
- BUG_ON(addr & ~DMA_BIT_MASK(36));
- if (unlikely(addr & ~IWL_TX_DMA_MASK))
- IWL_ERROR("Unaligned address = %llx\n",
- (unsigned long long)addr);
-
- iwl_tfd_set_tb(tfd, num_tbs, addr, len);
-
- return 0;
-}
-
/**
* iwl_txq_update_write_ptr - Send new write index to hardware
*/
@@ -241,7 +131,7 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
* Free all buffers.
* 0-fill, but do not free "txq" descriptor structure.
*/
-static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwl_queue *q = &txq->q;
@@ -254,7 +144,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* first, empty all BD's */
for (; q->write_ptr != q->read_ptr;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- iwl_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
len = sizeof(struct iwl_cmd) * q->n_window;
@@ -264,7 +154,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* De-alloc circular buffer of TFDs */
if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+ pci_free_consistent(dev, priv->hw_params.tfd_size *
txq->q.n_bd, txq->tfds, txq->q.dma_addr);
/* De-alloc array of per-TFD driver data */
@@ -274,7 +164,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq));
}
-
+EXPORT_SYMBOL(iwl_tx_queue_free);
/**
* iwl_cmd_queue_free - Deallocate DMA queue.
@@ -388,6 +278,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
struct iwl_tx_queue *txq, u32 id)
{
struct pci_dev *dev = priv->pci_dev;
+ size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
/* Driver private data, only for Tx (not command) queues,
* not shared with device. */
@@ -395,22 +286,20 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
txq->txb = kmalloc(sizeof(txq->txb[0]) *
TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
if (!txq->txb) {
- IWL_ERROR("kmalloc for auxiliary BD "
+ IWL_ERR(priv, "kmalloc for auxiliary BD "
"structures failed\n");
goto error;
}
- } else
+ } else {
txq->txb = NULL;
+ }
/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
- txq->tfds = pci_alloc_consistent(dev,
- sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
+ txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr);
if (!txq->tfds) {
- IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX);
+ IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
goto error;
}
txq->q.id = id;
@@ -424,42 +313,11 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
return -ENOMEM;
}
-/*
- * Tell nic where to find circular buffer of Tx Frame Descriptors for
- * given Tx queue, and enable the DMA channel used for that queue.
- *
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
- * channels supported in hardware.
- */
-static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
- struct iwl_tx_queue *txq)
-{
- int ret;
- unsigned long flags;
- int txq_id = txq->q.id;
-
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
- /* Circular buffer (TFD queue in DRAM) physical base address */
- iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
- txq->q.dma_addr >> 8);
-
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
/**
* iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
*/
-static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
- int slots_num, u32 txq_id)
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id)
{
int i, len;
int ret;
@@ -501,7 +359,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
/* Tell device where to find queue */
- iwl_hw_tx_queue_init(priv, txq);
+ priv->cfg->ops->lib->txq_init(priv, txq);
return 0;
err:
@@ -516,6 +374,8 @@ err:
}
return -ENOMEM;
}
+EXPORT_SYMBOL(iwl_tx_queue_init);
+
/**
* iwl_hw_txq_ctx_free - Free TXQ Context
*
@@ -557,13 +417,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
priv->hw_params.scd_bc_tbls_size);
if (ret) {
- IWL_ERROR("Scheduler BC Table allocation failed\n");
+ IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
goto error_bc_tbls;
}
/* Alloc keep-warm buffer */
ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
if (ret) {
- IWL_ERROR("Keep Warm allocation failed\n");
+ IWL_ERR(priv, "Keep Warm allocation failed\n");
goto error_kw;
}
spin_lock_irqsave(&priv->lock, flags);
@@ -589,7 +449,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
if (ret) {
- IWL_ERROR("Tx %d queue init failed\n", txq_id);
+ IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
goto error;
}
}
@@ -802,7 +662,7 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
break;
default:
- printk(KERN_ERR "Unknown encode alg %d\n", keyconf->alg);
+ IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
break;
}
}
@@ -822,7 +682,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl_tfd *tfd;
struct iwl_tx_queue *txq;
struct iwl_queue *q;
struct iwl_cmd *out_cmd;
@@ -850,7 +709,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
IWL_INVALID_RATE) {
- IWL_ERROR("ERROR: No TX rate available.\n");
+ IWL_ERR(priv, "ERROR: No TX rate available.\n");
goto drop_unlock;
}
@@ -913,10 +772,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
- /* Set up first empty TFD within this queue's circular TFD buffer */
- tfd = &txq->tfds[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb[0] = skb;
@@ -970,7 +825,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
txcmd_phys += offsetof(struct iwl_cmd, hdr);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ txcmd_phys, len, 1, 0);
if (info->control.hw_key)
iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
@@ -981,7 +837,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (len) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
len, PCI_DMA_TODEVICE);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, len,
+ 0, 0);
}
/* Tell NIC about any 2-byte padding after MAC header */
@@ -1063,7 +921,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
struct iwl_queue *q = &txq->q;
- struct iwl_tfd *tfd;
struct iwl_cmd *out_cmd;
dma_addr_t phys_addr;
unsigned long flags;
@@ -1086,16 +943,12 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
}
if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
- IWL_ERROR("No space for Tx\n");
+ IWL_ERR(priv, "No space for Tx\n");
return -ENOSPC;
}
spin_lock_irqsave(&priv->hcmd_lock, flags);
- tfd = &txq->tfds[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
-
idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
out_cmd = txq->cmd[idx];
@@ -1120,7 +973,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
pci_unmap_len_set(&out_cmd->meta, len, len);
phys_addr += offsetof(struct iwl_cmd, hdr);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, fix_size, 1,
+ U32_PAD(cmd->len));
#ifdef CONFIG_IWLWIFI_DEBUG
switch (out_cmd->hdr.cmd) {
@@ -1144,8 +999,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
#endif
txq->need_update = 1;
- /* Set up entry in queue's byte count circular buffer */
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
+ if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl)
+ /* Set up entry in queue's byte count circular buffer */
+ priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
/* Increment and update queue's write index */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -1163,7 +1019,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
int nfreed = 0;
if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
"is out of range [0-%d] %d %d.\n", txq_id,
index, q->n_bd, q->write_ptr, q->read_ptr);
return 0;
@@ -1180,7 +1036,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
- iwl_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
nfreed++;
}
return nfreed;
@@ -1203,7 +1059,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
int nfreed = 0;
if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
"is out of range [0-%d] %d %d.\n", txq_id,
idx, q->n_bd, q->write_ptr, q->read_ptr);
return;
@@ -1218,7 +1074,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
if (nfreed++ > 0) {
- IWL_ERROR("HCMD skipped: index (%d) %d %d\n", idx,
+ IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
q->write_ptr, q->read_ptr);
queue_work(priv->workqueue, &priv->restart);
}
@@ -1306,7 +1162,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
else
return -EINVAL;
- IWL_WARNING("%s on ra = %pM tid = %d\n",
+ IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
__func__, ra, tid);
sta_id = iwl_find_station(priv, ra);
@@ -1314,7 +1170,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return -ENXIO;
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
- IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n");
+ IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
return -ENXIO;
}
@@ -1334,7 +1190,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return ret;
if (tid_data->tfds_in_queue == 0) {
- printk(KERN_ERR "HW queue is empty\n");
+ IWL_ERR(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
} else {
@@ -1354,7 +1210,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
unsigned long flags;
if (!ra) {
- IWL_ERROR("ra = NULL\n");
+ IWL_ERR(priv, "ra = NULL\n");
return -EINVAL;
}
@@ -1369,7 +1225,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
return -ENXIO;
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
- IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n");
+ IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n");
tid_data = &priv->stations[sta_id].tid[tid];
ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
@@ -1455,7 +1311,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
struct ieee80211_tx_info *info;
if (unlikely(!agg->wait_for_ba)) {
- IWL_ERROR("Received BA when not expected\n");
+ IWL_ERR(priv, "Received BA when not expected\n");
return -EINVAL;
}
@@ -1528,7 +1384,8 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
if (scd_flow >= priv->hw_params.max_txq_num) {
- IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n");
+ IWL_ERR(priv,
+ "BUG_ON scd_flow is bigger than number of queues\n");
return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 95d01984c80..25a350810a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -46,40 +46,25 @@
#include <asm/div64.h>
-#include "iwl-3945-core.h"
+#define DRV_NAME "iwl3945"
+
+#include "iwl-fh.h"
+#include "iwl-3945-fh.h"
+#include "iwl-commands.h"
+#include "iwl-sta.h"
#include "iwl-3945.h"
#include "iwl-helpers.h"
-
-#ifdef CONFIG_IWL3945_DEBUG
-u32 iwl3945_debug_level;
-#endif
-
-static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq);
-
-/******************************************************************************
- *
- * module boiler plate
- *
- ******************************************************************************/
-
-/* module parameters */
-static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */
-static u32 iwl3945_param_debug; /* def: 0 = minimal debug log messages */
-static int iwl3945_param_disable; /* def: 0 = enable radio */
-static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */
-int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */
-int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
+#include "iwl-core.h"
+#include "iwl-dev.h"
/*
* module name, copyright, version, etc.
- * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
*/
#define DRV_DESCRIPTION \
"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux"
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
#define VD "d"
#else
#define VD
@@ -91,10 +76,10 @@ int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
#define VS
#endif
-#define IWLWIFI_VERSION "1.2.26k" VD VS
-#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define IWL39_VERSION "1.2.26k" VD VS
+#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
-#define DRV_VERSION IWLWIFI_VERSION
+#define DRV_VERSION IWL39_VERSION
MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -102,235 +87,13 @@ MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
-static const struct ieee80211_supported_band *iwl3945_get_band(
- struct iwl3945_priv *priv, enum ieee80211_band band)
-{
- return priv->hw->wiphy->bands[band];
-}
-
-/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
- * DMA services
- *
- * Theory of operation
- *
- * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
- * of buffer descriptors, each of which points to one or more data buffers for
- * the device to read from or fill. Driver and device exchange status of each
- * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty
- * entries in each circular buffer, to protect against confusing empty and full
- * queue states.
- *
- * The device reads or writes the data in the queues via the device's several
- * DMA/FIFO channels. Each queue is mapped to a single DMA channel.
- *
- * For Tx queue, there are low mark and high mark limits. If, after queuing
- * the packet for Tx, free space become < low mark, Tx queue stopped. When
- * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
- * Tx queue resumed.
- *
- * The 3945 operates with six queues: One receive queue, one transmit queue
- * (#4) for sending commands to the device firmware, and four transmit queues
- * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused.
- ***************************************************/
-
-int iwl3945_queue_space(const struct iwl3945_queue *q)
-{
- int s = q->read_ptr - q->write_ptr;
-
- if (q->read_ptr > q->write_ptr)
- s -= q->n_bd;
-
- if (s <= 0)
- s += q->n_window;
- /* keep some reserve to not confuse empty and full situations */
- s -= 2;
- if (s < 0)
- s = 0;
- return s;
-}
-
-int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i)
-{
- return q->write_ptr > q->read_ptr ?
- (i >= q->read_ptr && i < q->write_ptr) :
- !(i < q->read_ptr && i >= q->write_ptr);
-}
-
-
-static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge)
-{
- /* This is for scan command, the big buffer at end of command array */
- if (is_huge)
- return q->n_window; /* must be power of 2 */
-
- /* Otherwise, use normal size buffers */
- return index & (q->n_window - 1);
-}
-
-/**
- * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes
- */
-static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q,
- int count, int slots_num, u32 id)
-{
- q->n_bd = count;
- q->n_window = slots_num;
- q->id = id;
-
- /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
- * and iwl_queue_dec_wrap are broken. */
- BUG_ON(!is_power_of_2(count));
-
- /* slots_num must be power-of-two size, otherwise
- * get_cmd_index is broken. */
- BUG_ON(!is_power_of_2(slots_num));
-
- q->low_mark = q->n_window / 4;
- if (q->low_mark < 4)
- q->low_mark = 4;
-
- q->high_mark = q->n_window / 8;
- if (q->high_mark < 2)
- q->high_mark = 2;
-
- q->write_ptr = q->read_ptr = 0;
-
- return 0;
-}
-
-/**
- * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
- */
-static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, u32 id)
-{
- struct pci_dev *dev = priv->pci_dev;
-
- /* Driver private data, only for Tx (not command) queues,
- * not shared with device. */
- if (id != IWL_CMD_QUEUE_NUM) {
- txq->txb = kmalloc(sizeof(txq->txb[0]) *
- TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
- if (!txq->txb) {
- IWL_ERROR("kmalloc for auxiliary BD "
- "structures failed\n");
- goto error;
- }
- } else
- txq->txb = NULL;
-
- /* Circular buffer of transmit frame descriptors (TFDs),
- * shared with device */
- txq->bd = pci_alloc_consistent(dev,
- sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
-
- if (!txq->bd) {
- IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX);
- goto error;
- }
- txq->q.id = id;
-
- return 0;
-
- error:
- kfree(txq->txb);
- txq->txb = NULL;
-
- return -ENOMEM;
-}
-
-/**
- * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue
- */
-int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id)
-{
- struct pci_dev *dev = priv->pci_dev;
- int len;
- int rc = 0;
-
- /*
- * Alloc buffer array for commands (Tx or other types of commands).
- * For the command queue (#4), allocate command space + one big
- * command for scan, since scan command is very huge; the system will
- * not have two scans at the same time, so only one is needed.
- * For data Tx queues (all other queues), no super-size command
- * space is needed.
- */
- len = sizeof(struct iwl3945_cmd) * slots_num;
- if (txq_id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
- txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
- if (!txq->cmd)
- return -ENOMEM;
-
- /* Alloc driver data array and TFD circular buffer */
- rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
- if (rc) {
- pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
- return -ENOMEM;
- }
- txq->need_update = 0;
-
- /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
- * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
- BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
- /* Initialize queue high/low-water, head/tail indexes */
- iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
-
- /* Tell device where to find queue, enable DMA channel. */
- iwl3945_hw_tx_queue_init(priv, txq);
-
- return 0;
-}
-
-/**
- * iwl3945_tx_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
-{
- struct iwl3945_queue *q = &txq->q;
- struct pci_dev *dev = priv->pci_dev;
- int len;
-
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- iwl3945_hw_txq_free_tfd(priv, txq);
-
- len = sizeof(struct iwl3945_cmd) * q->n_window;
- if (q->id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
-
- /* De-alloc array of command/tx buffers */
- pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
- /* De-alloc circular buffer of TFDs */
- if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) *
- txq->q.n_bd, txq->bd, txq->q.dma_addr);
-
- /* De-alloc array of per-TFD driver data */
- kfree(txq->txb);
- txq->txb = NULL;
-
- /* 0-fill queue descriptor structure */
- memset(txq, 0, sizeof(*txq));
-}
-
-const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ /* module parameters */
+struct iwl_mod_params iwl3945_mod_params = {
+ .num_of_queues = IWL39_MAX_NUM_QUEUES,
+ .sw_crypto = 1,
+ .restart_fw = 1,
+ /* the rest are 0 by default */
+};
/*************** STATION TABLE MANAGEMENT ****
* mac80211 should be examined to determine if sta_info is duplicating
@@ -344,7 +107,7 @@ const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
*
* NOTE: This does not remove station from device's station table.
*/
-static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap)
+static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
{
int index = IWL_INVALID_STATION;
int i;
@@ -355,11 +118,11 @@ static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int
if (is_ap)
index = IWL_AP_ID;
else if (is_broadcast_ether_addr(addr))
- index = priv->hw_setting.bcast_sta_id;
+ index = priv->hw_params.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,
+ for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
+ if (priv->stations_39[i].used &&
+ !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
addr)) {
index = i;
break;
@@ -368,8 +131,8 @@ static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int
if (unlikely(index == IWL_INVALID_STATION))
goto out;
- if (priv->stations[index].used) {
- priv->stations[index].used = 0;
+ if (priv->stations_39[index].used) {
+ priv->stations_39[index].used = 0;
priv->num_stations--;
}
@@ -386,14 +149,14 @@ out:
*
* NOTE: This does not clear or otherwise alter the device's station table.
*/
-static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)
+static void iwl3945_clear_stations_table(struct iwl_priv *priv)
{
unsigned long flags;
spin_lock_irqsave(&priv->sta_lock, flags);
priv->num_stations = 0;
- memset(priv->stations, 0, sizeof(priv->stations));
+ memset(priv->stations_39, 0, sizeof(priv->stations_39));
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
@@ -401,7 +164,7 @@ static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)
/**
* iwl3945_add_station - Add station to station tables in driver and device
*/
-u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags)
+u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
{
int i;
int index = IWL_INVALID_STATION;
@@ -413,16 +176,16 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
if (is_ap)
index = IWL_AP_ID;
else if (is_broadcast_ether_addr(addr))
- index = priv->hw_setting.bcast_sta_id;
+ index = priv->hw_params.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,
+ for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
+ if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
addr)) {
index = i;
break;
}
- if (!priv->stations[i].used &&
+ if (!priv->stations_39[i].used &&
index == IWL_INVALID_STATION)
index = i;
}
@@ -434,14 +197,14 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
return index;
}
- if (priv->stations[index].used &&
- !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) {
+ if (priv->stations_39[index].used &&
+ !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
return index;
}
IWL_DEBUG_ASSOC("Add STA ID %d: %pM\n", index, addr);
- station = &priv->stations[index];
+ station = &priv->stations_39[index];
station->used = 1;
priv->num_stations++;
@@ -460,353 +223,16 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
/* Turn on both antennas for the station... */
station->sta.rate_n_flags =
iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
- station->current_rate.rate_n_flags =
- le16_to_cpu(station->sta.rate_n_flags);
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
/* Add station to device's station table */
- iwl3945_send_add_station(priv, &station->sta, flags);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&station->sta, flags);
return index;
}
-/*************** DRIVER STATUS FUNCTIONS *****/
-
-static inline int iwl3945_is_ready(struct iwl3945_priv *priv)
-{
- /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
- * set but EXIT_PENDING is not */
- return test_bit(STATUS_READY, &priv->status) &&
- test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
- !test_bit(STATUS_EXIT_PENDING, &priv->status);
-}
-
-static inline int iwl3945_is_alive(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_ALIVE, &priv->status);
-}
-
-static inline int iwl3945_is_init(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_INIT, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_HW, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
-{
- return iwl3945_is_rfkill_hw(priv) ||
- iwl3945_is_rfkill_sw(priv);
-}
-
-static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
-{
-
- if (iwl3945_is_rfkill(priv))
- return 0;
-
- return iwl3945_is_ready(priv);
-}
-
-/*************** HOST COMMAND QUEUE FUNCTIONS *****/
-
-#define IWL_CMD(x) case x: return #x
-
-static const char *get_cmd_string(u8 cmd)
-{
- switch (cmd) {
- IWL_CMD(REPLY_ALIVE);
- IWL_CMD(REPLY_ERROR);
- IWL_CMD(REPLY_RXON);
- IWL_CMD(REPLY_RXON_ASSOC);
- IWL_CMD(REPLY_QOS_PARAM);
- IWL_CMD(REPLY_RXON_TIMING);
- IWL_CMD(REPLY_ADD_STA);
- IWL_CMD(REPLY_REMOVE_STA);
- IWL_CMD(REPLY_REMOVE_ALL_STA);
- IWL_CMD(REPLY_3945_RX);
- IWL_CMD(REPLY_TX);
- IWL_CMD(REPLY_RATE_SCALE);
- IWL_CMD(REPLY_LEDS_CMD);
- IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
- IWL_CMD(RADAR_NOTIFICATION);
- IWL_CMD(REPLY_QUIET_CMD);
- IWL_CMD(REPLY_CHANNEL_SWITCH);
- IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
- IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
- IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
- IWL_CMD(POWER_TABLE_CMD);
- IWL_CMD(PM_SLEEP_NOTIFICATION);
- IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
- IWL_CMD(REPLY_SCAN_CMD);
- IWL_CMD(REPLY_SCAN_ABORT_CMD);
- IWL_CMD(SCAN_START_NOTIFICATION);
- IWL_CMD(SCAN_RESULTS_NOTIFICATION);
- IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
- IWL_CMD(BEACON_NOTIFICATION);
- IWL_CMD(REPLY_TX_BEACON);
- IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
- IWL_CMD(QUIET_NOTIFICATION);
- IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
- IWL_CMD(MEASURE_ABORT_NOTIFICATION);
- IWL_CMD(REPLY_BT_CONFIG);
- IWL_CMD(REPLY_STATISTICS_CMD);
- IWL_CMD(STATISTICS_NOTIFICATION);
- IWL_CMD(REPLY_CARD_STATE_CMD);
- IWL_CMD(CARD_STATE_NOTIFICATION);
- IWL_CMD(MISSED_BEACONS_NOTIFICATION);
- default:
- return "UNKNOWN";
-
- }
-}
-
-#define HOST_COMPLETE_TIMEOUT (HZ / 2)
-
-/**
- * iwl3945_enqueue_hcmd - enqueue a uCode command
- * @priv: device private data point
- * @cmd: a point to the ucode command structure
- *
- * The function returns < 0 values to indicate the operation is
- * failed. On success, it turns the index (> 0) of command in the
- * command queue.
- */
-static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- struct iwl3945_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
- struct iwl3945_queue *q = &txq->q;
- struct iwl3945_tfd_frame *tfd;
- u32 *control_flags;
- struct iwl3945_cmd *out_cmd;
- u32 idx;
- u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
- dma_addr_t phys_addr;
- int pad;
- u16 count;
- int ret;
- unsigned long flags;
-
- /* If any of the command structures end up being larger than
- * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
- * we will need to increase the size of the TFD entries */
- BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
- !(cmd->meta.flags & CMD_SIZE_HUGE));
-
-
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_INFO("Not sending command - RF KILL");
- return -EIO;
- }
-
- if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
- IWL_ERROR("No space for Tx\n");
- return -ENOSPC;
- }
-
- spin_lock_irqsave(&priv->hcmd_lock, flags);
-
- tfd = &txq->bd[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
- control_flags = (u32 *) tfd;
-
- idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
- out_cmd = &txq->cmd[idx];
-
- out_cmd->hdr.cmd = cmd->id;
- memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
- memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
-
- /* At this point, the out_cmd now has all of the incoming cmd
- * information */
-
- out_cmd->hdr.flags = 0;
- out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
- INDEX_TO_SEQ(q->write_ptr));
- if (out_cmd->meta.flags & CMD_SIZE_HUGE)
- out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
-
- phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
- offsetof(struct iwl3945_cmd, hdr);
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
-
- pad = U32_PAD(cmd->len);
- count = TFD_CTL_COUNT_GET(*control_flags);
- *control_flags = TFD_CTL_COUNT_SET(count) | TFD_CTL_PAD_SET(pad);
-
- IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
- "%d bytes at %d[%d]:%d\n",
- get_cmd_string(out_cmd->hdr.cmd),
- out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
- fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
-
- txq->need_update = 1;
-
- /* Increment and update queue's write index */
- q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- ret = iwl3945_tx_queue_update_write_ptr(priv, txq);
-
- spin_unlock_irqrestore(&priv->hcmd_lock, flags);
- return ret ? ret : idx;
-}
-
-static int iwl3945_send_cmd_async(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- int ret;
-
- BUG_ON(!(cmd->meta.flags & CMD_ASYNC));
-
- /* An asynchronous command can not expect an SKB to be set. */
- BUG_ON(cmd->meta.flags & CMD_WANT_SKB);
-
- /* An asynchronous command MUST have a callback. */
- BUG_ON(!cmd->meta.u.callback);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return -EBUSY;
-
- ret = iwl3945_enqueue_hcmd(priv, cmd);
- if (ret < 0) {
- IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
- get_cmd_string(cmd->id), ret);
- return ret;
- }
- return 0;
-}
-
-static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- int cmd_idx;
- int ret;
-
- BUG_ON(cmd->meta.flags & CMD_ASYNC);
-
- /* A synchronous command can not have a callback set. */
- BUG_ON(cmd->meta.u.callback != NULL);
-
- if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: Already sending a host command\n",
- get_cmd_string(cmd->id));
- ret = -EBUSY;
- goto out;
- }
-
- set_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
- if (cmd->meta.flags & CMD_WANT_SKB)
- cmd->meta.source = &cmd->meta;
-
- cmd_idx = iwl3945_enqueue_hcmd(priv, cmd);
- if (cmd_idx < 0) {
- ret = cmd_idx;
- IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
- get_cmd_string(cmd->id), ret);
- goto out;
- }
-
- ret = wait_event_interruptible_timeout(priv->wait_command_queue,
- !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
- HOST_COMPLETE_TIMEOUT);
- if (!ret) {
- if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: time out after %dms.\n",
- get_cmd_string(cmd->id),
- jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
-
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
- ret = -ETIMEDOUT;
- goto cancel;
- }
- }
-
- if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n",
- get_cmd_string(cmd->id));
- ret = -ECANCELED;
- goto fail;
- }
- if (test_bit(STATUS_FW_ERROR, &priv->status)) {
- IWL_DEBUG_INFO("Command %s failed: FW Error\n",
- get_cmd_string(cmd->id));
- ret = -EIO;
- goto fail;
- }
- if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
- IWL_ERROR("Error: Response NULL in '%s'\n",
- get_cmd_string(cmd->id));
- ret = -EIO;
- goto cancel;
- }
-
- ret = 0;
- goto out;
-
-cancel:
- if (cmd->meta.flags & CMD_WANT_SKB) {
- struct iwl3945_cmd *qcmd;
-
- /* Cancel the CMD_WANT_SKB flag for the cmd in the
- * TX cmd queue. Otherwise in case the cmd comes
- * in later, it will possibly set an invalid
- * address (cmd->meta.source). */
- qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
- qcmd->meta.flags &= ~CMD_WANT_SKB;
- }
-fail:
- if (cmd->meta.u.skb) {
- dev_kfree_skb_any(cmd->meta.u.skb);
- cmd->meta.u.skb = NULL;
- }
-out:
- clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
- return ret;
-}
-
-int iwl3945_send_cmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- if (cmd->meta.flags & CMD_ASYNC)
- return iwl3945_send_cmd_async(priv, cmd);
-
- return iwl3945_send_cmd_sync(priv, cmd);
-}
-
-int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, const void *data)
-{
- struct iwl3945_host_cmd cmd = {
- .id = id,
- .len = len,
- .data = data,
- };
-
- return iwl3945_send_cmd_sync(priv, &cmd);
-}
-
-static int __must_check iwl3945_send_cmd_u32(struct iwl3945_priv *priv, u8 id, u32 val)
-{
- struct iwl3945_host_cmd cmd = {
- .id = id,
- .len = sizeof(val),
- .data = &val,
- };
-
- return iwl3945_send_cmd_sync(priv, &cmd);
-}
-
-int iwl3945_send_statistics_request(struct iwl3945_priv *priv)
-{
- return iwl3945_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
-}
-
/**
* iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON
* @band: 2.4 or 5 GHz band
@@ -817,25 +243,25 @@ int iwl3945_send_statistics_request(struct iwl3945_priv *priv)
* NOTE: Does not commit to the hardware; it sets appropriate bit fields
* in the staging RXON flag structure based on the band
*/
-static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv,
+static int iwl3945_set_rxon_channel(struct iwl_priv *priv,
enum ieee80211_band band,
u16 channel)
{
- if (!iwl3945_get_channel_info(priv, band, channel)) {
+ if (!iwl_get_channel_info(priv, band, channel)) {
IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
channel, band);
return -EINVAL;
}
- if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
+ if ((le16_to_cpu(priv->staging39_rxon.channel) == channel) &&
(priv->band == band))
return 0;
- priv->staging_rxon.channel = cpu_to_le16(channel);
+ priv->staging39_rxon.channel = cpu_to_le16(channel);
if (band == IEEE80211_BAND_5GHZ)
- priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
else
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_BAND_24G_MSK;
priv->band = band;
@@ -851,73 +277,74 @@ static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv,
* be #ifdef'd out once the driver is stable and folks aren't actively
* making changes
*/
-static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon)
+static int iwl3945_check_rxon_cmd(struct iwl_priv *priv)
{
int error = 0;
int counter = 1;
+ struct iwl3945_rxon_cmd *rxon = &priv->staging39_rxon;
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
error |= le32_to_cpu(rxon->flags &
(RXON_FLG_TGJ_NARROW_BAND_MSK |
RXON_FLG_RADAR_DETECT_MSK));
if (error)
- IWL_WARNING("check 24G fields %d | %d\n",
+ IWL_WARN(priv, "check 24G fields %d | %d\n",
counter++, error);
} else {
error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
if (error)
- IWL_WARNING("check 52 fields %d | %d\n",
+ IWL_WARN(priv, "check 52 fields %d | %d\n",
counter++, error);
error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
if (error)
- IWL_WARNING("check 52 CCK %d | %d\n",
+ IWL_WARN(priv, "check 52 CCK %d | %d\n",
counter++, error);
}
error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
if (error)
- IWL_WARNING("check mac addr %d | %d\n", counter++, error);
+ IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error);
/* make sure basic rates 6Mbps and 1Mbps are supported */
error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
if (error)
- IWL_WARNING("check basic rate %d | %d\n", counter++, error);
+ IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error);
error |= (le16_to_cpu(rxon->assoc_id) > 2007);
if (error)
- IWL_WARNING("check assoc id %d | %d\n", counter++, error);
+ IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error);
error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
if (error)
- IWL_WARNING("check CCK and short slot %d | %d\n",
+ IWL_WARN(priv, "check CCK and short slot %d | %d\n",
counter++, error);
error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
if (error)
- IWL_WARNING("check CCK & auto detect %d | %d\n",
+ IWL_WARN(priv, "check CCK & auto detect %d | %d\n",
counter++, error);
error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
if (error)
- IWL_WARNING("check TGG and auto detect %d | %d\n",
+ IWL_WARN(priv, "check TGG and auto detect %d | %d\n",
counter++, error);
if ((rxon->flags & RXON_FLG_DIS_DIV_MSK))
error |= ((rxon->flags & (RXON_FLG_ANT_B_MSK |
RXON_FLG_ANT_A_MSK)) == 0);
if (error)
- IWL_WARNING("check antenna %d %d\n", counter++, error);
+ IWL_WARN(priv, "check antenna %d %d\n", counter++, error);
if (error)
- IWL_WARNING("Tuning to channel %d\n",
+ IWL_WARN(priv, "Tuning to channel %d\n",
le16_to_cpu(rxon->channel));
if (error) {
- IWL_ERROR("Not a valid iwl3945_rxon_assoc_cmd field values\n");
+ IWL_ERR(priv, "Not a valid rxon_assoc_cmd field values\n");
return -1;
}
return 0;
@@ -931,22 +358,22 @@ static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon)
* or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
* a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
*/
-static int iwl3945_full_rxon_required(struct iwl3945_priv *priv)
+static int iwl3945_full_rxon_required(struct iwl_priv *priv)
{
/* These items are only settable from the full RXON command */
if (!(iwl3945_is_associated(priv)) ||
- compare_ether_addr(priv->staging_rxon.bssid_addr,
- priv->active_rxon.bssid_addr) ||
- compare_ether_addr(priv->staging_rxon.node_addr,
- priv->active_rxon.node_addr) ||
- compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
- priv->active_rxon.wlap_bssid_addr) ||
- (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
- (priv->staging_rxon.channel != priv->active_rxon.channel) ||
- (priv->staging_rxon.air_propagation !=
- priv->active_rxon.air_propagation) ||
- (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
+ compare_ether_addr(priv->staging39_rxon.bssid_addr,
+ priv->active39_rxon.bssid_addr) ||
+ compare_ether_addr(priv->staging39_rxon.node_addr,
+ priv->active39_rxon.node_addr) ||
+ compare_ether_addr(priv->staging39_rxon.wlap_bssid_addr,
+ priv->active39_rxon.wlap_bssid_addr) ||
+ (priv->staging39_rxon.dev_type != priv->active39_rxon.dev_type) ||
+ (priv->staging39_rxon.channel != priv->active39_rxon.channel) ||
+ (priv->staging39_rxon.air_propagation !=
+ priv->active39_rxon.air_propagation) ||
+ (priv->staging39_rxon.assoc_id != priv->active39_rxon.assoc_id))
return 1;
/* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
@@ -954,31 +381,31 @@ static int iwl3945_full_rxon_required(struct iwl3945_priv *priv)
* flag transitions are allowed using RXON_ASSOC */
/* Check if we are not switching bands */
- if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
- (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
+ if ((priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
+ (priv->active39_rxon.flags & RXON_FLG_BAND_24G_MSK))
return 1;
/* Check if we are switching association toggle */
- if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
- (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
+ if ((priv->staging39_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
+ (priv->active39_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
return 1;
return 0;
}
-static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
{
int rc = 0;
- struct iwl3945_rx_packet *res = NULL;
+ struct iwl_rx_packet *res = NULL;
struct iwl3945_rxon_assoc_cmd rxon_assoc;
- struct iwl3945_host_cmd cmd = {
+ struct iwl_host_cmd cmd = {
.id = REPLY_RXON_ASSOC,
.len = sizeof(rxon_assoc),
.meta.flags = CMD_WANT_SKB,
.data = &rxon_assoc,
};
- const struct iwl3945_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl3945_rxon_cmd *rxon2 = &priv->active_rxon;
+ const struct iwl3945_rxon_cmd *rxon1 = &priv->staging39_rxon;
+ const struct iwl3945_rxon_cmd *rxon2 = &priv->active39_rxon;
if ((rxon1->flags == rxon2->flags) &&
(rxon1->filter_flags == rxon2->filter_flags) &&
@@ -988,19 +415,19 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
return 0;
}
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.flags = priv->staging39_rxon.flags;
+ rxon_assoc.filter_flags = priv->staging39_rxon.filter_flags;
+ rxon_assoc.ofdm_basic_rates = priv->staging39_rxon.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = priv->staging39_rxon.cck_basic_rates;
rxon_assoc.reserved = 0;
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
return rc;
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
rc = -EIO;
}
@@ -1011,6 +438,43 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
}
/**
+ * iwl3945_get_antenna_flags - Get antenna flags for RXON command
+ * @priv: eeprom and antenna fields are used to determine antenna flags
+ *
+ * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed
+ * iwl3945_mod_params.antenna specifies the antenna diversity mode:
+ *
+ * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
+ * IWL_ANTENNA_MAIN - Force MAIN antenna
+ * IWL_ANTENNA_AUX - Force AUX antenna
+ */
+__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
+{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+
+ switch (iwl3945_mod_params.antenna) {
+ case IWL_ANTENNA_DIVERSITY:
+ return 0;
+
+ case IWL_ANTENNA_MAIN:
+ if (eeprom->antenna_switch_type)
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+
+ case IWL_ANTENNA_AUX:
+ if (eeprom->antenna_switch_type)
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+ }
+
+ /* bad antenna selector value */
+ IWL_ERR(priv, "Bad antenna selector value (0x%x)\n",
+ iwl3945_mod_params.antenna);
+
+ return 0; /* "diversity" is default if error */
+}
+
+/**
* iwl3945_commit_rxon - commit staging_rxon to hardware
*
* The RXON command in staging_rxon is committed to the hardware and
@@ -1018,26 +482,26 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
+static int iwl3945_commit_rxon(struct iwl_priv *priv)
{
/* cast away the const for active_rxon in this function */
- struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+ struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active39_rxon;
int rc = 0;
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -1;
/* always get timestamp with Rx frame */
- priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
/* select antenna */
- priv->staging_rxon.flags &=
+ priv->staging39_rxon.flags &=
~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
- priv->staging_rxon.flags |= iwl3945_get_antenna_flags(priv);
+ priv->staging39_rxon.flags |= iwl3945_get_antenna_flags(priv);
- rc = iwl3945_check_rxon_cmd(&priv->staging_rxon);
+ rc = iwl3945_check_rxon_cmd(priv);
if (rc) {
- IWL_ERROR("Invalid RXON configuration. Not committing.\n");
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
}
@@ -1047,12 +511,12 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
if (!iwl3945_full_rxon_required(priv)) {
rc = iwl3945_send_rxon_assoc(priv);
if (rc) {
- IWL_ERROR("Error setting RXON_ASSOC "
+ IWL_ERR(priv, "Error setting RXON_ASSOC "
"configuration (%d).\n", rc);
return rc;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ memcpy(active_rxon, &priv->staging39_rxon, sizeof(*active_rxon));
return 0;
}
@@ -1062,19 +526,19 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
* we must clear the associated from the active configuration
* before we apply the new config */
if (iwl3945_is_associated(priv) &&
- (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
+ (priv->staging39_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl3945_rxon_cmd),
- &priv->active_rxon);
+ &priv->active39_rxon);
/* If the mask clearing failed then we set
* active_rxon back to what it was previously */
if (rc) {
active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERROR("Error clearing ASSOC_MSK on current "
+ IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
"configuration (%d).\n", rc);
return rc;
}
@@ -1084,35 +548,35 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
"* with%s RXON_FILTER_ASSOC_MSK\n"
"* channel = %d\n"
"* bssid = %pM\n",
- ((priv->staging_rxon.filter_flags &
+ ((priv->staging39_rxon.filter_flags &
RXON_FILTER_ASSOC_MSK) ? "" : "out"),
- le16_to_cpu(priv->staging_rxon.channel),
+ le16_to_cpu(priv->staging39_rxon.channel),
priv->staging_rxon.bssid_addr);
/* Apply the new configuration */
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd), &priv->staging_rxon);
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl3945_rxon_cmd), &priv->staging39_rxon);
if (rc) {
- IWL_ERROR("Error setting new configuration (%d).\n", rc);
+ IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
return rc;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ memcpy(active_rxon, &priv->staging39_rxon, sizeof(*active_rxon));
iwl3945_clear_stations_table(priv);
/* If we issue a new RXON command which required a tune then we must
* send a new TXPOWER command or we won't be able to Tx any frames */
- rc = iwl3945_hw_reg_send_txpower(priv);
+ rc = priv->cfg->ops->lib->send_tx_power(priv);
if (rc) {
- IWL_ERROR("Error setting Tx power (%d).\n", rc);
+ IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
return rc;
}
/* Add the broadcast address so we can send broadcast frames */
- if (iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0) ==
+ if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
IWL_INVALID_STATION) {
- IWL_ERROR("Error adding BROADCAST address for transmit.\n");
+ IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
return -EIO;
}
@@ -1120,185 +584,23 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
* add the IWL_AP_ID to the station rate table */
if (iwl3945_is_associated(priv) &&
(priv->iw_mode == NL80211_IFTYPE_STATION))
- if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
+ if (iwl3945_add_station(priv, priv->active39_rxon.bssid_addr, 1, 0)
== IWL_INVALID_STATION) {
- IWL_ERROR("Error adding AP address for transmit.\n");
+ IWL_ERR(priv, "Error adding AP address for transmit\n");
return -EIO;
}
/* Init the hardware's rate fallback order based on the band */
rc = iwl3945_init_hw_rate_table(priv);
if (rc) {
- IWL_ERROR("Error setting HW rate table: %02X\n", rc);
+ IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
return -EIO;
}
return 0;
}
-static int iwl3945_send_bt_config(struct iwl3945_priv *priv)
-{
- struct iwl3945_bt_cmd bt_cmd = {
- .flags = 3,
- .lead_time = 0xAA,
- .max_kill = 1,
- .kill_ack_mask = 0,
- .kill_cts_mask = 0,
- };
-
- return iwl3945_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(struct iwl3945_bt_cmd), &bt_cmd);
-}
-
-static int iwl3945_send_scan_abort(struct iwl3945_priv *priv)
-{
- int rc = 0;
- struct iwl3945_rx_packet *res;
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_SCAN_ABORT_CMD,
- .meta.flags = CMD_WANT_SKB,
- };
-
- /* If there isn't a scan actively going on in the hardware
- * then we are in between scan bands and not actually
- * actively scanning, so don't send the abort command */
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return 0;
- }
-
- rc = iwl3945_send_cmd_sync(priv, &cmd);
- if (rc) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return rc;
- }
-
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
- if (res->u.status != CAN_ABORT_STATUS) {
- /* The scan abort will return 1 for success or
- * 2 for "failure". A failure condition can be
- * due to simply not being in an active scan which
- * can occur if we send the scan abort before we
- * the microcode has notified us that a scan is
- * completed. */
- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- clear_bit(STATUS_SCAN_HW, &priv->status);
- }
-
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
-static int iwl3945_card_state_sync_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
- struct sk_buff *skb)
-{
- return 1;
-}
-
-/*
- * CARD_STATE_CMD
- *
- * Use: Sets the device's internal card state to enable, disable, or halt
- *
- * When in the 'enable' state the card operates as normal.
- * When in the 'disable' state, the card enters into a low power mode.
- * When in the 'halt' state, the card is shut down and must be fully
- * restarted to come back on.
- */
-static int iwl3945_send_card_state(struct iwl3945_priv *priv, u32 flags, u8 meta_flag)
-{
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_CARD_STATE_CMD,
- .len = sizeof(u32),
- .data = &flags,
- .meta.flags = meta_flag,
- };
-
- if (meta_flag & CMD_ASYNC)
- cmd.meta.u.callback = iwl3945_card_state_sync_callback;
-
- return iwl3945_send_cmd(priv, &cmd);
-}
-
-static int iwl3945_add_sta_sync_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd, struct sk_buff *skb)
-{
- struct iwl3945_rx_packet *res = NULL;
-
- if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
- return 1;
- }
-
- res = (struct iwl3945_rx_packet *)skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- return 1;
- }
-
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- break;
- default:
- break;
- }
-
- /* We didn't cache the SKB; let the caller free it */
- return 1;
-}
-
-int iwl3945_send_add_station(struct iwl3945_priv *priv,
- struct iwl3945_addsta_cmd *sta, u8 flags)
-{
- struct iwl3945_rx_packet *res = NULL;
- int rc = 0;
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_ADD_STA,
- .len = sizeof(struct iwl3945_addsta_cmd),
- .meta.flags = flags,
- .data = sta,
- };
-
- if (flags & CMD_ASYNC)
- cmd.meta.u.callback = iwl3945_add_sta_sync_callback;
- else
- cmd.meta.flags |= CMD_WANT_SKB;
-
- rc = iwl3945_send_cmd(priv, &cmd);
-
- if (rc || (flags & CMD_ASYNC))
- return rc;
-
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- rc = -EIO;
- }
-
- if (rc == 0) {
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
- break;
- default:
- rc = -EIO;
- IWL_WARNING("REPLY_ADD_STA failed\n");
- break;
- }
- }
-
- priv->alloc_rxb_skb--;
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
-static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv,
+static int iwl3945_update_sta_key_info(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
u8 sta_id)
{
@@ -1318,42 +620,45 @@ static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv,
return -EINVAL;
}
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
- memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
+ priv->stations_39[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen;
+ memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key,
keyconf->keylen);
- memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
+ memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
keyconf->keylen);
- priv->stations[sta_id].sta.key.key_flags = key_flags;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ priv->stations_39[sta_id].sta.key.key_flags = key_flags;
+ priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags);
IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
- iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
return 0;
}
-static int iwl3945_clear_sta_key_info(struct iwl3945_priv *priv, u8 sta_id)
+static int iwl3945_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 iwl3945_hw_key));
- memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl3945_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;
+ memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
+ memset(&priv->stations_39[sta_id].sta.key, 0,
+ sizeof(struct iwl4965_keyinfo));
+ priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
+ priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations_39[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");
- iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
return 0;
}
-static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
+static void iwl3945_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
@@ -1368,20 +673,20 @@ static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
}
if (priv->frames_count) {
- IWL_WARNING("%d frames still in use. Did we lose one?\n",
+ IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
priv->frames_count);
priv->frames_count = 0;
}
}
-static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
+static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv)
{
struct iwl3945_frame *frame;
struct list_head *element;
if (list_empty(&priv->free_frames)) {
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame) {
- IWL_ERROR("Could not allocate frame!\n");
+ IWL_ERR(priv, "Could not allocate frame!\n");
return NULL;
}
@@ -1394,13 +699,13 @@ static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
return list_entry(element, struct iwl3945_frame, list);
}
-static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *frame)
+static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame)
{
memset(frame, 0, sizeof(*frame));
list_add(&frame->list, &priv->free_frames);
}
-unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
int left)
{
@@ -1418,13 +723,13 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
return priv->ibss_beacon->len;
}
-static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
+static u8 iwl3945_rate_get_lowest_plcp(struct iwl_priv *priv)
{
u8 i;
int rate_mask;
/* Set rate mask*/
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ if (priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK)
rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
else
rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
@@ -1436,13 +741,13 @@ static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
}
/* No valid rate was found. Assign the lowest one */
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ if (priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK)
return IWL_RATE_1M_PLCP;
else
return IWL_RATE_6M_PLCP;
}
-static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
+static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
{
struct iwl3945_frame *frame;
unsigned int frame_size;
@@ -1452,7 +757,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
frame = iwl3945_get_free_frame(priv);
if (!frame) {
- IWL_ERROR("Could not obtain free frame buffer for beacon "
+ IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
"command.\n");
return -ENOMEM;
}
@@ -1461,7 +766,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
+ rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
&frame->u.cmd[0]);
iwl3945_free_frame(priv, frame);
@@ -1469,307 +774,27 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
return rc;
}
-/******************************************************************************
- *
- * EEPROM related functions
- *
- ******************************************************************************/
-
-static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
-{
- memcpy(mac, priv->eeprom.mac_address, 6);
-}
-
-/*
- * Clear the OWNER_MSK, to establish driver (instead of uCode running on
- * embedded controller) as EEPROM reader; each read is a series of pulses
- * to/from the EEPROM chip, not a single event, so even reads could conflict
- * if they weren't arbitrated by some ownership mechanism. Here, the driver
- * simply claims ownership, which should be safe when this function is called
- * (i.e. before loading uCode!).
- */
-static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
+static void iwl3945_unset_hw_params(struct iwl_priv *priv)
{
- _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
- return 0;
-}
-
-/**
- * iwl3945_eeprom_init - read EEPROM contents
- *
- * Load the EEPROM contents from adapter into priv->eeprom
- *
- * NOTE: This routine uses the non-debug IO access functions.
- */
-int iwl3945_eeprom_init(struct iwl3945_priv *priv)
-{
- u16 *e = (u16 *)&priv->eeprom;
- u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
- int sz = sizeof(priv->eeprom);
- int ret;
- u16 addr;
-
- /* The EEPROM structure has several padding buffers within it
- * and when adding new EEPROM maps is subject to programmer errors
- * which may be very difficult to identify without explicitly
- * checking the resulting size of the eeprom map. */
- BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
-
- if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
- return -ENOENT;
- }
-
- /* Make sure driver (instead of uCode) is allowed to read EEPROM */
- ret = iwl3945_eeprom_acquire_semaphore(priv);
- if (ret < 0) {
- IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
- return -ENOENT;
- }
-
- /* eeprom is an array of 16bit values */
- for (addr = 0; addr < sz; addr += sizeof(u16)) {
- u32 r;
-
- _iwl3945_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
- _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
- ret = iwl3945_poll_direct_bit(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_READ_VALID_MSK,
- IWL_EEPROM_ACCESS_TIMEOUT);
- if (ret < 0) {
- IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
- return ret;
- }
-
- r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
- e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
- }
-
- return 0;
-}
-
-static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv)
-{
- if (priv->hw_setting.shared_virt)
+ if (priv->shared_virt)
pci_free_consistent(priv->pci_dev,
sizeof(struct iwl3945_shared),
- priv->hw_setting.shared_virt,
- priv->hw_setting.shared_phys);
-}
-
-/**
- * iwl3945_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int *left)
-{
- u16 ret_rates = 0, bit;
- int i;
- u8 *cnt = ie;
- u8 *rates = ie + 1;
-
- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
- if (bit & supported_rate) {
- ret_rates |= bit;
- rates[*cnt] = iwl3945_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- (*cnt)++;
- (*left)--;
- if ((*left <= 0) ||
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
- break;
- }
- }
-
- return ret_rates;
-}
-
-/**
- * iwl3945_fill_probe_req - fill in all required fields and IE for probe request
- */
-static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
- struct ieee80211_mgmt *frame,
- int left)
-{
- int len = 0;
- u8 *pos = NULL;
- u16 active_rates, ret_rates, cck_rates;
-
- /* Make sure there is enough space for the probe request,
- * two mandatory IEs and the data */
- left -= 24;
- if (left < 0)
- return 0;
- len += 24;
-
- frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- memcpy(frame->da, iwl3945_broadcast_addr, ETH_ALEN);
- memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
- memcpy(frame->bssid, iwl3945_broadcast_addr, ETH_ALEN);
- frame->seq_ctrl = 0;
-
- /* fill in our indirect SSID IE */
- /* ...next IE... */
-
- left -= 2;
- if (left < 0)
- return 0;
- len += 2;
- pos = &(frame->u.probe_req.variable[0]);
- *pos++ = WLAN_EID_SSID;
- *pos++ = 0;
-
- /* fill in supported rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
-
- /* ... fill it in... */
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos = 0;
-
- priv->active_rate = priv->rates_mask;
- active_rates = priv->active_rate;
- priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
-
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
- ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates,
- priv->active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates,
- priv->active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- len += 2 + *pos;
- pos += (*pos) + 1;
- if (active_rates == 0)
- goto fill_end;
-
- /* fill in supported extended rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos = 0;
- iwl3945_supported_rate_to_ie(pos, active_rates,
- priv->active_rate_basic, &left);
- if (*pos > 0)
- len += 2 + *pos;
-
- fill_end:
- return (u16)len;
+ priv->shared_virt,
+ priv->shared_phys);
}
/*
* QoS support
*/
-static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv,
- struct iwl3945_qosparam_cmd *qos)
+static int iwl3945_send_qos_params_command(struct iwl_priv *priv,
+ struct iwl_qosparam_cmd *qos)
{
- return iwl3945_send_cmd_pdu(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl3945_qosparam_cmd), qos);
+ return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM,
+ sizeof(struct iwl_qosparam_cmd), qos);
}
-static void iwl3945_reset_qos(struct iwl3945_priv *priv)
-{
- u16 cw_min = 15;
- u16 cw_max = 1023;
- u8 aifs = 2;
- u8 is_legacy = 0;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.qos_active = 0;
-
- /* QoS always active in AP and ADHOC mode
- * In STA mode wait for association
- */
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
- priv->iw_mode == NL80211_IFTYPE_AP)
- priv->qos_data.qos_active = 1;
- else
- priv->qos_data.qos_active = 0;
-
-
- /* check for legacy mode */
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
- (priv->iw_mode == NL80211_IFTYPE_STATION &&
- (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
- cw_min = 31;
- is_legacy = 1;
- }
-
- if (priv->qos_data.qos_active)
- aifs = 3;
-
- priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
- priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
- priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
- priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
-
- if (priv->qos_data.qos_active) {
- i = 1;
- priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
- priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
- priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-
- i = 2;
- priv->qos_data.def_qos_parm.ac[i].cw_min =
- cpu_to_le16((cw_min + 1) / 2 - 1);
- priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16(cw_max);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
- if (is_legacy)
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(6016);
- else
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(3008);
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-
- i = 3;
- priv->qos_data.def_qos_parm.ac[i].cw_min =
- cpu_to_le16((cw_min + 1) / 4 - 1);
- priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16((cw_max + 1) / 2 - 1);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
- if (is_legacy)
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(3264);
- else
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(1504);
- } else {
- for (i = 1; i < 4; i++) {
- priv->qos_data.def_qos_parm.ac[i].cw_min =
- cpu_to_le16(cw_min);
- priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16(cw_max);
- priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
- priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
- }
- }
- IWL_DEBUG_QOS("set QoS to default \n");
-
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
+static void iwl3945_activate_qos(struct iwl_priv *priv, u8 force)
{
unsigned long flags;
@@ -1804,56 +829,42 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
*/
#define MSEC_TO_USEC 1024
-#define NOSLP __constant_cpu_to_le32(0)
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK
-#define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
- __constant_cpu_to_le32(X1), \
- __constant_cpu_to_le32(X2), \
- __constant_cpu_to_le32(X3), \
- __constant_cpu_to_le32(X4)}
-
/* default power management (not Tx power) table values */
/* for TIM 0-10 */
-static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
- {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},
- {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
+static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
+ {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},
+ {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
};
/* for TIM > 10 */
-static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = {
- {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
- SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300),
- SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100),
- SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25),
- SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
+static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
+ {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
};
-int iwl3945_power_init_handle(struct iwl3945_priv *priv)
+int iwl3945_power_init_handle(struct iwl_priv *priv)
{
int rc = 0, i;
- struct iwl3945_power_mgr *pow_data;
- int size = sizeof(struct iwl3945_power_vec_entry) * IWL_POWER_AC;
+ struct iwl_power_mgr *pow_data;
+ int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
u16 pci_pm;
IWL_DEBUG_POWER("Initialize power \n");
- pow_data = &(priv->power_data);
+ pow_data = &priv->power_data;
memset(pow_data, 0, sizeof(*pow_data));
- pow_data->active_index = IWL_POWER_RANGE_0;
- pow_data->dtim_val = 0xffff;
+ pow_data->dtim_period = 1;
memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
@@ -1862,11 +873,11 @@ int iwl3945_power_init_handle(struct iwl3945_priv *priv)
if (rc != 0)
return 0;
else {
- struct iwl3945_powertable_cmd *cmd;
+ struct iwl_powertable_cmd *cmd;
IWL_DEBUG_POWER("adjust power command flags\n");
- for (i = 0; i < IWL_POWER_AC; i++) {
+ for (i = 0; i < IWL_POWER_MAX; i++) {
cmd = &pow_data->pwr_range_0[i].cmd;
if (pci_pm & 0x1)
@@ -1878,56 +889,49 @@ int iwl3945_power_init_handle(struct iwl3945_priv *priv)
return rc;
}
-static int iwl3945_update_power_cmd(struct iwl3945_priv *priv,
- struct iwl3945_powertable_cmd *cmd, u32 mode)
+static int iwl3945_update_power_cmd(struct iwl_priv *priv,
+ struct iwl_powertable_cmd *cmd, u32 mode)
{
- int rc = 0, i;
- u8 skip;
+ struct iwl_power_mgr *pow_data;
+ struct iwl_power_vec_entry *range;
u32 max_sleep = 0;
- struct iwl3945_power_vec_entry *range;
+ int i;
u8 period = 0;
- struct iwl3945_power_mgr *pow_data;
+ bool skip;
if (mode > IWL_POWER_INDEX_5) {
IWL_DEBUG_POWER("Error invalid power mode \n");
- return -1;
+ return -EINVAL;
}
- pow_data = &(priv->power_data);
+ pow_data = &priv->power_data;
- if (pow_data->active_index == IWL_POWER_RANGE_0)
+ if (pow_data->dtim_period < 10)
range = &pow_data->pwr_range_0[0];
else
range = &pow_data->pwr_range_1[1];
memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd));
-#ifdef IWL_MAC80211_DISABLE
- if (priv->assoc_network != NULL) {
- unsigned long flags;
-
- period = priv->assoc_network->tim.tim_period;
- }
-#endif /*IWL_MAC80211_DISABLE */
- skip = range[mode].no_dtim;
if (period == 0) {
period = 1;
- skip = 0;
+ skip = false;
+ } else {
+ skip = !!range[mode].no_dtim;
}
- if (skip == 0) {
- max_sleep = period;
- cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
- } else {
+ if (skip) {
__le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ } else {
+ max_sleep = period;
+ cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
}
- for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
+ for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
- }
IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
@@ -1939,23 +943,23 @@ static int iwl3945_update_power_cmd(struct iwl3945_priv *priv,
le32_to_cpu(cmd->sleep_interval[3]),
le32_to_cpu(cmd->sleep_interval[4]));
- return rc;
+ return 0;
}
-static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
+static int iwl3945_send_power_mode(struct iwl_priv *priv, u32 mode)
{
u32 uninitialized_var(final_mode);
int rc;
- struct iwl3945_powertable_cmd cmd;
+ struct iwl_powertable_cmd cmd;
/* If on battery, set to 3,
* if plugged into AC power, set to CAM ("continuously aware mode"),
* else user level */
switch (mode) {
- case IWL_POWER_BATTERY:
+ case IWL39_POWER_BATTERY:
final_mode = IWL_POWER_INDEX_3;
break;
- case IWL_POWER_AC:
+ case IWL39_POWER_AC:
final_mode = IWL_POWER_MODE_CAM;
break;
default:
@@ -1965,7 +969,9 @@ static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
iwl3945_update_power_cmd(priv, &cmd, final_mode);
- rc = iwl3945_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
+ /* FIXME use get_hcmd_size 3945 command is 4 bytes shorter */
+ rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
+ sizeof(struct iwl3945_powertable_cmd), &cmd);
if (final_mode == IWL_POWER_MODE_CAM)
clear_bit(STATUS_POWER_PMI, &priv->status);
@@ -1975,58 +981,6 @@ static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
return rc;
}
-/**
- * iwl3945_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-static int iwl3945_scan_cancel(struct iwl3945_priv *priv)
-{
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCANNING, &priv->status);
- return 0;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Queuing scan abort.\n");
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- queue_work(priv->workqueue, &priv->abort_scan);
-
- } else
- IWL_DEBUG_SCAN("Scan abort already in progress.\n");
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return 0;
-}
-
-/**
- * iwl3945_scan_cancel_timeout - Cancel any currently executing HW scan
- * @ms: amount of time to wait (in milliseconds) for scan to abort
- *
- * NOTE: priv->mutex must be held before calling this function
- */
-static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long ms)
-{
- unsigned long now = jiffies;
- int ret;
-
- ret = iwl3945_scan_cancel(priv);
- if (ret && ms) {
- mutex_unlock(&priv->mutex);
- while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
- test_bit(STATUS_SCANNING, &priv->status))
- msleep(1);
- mutex_lock(&priv->mutex);
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return ret;
-}
-
#define MAX_UCODE_BEACON_INTERVAL 1024
#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
@@ -2043,7 +997,7 @@ static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
return cpu_to_le16(new_val);
}
-static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
+static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
{
u64 interval_tm_unit;
u64 tsf, result;
@@ -2054,13 +1008,10 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
conf = ieee80211_get_hw_conf(priv->hw);
spin_lock_irqsave(&priv->lock, flags);
- priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1);
- priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0);
-
+ priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
- tsf = priv->timestamp1;
- tsf = ((tsf << 32) | priv->timestamp0);
+ tsf = priv->timestamp;
beacon_int = priv->beacon_int;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -2099,9 +1050,9 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
+static int iwl3945_scan_initiate(struct iwl_priv *priv)
{
- if (!iwl3945_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
return -EIO;
}
@@ -2131,9 +1082,9 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
return 0;
}
-static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt)
+static int iwl3945_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
{
- struct iwl3945_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl3945_rxon_cmd *rxon = &priv->staging39_rxon;
if (hw_decrypt)
rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -2143,64 +1094,64 @@ static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt)
return 0;
}
-static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
+static void iwl3945_set_flags_for_phymode(struct iwl_priv *priv,
enum ieee80211_band band)
{
if (band == IEEE80211_BAND_5GHZ) {
- priv->staging_rxon.flags &=
+ priv->staging39_rxon.flags &=
~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
| RXON_FLG_CCK_MSK);
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
} else {
/* Copied from iwl3945_bg_post_associate() */
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
- priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
- priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_BAND_24G_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_CCK_MSK;
}
}
/*
* initialize rxon structure with default values from eeprom
*/
-static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
+static void iwl3945_connection_init_rx_config(struct iwl_priv *priv,
int mode)
{
- const struct iwl3945_channel_info *ch_info;
+ const struct iwl_channel_info *ch_info;
- memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
+ memset(&priv->staging39_rxon, 0, sizeof(priv->staging39_rxon));
switch (mode) {
case NL80211_IFTYPE_AP:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
+ priv->staging39_rxon.dev_type = RXON_DEV_TYPE_AP;
break;
case NL80211_IFTYPE_STATION:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
- priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+ priv->staging39_rxon.dev_type = RXON_DEV_TYPE_ESS;
+ priv->staging39_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
break;
case NL80211_IFTYPE_ADHOC:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
- priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
- priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
+ priv->staging39_rxon.dev_type = RXON_DEV_TYPE_IBSS;
+ priv->staging39_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging39_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
RXON_FILTER_ACCEPT_GRP_MSK;
break;
case NL80211_IFTYPE_MONITOR:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
- priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
+ priv->staging39_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
+ priv->staging39_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
break;
default:
- IWL_ERROR("Unsupported interface type %d\n", mode);
+ IWL_ERR(priv, "Unsupported interface type %d\n", mode);
break;
}
@@ -2208,13 +1159,13 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
/* TODO: Figure out when short_preamble would be set and cache from
* that */
if (!hw_to_local(priv->hw)->short_preamble)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
#endif
- ch_info = iwl3945_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->active_rxon.channel));
+ ch_info = iwl_get_channel_info(priv, priv->band,
+ le16_to_cpu(priv->active39_rxon.channel));
if (!ch_info)
ch_info = &priv->channel_info[0];
@@ -2226,7 +1177,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info)))
ch_info = &priv->channel_info[0];
- priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
+ priv->staging39_rxon.channel = cpu_to_le16(ch_info->channel);
if (is_channel_a_band(ch_info))
priv->band = IEEE80211_BAND_5GHZ;
else
@@ -2234,40 +1185,40 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
iwl3945_set_flags_for_phymode(priv, priv->band);
- priv->staging_rxon.ofdm_basic_rates =
+ priv->staging39_rxon.ofdm_basic_rates =
(IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
- priv->staging_rxon.cck_basic_rates =
+ priv->staging39_rxon.cck_basic_rates =
(IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
}
-static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
+static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
{
if (mode == NL80211_IFTYPE_ADHOC) {
- const struct iwl3945_channel_info *ch_info;
+ const struct iwl_channel_info *ch_info;
- ch_info = iwl3945_get_channel_info(priv,
+ ch_info = iwl_get_channel_info(priv,
priv->band,
- le16_to_cpu(priv->staging_rxon.channel));
+ le16_to_cpu(priv->staging39_rxon.channel));
if (!ch_info || !is_channel_ibss(ch_info)) {
- IWL_ERROR("channel %d not IBSS channel\n",
- le16_to_cpu(priv->staging_rxon.channel));
+ IWL_ERR(priv, "channel %d not IBSS channel\n",
+ le16_to_cpu(priv->staging39_rxon.channel));
return -EINVAL;
}
}
iwl3945_connection_init_rx_config(priv, mode);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+ memcpy(priv->staging39_rxon.node_addr, priv->mac_addr, ETH_ALEN);
iwl3945_clear_stations_table(priv);
/* don't commit rxon if rf-kill is on*/
- if (!iwl3945_is_ready_rf(priv))
+ if (!iwl_is_ready_rf(priv))
return -EAGAIN;
cancel_delayed_work(&priv->scan_check);
- if (iwl3945_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress after 100ms\n");
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
return -EAGAIN;
}
@@ -2277,49 +1228,50 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
return 0;
}
-static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
+static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
- struct iwl3945_cmd *cmd,
+ struct iwl_cmd *cmd,
struct sk_buff *skb_frag,
int last_frag)
{
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
struct iwl3945_hw_key *keyinfo =
- &priv->stations[info->control.hw_key->hw_key_idx].keyinfo;
+ &priv->stations_39[info->control.hw_key->hw_key_idx].keyinfo;
switch (keyinfo->alg) {
case ALG_CCMP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
- memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
+ tx->sec_ctl = TX_CMD_SEC_CCM;
+ memcpy(tx->key, keyinfo->key, keyinfo->keylen);
IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
break;
case ALG_TKIP:
#if 0
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP;
+ tx->sec_ctl = TX_CMD_SEC_TKIP;
if (last_frag)
- memcpy(cmd->cmd.tx.tkip_mic.byte, skb_frag->tail - 8,
+ memcpy(tx->tkip_mic.byte, skb_frag->tail - 8,
8);
else
- memset(cmd->cmd.tx.tkip_mic.byte, 0, 8);
+ memset(tx->tkip_mic.byte, 0, 8);
#endif
break;
case ALG_WEP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
+ tx->sec_ctl = TX_CMD_SEC_WEP |
(info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
if (keyinfo->keylen == 13)
- cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
+ tx->sec_ctl |= TX_CMD_SEC_KEY128;
- memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
+ memcpy(&tx->key[3], keyinfo->key, keyinfo->keylen);
IWL_DEBUG_TX("Configuring packet for WEP encryption "
"with key %d\n", info->control.hw_key->hw_key_idx);
break;
default:
- printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg);
+ IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg);
break;
}
}
@@ -2327,17 +1279,17 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
/*
* handle build REPLY_TX command notification.
*/
-static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
+ struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
- struct ieee80211_hdr *hdr,
- int is_unicast, u8 std_id)
+ struct ieee80211_hdr *hdr, u8 std_id)
{
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
+ __le32 tx_flags = tx->tx_flags;
__le16 fc = hdr->frame_control;
- __le32 tx_flags = cmd->cmd.tx.tx_flags;
u8 rc_flags = info->control.rates[0].flags;
- cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+ tx->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
tx_flags |= TX_CMD_FLG_ACK_MSK;
if (ieee80211_is_mgmt(fc))
@@ -2350,13 +1302,13 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
}
- cmd->cmd.tx.sta_id = std_id;
+ tx->sta_id = std_id;
if (ieee80211_has_morefrags(fc))
tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
if (ieee80211_is_data_qos(fc)) {
u8 *qc = ieee80211_get_qos_ctl(hdr);
- cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
+ tx->tid_tspec = qc[0] & 0xf;
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
} else {
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
@@ -2376,25 +1328,25 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
if (ieee80211_is_mgmt(fc)) {
if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
- cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
+ tx->timeout.pm_frame_timeout = cpu_to_le16(3);
else
- cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
+ tx->timeout.pm_frame_timeout = cpu_to_le16(2);
} else {
- cmd->cmd.tx.timeout.pm_frame_timeout = 0;
+ tx->timeout.pm_frame_timeout = 0;
#ifdef CONFIG_IWL3945_LEDS
priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
#endif
}
- cmd->cmd.tx.driver_txop = 0;
- cmd->cmd.tx.tx_flags = tx_flags;
- cmd->cmd.tx.next_frame_len = 0;
+ tx->driver_txop = 0;
+ tx->tx_flags = tx_flags;
+ tx->next_frame_len = 0;
}
/**
* iwl3945_get_sta_id - Find station's index within station table
*/
-static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr)
+static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
{
int sta_id;
u16 fc = le16_to_cpu(hdr->frame_control);
@@ -2402,7 +1354,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
/* If this frame is broadcast or management, use broadcast station id */
if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
is_multicast_ether_addr(hdr->addr1))
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
switch (priv->iw_mode) {
@@ -2416,7 +1368,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
if (sta_id != IWL_INVALID_STATION)
return sta_id;
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
/* If this frame is going out to an IBSS network, find the station,
* or create a new station table entry */
@@ -2434,35 +1386,35 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
IWL_DEBUG_DROP("Station %pM not in station map. "
"Defaulting to broadcast...\n",
hdr->addr1);
- iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
- return priv->hw_setting.bcast_sta_id;
+ iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
+ return priv->hw_params.bcast_sta_id;
}
/* If we are in monitor mode, use BCAST. This is required for
* packet injection. */
case NL80211_IFTYPE_MONITOR:
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
default:
- IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
- return priv->hw_setting.bcast_sta_id;
+ IWL_WARN(priv, "Unknown mode of operation: %d\n",
+ priv->iw_mode);
+ return priv->hw_params.bcast_sta_id;
}
}
/*
* start REPLY_TX command process
*/
-static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
+static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl3945_tfd_frame *tfd;
- u32 *control_flags;
- int txq_id = skb_get_queue_mapping(skb);
- struct iwl3945_tx_queue *txq = NULL;
- struct iwl3945_queue *q = NULL;
+ struct iwl3945_tx_cmd *tx;
+ struct iwl_tx_queue *txq = NULL;
+ struct iwl_queue *q = NULL;
+ struct iwl_cmd *out_cmd = NULL;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
- struct iwl3945_cmd *out_cmd = NULL;
+ int txq_id = skb_get_queue_mapping(skb);
u16 len, idx, len_org, hdr_len;
u8 id;
u8 unicast;
@@ -2476,13 +1428,13 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
int rc;
spin_lock_irqsave(&priv->lock, flags);
- if (iwl3945_is_rfkill(priv)) {
+ if (iwl_is_rfkill(priv)) {
IWL_DEBUG_DROP("Dropping - RF KILL\n");
goto drop_unlock;
}
if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) {
- IWL_ERROR("ERROR: No TX rate available.\n");
+ IWL_ERR(priv, "ERROR: No TX rate available.\n");
goto drop_unlock;
}
@@ -2491,7 +1443,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
fc = hdr->frame_control;
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
if (ieee80211_is_auth(fc))
IWL_DEBUG_TX("Sending AUTH frame\n");
else if (ieee80211_is_assoc_req(fc))
@@ -2526,7 +1478,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
- seq_number = priv->stations[sta_id].tid[tid].seq_number &
+ seq_number = priv->stations_39[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = cpu_to_le16(seq_number) |
(hdr->seq_ctrl &
@@ -2540,20 +1492,17 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
- /* Set up first empty TFD within this queue's circular TFD buffer */
- tfd = &txq->bd[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
- control_flags = (u32 *) tfd;
idx = get_cmd_index(q, q->write_ptr, 0);
/* Set up driver data for this TFD */
- memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info));
+ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb[0] = skb;
/* Init first empty entry in queue's array of Tx/cmd buffers */
- out_cmd = &txq->cmd[idx];
+ out_cmd = txq->cmd[idx];
+ tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
- memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
+ memset(tx, 0, sizeof(*tx));
/*
* Set up the Tx-command (not MAC!) header.
@@ -2566,7 +1515,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
INDEX_TO_SEQ(q->write_ptr)));
/* Copy MAC header from skb into command buffer */
- memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len);
+ memcpy(tx->hdr, hdr, hdr_len);
/*
* Use the first empty entry in this queue's command buffer array
@@ -2577,8 +1526,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
* of the MAC header (device reads on dword boundaries).
* We'll tell device about this padding later.
*/
- len = priv->hw_setting.tx_cmd_len +
- sizeof(struct iwl3945_cmd_header) + hdr_len;
+ len = sizeof(struct iwl3945_tx_cmd) +
+ sizeof(struct iwl_cmd_header) + hdr_len;
len_org = len;
len = (len + 3) & ~3;
@@ -2590,12 +1539,19 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
- txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx +
- offsetof(struct iwl3945_cmd, hdr);
+ txcmd_phys = pci_map_single(priv->pci_dev,
+ out_cmd, sizeof(struct iwl_cmd),
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
+ pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
+ /* Add buffer containing Tx command and MAC(!) header to TFD's
+ * first entry */
+ txcmd_phys += offsetof(struct iwl_cmd, hdr);
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ txcmd_phys, len, 1, 0);
if (info->control.hw_key)
iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
@@ -2606,60 +1562,52 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
if (len) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
len, PCI_DMA_TODEVICE);
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, len,
+ 0, U32_PAD(len));
}
- if (!len)
- /* If there is no payload, then we use only one Tx buffer */
- *control_flags = TFD_CTL_COUNT_SET(1);
- else
- /* Else use 2 buffers.
- * Tell 3945 about any padding after MAC header */
- *control_flags = TFD_CTL_COUNT_SET(2) |
- TFD_CTL_PAD_SET(U32_PAD(len));
-
/* Total # bytes to be transmitted */
len = (u16)skb->len;
- out_cmd->cmd.tx.len = cpu_to_le16(len);
+ tx->len = cpu_to_le16(len);
/* TODO need this for burst mode later on */
- iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, unicast, sta_id);
+ iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
/* set is_hcca to 0; it probably will never be implemented */
iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
- out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
- out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
+ tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
+ tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
if (qc)
- priv->stations[sta_id].tid[tid].seq_number = seq_number;
+ priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
} else {
wait_write_ptr = 1;
txq->need_update = 0;
}
- iwl3945_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
- sizeof(out_cmd->cmd.tx));
+ iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
- iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
+ iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
ieee80211_hdrlen(fc));
/* Tell device the write index *just past* this latest filled TFD */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- rc = iwl3945_tx_queue_update_write_ptr(priv, txq);
+ rc = iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
if (rc)
return rc;
- if ((iwl3945_queue_space(q) < q->high_mark)
+ if ((iwl_queue_space(q) < q->high_mark)
&& priv->mac80211_registered) {
if (wait_write_ptr) {
spin_lock_irqsave(&priv->lock, flags);
txq->need_update = 1;
- iwl3945_tx_queue_update_write_ptr(priv, txq);
+ iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -2674,15 +1622,15 @@ drop:
return -1;
}
-static void iwl3945_set_rate(struct iwl3945_priv *priv)
+static void iwl3945_set_rate(struct iwl_priv *priv)
{
const struct ieee80211_supported_band *sband = NULL;
struct ieee80211_rate *rate;
int i;
- sband = iwl3945_get_band(priv, priv->band);
+ sband = iwl_get_hw_mode(priv, priv->band);
if (!sband) {
- IWL_ERROR("Failed to set rate: unable to get hw mode\n");
+ IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n");
return;
}
@@ -2711,24 +1659,24 @@ static void iwl3945_set_rate(struct iwl3945_priv *priv)
* OFDM
*/
if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
- priv->staging_rxon.cck_basic_rates =
+ priv->staging39_rxon.cck_basic_rates =
((priv->active_rate_basic &
IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
else
- priv->staging_rxon.cck_basic_rates =
+ priv->staging39_rxon.cck_basic_rates =
(IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
- priv->staging_rxon.ofdm_basic_rates =
+ priv->staging39_rxon.ofdm_basic_rates =
((priv->active_rate_basic &
(IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
IWL_FIRST_OFDM_RATE) & 0xFF;
else
- priv->staging_rxon.ofdm_basic_rates =
+ priv->staging39_rxon.ofdm_basic_rates =
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
}
-static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
+static void iwl3945_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
{
unsigned long flags;
@@ -2739,21 +1687,21 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
disable_radio ? "OFF" : "ON");
if (disable_radio) {
- iwl3945_scan_cancel(priv);
+ iwl_scan_cancel(priv);
/* FIXME: This is a workaround for AP */
if (priv->iw_mode != NL80211_IFTYPE_AP) {
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_SW_BIT_RFKILL);
spin_unlock_irqrestore(&priv->lock, flags);
- iwl3945_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
+ iwl_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
set_bit(STATUS_RF_KILL_SW, &priv->status);
}
return;
}
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
clear_bit(STATUS_RF_KILL_SW, &priv->status);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -2762,9 +1710,9 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
msleep(10);
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
- if (!iwl3945_grab_nic_access(priv))
- iwl3945_release_nic_access(priv);
+ iwl_read32(priv, CSR_UCODE_DRV_GP1);
+ if (!iwl_grab_nic_access(priv))
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
@@ -2778,13 +1726,13 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
return;
}
-void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
+void iwl3945_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
u32 decrypt_res, struct ieee80211_rx_status *stats)
{
u16 fc =
le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control);
- if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
+ if (priv->active39_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
return;
if (!(fc & IEEE80211_FCTL_PROTECTED))
@@ -2863,13 +1811,13 @@ static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
return cpu_to_le32(res);
}
-static int iwl3945_get_measurement(struct iwl3945_priv *priv,
+static int iwl3945_get_measurement(struct iwl_priv *priv,
struct ieee80211_measurement_params *params,
u8 type)
{
- struct iwl3945_spectrum_cmd spectrum;
- struct iwl3945_rx_packet *res;
- struct iwl3945_host_cmd cmd = {
+ struct iwl_spectrum_cmd spectrum;
+ struct iwl_rx_packet *res;
+ struct iwl_host_cmd cmd = {
.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
.data = (void *)&spectrum,
.meta.flags = CMD_WANT_SKB,
@@ -2905,17 +1853,17 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
spectrum.channels[0].channel = params->channel;
spectrum.channels[0].type = type;
- if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ if (priv->active39_rxon.flags & RXON_FLG_BAND_24G_MSK)
spectrum.flags |= RXON_FLG_BAND_24G_MSK |
RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
return rc;
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
rc = -EIO;
}
@@ -2942,11 +1890,11 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
}
#endif
-static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_alive_resp *palive;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_alive_resp *palive;
struct delayed_work *pwork;
palive = &pkt->u.alive_frame;
@@ -2958,14 +1906,13 @@ static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
IWL_DEBUG_INFO("Initialization Alive received.\n");
- memcpy(&priv->card_alive_init,
- &pkt->u.alive_frame,
- sizeof(struct iwl3945_init_alive_resp));
+ memcpy(&priv->card_alive_init, &pkt->u.alive_frame,
+ sizeof(struct iwl_alive_resp));
pwork = &priv->init_alive_start;
} else {
IWL_DEBUG_INFO("Runtime Alive received.\n");
memcpy(&priv->card_alive, &pkt->u.alive_frame,
- sizeof(struct iwl3945_alive_resp));
+ sizeof(struct iwl_alive_resp));
pwork = &priv->alive_start;
iwl3945_disable_events(priv);
}
@@ -2976,24 +1923,26 @@ static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
queue_delayed_work(priv->workqueue, pwork,
msecs_to_jiffies(5));
else
- IWL_WARNING("uCode did not respond OK.\n");
+ IWL_WARN(priv, "uCode did not respond OK.\n");
}
-static void iwl3945_rx_reply_add_sta(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+#endif
IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
return;
}
-static void iwl3945_rx_reply_error(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_error(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
- IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
+ IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
"seq 0x%04X ser 0x%08X\n",
le32_to_cpu(pkt->u.err_resp.error_type),
get_cmd_string(pkt->u.err_resp.cmd_id),
@@ -3004,23 +1953,23 @@ static void iwl3945_rx_reply_error(struct iwl3945_priv *priv,
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-static void iwl3945_rx_csa(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_rxon_cmd *rxon = (void *)&priv->active_rxon;
- struct iwl3945_csa_notification *csa = &(pkt->u.csa_notif);
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl3945_rxon_cmd *rxon = (void *)&priv->active39_rxon;
+ struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
rxon->channel = csa->channel;
- priv->staging_rxon.channel = csa->channel;
+ priv->staging39_rxon.channel = csa->channel;
}
-static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_spectrum_measure_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_spectrum_notification *report = &(pkt->u.spectrum_notif);
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
if (!report->state) {
IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO,
@@ -3033,38 +1982,39 @@ static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv,
#endif
}
-static void iwl3945_rx_pm_sleep_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_pm_sleep_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_sleep_notification *sleep = &(pkt->u.sleep_notif);
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
sleep->pm_sleep_mode, sleep->pm_wakeup_src);
#endif
}
-static void iwl3945_rx_pm_debug_statistics_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
"notification for %s:\n",
le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
- iwl3945_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+ iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw,
+ le32_to_cpu(pkt->len));
}
static void iwl3945_bg_beacon_update(struct work_struct *work)
{
- struct iwl3945_priv *priv =
- container_of(work, struct iwl3945_priv, beacon_update);
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, beacon_update);
struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
beacon = ieee80211_beacon_get(priv->hw, priv->vif);
if (!beacon) {
- IWL_ERROR("update beacon failed\n");
+ IWL_ERR(priv, "update beacon failed\n");
return;
}
@@ -3079,11 +2029,11 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
iwl3945_send_beacon_cmd(priv);
}
-static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
u8 rate = beacon->beacon_notify_hdr.rate;
@@ -3102,25 +2052,25 @@ static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
}
/* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl3945_rx_reply_scan(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_scan(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanreq_notification *notif =
- (struct iwl3945_scanreq_notification *)pkt->u.raw;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_scanreq_notification *notif =
+ (struct iwl_scanreq_notification *)pkt->u.raw;
IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
#endif
}
/* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_scan_start_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanstart_notification *notif =
- (struct iwl3945_scanstart_notification *)pkt->u.raw;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_scanstart_notification *notif =
+ (struct iwl_scanstart_notification *)pkt->u.raw;
priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
IWL_DEBUG_SCAN("Scan start: "
"%d [802.11%s] "
@@ -3132,12 +2082,14 @@ static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv,
}
/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_scan_results_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanresults_notification *notif =
- (struct iwl3945_scanresults_notification *)pkt->u.raw;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_scanresults_notification *notif =
+ (struct iwl_scanresults_notification *)pkt->u.raw;
+#endif
IWL_DEBUG_SCAN("Scan ch.res: "
"%d [802.11%s] "
@@ -3157,11 +2109,13 @@ static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv,
}
/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_scan_complete_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
+#endif
IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
scan_notif->scanned_channels,
@@ -3220,10 +2174,10 @@ reschedule:
/* Handle notification from uCode that card's power state is changing
* due to software, hardware, or critical temperature RFKILL */
-static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
unsigned long status = priv->status;
@@ -3231,7 +2185,7 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
(flags & HW_CARD_DISABLED) ? "Kill" : "On",
(flags & SW_CARD_DISABLED) ? "Kill" : "On");
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
if (flags & HW_CARD_DISABLED)
@@ -3245,7 +2199,7 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
else
clear_bit(STATUS_RF_KILL_SW, &priv->status);
- iwl3945_scan_cancel(priv);
+ iwl_scan_cancel(priv);
if ((test_bit(STATUS_RF_KILL_HW, &status) !=
test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
@@ -3265,7 +2219,7 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
* This function chains into the hardware specific files for them to setup
* any hardware specific handlers as well.
*/
-static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
+static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
{
priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive;
priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
@@ -3303,15 +2257,15 @@ static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
* When FW advances 'R' index, all entries between old and new 'R' index
* need to be reclaimed.
*/
-static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
+static void iwl3945_cmd_queue_reclaim(struct iwl_priv *priv,
int txq_id, int index)
{
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
- struct iwl3945_queue *q = &txq->q;
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
int nfreed = 0;
- if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
+ IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
"is out of range [0-%d] %d %d.\n", txq_id,
index, q->n_bd, q->write_ptr, q->read_ptr);
return;
@@ -3320,7 +2274,7 @@ static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
if (nfreed > 1) {
- IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
+ IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", index,
q->write_ptr, q->read_ptr);
queue_work(priv->workqueue, &priv->restart);
break;
@@ -3338,21 +2292,28 @@ static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
* will be executed. The attached skb (if present) will only be freed
* if the callback returns 1
*/
-static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_tx_cmd_complete(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int index = SEQ_TO_INDEX(sequence);
- int huge = sequence & SEQ_HUGE_FRAME;
+ int huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
int cmd_index;
- struct iwl3945_cmd *cmd;
-
- BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
+ struct iwl_cmd *cmd;
+
+ if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
+ "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n",
+ txq_id, sequence,
+ priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
+ priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
+ iwl_print_hex_dump(priv, IWL_DL_INFO , rxb, 32);
+ return;
+ }
cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
- cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
+ cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
/* Input error checking is done when commands are added to queue. */
if (cmd->meta.flags & CMD_WANT_SKB) {
@@ -3417,7 +2378,6 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
*
* Driver sequence:
*
- * iwl3945_rx_queue_alloc() Allocates rx_free
* iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls
* iwl3945_rx_queue_restock
* iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx
@@ -3426,7 +2386,7 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
* are available, schedules iwl3945_rx_replenish
*
* -- enable interrupts --
- * ISR - iwl3945_rx() Detach iwl3945_rx_mem_buffers from pool up to the
+ * ISR - iwl3945_rx() Detach iwl_rx_mem_buffers from pool up to the
* READ INDEX, detaching the SKB from the pool.
* Moves the packet buffer from queue to rx_used.
* Calls iwl3945_rx_queue_restock to refill any empty
@@ -3436,70 +2396,9 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
*/
/**
- * iwl3945_rx_queue_space - Return number of free slots available in queue.
- */
-static int iwl3945_rx_queue_space(const struct iwl3945_rx_queue *q)
-{
- int s = q->read - q->write;
- if (s <= 0)
- s += RX_QUEUE_SIZE;
- /* keep some buffer to not confuse full and empty queue */
- s -= 2;
- if (s < 0)
- s = 0;
- return s;
-}
-
-/**
- * iwl3945_rx_queue_update_write_ptr - Update the write pointer for the RX queue
- */
-int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_rx_queue *q)
-{
- u32 reg = 0;
- int rc = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
-
- if (q->need_update == 0)
- goto exit_unlock;
-
- /* If power-saving is in use, make sure device is awake */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- goto exit_unlock;
- }
-
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- goto exit_unlock;
-
- /* Device expects a multiple of 8 */
- iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
- q->write & ~0x7);
- iwl3945_release_nic_access(priv);
-
- /* Else device is assumed to be awake */
- } else
- /* Device expects a multiple of 8 */
- iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
-
-
- q->need_update = 0;
-
- exit_unlock:
- spin_unlock_irqrestore(&q->lock, flags);
- return rc;
-}
-
-/**
* iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
*/
-static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
+static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv,
dma_addr_t dma_addr)
{
return cpu_to_le32((u32)dma_addr);
@@ -3516,24 +2415,24 @@ static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
* also updates the memory address in the firmware to reference the new
* target buffer.
*/
-static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
+static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
- struct iwl3945_rx_mem_buffer *rxb;
+ struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
int write, rc;
spin_lock_irqsave(&rxq->lock, flags);
write = rxq->write & ~0x7;
- while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+ while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
/* Get next free Rx buffer, remove from free list */
element = rxq->rx_free.next;
- rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
list_del(element);
/* Point to Rx buffer via next RBD in circular buffer */
- rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr);
+ rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr);
rxq->queue[rxq->write] = rxb;
rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
rxq->free_count--;
@@ -3552,7 +2451,7 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
spin_lock_irqsave(&rxq->lock, flags);
rxq->need_update = 1;
spin_unlock_irqrestore(&rxq->lock, flags);
- rc = iwl3945_rx_queue_update_write_ptr(priv, rxq);
+ rc = iwl_rx_queue_update_write_ptr(priv, rxq);
if (rc)
return rc;
}
@@ -3568,24 +2467,24 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
* Also restock the Rx queue via iwl3945_rx_queue_restock.
* This is called as a scheduled work item (except for during initialization)
*/
-static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
+static void iwl3945_rx_allocate(struct iwl_priv *priv)
{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
- struct iwl3945_rx_mem_buffer *rxb;
+ struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
spin_lock_irqsave(&rxq->lock, flags);
while (!list_empty(&rxq->rx_used)) {
element = rxq->rx_used.next;
- rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
/* Alloc a new receive buffer */
rxb->skb =
- alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC);
+ alloc_skb(priv->hw_params.rx_buf_size,
+ __GFP_NOWARN | GFP_ATOMIC);
if (!rxb->skb) {
if (net_ratelimit())
- printk(KERN_CRIT DRV_NAME
- ": Can not allocate SKB buffers\n");
+ IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
* call the restock method and if it still needs
* more buffers it will schedule replenish */
@@ -3604,9 +2503,10 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
list_del(element);
/* Get physical address of RB/SKB */
- rxb->dma_addr =
- pci_map_single(priv->pci_dev, rxb->skb->data,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ rxb->real_dma_addr = pci_map_single(priv->pci_dev,
+ rxb->skb->data,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
}
@@ -3618,7 +2518,7 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
*/
static void __iwl3945_rx_replenish(void *data)
{
- struct iwl3945_priv *priv = data;
+ struct iwl_priv *priv = data;
iwl3945_rx_allocate(priv);
iwl3945_rx_queue_restock(priv);
@@ -3627,7 +2527,7 @@ static void __iwl3945_rx_replenish(void *data)
void iwl3945_rx_replenish(void *data)
{
- struct iwl3945_priv *priv = data;
+ struct iwl_priv *priv = data;
unsigned long flags;
iwl3945_rx_allocate(priv);
@@ -3637,84 +2537,6 @@ void iwl3945_rx_replenish(void *data)
spin_unlock_irqrestore(&priv->lock, flags);
}
-/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
- * If an SKB has been detached, the POOL needs to have its SKB set to NULL
- * This free routine walks the list of POOL entries and if SKB is set to
- * non NULL it is unmapped and freed
- */
-static void iwl3945_rx_queue_free(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
-{
- int i;
- for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
- if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev,
- rxq->pool[i].dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- dev_kfree_skb(rxq->pool[i].skb);
- }
- }
-
- pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
- rxq->dma_addr);
- rxq->bd = NULL;
-}
-
-int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv)
-{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
- struct pci_dev *dev = priv->pci_dev;
- int i;
-
- spin_lock_init(&rxq->lock);
- INIT_LIST_HEAD(&rxq->rx_free);
- INIT_LIST_HEAD(&rxq->rx_used);
-
- /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
- rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
- if (!rxq->bd)
- return -ENOMEM;
-
- /* Fill the rx_used queue with _all_ of the Rx buffers */
- for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
- list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
-
- /* Set us so that we have processed and used all buffers, but have
- * not restocked the Rx queue with fresh buffers */
- rxq->read = rxq->write = 0;
- rxq->free_count = 0;
- rxq->need_update = 0;
- return 0;
-}
-
-void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
-{
- unsigned long flags;
- int i;
- spin_lock_irqsave(&rxq->lock, flags);
- INIT_LIST_HEAD(&rxq->rx_free);
- INIT_LIST_HEAD(&rxq->rx_used);
- /* Fill the rx_used queue with _all_ of the Rx buffers */
- for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
- /* In the reset function, these buffers may have been allocated
- * to an SKB, so we need to unmap and free potential storage */
- if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev,
- rxq->pool[i].dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- priv->alloc_rxb_skb--;
- dev_kfree_skb(rxq->pool[i].skb);
- rxq->pool[i].skb = NULL;
- }
- list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
- }
-
- /* Set us so that we have processed and used all buffers, but have
- * not restocked the Rx queue with fresh buffers */
- rxq->read = rxq->write = 0;
- rxq->free_count = 0;
- spin_unlock_irqrestore(&rxq->lock, flags);
-}
-
/* Convert linear signal-to-noise ratio into dB */
static u8 ratio2dB[100] = {
/* 0 1 2 3 4 5 6 7 8 9 */
@@ -3800,11 +2622,11 @@ int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm)
* the appropriate handlers, including command responses,
* frame-received notifications, and other notifications.
*/
-static void iwl3945_rx_handle(struct iwl3945_priv *priv)
+static void iwl3945_rx_handle(struct iwl_priv *priv)
{
- struct iwl3945_rx_mem_buffer *rxb;
- struct iwl3945_rx_packet *pkt;
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_mem_buffer *rxb;
+ struct iwl_rx_packet *pkt;
+ struct iwl_rx_queue *rxq = &priv->rxq;
u32 r, i;
int reclaim;
unsigned long flags;
@@ -3813,10 +2635,10 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
- r = iwl3945_hw_get_rx_read(priv);
+ r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
i = rxq->read;
- if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+ if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
/* Rx interrupt, but nothing sent from uCode */
if (i == r)
@@ -3832,10 +2654,10 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
rxq->queue[i] = NULL;
- pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
- IWL_RX_BUF_SIZE,
+ pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->real_dma_addr,
+ priv->hw_params.rx_buf_size,
PCI_DMA_FROMDEVICE);
- pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
+ pkt = (struct iwl_rx_packet *)rxb->skb->data;
/* Reclaim a command buffer only if this packet is a response
* to a (driver-originated) command.
@@ -3851,13 +2673,13 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
* handle those that need handling via function in
* rx_handlers table. See iwl3945_setup_rx_handlers() */
if (priv->rx_handlers[pkt->hdr.cmd]) {
- IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+ IWL_DEBUG(IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
"r = %d, i = %d, %s, 0x%02x\n", r, i,
get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
} else {
/* No handling needed */
- IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+ IWL_DEBUG(IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
"r %d i %d No handler needed for %s, 0x%02x\n",
r, i, get_cmd_string(pkt->hdr.cmd),
pkt->hdr.cmd);
@@ -3865,12 +2687,12 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
if (reclaim) {
/* Invoke any callbacks, transfer the skb to caller, and
- * fire off the (possibly) blocking iwl3945_send_cmd()
+ * fire off the (possibly) blocking iwl_send_cmd()
* as we reclaim the driver command queue */
if (rxb && rxb->skb)
iwl3945_tx_cmd_complete(priv, rxb);
else
- IWL_WARNING("Claim null rxb?\n");
+ IWL_WARN(priv, "Claim null rxb?\n");
}
/* For now we just don't re-use anything. We can tweak this
@@ -3882,8 +2704,9 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
rxb->skb = NULL;
}
- pci_unmap_single(priv->pci_dev, rxb->dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
spin_lock_irqsave(&rxq->lock, flags);
list_add_tail(&rxb->list, &priv->rxq.rx_used);
spin_unlock_irqrestore(&rxq->lock, flags);
@@ -3905,57 +2728,12 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
iwl3945_rx_queue_restock(priv);
}
-/**
- * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware
- */
-static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq)
-{
- u32 reg = 0;
- int rc = 0;
- int txq_id = txq->q.id;
-
- if (txq->need_update == 0)
- return rc;
-
- /* if we're trying to save power */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- /* wake up nic if it's powered down ...
- * uCode will wake up, and interrupt us again, so next
- * time we'll skip this part. */
- reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- return rc;
- }
-
- /* restore this queue's parameters in nic hardware. */
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- return rc;
- iwl3945_write_direct32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
- iwl3945_release_nic_access(priv);
-
- /* else not in power-save mode, uCode will never sleep when we're
- * trying to tx (during RFKILL, we're not trying to tx). */
- } else
- iwl3945_write32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
-
- txq->need_update = 0;
-
- return rc;
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
+#ifdef CONFIG_IWLWIFI_DEBUG
+static void iwl3945_print_rx_config_cmd(struct iwl_priv *priv,
+ struct iwl3945_rxon_cmd *rxon)
{
IWL_DEBUG_RADIO("RX CONFIG:\n");
- iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
+ iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
@@ -3970,16 +2748,16 @@ static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
}
#endif
-static void iwl3945_enable_interrupts(struct iwl3945_priv *priv)
+static void iwl3945_enable_interrupts(struct iwl_priv *priv)
{
IWL_DEBUG_ISR("Enabling interrupts\n");
set_bit(STATUS_INT_ENABLED, &priv->status);
- iwl3945_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
+ iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
}
/* call this function to flush any scheduled tasklet */
-static inline void iwl_synchronize_irq(struct iwl3945_priv *priv)
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
{
/* wait to make sure we flush pending tasklet*/
synchronize_irq(priv->pci_dev->irq);
@@ -3987,17 +2765,17 @@ static inline void iwl_synchronize_irq(struct iwl3945_priv *priv)
}
-static inline void iwl3945_disable_interrupts(struct iwl3945_priv *priv)
+static inline void iwl3945_disable_interrupts(struct iwl_priv *priv)
{
clear_bit(STATUS_INT_ENABLED, &priv->status);
/* disable interrupts from uCode/NIC to host */
- iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
+ iwl_write32(priv, CSR_INT_MASK, 0x00000000);
/* acknowledge/clear/reset any interrupts still pending
* from uCode or flow handler (Rx/Tx DMA) */
- iwl3945_write32(priv, CSR_INT, 0xffffffff);
- iwl3945_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
+ iwl_write32(priv, CSR_INT, 0xffffffff);
+ iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
IWL_DEBUG_ISR("Disabled interrupts\n");
}
@@ -4024,7 +2802,7 @@ static const char *desc_lookup(int i)
#define ERROR_START_OFFSET (1 * sizeof(u32))
#define ERROR_ELEM_SIZE (7 * sizeof(u32))
-static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
+static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
{
u32 i;
u32 desc, time, count, base, data1;
@@ -4034,49 +2812,50 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
return;
}
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
- count = iwl3945_read_targ_mem(priv, base);
+ count = iwl_read_targ_mem(priv, base);
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
- IWL_ERROR("Start IWL Error Log Dump:\n");
- IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+ IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+ IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+ priv->status, count);
}
- IWL_ERROR("Desc Time asrtPC blink2 "
+ IWL_ERR(priv, "Desc Time asrtPC blink2 "
"ilink1 nmiPC Line\n");
for (i = ERROR_START_OFFSET;
i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET;
i += ERROR_ELEM_SIZE) {
- desc = iwl3945_read_targ_mem(priv, base + i);
+ desc = iwl_read_targ_mem(priv, base + i);
time =
- iwl3945_read_targ_mem(priv, base + i + 1 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 1 * sizeof(u32));
blink1 =
- iwl3945_read_targ_mem(priv, base + i + 2 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 2 * sizeof(u32));
blink2 =
- iwl3945_read_targ_mem(priv, base + i + 3 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 3 * sizeof(u32));
ilink1 =
- iwl3945_read_targ_mem(priv, base + i + 4 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 4 * sizeof(u32));
ilink2 =
- iwl3945_read_targ_mem(priv, base + i + 5 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 5 * sizeof(u32));
data1 =
- iwl3945_read_targ_mem(priv, base + i + 6 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32));
- IWL_ERROR
- ("%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
- desc_lookup(desc), desc, time, blink1, blink2,
- ilink1, ilink2, data1);
+ IWL_ERR(priv,
+ "%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
+ desc_lookup(desc), desc, time, blink1, blink2,
+ ilink1, ilink2, data1);
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
@@ -4085,9 +2864,9 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
/**
* iwl3945_print_event_log - Dump error event log to syslog
*
- * NOTE: Must be called with iwl3945_grab_nic_access() already obtained!
+ * NOTE: Must be called with iwl_grab_nic_access() already obtained!
*/
-static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
+static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 num_events, u32 mode)
{
u32 i;
@@ -4111,21 +2890,22 @@ static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
/* "time" is actually "data" for mode 0 (no timestamp).
* place event id # at far right for easier visual parsing. */
for (i = 0; i < num_events; i++) {
- ev = iwl3945_read_targ_mem(priv, ptr);
+ ev = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- time = iwl3945_read_targ_mem(priv, ptr);
+ time = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- if (mode == 0)
- IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
- else {
- data = iwl3945_read_targ_mem(priv, ptr);
+ if (mode == 0) {
+ /* data, ev */
+ IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
+ } else {
+ data = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
+ IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
}
}
}
-static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
+static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
{
int rc;
u32 base; /* SRAM byte address of event log header */
@@ -4137,32 +2917,32 @@ static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
/* event log header */
- capacity = iwl3945_read_targ_mem(priv, base);
- mode = iwl3945_read_targ_mem(priv, base + (1 * sizeof(u32)));
- num_wraps = iwl3945_read_targ_mem(priv, base + (2 * sizeof(u32)));
- next_entry = iwl3945_read_targ_mem(priv, base + (3 * sizeof(u32)));
+ capacity = iwl_read_targ_mem(priv, base);
+ mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
+ num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
+ next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
size = num_wraps ? capacity : next_entry;
/* bail out if nothing in log */
if (size == 0) {
- IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
- iwl3945_release_nic_access(priv);
+ IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
+ iwl_release_nic_access(priv);
return;
}
- IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+ IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
size, num_wraps);
/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -4174,13 +2954,13 @@ static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
/* (then/else) start at top of log */
iwl3945_print_event_log(priv, 0, next_entry, mode);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
/**
* iwl3945_irq_handle_error - called for HW or SW error interrupt from card
*/
-static void iwl3945_irq_handle_error(struct iwl3945_priv *priv)
+static void iwl3945_irq_handle_error(struct iwl_priv *priv)
{
/* Set the FW error flag -- cleared on iwl3945_down */
set_bit(STATUS_FW_ERROR, &priv->status);
@@ -4188,11 +2968,11 @@ static void iwl3945_irq_handle_error(struct iwl3945_priv *priv)
/* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & IWL_DL_FW_ERRORS) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & IWL_DL_FW_ERRORS) {
iwl3945_dump_nic_error_log(priv);
iwl3945_dump_nic_event_log(priv);
- iwl3945_print_rx_config_cmd(&priv->staging_rxon);
+ iwl3945_print_rx_config_cmd(priv, &priv->staging39_rxon);
}
#endif
@@ -4207,37 +2987,38 @@ static void iwl3945_irq_handle_error(struct iwl3945_priv *priv)
"Restarting adapter due to uCode error.\n");
if (iwl3945_is_associated(priv)) {
- memcpy(&priv->recovery_rxon, &priv->active_rxon,
- sizeof(priv->recovery_rxon));
+ memcpy(&priv->recovery39_rxon, &priv->active39_rxon,
+ sizeof(priv->recovery39_rxon));
priv->error_recovering = 1;
}
- queue_work(priv->workqueue, &priv->restart);
+ if (priv->cfg->mod_params->restart_fw)
+ queue_work(priv->workqueue, &priv->restart);
}
}
-static void iwl3945_error_recovery(struct iwl3945_priv *priv)
+static void iwl3945_error_recovery(struct iwl_priv *priv)
{
unsigned long flags;
- memcpy(&priv->staging_rxon, &priv->recovery_rxon,
- sizeof(priv->staging_rxon));
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ memcpy(&priv->staging39_rxon, &priv->recovery39_rxon,
+ sizeof(priv->staging39_rxon));
+ priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
iwl3945_add_station(priv, priv->bssid, 1, 0);
spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
+ priv->assoc_id = le16_to_cpu(priv->staging39_rxon.assoc_id);
priv->error_recovering = 0;
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
+static void iwl3945_irq_tasklet(struct iwl_priv *priv)
{
u32 inta, handled = 0;
u32 inta_fh;
unsigned long flags;
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
u32 inta_mask;
#endif
@@ -4246,19 +3027,19 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Ack/clear/reset pending uCode interrupts.
* Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
* and will clear only when CSR_FH_INT_STATUS gets cleared. */
- inta = iwl3945_read32(priv, CSR_INT);
- iwl3945_write32(priv, CSR_INT, inta);
+ inta = iwl_read32(priv, CSR_INT);
+ iwl_write32(priv, CSR_INT, inta);
/* Ack/clear/reset pending flow-handler (DMA) interrupts.
* Any new interrupts that happen after this, either while we're
* in this tasklet, or later, will show up in next ISR/tasklet. */
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
- iwl3945_write32(priv, CSR_FH_INT_STATUS, inta_fh);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+ iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & IWL_DL_ISR) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & IWL_DL_ISR) {
/* just for debug */
- inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
+ inta_mask = iwl_read32(priv, CSR_INT_MASK);
IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
}
@@ -4275,7 +3056,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Now service all interrupt bits discovered above. */
if (inta & CSR_INT_BIT_HW_ERR) {
- IWL_ERROR("Microcode HW error detected. Restarting.\n");
+ IWL_ERR(priv, "Microcode HW error detected. Restarting.\n");
/* Tell the device to stop sending interrupts */
iwl3945_disable_interrupts(priv);
@@ -4289,8 +3070,8 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
return;
}
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_ISR)) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
if (inta & CSR_INT_BIT_SCD)
IWL_DEBUG_ISR("Scheduler finished to transmit "
@@ -4306,8 +3087,8 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Error detected by uCode */
if (inta & CSR_INT_BIT_SW_ERR) {
- IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n",
- inta);
+ IWL_ERR(priv, "Microcode SW error detected. "
+ "Restarting 0x%X.\n", inta);
iwl3945_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -4315,13 +3096,13 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* uCode wakes up after power-down sleep */
if (inta & CSR_INT_BIT_WAKEUP) {
IWL_DEBUG_ISR("Wakeup interrupt\n");
- iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[0]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[1]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[2]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[3]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[4]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[5]);
+ iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
+ iwl_txq_update_write_ptr(priv, &priv->txq[0]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[1]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[2]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[3]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[4]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[5]);
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -4337,23 +3118,22 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
if (inta & CSR_INT_BIT_FH_TX) {
IWL_DEBUG_ISR("Tx interrupt\n");
- iwl3945_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
- if (!iwl3945_grab_nic_access(priv)) {
- iwl3945_write_direct32(priv,
- FH_TCSR_CREDIT
- (ALM_FH_SRVC_CHNL), 0x0);
- iwl3945_release_nic_access(priv);
+ iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write_direct32(priv, FH39_TCSR_CREDIT
+ (FH39_SRVC_CHNL), 0x0);
+ iwl_release_nic_access(priv);
}
handled |= CSR_INT_BIT_FH_TX;
}
if (inta & ~handled)
- IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
if (inta & ~CSR_INI_SET_MASK) {
- IWL_WARNING("Disabled INTA bits 0x%08x were pending\n",
+ IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
inta & ~CSR_INI_SET_MASK);
- IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh);
+ IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
/* Re-enable all interrupts */
@@ -4361,11 +3141,11 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
if (test_bit(STATUS_INT_ENABLED, &priv->status))
iwl3945_enable_interrupts(priv);
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_ISR)) {
- inta = iwl3945_read32(priv, CSR_INT);
- inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & (IWL_DL_ISR)) {
+ inta = iwl_read32(priv, CSR_INT);
+ inta_mask = iwl_read32(priv, CSR_INT_MASK);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
}
@@ -4375,7 +3155,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
static irqreturn_t iwl3945_isr(int irq, void *data)
{
- struct iwl3945_priv *priv = data;
+ struct iwl_priv *priv = data;
u32 inta, inta_mask;
u32 inta_fh;
if (!priv)
@@ -4387,12 +3167,12 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
* back-to-back ISRs and sporadic interrupts from our NIC.
* If we have something to service, the tasklet will re-enable ints.
* If we *don't* have something, we'll re-enable before leaving here. */
- inta_mask = iwl3945_read32(priv, CSR_INT_MASK); /* just for debug */
- iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
+ inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
+ iwl_write32(priv, CSR_INT_MASK, 0x00000000);
/* Discover which interrupts are active/pending */
- inta = iwl3945_read32(priv, CSR_INT);
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
+ inta = iwl_read32(priv, CSR_INT);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
/* Ignore interrupt if there's nothing in NIC to service.
* This may be due to IRQ shared with another device,
@@ -4404,7 +3184,7 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
/* Hardware disappeared */
- IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
+ IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
goto unplugged;
}
@@ -4430,337 +3210,26 @@ unplugged:
return IRQ_NONE;
}
-/************************** EEPROM BANDS ****************************
- *
- * The iwl3945_eeprom_band definitions below provide the mapping from the
- * EEPROM contents to the specific channel number supported for each
- * band.
- *
- * For example, iwl3945_priv->eeprom.band_3_channels[4] from the band_3
- * definition below maps to physical channel 42 in the 5.2GHz spectrum.
- * The specific geography and calibration information for that channel
- * is contained in the eeprom map itself.
- *
- * During init, we copy the eeprom information and channel map
- * information into priv->channel_info_24/52 and priv->channel_map_24/52
- *
- * channel_map_24/52 provides the index in the channel_info array for a
- * given channel. We have to have two separate maps as there is channel
- * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
- * band_2
- *
- * A value of 0xff stored in the channel_map indicates that the channel
- * is not supported by the hardware at all.
- *
- * A value of 0xfe in the channel_map indicates that the channel is not
- * valid for Tx with the current hardware. This means that
- * while the system can tune and receive on a given channel, it may not
- * be able to associate or transmit any frames on that
- * channel. There is no corresponding channel information for that
- * entry.
- *
- *********************************************************************/
-
-/* 2.4 GHz */
-static const u8 iwl3945_eeprom_band_1[14] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-};
-
-/* 5.2 GHz bands */
-static const u8 iwl3945_eeprom_band_2[] = { /* 4915-5080MHz */
- 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16
-};
-
-static const u8 iwl3945_eeprom_band_3[] = { /* 5170-5320MHz */
- 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
-};
-
-static const u8 iwl3945_eeprom_band_4[] = { /* 5500-5700MHz */
- 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
-};
-
-static const u8 iwl3945_eeprom_band_5[] = { /* 5725-5825MHz */
- 145, 149, 153, 157, 161, 165
-};
-
-static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int band,
- int *eeprom_ch_count,
- const struct iwl3945_eeprom_channel
- **eeprom_ch_info,
- const u8 **eeprom_ch_index)
-{
- switch (band) {
- case 1: /* 2.4GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_1);
- *eeprom_ch_info = priv->eeprom.band_1_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_1;
- break;
- case 2: /* 4.9GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_2);
- *eeprom_ch_info = priv->eeprom.band_2_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_2;
- break;
- case 3: /* 5.2GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_3);
- *eeprom_ch_info = priv->eeprom.band_3_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_3;
- break;
- case 4: /* 5.5GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_4);
- *eeprom_ch_info = priv->eeprom.band_4_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_4;
- break;
- case 5: /* 5.7GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_5);
- *eeprom_ch_info = priv->eeprom.band_5_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_5;
- break;
- default:
- BUG();
- return;
- }
-}
-
-/**
- * iwl3945_get_channel_info - Find driver's private channel info
- *
- * Based on band and channel number.
- */
-const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv,
- enum ieee80211_band band, u16 channel)
-{
- int i;
-
- switch (band) {
- case IEEE80211_BAND_5GHZ:
- for (i = 14; i < priv->channel_count; i++) {
- if (priv->channel_info[i].channel == channel)
- return &priv->channel_info[i];
- }
- break;
-
- case IEEE80211_BAND_2GHZ:
- if (channel >= 1 && channel <= 14)
- return &priv->channel_info[channel - 1];
- break;
- case IEEE80211_NUM_BANDS:
- WARN_ON(1);
- }
-
- return NULL;
-}
-
-#define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
- ? # x " " : "")
-
-/**
- * iwl3945_init_channel_map - Set up driver's info for all possible channels
- */
-static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
-{
- int eeprom_ch_count = 0;
- const u8 *eeprom_ch_index = NULL;
- const struct iwl3945_eeprom_channel *eeprom_ch_info = NULL;
- int band, ch;
- struct iwl3945_channel_info *ch_info;
-
- if (priv->channel_count) {
- IWL_DEBUG_INFO("Channel map already initialized.\n");
- return 0;
- }
-
- if (priv->eeprom.version < 0x2f) {
- IWL_WARNING("Unsupported EEPROM version: 0x%04X\n",
- priv->eeprom.version);
- return -EINVAL;
- }
-
- IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
-
- priv->channel_count =
- ARRAY_SIZE(iwl3945_eeprom_band_1) +
- ARRAY_SIZE(iwl3945_eeprom_band_2) +
- ARRAY_SIZE(iwl3945_eeprom_band_3) +
- ARRAY_SIZE(iwl3945_eeprom_band_4) +
- ARRAY_SIZE(iwl3945_eeprom_band_5);
-
- IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
-
- priv->channel_info = kzalloc(sizeof(struct iwl3945_channel_info) *
- priv->channel_count, GFP_KERNEL);
- if (!priv->channel_info) {
- IWL_ERROR("Could not allocate channel_info\n");
- priv->channel_count = 0;
- return -ENOMEM;
- }
-
- ch_info = priv->channel_info;
-
- /* Loop through the 5 EEPROM bands adding them in order to the
- * channel map we maintain (that contains additional information than
- * what just in the EEPROM) */
- for (band = 1; band <= 5; band++) {
-
- iwl3945_init_band_reference(priv, band, &eeprom_ch_count,
- &eeprom_ch_info, &eeprom_ch_index);
-
- /* Loop through each band adding each of the channels */
- for (ch = 0; ch < eeprom_ch_count; ch++) {
- ch_info->channel = eeprom_ch_index[ch];
- ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ :
- IEEE80211_BAND_5GHZ;
-
- /* permanently store EEPROM's channel regulatory flags
- * and max power in channel info database. */
- ch_info->eeprom = eeprom_ch_info[ch];
-
- /* Copy the run-time flags so they are there even on
- * invalid channels */
- ch_info->flags = eeprom_ch_info[ch].flags;
-
- if (!(is_channel_valid(ch_info))) {
- IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
- "No traffic\n",
- ch_info->channel,
- ch_info->flags,
- is_channel_a_band(ch_info) ?
- "5.2" : "2.4");
- ch_info++;
- continue;
- }
-
- /* Initialize regulatory-based run-time data */
- ch_info->max_power_avg = ch_info->curr_txpow =
- eeprom_ch_info[ch].max_power_avg;
- ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
- ch_info->min_power = 0;
-
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
- " %ddBm): Ad-Hoc %ssupported\n",
- ch_info->channel,
- is_channel_a_band(ch_info) ?
- "5.2" : "2.4",
- CHECK_AND_PRINT(VALID),
- CHECK_AND_PRINT(IBSS),
- CHECK_AND_PRINT(ACTIVE),
- CHECK_AND_PRINT(RADAR),
- CHECK_AND_PRINT(WIDE),
- CHECK_AND_PRINT(DFS),
- eeprom_ch_info[ch].flags,
- eeprom_ch_info[ch].max_power_avg,
- ((eeprom_ch_info[ch].
- flags & EEPROM_CHANNEL_IBSS)
- && !(eeprom_ch_info[ch].
- flags & EEPROM_CHANNEL_RADAR))
- ? "" : "not ");
-
- /* Set the user_txpower_limit to the highest power
- * supported by any channel */
- if (eeprom_ch_info[ch].max_power_avg >
- priv->user_txpower_limit)
- priv->user_txpower_limit =
- eeprom_ch_info[ch].max_power_avg;
-
- ch_info++;
- }
- }
-
- /* Set up txpower settings in driver for all channels */
- if (iwl3945_txpower_set_from_eeprom(priv))
- return -EIO;
-
- return 0;
-}
-
-/*
- * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
- */
-static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
-{
- kfree(priv->channel_info);
- priv->channel_count = 0;
-}
-
-/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
- * sending probe req. This should be set long enough to hear probe responses
- * from more than one AP. */
-#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */
-#define IWL_ACTIVE_DWELL_TIME_52 (20)
-
-#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
-#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
-
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
-
-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
- * Must be set longer than active dwell time.
- * For the most reliable scan, set > AP beacon interval (typically 100msec). */
-#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
-#define IWL_PASSIVE_DWELL_TIME_52 (10)
-#define IWL_PASSIVE_DWELL_BASE (100)
-#define IWL_CHANNEL_TUNE_TIME 5
-
-#define IWL_SCAN_PROBE_MASK(n) (BIT(n) | (BIT(n) - BIT(1)))
-
-static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
- enum ieee80211_band band,
- u8 n_probes)
-{
- if (band == IEEE80211_BAND_5GHZ)
- return IWL_ACTIVE_DWELL_TIME_52 +
- IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
- else
- return IWL_ACTIVE_DWELL_TIME_24 +
- IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
-}
-
-static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
- enum ieee80211_band band)
-{
- u16 passive = (band == IEEE80211_BAND_2GHZ) ?
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
-
- if (iwl3945_is_associated(priv)) {
- /* If we're associated, we clamp the maximum passive
- * dwell time to be 98% of the beacon interval (minus
- * 2 * channel tune time) */
- passive = priv->beacon_int;
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
- passive = IWL_PASSIVE_DWELL_BASE;
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
- }
-
- return passive;
-}
-
-static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
+static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
u8 is_active, u8 n_probes,
struct iwl3945_scan_channel *scan_ch)
{
const struct ieee80211_channel *channels = NULL;
const struct ieee80211_supported_band *sband;
- const struct iwl3945_channel_info *ch_info;
+ const struct iwl_channel_info *ch_info;
u16 passive_dwell = 0;
u16 active_dwell = 0;
int added, i;
- sband = iwl3945_get_band(priv, band);
+ sband = iwl_get_hw_mode(priv, band);
if (!sband)
return 0;
channels = sband->channels;
- active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
- passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
+ active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band);
if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
@@ -4771,7 +3240,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
scan_ch->channel = channels[i].hw_value;
- ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
+ ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
scan_ch->channel);
@@ -4798,12 +3267,12 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
* hearing clear Rx packet).*/
if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
if (n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+ scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
} else {
/* uCode v1 does not allow setting direct probe bits on
* passive channel. */
if ((scan_ch->type & 1) && n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+ scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
}
/* Set txpower levels to defaults */
@@ -4835,7 +3304,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
return added;
}
-static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
+static void iwl3945_init_hw_rates(struct iwl_priv *priv,
struct ieee80211_rate *rates)
{
int i;
@@ -4845,7 +3314,7 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
rates[i].hw_value = i; /* Rate scaling will work on indexes */
rates[i].hw_value_short = i;
rates[i].flags = 0;
- if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
+ if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
/*
* If CCK != 1M then set short preamble rate flag.
*/
@@ -4855,145 +3324,13 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
}
}
-/**
- * iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom
- */
-static int iwl3945_init_geos(struct iwl3945_priv *priv)
-{
- struct iwl3945_channel_info *ch;
- struct ieee80211_supported_band *sband;
- struct ieee80211_channel *channels;
- struct ieee80211_channel *geo_ch;
- struct ieee80211_rate *rates;
- int i = 0;
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
- priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
- IWL_DEBUG_INFO("Geography modes already initialized.\n");
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
- return 0;
- }
-
- channels = kzalloc(sizeof(struct ieee80211_channel) *
- priv->channel_count, GFP_KERNEL);
- if (!channels)
- return -ENOMEM;
-
- rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
- GFP_KERNEL);
- if (!rates) {
- kfree(channels);
- return -ENOMEM;
- }
-
- /* 5.2GHz channels start after the 2.4GHz channels */
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
- /* just OFDM */
- sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
- sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
-
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
- sband->channels = channels;
- /* OFDM & CCK */
- sband->bitrates = rates;
- sband->n_bitrates = IWL_RATE_COUNT;
-
- priv->ieee_channels = channels;
- priv->ieee_rates = rates;
-
- iwl3945_init_hw_rates(priv, rates);
-
- for (i = 0; i < priv->channel_count; i++) {
- ch = &priv->channel_info[i];
-
- /* FIXME: might be removed if scan is OK*/
- if (!is_channel_valid(ch))
- continue;
-
- if (is_channel_a_band(ch))
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- else
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
-
- geo_ch = &sband->channels[sband->n_channels++];
-
- geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
- geo_ch->max_power = ch->max_power_avg;
- geo_ch->max_antenna_gain = 0xff;
- geo_ch->hw_value = ch->channel;
-
- if (is_channel_valid(ch)) {
- if (!(ch->flags & EEPROM_CHANNEL_IBSS))
- geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
-
- if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
- geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- if (ch->flags & EEPROM_CHANNEL_RADAR)
- geo_ch->flags |= IEEE80211_CHAN_RADAR;
-
- if (ch->max_power_avg > priv->max_channel_txpower_limit)
- priv->max_channel_txpower_limit =
- ch->max_power_avg;
- } else {
- geo_ch->flags |= IEEE80211_CHAN_DISABLED;
- }
-
- /* Save flags for reg domain usage */
- geo_ch->orig_flags = geo_ch->flags;
-
- IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
- ch->channel, geo_ch->center_freq,
- is_channel_a_band(ch) ? "5.2" : "2.4",
- geo_ch->flags & IEEE80211_CHAN_DISABLED ?
- "restricted" : "valid",
- geo_ch->flags);
- }
-
- if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
- priv->cfg->sku & IWL_SKU_A) {
- printk(KERN_INFO DRV_NAME
- ": Incorrectly detected BG card as ABG. Please send "
- "your PCI ID 0x%04X:0x%04X to maintainer.\n",
- priv->pci_dev->device, priv->pci_dev->subsystem_device);
- priv->cfg->sku &= ~IWL_SKU_A;
- }
-
- printk(KERN_INFO DRV_NAME
- ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- priv->bands[IEEE80211_BAND_2GHZ].n_channels,
- priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
- &priv->bands[IEEE80211_BAND_2GHZ];
- if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
- &priv->bands[IEEE80211_BAND_5GHZ];
-
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
-
- return 0;
-}
-
-/*
- * iwl3945_free_geos - undo allocations in iwl3945_init_geos
- */
-static void iwl3945_free_geos(struct iwl3945_priv *priv)
-{
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
- clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
-}
-
/******************************************************************************
*
* uCode download functions
*
******************************************************************************/
-static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
+static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv)
{
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
@@ -5007,7 +3344,7 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
* iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
* looking at all data.
*/
-static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len)
{
u32 val;
u32 save_len = len;
@@ -5016,20 +3353,21 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3
IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc)
return rc;
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ IWL39_RTC_INST_LOWER_BOUND);
errcnt = 0;
for (; len > 0; len -= sizeof(u32), image++) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
- val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
save_len - len, val, le32_to_cpu(*image));
rc = -EIO;
@@ -5039,7 +3377,7 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3
}
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
if (!errcnt)
IWL_DEBUG_INFO("ucode image in INSTRUCTION memory is good\n");
@@ -5053,7 +3391,7 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3
* using sample data 100 bytes apart. If these sample points are good,
* it's a pretty good bet that everything between them is good, too.
*/
-static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
{
u32 val;
int rc = 0;
@@ -5062,7 +3400,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc)
return rc;
@@ -5070,12 +3408,12 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR,
- i + RTC_INST_LOWER_BOUND);
- val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ i + IWL39_RTC_INST_LOWER_BOUND);
+ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
#if 0 /* Enable this if you want to see details */
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
i, val, *image);
#endif
@@ -5086,7 +3424,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
}
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
return rc;
}
@@ -5096,7 +3434,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
* iwl3945_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
-static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
+static int iwl3945_verify_ucode(struct iwl_priv *priv)
{
__le32 *image;
u32 len;
@@ -5129,7 +3467,7 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
return 0;
}
- IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
/* Since nothing seems to match, show first several data entries in
* instruction SRAM, so maybe visual inspection will give a clue.
@@ -5141,160 +3479,10 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
return rc;
}
-
-/* check contents of special bootstrap uCode SRAM */
-static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
-{
- __le32 *image = priv->ucode_boot.v_addr;
- u32 len = priv->ucode_boot.len;
- u32 reg;
- u32 val;
-
- IWL_DEBUG_INFO("Begin verify bsm\n");
-
- /* verify BSM SRAM contents */
- val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
- for (reg = BSM_SRAM_LOWER_BOUND;
- reg < BSM_SRAM_LOWER_BOUND + len;
- reg += sizeof(u32), image++) {
- val = iwl3945_read_prph(priv, reg);
- if (val != le32_to_cpu(*image)) {
- IWL_ERROR("BSM uCode verification failed at "
- "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
- BSM_SRAM_LOWER_BOUND,
- reg - BSM_SRAM_LOWER_BOUND, len,
- val, le32_to_cpu(*image));
- return -EIO;
- }
- }
-
- IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
-
- return 0;
-}
-
-/**
- * iwl3945_load_bsm - Load bootstrap instructions
- *
- * BSM operation:
- *
- * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
- * in special SRAM that does not power down during RFKILL. When powering back
- * up after power-saving sleeps (or during initial uCode load), the BSM loads
- * the bootstrap program into the on-board processor, and starts it.
- *
- * The bootstrap program loads (via DMA) instructions and data for a new
- * program from host DRAM locations indicated by the host driver in the
- * BSM_DRAM_* registers. Once the new program is loaded, it starts
- * automatically.
- *
- * When initializing the NIC, the host driver points the BSM to the
- * "initialize" uCode image. This uCode sets up some internal data, then
- * notifies host via "initialize alive" that it is complete.
- *
- * The host then replaces the BSM_DRAM_* pointer values to point to the
- * normal runtime uCode instructions and a backup uCode data cache buffer
- * (filled initially with starting data values for the on-board processor),
- * then triggers the "initialize" uCode to load and launch the runtime uCode,
- * which begins normal operation.
- *
- * When doing a power-save shutdown, runtime uCode saves data SRAM into
- * the backup data cache in DRAM before SRAM is powered down.
- *
- * When powering back up, the BSM loads the bootstrap program. This reloads
- * the runtime uCode instructions and the backup data cache into SRAM,
- * and re-launches the runtime uCode from where it left off.
- */
-static int iwl3945_load_bsm(struct iwl3945_priv *priv)
-{
- __le32 *image = priv->ucode_boot.v_addr;
- u32 len = priv->ucode_boot.len;
- dma_addr_t pinst;
- dma_addr_t pdata;
- u32 inst_len;
- u32 data_len;
- int rc;
- int i;
- u32 done;
- u32 reg_offset;
-
- IWL_DEBUG_INFO("Begin load bsm\n");
-
- /* make sure bootstrap program is no larger than BSM's SRAM size */
- if (len > IWL_MAX_BSM_SIZE)
- return -EINVAL;
-
- /* Tell bootstrap uCode where to find the "Initialize" uCode
- * in host DRAM ... host DRAM physical address bits 31:0 for 3945.
- * NOTE: iwl3945_initialize_alive_start() will replace these values,
- * after the "initialize" uCode has run, to point to
- * runtime/protocol instructions and backup data cache. */
- pinst = priv->ucode_init.p_addr;
- pdata = priv->ucode_init_data.p_addr;
- inst_len = priv->ucode_init.len;
- data_len = priv->ucode_init_data.len;
-
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- return rc;
-
- iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
- iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
-
- /* Fill BSM memory with bootstrap instructions */
- for (reg_offset = BSM_SRAM_LOWER_BOUND;
- reg_offset < BSM_SRAM_LOWER_BOUND + len;
- reg_offset += sizeof(u32), image++)
- _iwl3945_write_prph(priv, reg_offset,
- le32_to_cpu(*image));
-
- rc = iwl3945_verify_bsm(priv);
- if (rc) {
- iwl3945_release_nic_access(priv);
- return rc;
- }
-
- /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
- iwl3945_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
- iwl3945_write_prph(priv, BSM_WR_MEM_DST_REG,
- RTC_INST_LOWER_BOUND);
- iwl3945_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
-
- /* Load bootstrap code into instruction SRAM now,
- * to prepare to load "initialize" uCode */
- iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
- BSM_WR_CTRL_REG_BIT_START);
-
- /* Wait for load of bootstrap uCode to finish */
- for (i = 0; i < 100; i++) {
- done = iwl3945_read_prph(priv, BSM_WR_CTRL_REG);
- if (!(done & BSM_WR_CTRL_REG_BIT_START))
- break;
- udelay(10);
- }
- if (i < 100)
- IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
- else {
- IWL_ERROR("BSM write did not complete!\n");
- return -EIO;
- }
-
- /* Enable future boot loads whenever power management unit triggers it
- * (e.g. when powering back up after power-save shutdown) */
- iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
- BSM_WR_CTRL_REG_BIT_START_EN);
-
- iwl3945_release_nic_access(priv);
-
- return 0;
-}
-
-static void iwl3945_nic_start(struct iwl3945_priv *priv)
+static void iwl3945_nic_start(struct iwl_priv *priv)
{
/* Remove all resets to allow NIC to operate */
- iwl3945_write32(priv, CSR_RESET, 0);
+ iwl_write32(priv, CSR_RESET, 0);
}
/**
@@ -5302,9 +3490,9 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv)
*
* Copy into buffers for card to fetch via bus-mastering
*/
-static int iwl3945_read_ucode(struct iwl3945_priv *priv)
+static int iwl3945_read_ucode(struct iwl_priv *priv)
{
- struct iwl3945_ucode *ucode;
+ struct iwl_ucode *ucode;
int ret = -EINVAL, index;
const struct firmware *ucode_raw;
/* firmware file name contains uCode/driver compatibility version */
@@ -5322,7 +3510,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
sprintf(buf, "%s%u%s", name_pre, index, ".ucode");
ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
if (ret < 0) {
- IWL_ERROR("%s firmware file req failed: Reason %d\n",
+ IWL_ERR(priv, "%s firmware file req failed: %d\n",
buf, ret);
if (ret == -ENOENT)
continue;
@@ -5330,7 +3518,9 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
goto error;
} else {
if (index < api_max)
- IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+ IWL_ERR(priv, "Loaded firmware %s, "
+ "which is deprecated. "
+ " Please use API v%u instead.\n",
buf, api_max);
IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
buf, ucode_raw->size);
@@ -5343,7 +3533,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
/* Make sure that we got at least our header! */
if (ucode_raw->size < sizeof(*ucode)) {
- IWL_ERROR("File size way too small!\n");
+ IWL_ERR(priv, "File size way too small!\n");
ret = -EINVAL;
goto err_release;
}
@@ -5364,7 +3554,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
* on the API version read from firware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
- IWL_ERROR("Driver unable to support your firmware API. "
+ IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
api_max, api_ver);
priv->ucode_ver = 0;
@@ -5372,16 +3562,17 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
goto err_release;
}
if (api_ver != api_max)
- IWL_ERROR("Firmware has old API version. Expected %u, "
+ IWL_ERR(priv, "Firmware has old API version. Expected %u, "
"got %u. New firmware can be obtained "
"from http://www.intellinuxwireless.org.\n",
api_max, api_ver);
- printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
- IWL_UCODE_MAJOR(priv->ucode_ver),
- IWL_UCODE_MINOR(priv->ucode_ver),
- IWL_UCODE_API(priv->ucode_ver),
- IWL_UCODE_SERIAL(priv->ucode_ver));
+ IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
+ IWL_UCODE_MAJOR(priv->ucode_ver),
+ IWL_UCODE_MINOR(priv->ucode_ver),
+ IWL_UCODE_API(priv->ucode_ver),
+ IWL_UCODE_SERIAL(priv->ucode_ver));
+
IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
priv->ucode_ver);
IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size);
@@ -5403,32 +3594,32 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
}
/* Verify that uCode images will fit in card's SRAM */
- if (inst_size > IWL_MAX_INST_SIZE) {
+ if (inst_size > IWL39_MAX_INST_SIZE) {
IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
inst_size);
ret = -EINVAL;
goto err_release;
}
- if (data_size > IWL_MAX_DATA_SIZE) {
+ if (data_size > IWL39_MAX_DATA_SIZE) {
IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
data_size);
ret = -EINVAL;
goto err_release;
}
- if (init_size > IWL_MAX_INST_SIZE) {
+ if (init_size > IWL39_MAX_INST_SIZE) {
IWL_DEBUG_INFO("uCode init instr len %d too large to fit in\n",
init_size);
ret = -EINVAL;
goto err_release;
}
- if (init_data_size > IWL_MAX_DATA_SIZE) {
+ if (init_data_size > IWL39_MAX_DATA_SIZE) {
IWL_DEBUG_INFO("uCode init data len %d too large to fit in\n",
init_data_size);
ret = -EINVAL;
goto err_release;
}
- if (boot_size > IWL_MAX_BSM_SIZE) {
+ if (boot_size > IWL39_MAX_BSM_SIZE) {
IWL_DEBUG_INFO("uCode boot instr len %d too large to fit in\n",
boot_size);
ret = -EINVAL;
@@ -5522,7 +3713,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
return 0;
err_pci_alloc:
- IWL_ERROR("failed to allocate pci memory\n");
+ IWL_ERR(priv, "failed to allocate pci memory\n");
ret = -ENOMEM;
iwl3945_dealloc_ucode_pci(priv);
@@ -5543,7 +3734,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
* We need to replace them to load runtime uCode inst and data,
* and to save runtime data when powering down.
*/
-static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
+static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
{
dma_addr_t pinst;
dma_addr_t pdata;
@@ -5555,24 +3746,24 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
pdata = priv->ucode_data_backup.p_addr;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
/* Tell bootstrap uCode where to find image to load */
- iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+ iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+ iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+ iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
priv->ucode_data.len);
/* Inst byte count must be last to set up, bit 31 signals uCode
* that all new ptr/size info is in place */
- iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+ iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
priv->ucode_code.len | BSM_DRAM_INST_LOAD);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -5588,7 +3779,7 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
*
* Tell "initialize" uCode to go ahead and load the runtime uCode.
*/
-static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
+static void iwl3945_init_alive_start(struct iwl_priv *priv)
{
/* Check alive response for "valid" sign from uCode */
if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
@@ -5634,7 +3825,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
* from protocol/runtime uCode (initialization uCode's
* Alive gets handled by iwl3945_init_alive_start()).
*/
-static void iwl3945_alive_start(struct iwl3945_priv *priv)
+static void iwl3945_alive_start(struct iwl_priv *priv)
{
int rc = 0;
int thermal_spin = 0;
@@ -5661,15 +3852,15 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
iwl3945_clear_stations_table(priv);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read RFKILL status from adapter\n");
+ IWL_WARN(priv, "Can not read RFKILL status from adapter\n");
return;
}
- rfkill = iwl3945_read_prph(priv, APMG_RFKILL_REG);
+ rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
IWL_DEBUG_INFO("RFKILL status: 0x%x\n", rfkill);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
if (rfkill & 0x1) {
clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -5692,7 +3883,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
/* Clear out the uCode error bit if it is set */
clear_bit(STATUS_FW_ERROR, &priv->status);
- if (iwl3945_is_rfkill(priv))
+ if (iwl_is_rfkill(priv))
return;
ieee80211_wake_queues(priv->hw);
@@ -5704,19 +3895,19 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
if (iwl3945_is_associated(priv)) {
struct iwl3945_rxon_cmd *active_rxon =
- (struct iwl3945_rxon_cmd *)(&priv->active_rxon);
+ (struct iwl3945_rxon_cmd *)(&priv->active39_rxon);
- memcpy(&priv->staging_rxon, &priv->active_rxon,
- sizeof(priv->staging_rxon));
+ memcpy(&priv->staging39_rxon, &priv->active39_rxon,
+ sizeof(priv->staging39_rxon));
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
iwl3945_connection_init_rx_config(priv, priv->iw_mode);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+ memcpy(priv->staging39_rxon.node_addr, priv->mac_addr, ETH_ALEN);
}
/* Configure Bluetooth device coexistence support */
- iwl3945_send_bt_config(priv);
+ iwl_send_bt_config(priv);
/* Configure the adapter for unassociated operation */
iwl3945_commit_rxon(priv);
@@ -5746,9 +3937,9 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
queue_work(priv->workqueue, &priv->restart);
}
-static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv);
+static void iwl3945_cancel_deferred_work(struct iwl_priv *priv);
-static void __iwl3945_down(struct iwl3945_priv *priv)
+static void __iwl3945_down(struct iwl_priv *priv)
{
unsigned long flags;
int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
@@ -5773,7 +3964,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
clear_bit(STATUS_EXIT_PENDING, &priv->status);
/* stop and reset the on-board processor */
- iwl3945_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
/* tell the device to stop sending interrupts */
spin_lock_irqsave(&priv->lock, flags);
@@ -5786,7 +3977,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
/* If we have not previously called iwl3945_init() then
* clear all bits but the RF Kill and SUSPEND bits and return */
- if (!iwl3945_is_init(priv)) {
+ if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
@@ -5815,29 +4006,31 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
+ priv->cfg->ops->lib->apm_ops.reset(priv);
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_stop(priv);
iwl3945_hw_rxq_stop(priv);
spin_lock_irqsave(&priv->lock, flags);
- if (!iwl3945_grab_nic_access(priv)) {
- iwl3945_write_prph(priv, APMG_CLK_DIS_REG,
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write_prph(priv, APMG_CLK_DIS_REG,
APMG_CLK_VAL_DMA_CLK_RQT);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
spin_unlock_irqrestore(&priv->lock, flags);
udelay(5);
- iwl3945_hw_nic_stop_master(priv);
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
- iwl3945_hw_nic_reset(priv);
+ if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ priv->cfg->ops->lib->apm_ops.stop(priv);
+ else
+ priv->cfg->ops->lib->apm_ops.reset(priv);
exit:
- memset(&priv->card_alive, 0, sizeof(struct iwl3945_alive_resp));
+ memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
@@ -5847,7 +4040,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
iwl3945_clear_free_frames(priv);
}
-static void iwl3945_down(struct iwl3945_priv *priv)
+static void iwl3945_down(struct iwl_priv *priv)
{
mutex_lock(&priv->mutex);
__iwl3945_down(priv);
@@ -5858,58 +4051,58 @@ static void iwl3945_down(struct iwl3945_priv *priv)
#define MAX_HW_RESTARTS 5
-static int __iwl3945_up(struct iwl3945_priv *priv)
+static int __iwl3945_up(struct iwl_priv *priv)
{
int rc, i;
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_WARNING("Exit pending; will not bring the NIC up\n");
+ IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
}
if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARNING("Radio disabled by SW RF kill (module "
+ IWL_WARN(priv, "Radio disabled by SW RF kill (module "
"parameter)\n");
return -ENODEV;
}
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
- IWL_ERROR("ucode not available for device bring up\n");
+ IWL_ERR(priv, "ucode not available for device bring up\n");
return -EIO;
}
/* If platform's RF_KILL switch is NOT set to KILL */
- if (iwl3945_read32(priv, CSR_GP_CNTRL) &
+ if (iwl_read32(priv, CSR_GP_CNTRL) &
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else {
set_bit(STATUS_RF_KILL_HW, &priv->status);
if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
- IWL_WARNING("Radio disabled by HW RF Kill switch\n");
+ IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
return -ENODEV;
}
}
- iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
rc = iwl3945_hw_nic_init(priv);
if (rc) {
- IWL_ERROR("Unable to int nic\n");
+ IWL_ERR(priv, "Unable to int nic\n");
return rc;
}
/* make sure rfkill handshake bits are cleared */
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
/* clear (again), then enable host interrupts */
- iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
iwl3945_enable_interrupts(priv);
/* really make sure rfkill handshake bits are cleared */
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
/* Copy original ucode data image from disk into backup cache.
* This will be used to initialize the on-board processor's
@@ -5928,10 +4121,11 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
- rc = iwl3945_load_bsm(priv);
+ priv->cfg->ops->lib->load_ucode(priv);
if (rc) {
- IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc);
+ IWL_ERR(priv,
+ "Unable to set up bootstrap uCode: %d\n", rc);
continue;
}
@@ -5949,7 +4143,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
/* tried to restart and config the device for as long as our
* patience could withstand */
- IWL_ERROR("Unable to initialize device after %d attempts.\n", i);
+ IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
return -EIO;
}
@@ -5962,8 +4156,8 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
static void iwl3945_bg_init_alive_start(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, init_alive_start.work);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, init_alive_start.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -5975,8 +4169,8 @@ static void iwl3945_bg_init_alive_start(struct work_struct *data)
static void iwl3945_bg_alive_start(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, alive_start.work);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, alive_start.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -5986,66 +4180,31 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl3945_bg_rf_kill(struct work_struct *work)
+static void iwl3945_rfkill_poll(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, rf_kill);
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, rfkill_poll.work);
+ unsigned long status = priv->status;
- mutex_lock(&priv->mutex);
+ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
- if (!iwl3945_is_rfkill(priv)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
- "HW and/or SW RF Kill no longer active, restarting "
- "device\n");
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- queue_work(priv->workqueue, &priv->restart);
- } else {
+ if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status))
+ queue_work(priv->workqueue, &priv->rf_kill);
- if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by SW switch\n");
- else
- IWL_WARNING("Radio Frequency Kill Switch is On:\n"
- "Kill switch must be turned off for "
- "wireless networking to work.\n");
- }
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ round_jiffies_relative(2 * HZ));
- mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
}
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-
-static void iwl3945_bg_scan_check(struct work_struct *data)
-{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, scan_check.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) ||
- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
- "Scan completion watchdog resetting adapter (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- iwl3945_send_scan_abort(priv);
- }
- mutex_unlock(&priv->mutex);
-}
-
static void iwl3945_bg_request_scan(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, request_scan);
- struct iwl3945_host_cmd cmd = {
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, request_scan);
+ struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
.len = sizeof(struct iwl3945_scan_cmd),
.meta.flags = CMD_SIZE_HUGE,
@@ -6061,8 +4220,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
mutex_lock(&priv->mutex);
- if (!iwl3945_is_ready(priv)) {
- IWL_WARNING("request scan called when driver not ready.\n");
+ if (!iwl_is_ready(priv)) {
+ IWL_WARN(priv, "request scan called when driver not ready.\n");
goto done;
}
@@ -6090,7 +4249,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
goto done;
}
- if (iwl3945_is_rfkill(priv)) {
+ if (iwl_is_rfkill(priv)) {
IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
goto done;
}
@@ -6168,11 +4327,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
- scan->tx_cmd.len = cpu_to_le16(
- iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan)));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
+ scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
/* flags + rate selection */
@@ -6187,10 +4343,15 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->good_CRC_th = IWL_GOOD_CRC_TH;
band = IEEE80211_BAND_5GHZ;
} else {
- IWL_WARNING("Invalid scan band count\n");
+ IWL_WARN(priv, "Invalid scan band count\n");
goto done;
}
+ scan->tx_cmd.len = cpu_to_le16(
+ iwl_fill_probe_req(priv, band,
+ (struct ieee80211_mgmt *)scan->data,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+
/* select Rx antennas */
scan->flags |= iwl3945_get_antenna_flags(priv);
@@ -6213,7 +4374,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->len = cpu_to_le16(cmd.len);
set_bit(STATUS_SCAN_HW, &priv->status);
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
goto done;
@@ -6239,7 +4400,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
static void iwl3945_bg_up(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, up);
+ struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6247,12 +4408,12 @@ static void iwl3945_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
+ iwl_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_restart(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, restart);
+ struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6263,8 +4424,8 @@ static void iwl3945_bg_restart(struct work_struct *data)
static void iwl3945_bg_rx_replenish(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, rx_replenish);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, rx_replenish);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6276,19 +4437,19 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl3945_post_associate(struct iwl3945_priv *priv)
+static void iwl3945_post_associate(struct iwl_priv *priv)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- IWL_ERROR("%s Should not be called in AP mode\n", __func__);
+ IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
- priv->assoc_id, priv->active_rxon.bssid_addr);
+ priv->assoc_id, priv->active39_rxon.bssid_addr);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6296,41 +4457,41 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
if (!priv->vif || !priv->is_open)
return;
- iwl3945_scan_cancel_timeout(priv, 200);
+ iwl_scan_cancel_timeout(priv, 200);
conf = ieee80211_get_hw_conf(priv->hw);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
- memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+ memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (rc)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ priv->staging39_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
+ priv->staging39_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n",
priv->assoc_id, priv->beacon_int);
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK) {
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
@@ -6355,7 +4516,7 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
break;
default:
- IWL_ERROR("%s Should not be called in %d mode\n",
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
__func__, priv->iw_mode);
break;
}
@@ -6366,45 +4527,8 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
-static void iwl3945_bg_abort_scan(struct work_struct *work)
-{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, abort_scan);
-
- if (!iwl3945_is_ready(priv))
- return;
-
- mutex_lock(&priv->mutex);
-
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- iwl3945_send_scan_abort(priv);
-
- mutex_unlock(&priv->mutex);
-}
-
static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
-static void iwl3945_bg_scan_completed(struct work_struct *work)
-{
- struct iwl3945_priv *priv =
- container_of(work, struct iwl3945_priv, scan_completed);
-
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (test_bit(STATUS_CONF_PENDING, &priv->status))
- iwl3945_mac_config(priv->hw, 0);
-
- ieee80211_scan_completed(priv->hw);
-
- /* Since setting the TXPOWER may have been deferred while
- * performing the scan, fire one off */
- mutex_lock(&priv->mutex);
- iwl3945_hw_reg_send_txpower(priv);
- mutex_unlock(&priv->mutex);
-}
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -6415,36 +4539,22 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
static int iwl3945_mac_start(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int ret;
IWL_DEBUG_MAC80211("enter\n");
- if (pci_enable_device(priv->pci_dev)) {
- IWL_ERROR("Fail to pci_enable_device\n");
- return -ENODEV;
- }
- pci_restore_state(priv->pci_dev);
- pci_enable_msi(priv->pci_dev);
-
- ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED,
- DRV_NAME, priv);
- if (ret) {
- IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
- goto out_disable_msi;
- }
-
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
- memset(&priv->staging_rxon, 0, sizeof(struct iwl3945_rxon_cmd));
+ memset(&priv->staging39_rxon, 0, sizeof(struct iwl3945_rxon_cmd));
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */
if (!priv->ucode_code.len) {
ret = iwl3945_read_ucode(priv);
if (ret) {
- IWL_ERROR("Could not read microcode: %d\n", ret);
+ IWL_ERR(priv, "Could not read microcode: %d\n", ret);
mutex_unlock(&priv->mutex);
goto out_release_irq;
}
@@ -6454,7 +4564,7 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
+ iwl_rfkill_set_hw_state(priv);
if (ret)
goto out_release_irq;
@@ -6471,22 +4581,23 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
UCODE_READY_TIMEOUT);
if (!ret) {
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n",
- jiffies_to_msecs(UCODE_READY_TIMEOUT));
+ IWL_ERR(priv,
+ "Wait for START_ALIVE timeout after %dms.\n",
+ jiffies_to_msecs(UCODE_READY_TIMEOUT));
ret = -ETIMEDOUT;
goto out_release_irq;
}
}
+ /* ucode is running and will send rfkill notifications,
+ * no need to poll the killswitch state anymore */
+ cancel_delayed_work(&priv->rfkill_poll);
+
priv->is_open = 1;
IWL_DEBUG_MAC80211("leave\n");
return 0;
out_release_irq:
- free_irq(priv->pci_dev->irq, priv);
-out_disable_msi:
- pci_disable_msi(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
priv->is_open = 0;
IWL_DEBUG_MAC80211("leave - failed\n");
return ret;
@@ -6494,7 +4605,7 @@ out_disable_msi:
static void iwl3945_mac_stop(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
IWL_DEBUG_MAC80211("enter\n");
@@ -6505,29 +4616,29 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
priv->is_open = 0;
- if (iwl3945_is_ready_rf(priv)) {
+ if (iwl_is_ready_rf(priv)) {
/* stop mac, cancel any scan request and clear
* RXON_FILTER_ASSOC_MSK BIT
*/
mutex_lock(&priv->mutex);
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
mutex_unlock(&priv->mutex);
}
iwl3945_down(priv);
flush_workqueue(priv->workqueue);
- free_irq(priv->pci_dev->irq, priv);
- pci_disable_msi(priv->pci_dev);
- pci_save_state(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
+
+ /* start polling the killswitch state again */
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ round_jiffies_relative(2 * HZ));
IWL_DEBUG_MAC80211("leave\n");
}
static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
IWL_DEBUG_MAC80211("enter\n");
@@ -6544,7 +4655,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
@@ -6567,7 +4678,7 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
}
- if (iwl3945_is_ready(priv))
+ if (iwl_is_ready(priv))
iwl3945_set_mode(priv, conf->type);
mutex_unlock(&priv->mutex);
@@ -6585,8 +4696,8 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
*/
static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
{
- struct iwl3945_priv *priv = hw->priv;
- const struct iwl3945_channel_info *ch_info;
+ struct iwl_priv *priv = hw->priv;
+ const struct iwl_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
unsigned long flags;
int ret = 0;
@@ -6594,13 +4705,13 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
- if (!iwl3945_is_ready(priv)) {
+ if (!iwl_is_ready(priv)) {
IWL_DEBUG_MAC80211("leave - not ready\n");
ret = -EIO;
goto out;
}
- if (unlikely(!iwl3945_param_disable_hw_scan &&
+ if (unlikely(!iwl3945_mod_params.disable_hw_scan &&
test_bit(STATUS_SCANNING, &priv->status))) {
IWL_DEBUG_MAC80211("leave - scanning\n");
set_bit(STATUS_CONF_PENDING, &priv->status);
@@ -6610,8 +4721,8 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
spin_lock_irqsave(&priv->lock, flags);
- ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
- conf->channel->hw_value);
+ ch_info = iwl_get_channel_info(priv, conf->channel->band,
+ conf->channel->hw_value);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
conf->channel->hw_value, conf->channel->band);
@@ -6646,7 +4757,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
goto out;
}
- if (iwl3945_is_rfkill(priv)) {
+ if (iwl_is_rfkill(priv)) {
IWL_DEBUG_MAC80211("leave - RF kill\n");
ret = -EIO;
goto out;
@@ -6654,8 +4765,8 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
iwl3945_set_rate(priv);
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
+ if (memcmp(&priv->active39_rxon,
+ &priv->staging39_rxon, sizeof(priv->staging39_rxon)))
iwl3945_commit_rxon(priv);
else
IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
@@ -6668,7 +4779,7 @@ out:
return ret;
}
-static void iwl3945_config_ap(struct iwl3945_priv *priv)
+static void iwl3945_config_ap(struct iwl_priv *priv)
{
int rc = 0;
@@ -6679,44 +4790,45 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
if (!(iwl3945_is_associated(priv))) {
/* RXON - unassoc (to set timing command) */
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
/* RXON Timing */
- memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+ memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+ sizeof(priv->rxon_timing),
+ &priv->rxon_timing);
if (rc)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
/* FIXME: what should be the assoc_id for AP? */
- priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
+ priv->staging39_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- priv->staging_rxon.flags |=
+ priv->staging39_rxon.flags |=
RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &=
+ priv->staging39_rxon.flags &=
~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
+ if (priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK) {
if (priv->assoc_capability &
WLAN_CAPABILITY_SHORT_SLOT_TIME)
- priv->staging_rxon.flags |=
+ priv->staging39_rxon.flags |=
RXON_FLG_SHORT_SLOT_MSK;
else
- priv->staging_rxon.flags &=
+ priv->staging39_rxon.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
- priv->staging_rxon.flags &=
+ priv->staging39_rxon.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
}
/* restore RXON assoc */
- priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ priv->staging39_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
- iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
+ iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
}
iwl3945_send_beacon_cmd(priv);
@@ -6727,9 +4839,9 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
+ struct ieee80211_if_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int rc;
if (conf == NULL)
@@ -6753,7 +4865,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
return rc;
}
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
mutex_lock(&priv->mutex);
@@ -6781,21 +4893,21 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
- if (iwl3945_is_rfkill(priv))
+ if (iwl_is_rfkill(priv))
goto done;
if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
!is_multicast_ether_addr(conf->bssid)) {
/* If there is currently a HW scan going on in the background
* then we need to cancel it else the RXON below will fail. */
- if (iwl3945_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress "
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress "
"after 100ms\n");
IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
mutex_unlock(&priv->mutex);
return -EAGAIN;
}
- memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
+ memcpy(priv->staging39_rxon.bssid_addr, conf->bssid, ETH_ALEN);
/* TODO: Audit driver for usage of these members and see
* if mac80211 deprecates them (priv->bssid looks like it
@@ -6809,12 +4921,12 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
rc = iwl3945_commit_rxon(priv);
if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
iwl3945_add_station(priv,
- priv->active_rxon.bssid_addr, 1, 0);
+ priv->active39_rxon.bssid_addr, 1, 0);
}
} else {
- iwl3945_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
@@ -6830,8 +4942,8 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
unsigned int *total_flags,
int mc_count, struct dev_addr_list *mc_list)
{
- struct iwl3945_priv *priv = hw->priv;
- __le32 *filter_flags = &priv->staging_rxon.filter_flags;
+ struct iwl_priv *priv = hw->priv;
+ __le32 *filter_flags = &priv->staging39_rxon.filter_flags;
IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
changed_flags, *total_flags);
@@ -6874,15 +4986,15 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
IWL_DEBUG_MAC80211("enter\n");
mutex_lock(&priv->mutex);
- if (iwl3945_is_ready_rf(priv)) {
- iwl3945_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ if (iwl_is_ready_rf(priv)) {
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
if (priv->vif == conf->vif) {
@@ -6901,7 +5013,7 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changes)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
@@ -6909,17 +5021,17 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
- priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ priv->staging39_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ priv->staging39_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
}
if (changes & BSS_CHANGED_ASSOC) {
@@ -6931,10 +5043,9 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
if (bss_conf->assoc) {
priv->assoc_id = bss_conf->aid;
priv->beacon_int = bss_conf->beacon_int;
- priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF;
- priv->timestamp1 = (bss_conf->timestamp >> 32) &
- 0xFFFFFFFF;
+ priv->timestamp = bss_conf->timestamp;
priv->assoc_capability = bss_conf->assoc_capability;
+ priv->power_data.dtim_period = bss_conf->dtim_period;
priv->next_scan_jiffies = jiffies +
IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
mutex_lock(&priv->mutex);
@@ -6955,7 +5066,7 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
{
int rc = 0;
unsigned long flags;
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
DECLARE_SSID_BUF(ssid_buf);
IWL_DEBUG_MAC80211("enter\n");
@@ -6963,7 +5074,7 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
mutex_lock(&priv->mutex);
spin_lock_irqsave(&priv->lock, flags);
- if (!iwl3945_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
rc = -EIO;
IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
goto out_unlock;
@@ -7005,24 +5116,23 @@ out_unlock:
}
static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
- struct iwl3945_priv *priv = hw->priv;
- int rc = 0;
+ struct iwl_priv *priv = hw->priv;
+ const u8 *addr;
+ int ret;
u8 sta_id;
IWL_DEBUG_MAC80211("enter\n");
- if (!iwl3945_param_hwcrypto) {
+ if (iwl3945_mod_params.sw_crypto) {
IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
- if (is_zero_ether_addr(addr))
- /* only support pairwise keys */
- return -EOPNOTSUPP;
-
+ addr = sta ? sta->addr : iwl_bcast_addr;
sta_id = iwl3945_hw_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
@@ -7032,12 +5142,12 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
mutex_lock(&priv->mutex);
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
switch (cmd) {
case SET_KEY:
- rc = iwl3945_update_sta_key_info(priv, key, sta_id);
- if (!rc) {
+ ret = iwl3945_update_sta_key_info(priv, key, sta_id);
+ if (!ret) {
iwl3945_set_rxon_hwcrypto(priv, 1);
iwl3945_commit_rxon(priv);
key->hw_key_idx = sta_id;
@@ -7046,33 +5156,33 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}
break;
case DISABLE_KEY:
- rc = iwl3945_clear_sta_key_info(priv, sta_id);
- if (!rc) {
+ ret = iwl3945_clear_sta_key_info(priv, sta_id);
+ if (!ret) {
iwl3945_set_rxon_hwcrypto(priv, 0);
iwl3945_commit_rxon(priv);
IWL_DEBUG_MAC80211("disable hwcrypto key\n");
}
break;
default:
- rc = -EINVAL;
+ ret = -EINVAL;
}
IWL_DEBUG_MAC80211("leave\n");
mutex_unlock(&priv->mutex);
- return rc;
+ return ret;
}
static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
int q;
IWL_DEBUG_MAC80211("enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211("leave - RF not ready\n");
return -EIO;
}
@@ -7112,15 +5222,15 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int i, avail;
- struct iwl3945_tx_queue *txq;
- struct iwl3945_queue *q;
+ struct iwl_tx_queue *txq;
+ struct iwl_queue *q;
unsigned long flags;
IWL_DEBUG_MAC80211("enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211("leave - RF not ready\n");
return -EIO;
}
@@ -7130,7 +5240,7 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
for (i = 0; i < AC_NUM; i++) {
txq = &priv->txq[i];
q = &txq->q;
- avail = iwl3945_queue_space(q);
+ avail = iwl_queue_space(q);
stats[i].len = q->n_window - avail;
stats[i].limit = q->n_window - q->high_mark;
@@ -7144,29 +5254,19 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
return 0;
}
-static int iwl3945_mac_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats)
-{
- IWL_DEBUG_MAC80211("enter\n");
- IWL_DEBUG_MAC80211("leave\n");
-
- return 0;
-}
-
static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter\n");
- iwl3945_reset_qos(priv);
+ iwl_reset_qos(priv);
spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = 0;
priv->assoc_capability = 0;
- priv->call_post_assoc_from_beacon = 0;
/* new association get rid of ibss beacon skb */
if (priv->ibss_beacon)
@@ -7175,14 +5275,13 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
priv->ibss_beacon = NULL;
priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp1 = 0;
- priv->timestamp0 = 0;
+ priv->timestamp = 0;
if ((priv->iw_mode == NL80211_IFTYPE_STATION))
priv->beacon_int = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- if (!iwl3945_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211("leave - not ready\n");
mutex_unlock(&priv->mutex);
return;
@@ -7192,8 +5291,8 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
* clear RXON_FILTER_ASSOC_MSK bit
*/
if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl3945_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ iwl_scan_cancel_timeout(priv, 100);
+ priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
@@ -7215,12 +5314,12 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
IWL_DEBUG_MAC80211("enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211("leave - RF not ready\n");
return -EIO;
}
@@ -7242,7 +5341,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
IWL_DEBUG_MAC80211("leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
- iwl3945_reset_qos(priv);
+ iwl_reset_qos(priv);
iwl3945_post_associate(priv);
@@ -7256,7 +5355,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
*
*****************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
/*
* The following adds a new attribute to the sysfs representation
@@ -7265,38 +5364,41 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
*
* See the level definitions in iwl for details.
*/
-
-static ssize_t show_debug_level(struct device_driver *d, char *buf)
+static ssize_t show_debug_level(struct device *d,
+ struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "0x%08X\n", iwl3945_debug_level);
+ struct iwl_priv *priv = d->driver_data;
+
+ return sprintf(buf, "0x%08X\n", priv->debug_level);
}
-static ssize_t store_debug_level(struct device_driver *d,
+static ssize_t store_debug_level(struct device *d,
+ struct device_attribute *attr,
const char *buf, size_t count)
{
- char *p = (char *)buf;
- u32 val;
+ struct iwl_priv *priv = d->driver_data;
+ unsigned long val;
+ int ret;
- val = simple_strtoul(p, &p, 0);
- if (p == buf)
- printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret)
+ IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf);
else
- iwl3945_debug_level = val;
+ priv->debug_level = val;
return strnlen(buf, count);
}
-static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
- show_debug_level, store_debug_level);
+static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
+ show_debug_level, store_debug_level);
-#endif /* CONFIG_IWL3945_DEBUG */
+#endif /* CONFIG_IWLWIFI_DEBUG */
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv));
@@ -7307,22 +5409,21 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
- return sprintf(buf, "%d\n", priv->user_txpower_limit);
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
}
static ssize_t store_tx_power(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
char *p = (char *)buf;
u32 val;
val = simple_strtoul(p, &p, 10);
if (p == buf)
- printk(KERN_INFO DRV_NAME
- ": %s is not in decimal form.\n", buf);
+ IWL_INFO(priv, ": %s is not in decimal form.\n", buf);
else
iwl3945_hw_reg_set_txpower(priv, val);
@@ -7334,27 +5435,27 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
+ return sprintf(buf, "0x%04X\n", priv->active39_rxon.flags);
}
static ssize_t store_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
u32 flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
- if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
+ if (le32_to_cpu(priv->staging39_rxon.flags) != flags) {
/* Cancel any currently running scans... */
- if (iwl3945_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ if (iwl_scan_cancel_timeout(priv, 100))
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
flags);
- priv->staging_rxon.flags = cpu_to_le32(flags);
+ priv->staging39_rxon.flags = cpu_to_le32(flags);
iwl3945_commit_rxon(priv);
}
}
@@ -7368,28 +5469,28 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
return sprintf(buf, "0x%04X\n",
- le32_to_cpu(priv->active_rxon.filter_flags));
+ le32_to_cpu(priv->active39_rxon.filter_flags));
}
static ssize_t store_filter_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
- if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
+ if (le32_to_cpu(priv->staging39_rxon.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
- if (iwl3945_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ if (iwl_scan_cancel_timeout(priv, 100))
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
IWL_DEBUG_INFO("Committing rxon.filter_flags = "
"0x%04X\n", filter_flags);
- priv->staging_rxon.filter_flags =
+ priv->staging39_rxon.filter_flags =
cpu_to_le32(filter_flags);
iwl3945_commit_rxon(priv);
}
@@ -7407,8 +5508,8 @@ static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
static ssize_t show_measurement(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
- struct iwl3945_spectrum_notification measure_report;
+ struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_spectrum_notification measure_report;
u32 size = sizeof(measure_report), len = 0, ofs = 0;
u8 *data = (u8 *)&measure_report;
unsigned long flags;
@@ -7440,9 +5541,9 @@ static ssize_t store_measurement(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
struct ieee80211_measurement_params params = {
- .channel = le16_to_cpu(priv->active_rxon.channel),
+ .channel = le16_to_cpu(priv->active39_rxon.channel),
.start_time = cpu_to_le64(priv->last_tsf),
.duration = cpu_to_le16(1),
};
@@ -7479,7 +5580,7 @@ static ssize_t store_retry_rate(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
priv->retry_rate = simple_strtoul(buf, NULL, 0);
if (priv->retry_rate <= 0)
@@ -7491,7 +5592,7 @@ static ssize_t store_retry_rate(struct device *d,
static ssize_t show_retry_rate(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%d", priv->retry_rate);
}
@@ -7502,20 +5603,21 @@ static ssize_t store_power_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
int rc;
int mode;
mode = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
- if (!iwl3945_is_ready(priv)) {
+ if (!iwl_is_ready(priv)) {
rc = -EAGAIN;
goto out;
}
- if ((mode < 1) || (mode > IWL_POWER_LIMIT) || (mode == IWL_POWER_AC))
- mode = IWL_POWER_AC;
+ if ((mode < 1) || (mode > IWL39_POWER_LIMIT) ||
+ (mode == IWL39_POWER_AC))
+ mode = IWL39_POWER_AC;
else
mode |= IWL_POWER_ENABLED;
@@ -7556,17 +5658,17 @@ static const s32 period_duration[] = {
static ssize_t show_power_level(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
int level = IWL_POWER_LEVEL(priv->power_mode);
char *p = buf;
p += sprintf(p, "%d ", level);
switch (level) {
case IWL_POWER_MODE_CAM:
- case IWL_POWER_AC:
+ case IWL39_POWER_AC:
p += sprintf(p, "(AC)");
break;
- case IWL_POWER_BATTERY:
+ case IWL39_POWER_BATTERY:
p += sprintf(p, "(BATTERY)");
break;
default:
@@ -7600,17 +5702,17 @@ static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
static ssize_t show_statistics(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 size = sizeof(struct iwl3945_notif_statistics);
u32 len = 0, ofs = 0;
- u8 *data = (u8 *)&priv->statistics;
+ u8 *data = (u8 *)&priv->statistics_39;
int rc = 0;
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
mutex_lock(&priv->mutex);
- rc = iwl3945_send_statistics_request(priv);
+ rc = iwl_send_statistics_request(priv, 0);
mutex_unlock(&priv->mutex);
if (rc) {
@@ -7638,12 +5740,12 @@ static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
static ssize_t show_antenna(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
- return sprintf(buf, "%d\n", priv->antenna);
+ return sprintf(buf, "%d\n", iwl3945_mod_params.antenna);
}
static ssize_t store_antenna(struct device *d,
@@ -7651,7 +5753,7 @@ static ssize_t store_antenna(struct device *d,
const char *buf, size_t count)
{
int ant;
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (count == 0)
return 0;
@@ -7663,7 +5765,7 @@ static ssize_t store_antenna(struct device *d,
if ((ant >= 0) && (ant <= 2)) {
IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
- priv->antenna = (enum iwl3945_antenna)ant;
+ iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant;
} else
IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);
@@ -7676,8 +5778,8 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
- if (!iwl3945_is_alive(priv))
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "0x%08x\n", (int)priv->status);
}
@@ -7691,7 +5793,7 @@ static ssize_t dump_error_log(struct device *d,
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_error_log((struct iwl3945_priv *)d->driver_data);
+ iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data);
return strnlen(buf, count);
}
@@ -7705,7 +5807,7 @@ static ssize_t dump_event_log(struct device *d,
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_event_log((struct iwl3945_priv *)d->driver_data);
+ iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data);
return strnlen(buf, count);
}
@@ -7718,7 +5820,7 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
*
*****************************************************************************/
-static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
+static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
{
priv->workqueue = create_workqueue(DRV_NAME);
@@ -7727,14 +5829,15 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
INIT_WORK(&priv->up, iwl3945_bg_up);
INIT_WORK(&priv->restart, iwl3945_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
- INIT_WORK(&priv->scan_completed, iwl3945_bg_scan_completed);
- INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
- INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
- INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
+ INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
- INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
+ INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll);
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+ INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
+ INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+ INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
iwl3945_hw_setup_deferred_work(priv);
@@ -7742,7 +5845,7 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
iwl3945_irq_tasklet, (unsigned long)priv);
}
-static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv)
+static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
{
iwl3945_hw_cancel_deferred_work(priv);
@@ -7768,7 +5871,9 @@ static struct attribute *iwl3945_sysfs_entries[] = {
&dev_attr_status.attr,
&dev_attr_temperature.attr,
&dev_attr_tx_power.attr,
-
+#ifdef CONFIG_IWLWIFI_DEBUG
+ &dev_attr_debug_level.attr,
+#endif
NULL
};
@@ -7787,7 +5892,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.config_interface = iwl3945_mac_config_interface,
.configure_filter = iwl3945_configure_filter,
.set_key = iwl3945_mac_set_key,
- .get_stats = iwl3945_mac_get_stats,
.get_tx_stats = iwl3945_mac_get_tx_stats,
.conf_tx = iwl3945_mac_conf_tx,
.reset_tsf = iwl3945_mac_reset_tsf,
@@ -7795,59 +5899,136 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.hw_scan = iwl3945_mac_hw_scan
};
+static int iwl3945_init_drv(struct iwl_priv *priv)
+{
+ int ret;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+
+ priv->retry_rate = 1;
+ priv->ibss_beacon = NULL;
+
+ spin_lock_init(&priv->lock);
+ spin_lock_init(&priv->power_data.lock);
+ spin_lock_init(&priv->sta_lock);
+ spin_lock_init(&priv->hcmd_lock);
+
+ INIT_LIST_HEAD(&priv->free_frames);
+
+ mutex_init(&priv->mutex);
+
+ /* Clear the driver's (not device's) station table */
+ iwl3945_clear_stations_table(priv);
+
+ priv->data_retry_limit = -1;
+ priv->ieee_channels = NULL;
+ priv->ieee_rates = NULL;
+ priv->band = IEEE80211_BAND_2GHZ;
+
+ priv->iw_mode = NL80211_IFTYPE_STATION;
+
+ iwl_reset_qos(priv);
+
+ priv->qos_data.qos_active = 0;
+ priv->qos_data.qos_cap.val = 0;
+
+ priv->rates_mask = IWL_RATES_MASK;
+ /* If power management is turned on, default to AC mode */
+ priv->power_mode = IWL39_POWER_AC;
+ priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
+
+ if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
+ IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
+ eeprom->version);
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = iwl_init_channel_map(priv);
+ if (ret) {
+ IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
+ goto err;
+ }
+
+ /* Set up txpower settings in driver for all channels */
+ if (iwl3945_txpower_set_from_eeprom(priv)) {
+ ret = -EIO;
+ goto err_free_channel_map;
+ }
+
+ ret = iwlcore_init_geos(priv);
+ if (ret) {
+ IWL_ERR(priv, "initializing geos failed: %d\n", ret);
+ goto err_free_channel_map;
+ }
+ iwl3945_init_hw_rates(priv, priv->ieee_rates);
+
+ if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &priv->bands[IEEE80211_BAND_2GHZ];
+ if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &priv->bands[IEEE80211_BAND_5GHZ];
+
+ return 0;
+
+err_free_channel_map:
+ iwl_free_channel_map(priv);
+err:
+ return ret;
+}
+
static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int err = 0;
- struct iwl3945_priv *priv;
+ struct iwl_priv *priv;
struct ieee80211_hw *hw;
- struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
+ struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+ struct iwl3945_eeprom *eeprom;
unsigned long flags;
/***********************
* 1. Allocating HW data
* ********************/
- /* Disabling hardware scan means that mac80211 will perform scans
- * "the hard way", rather than using device's scan. */
- if (iwl3945_param_disable_hw_scan) {
- IWL_DEBUG_INFO("Disabling hw_scan\n");
- iwl3945_hw_ops.hw_scan = NULL;
- }
-
- if ((iwl3945_param_queues_num > IWL39_MAX_NUM_QUEUES) ||
- (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
- err = -EINVAL;
- goto out;
- }
-
/* mac80211 allocates memory for this device instance, including
* space for this driver's private structure */
- hw = ieee80211_alloc_hw(sizeof(struct iwl3945_priv), &iwl3945_hw_ops);
+ hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
if (hw == NULL) {
- IWL_ERROR("Can not allocate network device\n");
+ printk(KERN_ERR DRV_NAME "Can not allocate network device\n");
err = -ENOMEM;
goto out;
}
-
+ priv = hw->priv;
SET_IEEE80211_DEV(hw, &pdev->dev);
- priv = hw->priv;
- priv->hw = hw;
- priv->pci_dev = pdev;
- priv->cfg = cfg;
+ if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) ||
+ (iwl3945_mod_params.num_of_queues < IWL_MIN_NUM_QUEUES)) {
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * Disabling hardware scan means that mac80211 will perform scans
+ * "the hard way", rather than using device's scan.
+ */
+ if (iwl3945_mod_params.disable_hw_scan) {
+ IWL_DEBUG_INFO("Disabling hw_scan\n");
+ iwl3945_hw_ops.hw_scan = NULL;
+ }
+
IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
- hw->rate_control_algorithm = "iwl-3945-rs";
- hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
+ priv->cfg = cfg;
+ priv->pci_dev = pdev;
- /* Select antenna (may be helpful if only one antenna is connected) */
- priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
-#ifdef CONFIG_IWL3945_DEBUG
- iwl3945_debug_level = iwl3945_param_debug;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ priv->debug_level = iwl3945_mod_params.debug;
atomic_set(&priv->restrict_refcnt, 0);
#endif
+ hw->rate_control_algorithm = "iwl-3945-rs";
+ hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
@@ -7857,7 +6038,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->fw_handles_regulatory = true;
+ hw->wiphy->custom_regulatory = true;
/* 4 EDCA QOS priorities */
hw->queues = 4;
@@ -7876,7 +6057,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if (!err)
err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
- printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
+ IWL_WARN(priv, "No suitable DMA available.\n");
goto out_pci_disable_device;
}
@@ -7902,29 +6083,26 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, 0x41, 0x00);
- /* nic init */
- iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- err = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ /* amp init */
+ err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
- goto out_remove_sysfs;
+ IWL_DEBUG_INFO("Failed to init APMG\n");
+ goto out_iounmap;
}
/***********************
* 4. Read EEPROM
* ********************/
+
/* Read the EEPROM */
- err = iwl3945_eeprom_init(priv);
+ err = iwl_eeprom_init(priv);
if (err) {
- IWL_ERROR("Unable to init EEPROM\n");
+ IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_remove_sysfs;
}
/* MAC Address location in EEPROM same for 3945/4965 */
- get_eeprom_mac(priv, priv->mac_addr);
+ eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN);
IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
@@ -7932,60 +6110,23 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* 5. Setup HW Constants
* ********************/
/* Device-specific setup */
- if (iwl3945_hw_set_hw_setting(priv)) {
- IWL_ERROR("failed to set hw settings\n");
+ if (iwl3945_hw_set_hw_params(priv)) {
+ IWL_ERR(priv, "failed to set hw settings\n");
goto out_iounmap;
}
/***********************
* 6. Setup priv
* ********************/
- priv->retry_rate = 1;
- priv->ibss_beacon = NULL;
-
- spin_lock_init(&priv->lock);
- spin_lock_init(&priv->power_data.lock);
- spin_lock_init(&priv->sta_lock);
- spin_lock_init(&priv->hcmd_lock);
-
- INIT_LIST_HEAD(&priv->free_frames);
- mutex_init(&priv->mutex);
-
- /* Clear the driver's (not device's) station table */
- iwl3945_clear_stations_table(priv);
-
- priv->data_retry_limit = -1;
- priv->ieee_channels = NULL;
- priv->ieee_rates = NULL;
- priv->band = IEEE80211_BAND_2GHZ;
-
- priv->iw_mode = NL80211_IFTYPE_STATION;
-
- iwl3945_reset_qos(priv);
-
- priv->qos_data.qos_active = 0;
- priv->qos_data.qos_cap.val = 0;
-
-
- priv->rates_mask = IWL_RATES_MASK;
- /* If power management is turned on, default to AC mode */
- priv->power_mode = IWL_POWER_AC;
- priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
- err = iwl3945_init_channel_map(priv);
+ err = iwl3945_init_drv(priv);
if (err) {
- IWL_ERROR("initializing regulatory failed: %d\n", err);
- goto out_release_irq;
- }
-
- err = iwl3945_init_geos(priv);
- if (err) {
- IWL_ERROR("initializing geos failed: %d\n", err);
- goto out_free_channel_map;
+ IWL_ERR(priv, "initializing driver failed\n");
+ goto out_free_geos;
}
- printk(KERN_INFO DRV_NAME
- ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+ IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
+ priv->cfg->name);
/***********************************
* 7. Initialize Module Parameters
@@ -7993,7 +6134,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* Initialize module parameter values here */
/* Disable radio (SW RF KILL) via parameter when loading driver */
- if (iwl3945_param_disable) {
+ if (iwl3945_mod_params.disable) {
set_bit(STATUS_RF_KILL_SW, &priv->status);
IWL_DEBUG_INFO("Radio disabled.\n");
}
@@ -8007,56 +6148,61 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
iwl3945_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
+ pci_enable_msi(priv->pci_dev);
+
+ err = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED,
+ DRV_NAME, priv);
+ if (err) {
+ IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
+ goto out_disable_msi;
+ }
+
err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
if (err) {
- IWL_ERROR("failed to create sysfs device attributes\n");
- goto out_free_geos;
+ IWL_ERR(priv, "failed to create sysfs device attributes\n");
+ goto out_release_irq;
}
iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
iwl3945_setup_deferred_work(priv);
iwl3945_setup_rx_handlers(priv);
- /***********************
- * 9. Conclude
- * ********************/
- pci_save_state(pdev);
- pci_disable_device(pdev);
-
/*********************************
- * 10. Setup and Register mac80211
+ * 9. Setup and Register mac80211
* *******************************/
err = ieee80211_register_hw(priv->hw);
if (err) {
- IWL_ERROR("Failed to register network device (error %d)\n", err);
+ IWL_ERR(priv, "Failed to register network device: %d\n", err);
goto out_remove_sysfs;
}
priv->hw->conf.beacon_int = 100;
priv->mac80211_registered = 1;
-
- err = iwl3945_rfkill_init(priv);
+ err = iwl_rfkill_init(priv);
if (err)
- IWL_ERROR("Unable to initialize RFKILL system. "
+ IWL_ERR(priv, "Unable to initialize RFKILL system. "
"Ignoring error: %d\n", err);
+ /* Start monitoring the killswitch */
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ 2 * HZ);
+
return 0;
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
out_free_geos:
- iwl3945_free_geos(priv);
- out_free_channel_map:
- iwl3945_free_channel_map(priv);
-
+ iwlcore_free_geos(priv);
out_release_irq:
+ free_irq(priv->pci_dev->irq, priv);
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
- iwl3945_unset_hw_setting(priv);
-
+ iwl3945_unset_hw_params(priv);
+ out_disable_msi:
+ pci_disable_msi(priv->pci_dev);
out_iounmap:
pci_iounmap(pdev, priv->hw_base);
out_pci_release_regions:
@@ -8072,7 +6218,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
{
- struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
unsigned long flags;
if (!priv)
@@ -8082,7 +6228,12 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
set_bit(STATUS_EXIT_PENDING, &priv->status);
- iwl3945_down(priv);
+ if (priv->mac80211_registered) {
+ ieee80211_unregister_hw(priv->hw);
+ priv->mac80211_registered = 0;
+ } else {
+ iwl3945_down(priv);
+ }
/* make sure we flush any pending irq or
* tasklet for the driver
@@ -8095,19 +6246,18 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- iwl3945_rfkill_unregister(priv);
+ iwl_rfkill_unregister(priv);
+ cancel_delayed_work(&priv->rfkill_poll);
+
iwl3945_dealloc_ucode_pci(priv);
if (priv->rxq.bd)
- iwl3945_rx_queue_free(priv, &priv->rxq);
+ iwl_rx_queue_free(priv, &priv->rxq);
iwl3945_hw_txq_ctx_free(priv);
- iwl3945_unset_hw_setting(priv);
+ iwl3945_unset_hw_params(priv);
iwl3945_clear_stations_table(priv);
- if (priv->mac80211_registered)
- ieee80211_unregister_hw(priv->hw);
-
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
@@ -8117,13 +6267,16 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
+ free_irq(pdev->irq, priv);
+ pci_disable_msi(pdev);
+
pci_iounmap(pdev, priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- iwl3945_free_channel_map(priv);
- iwl3945_free_geos(priv);
+ iwl_free_channel_map(priv);
+ iwlcore_free_geos(priv);
kfree(priv->scan);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
@@ -8135,14 +6288,15 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
if (priv->is_open) {
set_bit(STATUS_IN_SUSPEND, &priv->status);
iwl3945_mac_stop(priv->hw);
priv->is_open = 1;
}
-
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
@@ -8150,9 +6304,11 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int iwl3945_pci_resume(struct pci_dev *pdev)
{
- struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
pci_set_power_state(pdev, PCI_D0);
+ pci_enable_device(pdev);
+ pci_restore_state(pdev);
if (priv->is_open)
iwl3945_mac_start(priv->hw);
@@ -8163,114 +6319,6 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-/*************** RFKILL FUNCTIONS **********/
-#ifdef CONFIG_IWL3945_RFKILL
-/* software rf-kill from user */
-static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
-{
- struct iwl3945_priv *priv = data;
- int err = 0;
-
- if (!priv->rfkill)
- return 0;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return 0;
-
- IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
- mutex_lock(&priv->mutex);
-
- switch (state) {
- case RFKILL_STATE_UNBLOCKED:
- if (iwl3945_is_rfkill_hw(priv)) {
- err = -EBUSY;
- goto out_unlock;
- }
- iwl3945_radio_kill_sw(priv, 0);
- break;
- case RFKILL_STATE_SOFT_BLOCKED:
- iwl3945_radio_kill_sw(priv, 1);
- break;
- default:
- IWL_WARNING("we received unexpected RFKILL state %d\n", state);
- break;
- }
-out_unlock:
- mutex_unlock(&priv->mutex);
-
- return err;
-}
-
-int iwl3945_rfkill_init(struct iwl3945_priv *priv)
-{
- struct device *device = wiphy_dev(priv->hw->wiphy);
- int ret = 0;
-
- BUG_ON(device == NULL);
-
- IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
- priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
- if (!priv->rfkill) {
- IWL_ERROR("Unable to allocate rfkill device.\n");
- ret = -ENOMEM;
- goto error;
- }
-
- priv->rfkill->name = priv->cfg->name;
- priv->rfkill->data = priv;
- priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
- priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
- priv->rfkill->user_claim_unsupported = 1;
-
- priv->rfkill->dev.class->suspend = NULL;
- priv->rfkill->dev.class->resume = NULL;
-
- ret = rfkill_register(priv->rfkill);
- if (ret) {
- IWL_ERROR("Unable to register rfkill: %d\n", ret);
- goto freed_rfkill;
- }
-
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
- return ret;
-
-freed_rfkill:
- if (priv->rfkill != NULL)
- rfkill_free(priv->rfkill);
- priv->rfkill = NULL;
-
-error:
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
- return ret;
-}
-
-void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
-{
- if (priv->rfkill)
- rfkill_unregister(priv->rfkill);
-
- priv->rfkill = NULL;
-}
-
-/* set rf-kill to the right state. */
-void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
-{
-
- if (!priv->rfkill)
- return;
-
- if (iwl3945_is_rfkill_hw(priv)) {
- rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
- return;
- }
-
- if (!iwl3945_is_rfkill_sw(priv))
- rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
- else
- rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
-}
-#endif
-
/*****************************************************************************
*
* driver and module entry point
@@ -8297,29 +6345,19 @@ static int __init iwl3945_init(void)
ret = iwl3945_rate_control_register();
if (ret) {
- IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+ printk(KERN_ERR DRV_NAME
+ "Unable to register rate control algorithm: %d\n", ret);
return ret;
}
ret = pci_register_driver(&iwl3945_driver);
if (ret) {
- IWL_ERROR("Unable to initialize PCI module\n");
+ printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
goto error_register;
}
-#ifdef CONFIG_IWL3945_DEBUG
- ret = driver_create_file(&iwl3945_driver.driver, &driver_attr_debug_level);
- if (ret) {
- IWL_ERROR("Unable to create driver sysfs file\n");
- goto error_debug;
- }
-#endif
return ret;
-#ifdef CONFIG_IWL3945_DEBUG
-error_debug:
- pci_unregister_driver(&iwl3945_driver);
-#endif
error_register:
iwl3945_rate_control_unregister();
return ret;
@@ -8327,29 +6365,29 @@ error_register:
static void __exit iwl3945_exit(void)
{
-#ifdef CONFIG_IWL3945_DEBUG
- driver_remove_file(&iwl3945_driver.driver, &driver_attr_debug_level);
-#endif
pci_unregister_driver(&iwl3945_driver);
iwl3945_rate_control_unregister();
}
MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
-module_param_named(antenna, iwl3945_param_antenna, int, 0444);
+module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl3945_param_disable, int, 0444);
+module_param_named(disable, iwl3945_mod_params.disable, int, 0444);
MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
-module_param_named(hwcrypto, iwl3945_param_hwcrypto, int, 0444);
-MODULE_PARM_DESC(hwcrypto,
- "using hardware crypto engine (default 0 [software])\n");
-module_param_named(debug, iwl3945_param_debug, uint, 0444);
+module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
+MODULE_PARM_DESC(swcrypto,
+ "using software crypto (default 1 [software])\n");
+module_param_named(debug, iwl3945_mod_params.debug, uint, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
-module_param_named(disable_hw_scan, iwl3945_param_disable_hw_scan, int, 0444);
+module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444);
MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
-module_param_named(queues_num, iwl3945_param_queues_num, int, 0444);
+module_param_named(queues_num, iwl3945_mod_params.num_of_queues, int, 0444);
MODULE_PARM_DESC(queues_num, "number of hw queues.");
+module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
+MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
+
module_exit(iwl3945_exit);
module_init(iwl3945_init);