summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig39
-rw-r--r--drivers/net/wireless/wl12xx/Makefile12
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.h432
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.c1048
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.h1413
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.c559
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.h41
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.c496
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.h417
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_debugfs.c543
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_debugfs.h33
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_event.c143
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_event.h121
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.c425
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_init.h88
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_io.c196
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_io.h84
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c1442
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ps.c196
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ps.h37
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_reg.h657
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.c192
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.h124
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_sdio.c342
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.c348
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_spi.h61
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_tx.c562
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_tx.h233
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h32
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c36
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h31
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c67
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.h1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c143
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h73
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h78
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c6
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c15
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c39
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.h9
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c416
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c20
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c67
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.c83
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_scan.h6
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c98
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c151
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_testmode.c14
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c109
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h17
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx_platform_data.c28
52 files changed, 946 insertions, 10879 deletions
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 2f98058be451..b447559f1db5 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -5,40 +5,6 @@ menuconfig WL12XX
This will enable TI wl12xx driver support. The drivers make
use of the mac80211 stack.
-config WL1251
- tristate "TI wl1251 support"
- depends on WL12XX && GENERIC_HARDIRQS
- select FW_LOADER
- select CRC7
- ---help---
- This module adds support for wireless adapters based on
- TI wl1251 chipset.
-
- If you choose to build a module, it'll be called wl1251. Say
- N if unsure.
-
-config WL1251_SPI
- tristate "TI wl1251 SPI support"
- depends on WL1251 && SPI_MASTER
- ---help---
- This module adds support for the SPI interface of adapters using
- TI wl1251 chipset. Select this if your platform is using
- the SPI bus.
-
- If you choose to build a module, it'll be called wl1251_spi.
- Say N if unsure.
-
-config WL1251_SDIO
- tristate "TI wl1251 SDIO support"
- depends on WL1251 && MMC
- ---help---
- This module adds support for the SDIO interface of adapters using
- TI wl1251 chipset. Select this if your platform is using
- the SDIO bus.
-
- If you choose to build a module, it'll be called
- wl1251_sdio. Say N if unsure.
-
config WL1271
tristate "TI wl1271 support"
depends on WL12XX && GENERIC_HARDIRQS
@@ -74,4 +40,7 @@ config WL1271_SDIO
If you choose to build a module, it'll be called
wl1271_sdio. Say N if unsure.
-
+config WL12XX_PLATFORM_DATA
+ bool
+ depends on WL1271_SDIO != n
+ default y
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index 078b4398ac1f..3a807444b2af 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -1,12 +1,3 @@
-wl1251-objs = wl1251_main.o wl1251_event.o \
- wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \
- wl1251_acx.o wl1251_boot.o wl1251_init.o \
- wl1251_debugfs.o wl1251_io.o
-
-obj-$(CONFIG_WL1251) += wl1251.o
-obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o
-obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o
-
wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \
wl1271_event.o wl1271_tx.o wl1271_rx.o \
wl1271_ps.o wl1271_acx.o wl1271_boot.o \
@@ -16,3 +7,6 @@ wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o
obj-$(CONFIG_WL1271) += wl1271.o
obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o
obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o
+
+# small builtin driver bit
+obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
deleted file mode 100644
index 6b942a28e6a5..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_H__
-#define __WL1251_H__
-
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <linux/bitops.h>
-#include <net/mac80211.h>
-
-#define DRIVER_NAME "wl1251"
-#define DRIVER_PREFIX DRIVER_NAME ": "
-
-enum {
- DEBUG_NONE = 0,
- DEBUG_IRQ = BIT(0),
- DEBUG_SPI = BIT(1),
- DEBUG_BOOT = BIT(2),
- DEBUG_MAILBOX = BIT(3),
- DEBUG_NETLINK = BIT(4),
- DEBUG_EVENT = BIT(5),
- DEBUG_TX = BIT(6),
- DEBUG_RX = BIT(7),
- DEBUG_SCAN = BIT(8),
- DEBUG_CRYPT = BIT(9),
- DEBUG_PSM = BIT(10),
- DEBUG_MAC80211 = BIT(11),
- DEBUG_CMD = BIT(12),
- DEBUG_ACX = BIT(13),
- DEBUG_ALL = ~0,
-};
-
-#define DEBUG_LEVEL (DEBUG_NONE)
-
-#define DEBUG_DUMP_LIMIT 1024
-
-#define wl1251_error(fmt, arg...) \
- printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
-
-#define wl1251_warning(fmt, arg...) \
- printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
-
-#define wl1251_notice(fmt, arg...) \
- printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
-
-#define wl1251_info(fmt, arg...) \
- printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
-
-#define wl1251_debug(level, fmt, arg...) \
- do { \
- if (level & DEBUG_LEVEL) \
- printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
- } while (0)
-
-#define wl1251_dump(level, prefix, buf, len) \
- do { \
- if (level & DEBUG_LEVEL) \
- print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
- DUMP_PREFIX_OFFSET, 16, 1, \
- buf, \
- min_t(size_t, len, DEBUG_DUMP_LIMIT), \
- 0); \
- } while (0)
-
-#define wl1251_dump_ascii(level, prefix, buf, len) \
- do { \
- if (level & DEBUG_LEVEL) \
- print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
- DUMP_PREFIX_OFFSET, 16, 1, \
- buf, \
- min_t(size_t, len, DEBUG_DUMP_LIMIT), \
- true); \
- } while (0)
-
-#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \
- CFG_BSSID_FILTER_EN)
-
-#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN | \
- CFG_RX_MGMT_EN | \
- CFG_RX_DATA_EN | \
- CFG_RX_CTL_EN | \
- CFG_RX_BCN_EN | \
- CFG_RX_AUTH_EN | \
- CFG_RX_ASSOC_EN)
-
-#define WL1251_BUSY_WORD_LEN 8
-
-struct boot_attr {
- u32 radio_type;
- u8 mac_clock;
- u8 arm_clock;
- int firmware_debug;
- u32 minor;
- u32 major;
- u32 bugfix;
-};
-
-enum wl1251_state {
- WL1251_STATE_OFF,
- WL1251_STATE_ON,
- WL1251_STATE_PLT,
-};
-
-enum wl1251_partition_type {
- PART_DOWN,
- PART_WORK,
- PART_DRPW,
-
- PART_TABLE_LEN
-};
-
-struct wl1251_partition {
- u32 size;
- u32 start;
-};
-
-struct wl1251_partition_set {
- struct wl1251_partition mem;
- struct wl1251_partition reg;
-};
-
-struct wl1251;
-
-struct wl1251_stats {
- struct acx_statistics *fw_stats;
- unsigned long fw_stats_update;
-
- unsigned int retry_count;
- unsigned int excessive_retries;
-};
-
-struct wl1251_debugfs {
- struct dentry *rootdir;
- struct dentry *fw_statistics;
-
- struct dentry *tx_internal_desc_overflow;
-
- struct dentry *rx_out_of_mem;
- struct dentry *rx_hdr_overflow;
- struct dentry *rx_hw_stuck;
- struct dentry *rx_dropped;
- struct dentry *rx_fcs_err;
- struct dentry *rx_xfr_hint_trig;
- struct dentry *rx_path_reset;
- struct dentry *rx_reset_counter;
-
- struct dentry *dma_rx_requested;
- struct dentry *dma_rx_errors;
- struct dentry *dma_tx_requested;
- struct dentry *dma_tx_errors;
-
- struct dentry *isr_cmd_cmplt;
- struct dentry *isr_fiqs;
- struct dentry *isr_rx_headers;
- struct dentry *isr_rx_mem_overflow;
- struct dentry *isr_rx_rdys;
- struct dentry *isr_irqs;
- struct dentry *isr_tx_procs;
- struct dentry *isr_decrypt_done;
- struct dentry *isr_dma0_done;
- struct dentry *isr_dma1_done;
- struct dentry *isr_tx_exch_complete;
- struct dentry *isr_commands;
- struct dentry *isr_rx_procs;
- struct dentry *isr_hw_pm_mode_changes;
- struct dentry *isr_host_acknowledges;
- struct dentry *isr_pci_pm;
- struct dentry *isr_wakeups;
- struct dentry *isr_low_rssi;
-
- struct dentry *wep_addr_key_count;
- struct dentry *wep_default_key_count;
- /* skipping wep.reserved */
- struct dentry *wep_key_not_found;
- struct dentry *wep_decrypt_fail;
- struct dentry *wep_packets;
- struct dentry *wep_interrupt;
-
- struct dentry *pwr_ps_enter;
- struct dentry *pwr_elp_enter;
- struct dentry *pwr_missing_bcns;
- struct dentry *pwr_wake_on_host;
- struct dentry *pwr_wake_on_timer_exp;
- struct dentry *pwr_tx_with_ps;
- struct dentry *pwr_tx_without_ps;
- struct dentry *pwr_rcvd_beacons;
- struct dentry *pwr_power_save_off;
- struct dentry *pwr_enable_ps;
- struct dentry *pwr_disable_ps;
- struct dentry *pwr_fix_tsf_ps;
- /* skipping cont_miss_bcns_spread for now */
- struct dentry *pwr_rcvd_awake_beacons;
-
- struct dentry *mic_rx_pkts;
- struct dentry *mic_calc_failure;
-
- struct dentry *aes_encrypt_fail;
- struct dentry *aes_decrypt_fail;
- struct dentry *aes_encrypt_packets;
- struct dentry *aes_decrypt_packets;
- struct dentry *aes_encrypt_interrupt;
- struct dentry *aes_decrypt_interrupt;
-
- struct dentry *event_heart_beat;
- struct dentry *event_calibration;
- struct dentry *event_rx_mismatch;
- struct dentry *event_rx_mem_empty;
- struct dentry *event_rx_pool;
- struct dentry *event_oom_late;
- struct dentry *event_phy_transmit_error;
- struct dentry *event_tx_stuck;
-
- struct dentry *ps_pspoll_timeouts;
- struct dentry *ps_upsd_timeouts;
- struct dentry *ps_upsd_max_sptime;
- struct dentry *ps_upsd_max_apturn;
- struct dentry *ps_pspoll_max_apturn;
- struct dentry *ps_pspoll_utilization;
- struct dentry *ps_upsd_utilization;
-
- struct dentry *rxpipe_rx_prep_beacon_drop;
- struct dentry *rxpipe_descr_host_int_trig_rx_data;
- struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
- struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
- struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
-
- struct dentry *tx_queue_len;
- struct dentry *tx_queue_status;
-
- struct dentry *retry_count;
- struct dentry *excessive_retries;
-};
-
-struct wl1251_if_operations {
- void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len);
- void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
- void (*read_elp)(struct wl1251 *wl, int addr, u32 *val);
- void (*write_elp)(struct wl1251 *wl, int addr, u32 val);
- void (*reset)(struct wl1251 *wl);
- void (*enable_irq)(struct wl1251 *wl);
- void (*disable_irq)(struct wl1251 *wl);
-};
-
-struct wl1251 {
- struct ieee80211_hw *hw;
- bool mac80211_registered;
-
- void *if_priv;
- const struct wl1251_if_operations *if_ops;
-
- void (*set_power)(bool enable);
- int irq;
- bool use_eeprom;
-
- enum wl1251_state state;
- struct mutex mutex;
-
- int physical_mem_addr;
- int physical_reg_addr;
- int virtual_mem_addr;
- int virtual_reg_addr;
-
- int cmd_box_addr;
- int event_box_addr;
- struct boot_attr boot_attr;
-
- u8 *fw;
- size_t fw_len;
- u8 *nvs;
- size_t nvs_len;
-
- u8 bssid[ETH_ALEN];
- u8 mac_addr[ETH_ALEN];
- u8 bss_type;
- u8 listen_int;
- int channel;
-
- void *target_mem_map;
- struct acx_data_path_params_resp *data_path;
-
- /* Number of TX packets transferred to the FW, modulo 16 */
- u32 data_in_count;
-
- /* Frames scheduled for transmission, not handled yet */
- struct sk_buff_head tx_queue;
- bool tx_queue_stopped;
-
- struct work_struct tx_work;
- struct work_struct filter_work;
-
- /* Pending TX frames */
- struct sk_buff *tx_frames[16];
-
- /*
- * Index pointing to the next TX complete entry
- * in the cyclic XT complete array we get from
- * the FW.
- */
- u32 next_tx_complete;
-
- /* FW Rx counter */
- u32 rx_counter;
-
- /* Rx frames handled */
- u32 rx_handled;
-
- /* Current double buffer */
- u32 rx_current_buffer;
- u32 rx_last_id;
-
- /* The target interrupt mask */
- u32 intr_mask;
- struct work_struct irq_work;
-
- /* The mbox event mask */
- u32 event_mask;
-
- /* Mailbox pointers */
- u32 mbox_ptr[2];
-
- /* Are we currently scanning */
- bool scanning;
-
- /* Default key (for WEP) */
- u32 default_key;
-
- unsigned int tx_mgmt_frm_rate;
- unsigned int tx_mgmt_frm_mod;
-
- unsigned int rx_config;
- unsigned int rx_filter;
-
- /* is firmware in elp mode */
- bool elp;
-
- struct delayed_work elp_work;
-
- /* we can be in psm, but not in elp, we have to differentiate */
- bool psm;
-
- /* PSM mode requested */
- bool psm_requested;
-
- u16 beacon_int;
- u8 dtim_period;
-
- /* in dBm */
- int power_level;
-
- struct wl1251_stats stats;
- struct wl1251_debugfs debugfs;
-
- u32 buffer_32;
- u32 buffer_cmd;
- u8 buffer_busyword[WL1251_BUSY_WORD_LEN];
- struct wl1251_rx_descriptor *rx_descriptor;
-
- struct ieee80211_vif *vif;
-
- u32 chip_id;
- char fw_ver[21];
-
- /* Most recently reported noise in dBm */
- s8 noise;
-};
-
-int wl1251_plt_start(struct wl1251 *wl);
-int wl1251_plt_stop(struct wl1251 *wl);
-
-struct ieee80211_hw *wl1251_alloc_hw(void);
-int wl1251_free_hw(struct wl1251 *wl);
-int wl1251_init_ieee80211(struct wl1251 *wl);
-void wl1251_enable_interrupts(struct wl1251 *wl);
-void wl1251_disable_interrupts(struct wl1251 *wl);
-
-#define DEFAULT_HW_GEN_MODULATION_TYPE CCK_LONG /* Long Preamble */
-#define DEFAULT_HW_GEN_TX_RATE RATE_2MBPS
-#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
-
-#define WL1251_DEFAULT_POWER_LEVEL 20
-
-#define WL1251_TX_QUEUE_MAX_LENGTH 20
-
-#define WL1251_DEFAULT_BEACON_INT 100
-#define WL1251_DEFAULT_DTIM_PERIOD 1
-
-#define WL1251_DEFAULT_CHANNEL 0
-
-#define CHIP_ID_1251_PG10 (0x7010101)
-#define CHIP_ID_1251_PG11 (0x7020101)
-#define CHIP_ID_1251_PG12 (0x7030101)
-#define CHIP_ID_1271_PG10 (0x4030101)
-#define CHIP_ID_1271_PG20 (0x4030111)
-
-#define WL1251_FW_NAME "wl1251-fw.bin"
-#define WL1251_NVS_NAME "wl1251-nvs.bin"
-
-#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
-
-#define WL1251_PART_DOWN_MEM_START 0x0
-#define WL1251_PART_DOWN_MEM_SIZE 0x16800
-#define WL1251_PART_DOWN_REG_START REGISTERS_BASE
-#define WL1251_PART_DOWN_REG_SIZE REGISTERS_DOWN_SIZE
-
-#define WL1251_PART_WORK_MEM_START 0x28000
-#define WL1251_PART_WORK_MEM_SIZE 0x14000
-#define WL1251_PART_WORK_REG_START REGISTERS_BASE
-#define WL1251_PART_WORK_REG_SIZE REGISTERS_WORK_SIZE
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
deleted file mode 100644
index 91891f928070..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ /dev/null
@@ -1,1048 +0,0 @@
-#include "wl1251_acx.h"
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/crc7.h>
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_cmd.h"
-#include "wl1251_ps.h"
-
-int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
- u8 mgt_rate, u8 mgt_mod)
-{
- struct acx_fw_gen_frame_rates *rates;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx frame rates");
-
- rates = kzalloc(sizeof(*rates), GFP_KERNEL);
- if (!rates) {
- ret = -ENOMEM;
- goto out;
- }
-
- rates->tx_ctrl_frame_rate = ctrl_rate;
- rates->tx_ctrl_frame_mod = ctrl_mod;
- rates->tx_mgt_frame_rate = mgt_rate;
- rates->tx_mgt_frame_mod = mgt_mod;
-
- ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
- rates, sizeof(*rates));
- if (ret < 0) {
- wl1251_error("Failed to set FW rates and modulation");
- goto out;
- }
-
-out:
- kfree(rates);
- return ret;
-}
-
-
-int wl1251_acx_station_id(struct wl1251 *wl)
-{
- struct acx_dot11_station_id *mac;
- int ret, i;
-
- wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
-
- mac = kzalloc(sizeof(*mac), GFP_KERNEL);
- if (!mac) {
- ret = -ENOMEM;
- goto out;
- }
-
- for (i = 0; i < ETH_ALEN; i++)
- mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
-
- ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
- if (ret < 0)
- goto out;
-
-out:
- kfree(mac);
- return ret;
-}
-
-int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
-{
- struct acx_dot11_default_key *default_key;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
-
- default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
- if (!default_key) {
- ret = -ENOMEM;
- goto out;
- }
-
- default_key->id = key_id;
-
- ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
- default_key, sizeof(*default_key));
- if (ret < 0) {
- wl1251_error("Couldn't set default key");
- goto out;
- }
-
- wl->default_key = key_id;
-
-out:
- kfree(default_key);
- return ret;
-}
-
-int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
- u8 listen_interval)
-{
- struct acx_wake_up_condition *wake_up;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx wake up conditions");
-
- wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
- if (!wake_up) {
- ret = -ENOMEM;
- goto out;
- }
-
- wake_up->wake_up_event = wake_up_event;
- wake_up->listen_interval = listen_interval;
-
- ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
- wake_up, sizeof(*wake_up));
- if (ret < 0) {
- wl1251_warning("could not set wake up conditions: %d", ret);
- goto out;
- }
-
-out:
- kfree(wake_up);
- return ret;
-}
-
-int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
-{
- struct acx_sleep_auth *auth;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx sleep auth");
-
- auth = kzalloc(sizeof(*auth), GFP_KERNEL);
- if (!auth) {
- ret = -ENOMEM;
- goto out;
- }
-
- auth->sleep_auth = sleep_auth;
-
- ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
- if (ret < 0)
- return ret;
-
-out:
- kfree(auth);
- return ret;
-}
-
-int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
-{
- struct acx_revision *rev;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx fw rev");
-
- rev = kzalloc(sizeof(*rev), GFP_KERNEL);
- if (!rev) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
- if (ret < 0) {
- wl1251_warning("ACX_FW_REV interrogate failed");
- goto out;
- }
-
- /* be careful with the buffer sizes */
- strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
-
- /*
- * if the firmware version string is exactly
- * sizeof(rev->fw_version) long or fw_len is less than
- * sizeof(rev->fw_version) it won't be null terminated
- */
- buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
-
-out:
- kfree(rev);
- return ret;
-}
-
-int wl1251_acx_tx_power(struct wl1251 *wl, int power)
-{
- struct acx_current_tx_power *acx;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
-
- if (power < 0 || power > 25)
- return -EINVAL;
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->current_tx_power = power * 10;
-
- ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("configure of tx power failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_feature_cfg(struct wl1251 *wl)
-{
- struct acx_feature_config *feature;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx feature cfg");
-
- feature = kzalloc(sizeof(*feature), GFP_KERNEL);
- if (!feature) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
- feature->data_flow_options = 0;
- feature->options = 0;
-
- ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
- feature, sizeof(*feature));
- if (ret < 0) {
- wl1251_error("Couldn't set HW encryption");
- goto out;
- }
-
-out:
- kfree(feature);
- return ret;
-}
-
-int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
- size_t len)
-{
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx mem map");
-
- ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1251_acx_data_path_params(struct wl1251 *wl,
- struct acx_data_path_params_resp *resp)
-{
- struct acx_data_path_params *params;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx data path params");
-
- params = kzalloc(sizeof(*params), GFP_KERNEL);
- if (!params) {
- ret = -ENOMEM;
- goto out;
- }
-
- params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
- params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
-
- params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
- params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
-
- params->tx_complete_threshold = 1;
-
- params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
-
- params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
-
- ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
- params, sizeof(*params));
- if (ret < 0)
- goto out;
-
- /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
- ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
- resp, sizeof(*resp));
-
- if (ret < 0) {
- wl1251_warning("failed to read data path parameters: %d", ret);
- goto out;
- } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
- wl1251_warning("data path parameter acx status failed");
- ret = -EIO;
- goto out;
- }
-
-out:
- kfree(params);
- return ret;
-}
-
-int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
-{
- struct acx_rx_msdu_lifetime *acx;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->lifetime = life_time;
- ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("failed to set rx msdu life time: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
-{
- struct acx_rx_config *rx_config;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx rx config");
-
- rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
- if (!rx_config) {
- ret = -ENOMEM;
- goto out;
- }
-
- rx_config->config_options = config;
- rx_config->filter_options = filter;
-
- ret = wl1251_cmd_configure(wl, ACX_RX_CFG,
- rx_config, sizeof(*rx_config));
- if (ret < 0) {
- wl1251_warning("failed to set rx config: %d", ret);
- goto out;
- }
-
-out:
- kfree(rx_config);
- return ret;
-}
-
-int wl1251_acx_pd_threshold(struct wl1251 *wl)
-{
- struct acx_packet_detection *pd;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx data pd threshold");
-
- pd = kzalloc(sizeof(*pd), GFP_KERNEL);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* FIXME: threshold value not set */
-
- ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
- if (ret < 0) {
- wl1251_warning("failed to set pd threshold: %d", ret);
- goto out;
- }
-
-out:
- kfree(pd);
- return 0;
-}
-
-int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
-{
- struct acx_slot *slot;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx slot");
-
- slot = kzalloc(sizeof(*slot), GFP_KERNEL);
- if (!slot) {
- ret = -ENOMEM;
- goto out;
- }
-
- slot->wone_index = STATION_WONE_INDEX;
- slot->slot_time = slot_time;
-
- ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
- if (ret < 0) {
- wl1251_warning("failed to set slot time: %d", ret);
- goto out;
- }
-
-out:
- kfree(slot);
- return ret;
-}
-
-int wl1251_acx_group_address_tbl(struct wl1251 *wl)
-{
- struct acx_dot11_grp_addr_tbl *acx;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx group address tbl");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* MAC filtering */
- acx->enabled = 0;
- acx->num_groups = 0;
- memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
-
- ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("failed to set group addr table: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_service_period_timeout(struct wl1251 *wl)
-{
- struct acx_rx_timeout *rx_timeout;
- int ret;
-
- rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
- if (!rx_timeout) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1251_debug(DEBUG_ACX, "acx service period timeout");
-
- rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
- rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
-
- ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
- rx_timeout, sizeof(*rx_timeout));
- if (ret < 0) {
- wl1251_warning("failed to set service period timeout: %d",
- ret);
- goto out;
- }
-
-out:
- kfree(rx_timeout);
- return ret;
-}
-
-int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
-{
- struct acx_rts_threshold *rts;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx rts threshold");
-
- rts = kzalloc(sizeof(*rts), GFP_KERNEL);
- if (!rts) {
- ret = -ENOMEM;
- goto out;
- }
-
- rts->threshold = rts_threshold;
-
- ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
- if (ret < 0) {
- wl1251_warning("failed to set rts threshold: %d", ret);
- goto out;
- }
-
-out:
- kfree(rts);
- return ret;
-}
-
-int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
-{
- struct acx_beacon_filter_option *beacon_filter;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
-
- beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
- if (!beacon_filter) {
- ret = -ENOMEM;
- goto out;
- }
-
- beacon_filter->enable = enable_filter;
- beacon_filter->max_num_beacons = 0;
-
- ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
- beacon_filter, sizeof(*beacon_filter));
- if (ret < 0) {
- wl1251_warning("failed to set beacon filter opt: %d", ret);
- goto out;
- }
-
-out:
- kfree(beacon_filter);
- return ret;
-}
-
-int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
-{
- struct acx_beacon_filter_ie_table *ie_table;
- int idx = 0;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx beacon filter table");
-
- ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
- if (!ie_table) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* configure default beacon pass-through rules */
- ie_table->num_ie = 1;
- ie_table->table[idx++] = BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN;
- ie_table->table[idx++] = BEACON_RULE_PASS_ON_APPEARANCE;
-
- ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
- ie_table, sizeof(*ie_table));
- if (ret < 0) {
- wl1251_warning("failed to set beacon filter table: %d", ret);
- goto out;
- }
-
-out:
- kfree(ie_table);
- return ret;
-}
-
-int wl1251_acx_conn_monit_params(struct wl1251 *wl)
-{
- struct acx_conn_monit_params *acx;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
- acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
-
- ret = wl1251_cmd_configure(wl, ACX_CONN_MONIT_PARAMS,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("failed to set connection monitor "
- "parameters: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_sg_enable(struct wl1251 *wl)
-{
- struct acx_bt_wlan_coex *pta;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx sg enable");
-
- pta = kzalloc(sizeof(*pta), GFP_KERNEL);
- if (!pta) {
- ret = -ENOMEM;
- goto out;
- }
-
- pta->enable = SG_ENABLE;
-
- ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
- if (ret < 0) {
- wl1251_warning("failed to set softgemini enable: %d", ret);
- goto out;
- }
-
-out:
- kfree(pta);
- return ret;
-}
-
-int wl1251_acx_sg_cfg(struct wl1251 *wl)
-{
- struct acx_bt_wlan_coex_param *param;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx sg cfg");
-
- param = kzalloc(sizeof(*param), GFP_KERNEL);
- if (!param) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* BT-WLAN coext parameters */
- param->min_rate = RATE_INDEX_24MBPS;
- param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
- param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
- param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
- param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
- param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
- param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
- param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
- param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
- param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
- param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
- param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
- param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
- param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
- param->antenna_type = PTA_ANTENNA_TYPE_DEF;
- param->signal_type = PTA_SIGNALING_TYPE_DEF;
- param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
- param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
- param->max_cts = PTA_MAX_NUM_CTS_DEF;
- param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
- param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
- param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
- param->wlan_elp_hp = PTA_ELP_HP_DEF;
- param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
- param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
- param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
- param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
- param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
-
- ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
- if (ret < 0) {
- wl1251_warning("failed to set sg config: %d", ret);
- goto out;
- }
-
-out:
- kfree(param);
- return ret;
-}
-
-int wl1251_acx_cca_threshold(struct wl1251 *wl)
-{
- struct acx_energy_detection *detection;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx cca threshold");
-
- detection = kzalloc(sizeof(*detection), GFP_KERNEL);
- if (!detection) {
- ret = -ENOMEM;
- goto out;
- }
-
- detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
- detection->tx_energy_detection = 0;
-
- ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
- detection, sizeof(*detection));
- if (ret < 0) {
- wl1251_warning("failed to set cca threshold: %d", ret);
- return ret;
- }
-
-out:
- kfree(detection);
- return ret;
-}
-
-int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
-{
- struct acx_beacon_broadcast *bb;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
-
- bb = kzalloc(sizeof(*bb), GFP_KERNEL);
- if (!bb) {
- ret = -ENOMEM;
- goto out;
- }
-
- bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
- bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
- bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
- bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
-
- ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
- if (ret < 0) {
- wl1251_warning("failed to set rx config: %d", ret);
- goto out;
- }
-
-out:
- kfree(bb);
- return ret;
-}
-
-int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
-{
- struct acx_aid *acx_aid;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx aid");
-
- acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
- if (!acx_aid) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx_aid->aid = aid;
-
- ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
- if (ret < 0) {
- wl1251_warning("failed to set aid: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx_aid);
- return ret;
-}
-
-int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
-{
- struct acx_event_mask *mask;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx event mbox mask");
-
- mask = kzalloc(sizeof(*mask), GFP_KERNEL);
- if (!mask) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* high event mask is unused */
- mask->high_event_mask = 0xffffffff;
-
- mask->event_mask = event_mask;
-
- ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
- mask, sizeof(*mask));
- if (ret < 0) {
- wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
- goto out;
- }
-
-out:
- kfree(mask);
- return ret;
-}
-
-int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
-{
- struct acx_preamble *acx;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx_set_preamble");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->preamble = preamble;
-
- ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("Setting of preamble failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_cts_protect(struct wl1251 *wl,
- enum acx_ctsprotect_type ctsprotect)
-{
- struct acx_ctsprotect *acx;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->ctsprotect = ctsprotect;
-
- ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("Setting of ctsprotect failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
-{
- struct acx_tsf_info *tsf_info;
- int ret;
-
- tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
- if (!tsf_info) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
- tsf_info, sizeof(*tsf_info));
- if (ret < 0) {
- wl1251_warning("ACX_FW_REV interrogate failed");
- goto out;
- }
-
- *mactime = tsf_info->current_tsf_lsb |
- (tsf_info->current_tsf_msb << 31);
-
-out:
- kfree(tsf_info);
- return ret;
-}
-
-int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
-{
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx statistics");
-
- ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
- sizeof(*stats));
- if (ret < 0) {
- wl1251_warning("acx statistics failed: %d", ret);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-int wl1251_acx_rate_policies(struct wl1251 *wl)
-{
- struct acx_rate_policy *acx;
- int ret = 0;
-
- wl1251_debug(DEBUG_ACX, "acx rate policies");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* configure one default (one-size-fits-all) rate class */
- acx->rate_class_cnt = 1;
- acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
- acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
- acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
- acx->rate_class[0].aflags = 0;
-
- ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("Setting of rate policies failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_mem_cfg(struct wl1251 *wl)
-{
- struct wl1251_acx_config_memory *mem_conf;
- int ret, i;
-
- wl1251_debug(DEBUG_ACX, "acx mem cfg");
-
- mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
- if (!mem_conf) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* memory config */
- mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
- mem_conf->mem_config.rx_mem_block_num = 35;
- mem_conf->mem_config.tx_min_mem_block_num = 64;
- mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
- mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
- mem_conf->mem_config.num_ssid_profiles = 1;
- mem_conf->mem_config.debug_buffer_size =
- cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
-
- /* RX queue config */
- mem_conf->rx_queue_config.dma_address = 0;
- mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
- mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
- mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;
-
- /* TX queue config */
- for (i = 0; i < MAX_TX_QUEUES; i++) {
- mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
- mem_conf->tx_queue_config[i].attributes = i;
- }
-
- ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
- sizeof(*mem_conf));
- if (ret < 0) {
- wl1251_warning("wl1251 mem config failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(mem_conf);
- return ret;
-}
-
-int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
-{
- struct wl1251_acx_wr_tbtt_and_dtim *acx;
- int ret;
-
- wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->tbtt = tbtt;
- acx->dtim = dtim;
-
- ret = wl1251_cmd_configure(wl, ACX_WR_TBTT_AND_DTIM,
- acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("failed to set tbtt and dtim: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
- u8 aifs, u16 txop)
-{
- struct wl1251_acx_ac_cfg *acx;
- int ret = 0;
-
- wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
- "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->ac = ac;
- acx->cw_min = cw_min;
- acx->cw_max = cw_max;
- acx->aifsn = aifs;
- acx->txop_limit = txop;
-
- ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("acx ac cfg failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
-
-int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
- enum wl1251_acx_channel_type type,
- u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
- enum wl1251_acx_ack_policy ack_policy)
-{
- struct wl1251_acx_tid_cfg *acx;
- int ret = 0;
-
- wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
- "ps_scheme %d ack_policy %d", queue, type, tsid,
- ps_scheme, ack_policy);
-
- acx = kzalloc(sizeof(*acx), GFP_KERNEL);
-
- if (!acx) {
- ret = -ENOMEM;
- goto out;
- }
-
- acx->queue = queue;
- acx->type = type;
- acx->tsid = tsid;
- acx->ps_scheme = ps_scheme;
- acx->ack_policy = ack_policy;
-
- ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_warning("acx tid cfg failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(acx);
- return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h
deleted file mode 100644
index 842df310d92a..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ /dev/null
@@ -1,1413 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_ACX_H__
-#define __WL1251_ACX_H__
-
-#include "wl1251.h"
-#include "wl1251_cmd.h"
-
-/* Target's information element */
-struct acx_header {
- struct wl1251_cmd_header cmd;
-
- /* acx (or information element) header */
- u16 id;
-
- /* payload length (not including headers */
- u16 len;
-};
-
-struct acx_error_counter {
- struct acx_header header;
-
- /* The number of PLCP errors since the last time this */
- /* information element was interrogated. This field is */
- /* automatically cleared when it is interrogated.*/
- u32 PLCP_error;
-
- /* The number of FCS errors since the last time this */
- /* information element was interrogated. This field is */
- /* automatically cleared when it is interrogated.*/
- u32 FCS_error;
-
- /* The number of MPDUs without PLCP header errors received*/
- /* since the last time this information element was interrogated. */
- /* This field is automatically cleared when it is interrogated.*/
- u32 valid_frame;
-
- /* the number of missed sequence numbers in the squentially */
- /* values of frames seq numbers */
- u32 seq_num_miss;
-} __packed;
-
-struct acx_revision {
- struct acx_header header;
-
- /*
- * The WiLink firmware version, an ASCII string x.x.x.x,
- * that uniquely identifies the current firmware.
- * The left most digit is incremented each time a
- * significant change is made to the firmware, such as
- * code redesign or new platform support.
- * The second digit is incremented when major enhancements
- * are added or major fixes are made.
- * The third digit is incremented for each GA release.
- * The fourth digit is incremented for each build.
- * The first two digits identify a firmware release version,
- * in other words, a unique set of features.
- * The first three digits identify a GA release.
- */
- char fw_version[20];
-
- /*
- * This 4 byte field specifies the WiLink hardware version.
- * bits 0 - 15: Reserved.
- * bits 16 - 23: Version ID - The WiLink version ID
- * (1 = first spin, 2 = second spin, and so on).
- * bits 24 - 31: Chip ID - The WiLink chip ID.
- */
- u32 hw_version;
-} __packed;
-
-enum wl1251_psm_mode {
- /* Active mode */
- WL1251_PSM_CAM = 0,
-
- /* Power save mode */
- WL1251_PSM_PS = 1,
-
- /* Extreme low power */
- WL1251_PSM_ELP = 2,
-};
-
-struct acx_sleep_auth {
- struct acx_header header;
-
- /* The sleep level authorization of the device. */
- /* 0 - Always active*/
- /* 1 - Power down mode: light / fast sleep*/
- /* 2 - ELP mode: Deep / Max sleep*/
- u8 sleep_auth;
- u8 padding[3];
-} __packed;
-
-enum {
- HOSTIF_PCI_MASTER_HOST_INDIRECT,
- HOSTIF_PCI_MASTER_HOST_DIRECT,
- HOSTIF_SLAVE,
- HOSTIF_PKT_RING,
- HOSTIF_DONTCARE = 0xFF
-};
-
-#define DEFAULT_UCAST_PRIORITY 0
-#define DEFAULT_RX_Q_PRIORITY 0
-#define DEFAULT_NUM_STATIONS 1
-#define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */
-#define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */
-#define TRACE_BUFFER_MAX_SIZE 256
-
-#define DP_RX_PACKET_RING_CHUNK_SIZE 1600
-#define DP_TX_PACKET_RING_CHUNK_SIZE 1600
-#define DP_RX_PACKET_RING_CHUNK_NUM 2
-#define DP_TX_PACKET_RING_CHUNK_NUM 2
-#define DP_TX_COMPLETE_TIME_OUT 20
-#define FW_TX_CMPLT_BLOCK_SIZE 16
-
-struct acx_data_path_params {
- struct acx_header header;
-
- u16 rx_packet_ring_chunk_size;
- u16 tx_packet_ring_chunk_size;
-
- u8 rx_packet_ring_chunk_num;
- u8 tx_packet_ring_chunk_num;
-
- /*
- * Maximum number of packets that can be gathered
- * in the TX complete ring before an interrupt
- * is generated.
- */
- u8 tx_complete_threshold;
-
- /* Number of pending TX complete entries in cyclic ring.*/
- u8 tx_complete_ring_depth;
-
- /*
- * Max num microseconds since a packet enters the TX
- * complete ring until an interrupt is generated.
- */
- u32 tx_complete_timeout;
-} __packed;
-
-
-struct acx_data_path_params_resp {
- struct acx_header header;
-
- u16 rx_packet_ring_chunk_size;
- u16 tx_packet_ring_chunk_size;
-
- u8 rx_packet_ring_chunk_num;
- u8 tx_packet_ring_chunk_num;
-
- u8 pad[2];
-
- u32 rx_packet_ring_addr;
- u32 tx_packet_ring_addr;
-
- u32 rx_control_addr;
- u32 tx_control_addr;
-
- u32 tx_complete_addr;
-} __packed;
-
-#define TX_MSDU_LIFETIME_MIN 0
-#define TX_MSDU_LIFETIME_MAX 3000
-#define TX_MSDU_LIFETIME_DEF 512
-#define RX_MSDU_LIFETIME_MIN 0
-#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF
-#define RX_MSDU_LIFETIME_DEF 512000
-
-struct acx_rx_msdu_lifetime {
- struct acx_header header;
-
- /*
- * The maximum amount of time, in TU, before the
- * firmware discards the MSDU.
- */
- u32 lifetime;
-} __packed;
-
-/*
- * RX Config Options Table
- * Bit Definition
- * === ==========
- * 31:14 Reserved
- * 13 Copy RX Status - when set, write three receive status words
- * to top of rx'd MPDUs.
- * When cleared, do not write three status words (added rev 1.5)
- * 12 Reserved
- * 11 RX Complete upon FCS error - when set, give rx complete
- * interrupt for FCS errors, after the rx filtering, e.g. unicast
- * frames not to us with FCS error will not generate an interrupt.
- * 10 SSID Filter Enable - When set, the WiLink discards all beacon,
- * probe request, and probe response frames with an SSID that does
- * not match the SSID specified by the host in the START/JOIN
- * command.
- * When clear, the WiLink receives frames with any SSID.
- * 9 Broadcast Filter Enable - When set, the WiLink discards all
- * broadcast frames. When clear, the WiLink receives all received
- * broadcast frames.
- * 8:6 Reserved
- * 5 BSSID Filter Enable - When set, the WiLink discards any frames
- * with a BSSID that does not match the BSSID specified by the
- * host.
- * When clear, the WiLink receives frames from any BSSID.
- * 4 MAC Addr Filter - When set, the WiLink discards any frames
- * with a destination address that does not match the MAC address
- * of the adaptor.
- * When clear, the WiLink receives frames destined to any MAC
- * address.
- * 3 Promiscuous - When set, the WiLink receives all valid frames
- * (i.e., all frames that pass the FCS check).
- * When clear, only frames that pass the other filters specified
- * are received.
- * 2 FCS - When set, the WiLink includes the FCS with the received
- * frame.
- * When cleared, the FCS is discarded.
- * 1 PLCP header - When set, write all data from baseband to frame
- * buffer including PHY header.
- * 0 Reserved - Always equal to 0.
- *
- * RX Filter Options Table
- * Bit Definition
- * === ==========
- * 31:12 Reserved - Always equal to 0.
- * 11 Association - When set, the WiLink receives all association
- * related frames (association request/response, reassocation
- * request/response, and disassociation). When clear, these frames
- * are discarded.
- * 10 Auth/De auth - When set, the WiLink receives all authentication
- * and de-authentication frames. When clear, these frames are
- * discarded.
- * 9 Beacon - When set, the WiLink receives all beacon frames.
- * When clear, these frames are discarded.
- * 8 Contention Free - When set, the WiLink receives all contention
- * free frames.
- * When clear, these frames are discarded.
- * 7 Control - When set, the WiLink receives all control frames.
- * When clear, these frames are discarded.
- * 6 Data - When set, the WiLink receives all data frames.
- * When clear, these frames are discarded.
- * 5 FCS Error - When set, the WiLink receives frames that have FCS
- * errors.
- * When clear, these frames are discarded.
- * 4 Management - When set, the WiLink receives all management
- * frames.
- * When clear, these frames are discarded.
- * 3 Probe Request - When set, the WiLink receives all probe request
- * frames.
- * When clear, these frames are discarded.
- * 2 Probe Response - When set, the WiLink receives all probe
- * response frames.
- * When clear, these frames are discarded.
- * 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
- * frames.
- * When clear, these frames are discarded.
- * 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames
- * that have reserved frame types and sub types as defined by the
- * 802.11 specification.
- * When clear, these frames are discarded.
- */
-struct acx_rx_config {
- struct acx_header header;
-
- u32 config_options;
- u32 filter_options;
-} __packed;
-
-enum {
- QOS_AC_BE = 0,
- QOS_AC_BK,
- QOS_AC_VI,
- QOS_AC_VO,
- QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
-};
-
-#define MAX_NUM_OF_AC (QOS_HIGHEST_AC_INDEX+1)
-#define FIRST_AC_INDEX QOS_AC_BE
-#define MAX_NUM_OF_802_1d_TAGS 8
-#define AC_PARAMS_MAX_TSID 15
-#define MAX_APSD_CONF 0xffff
-
-#define QOS_TX_HIGH_MIN (0)
-#define QOS_TX_HIGH_MAX (100)
-
-#define QOS_TX_HIGH_BK_DEF (25)
-#define QOS_TX_HIGH_BE_DEF (35)
-#define QOS_TX_HIGH_VI_DEF (35)
-#define QOS_TX_HIGH_VO_DEF (35)
-
-#define QOS_TX_LOW_BK_DEF (15)
-#define QOS_TX_LOW_BE_DEF (25)
-#define QOS_TX_LOW_VI_DEF (25)
-#define QOS_TX_LOW_VO_DEF (25)
-
-struct acx_tx_queue_qos_config {
- struct acx_header header;
-
- u8 qid;
- u8 pad[3];
-
- /* Max number of blocks allowd in the queue */
- u16 high_threshold;
-
- /* Lowest memory blocks guaranteed for this queue */
- u16 low_threshold;
-} __packed;
-
-struct acx_packet_detection {
- struct acx_header header;
-
- u32 threshold;
-} __packed;
-
-
-enum acx_slot_type {
- SLOT_TIME_LONG = 0,
- SLOT_TIME_SHORT = 1,
- DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
- MAX_SLOT_TIMES = 0xFF
-};
-
-#define STATION_WONE_INDEX 0
-
-struct acx_slot {
- struct acx_header header;
-
- u8 wone_index; /* Reserved */
- u8 slot_time;
- u8 reserved[6];
-} __packed;
-
-
-#define ADDRESS_GROUP_MAX (8)
-#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX)
-
-struct acx_dot11_grp_addr_tbl {
- struct acx_header header;
-
- u8 enabled;
- u8 num_groups;
- u8 pad[2];
- u8 mac_table[ADDRESS_GROUP_MAX_LEN];
-} __packed;
-
-
-#define RX_TIMEOUT_PS_POLL_MIN 0
-#define RX_TIMEOUT_PS_POLL_MAX (200000)
-#define RX_TIMEOUT_PS_POLL_DEF (15)
-#define RX_TIMEOUT_UPSD_MIN 0
-#define RX_TIMEOUT_UPSD_MAX (200000)
-#define RX_TIMEOUT_UPSD_DEF (15)
-
-struct acx_rx_timeout {
- struct acx_header header;
-
- /*
- * The longest time the STA will wait to receive
- * traffic from the AP after a PS-poll has been
- * transmitted.
- */
- u16 ps_poll_timeout;
-
- /*
- * The longest time the STA will wait to receive
- * traffic from the AP after a frame has been sent
- * from an UPSD enabled queue.
- */
- u16 upsd_timeout;
-} __packed;
-
-#define RTS_THRESHOLD_MIN 0
-#define RTS_THRESHOLD_MAX 4096
-#define RTS_THRESHOLD_DEF 2347
-
-struct acx_rts_threshold {
- struct acx_header header;
-
- u16 threshold;
- u8 pad[2];
-} __packed;
-
-struct acx_beacon_filter_option {
- struct acx_header header;
-
- u8 enable;
-
- /*
- * The number of beacons without the unicast TIM
- * bit set that the firmware buffers before
- * signaling the host about ready frames.
- * When set to 0 and the filter is enabled, beacons
- * without the unicast TIM bit set are dropped.
- */
- u8 max_num_beacons;
- u8 pad[2];
-} __packed;
-
-/*
- * ACXBeaconFilterEntry (not 221)
- * Byte Offset Size (Bytes) Definition
- * =========== ============ ==========
- * 0 1 IE identifier
- * 1 1 Treatment bit mask
- *
- * ACXBeaconFilterEntry (221)
- * Byte Offset Size (Bytes) Definition
- * =========== ============ ==========
- * 0 1 IE identifier
- * 1 1 Treatment bit mask
- * 2 3 OUI
- * 5 1 Type
- * 6 2 Version
- *
- *
- * Treatment bit mask - The information element handling:
- * bit 0 - The information element is compared and transferred
- * in case of change.
- * bit 1 - The information element is transferred to the host
- * with each appearance or disappearance.
- * Note that both bits can be set at the same time.
- */
-#define BEACON_FILTER_TABLE_MAX_IE_NUM (32)
-#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
-#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE (2)
-#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
-#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
- BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
- (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
- BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
-
-#define BEACON_RULE_PASS_ON_CHANGE BIT(0)
-#define BEACON_RULE_PASS_ON_APPEARANCE BIT(1)
-
-#define BEACON_FILTER_IE_ID_CHANNEL_SWITCH_ANN (37)
-
-struct acx_beacon_filter_ie_table {
- struct acx_header header;
-
- u8 num_ie;
- u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
- u8 pad[3];
-} __packed;
-
-#define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */
-#define NO_BEACON_DEFAULT_TIMEOUT (500) /* in microseconds */
-
-struct acx_conn_monit_params {
- struct acx_header header;
-
- u32 synch_fail_thold; /* number of beacons missed */
- u32 bss_lose_timeout; /* number of TU's from synch fail */
-};
-
-enum {
- SG_ENABLE = 0,
- SG_DISABLE,
- SG_SENSE_NO_ACTIVITY,
- SG_SENSE_ACTIVE
-};
-
-struct acx_bt_wlan_coex {
- struct acx_header header;
-
- /*
- * 0 -> PTA enabled
- * 1 -> PTA disabled
- * 2 -> sense no active mode, i.e.
- * an interrupt is sent upon
- * BT activity.
- * 3 -> PTA is switched on in response
- * to the interrupt sending.
- */
- u8 enable;
- u8 pad[3];
-} __packed;
-
-#define PTA_ANTENNA_TYPE_DEF (0)
-#define PTA_BT_HP_MAXTIME_DEF (2000)
-#define PTA_WLAN_HP_MAX_TIME_DEF (5000)
-#define PTA_SENSE_DISABLE_TIMER_DEF (1350)
-#define PTA_PROTECTIVE_RX_TIME_DEF (1500)
-#define PTA_PROTECTIVE_TX_TIME_DEF (1500)
-#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
-#define PTA_SIGNALING_TYPE_DEF (1)
-#define PTA_AFH_LEVERAGE_ON_DEF (0)
-#define PTA_NUMBER_QUIET_CYCLE_DEF (0)
-#define PTA_MAX_NUM_CTS_DEF (3)
-#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2)
-#define PTA_NUMBER_OF_BT_PACKETS_DEF (2)
-#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500)
-#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000)
-#define PTA_CYCLE_TIME_FAST_DEF (8700)
-#define PTA_RX_FOR_AVALANCHE_DEF (5)
-#define PTA_ELP_HP_DEF (0)
-#define PTA_ANTI_STARVE_PERIOD_DEF (500)
-#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4)
-#define PTA_ALLOW_PA_SD_DEF (1)
-#define PTA_TIME_BEFORE_BEACON_DEF (6300)
-#define PTA_HPDM_MAX_TIME_DEF (1600)
-#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550)
-#define PTA_AUTO_MODE_NO_CTS_DEF (0)
-#define PTA_BT_HP_RESPECTED_DEF (3)
-#define PTA_WLAN_RX_MIN_RATE_DEF (24)
-#define PTA_ACK_MODE_DEF (1)
-
-struct acx_bt_wlan_coex_param {
- struct acx_header header;
-
- /*
- * The minimum rate of a received WLAN packet in the STA,
- * during protective mode, of which a new BT-HP request
- * during this Rx will always be respected and gain the antenna.
- */
- u32 min_rate;
-
- /* Max time the BT HP will be respected. */
- u16 bt_hp_max_time;
-
- /* Max time the WLAN HP will be respected. */
- u16 wlan_hp_max_time;
-
- /*
- * The time between the last BT activity
- * and the moment when the sense mode returns
- * to SENSE_INACTIVE.
- */
- u16 sense_disable_timer;
-
- /* Time before the next BT HP instance */
- u16 rx_time_bt_hp;
- u16 tx_time_bt_hp;
-
- /* range: 10-20000 default: 1500 */
- u16 rx_time_bt_hp_fast;
- u16 tx_time_bt_hp_fast;
-
- /* range: 2000-65535 default: 8700 */
- u16 wlan_cycle_fast;
-
- /* range: 0 - 15000 (Msec) default: 1000 */
- u16 bt_anti_starvation_period;
-
- /* range 400-10000(Usec) default: 3000 */
- u16 next_bt_lp_packet;
-
- /* Deafult: worst case for BT DH5 traffic */
- u16 wake_up_beacon;
-
- /* range: 0-50000(Usec) default: 1050 */
- u16 hp_dm_max_guard_time;
-
- /*
- * This is to prevent both BT & WLAN antenna
- * starvation.
- * Range: 100-50000(Usec) default:2550
- */
- u16 next_wlan_packet;
-
- /* 0 -> shared antenna */
- u8 antenna_type;
-
- /*
- * 0 -> TI legacy
- * 1 -> Palau
- */
- u8 signal_type;
-
- /*
- * BT AFH status
- * 0 -> no AFH
- * 1 -> from dedicated GPIO
- * 2 -> AFH on (from host)
- */
- u8 afh_leverage_on;
-
- /*
- * The number of cycles during which no
- * TX will be sent after 1 cycle of RX
- * transaction in protective mode
- */
- u8 quiet_cycle_num;
-
- /*
- * The maximum number of CTSs that will
- * be sent for receiving RX packet in
- * protective mode
- */
- u8 max_cts;
-
- /*
- * The number of WLAN packets
- * transferred in common mode before
- * switching to BT.
- */
- u8 wlan_packets_num;
-
- /*
- * The number of BT packets
- * transferred in common mode before
- * switching to WLAN.
- */
- u8 bt_packets_num;
-
- /* range: 1-255 default: 5 */
- u8 missed_rx_avalanche;
-
- /* range: 0-1 default: 1 */
- u8 wlan_elp_hp;
-
- /* range: 0 - 15 default: 4 */
- u8 bt_anti_starvation_cycles;
-
- u8 ack_mode_dual_ant;
-
- /*
- * Allow PA_SD assertion/de-assertion
- * during enabled BT activity.
- */
- u8 pa_sd_enable;
-
- /*
- * Enable/Disable PTA in auto mode:
- * Support Both Active & P.S modes
- */
- u8 pta_auto_mode_enable;
-
- /* range: 0 - 20 default: 1 */
- u8 bt_hp_respected_num;
-} __packed;
-
-#define CCA_THRSH_ENABLE_ENERGY_D 0x140A
-#define CCA_THRSH_DISABLE_ENERGY_D 0xFFEF
-
-struct acx_energy_detection {
- struct acx_header header;
-
- /* The RX Clear Channel Assessment threshold in the PHY */
- u16 rx_cca_threshold;
- u8 tx_energy_detection;
- u8 pad;
-} __packed;
-
-#define BCN_RX_TIMEOUT_DEF_VALUE 10000
-#define BROADCAST_RX_TIMEOUT_DEF_VALUE 20000
-#define RX_BROADCAST_IN_PS_DEF_VALUE 1
-#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
-
-struct acx_beacon_broadcast {
- struct acx_header header;
-
- u16 beacon_rx_timeout;
- u16 broadcast_timeout;
-
- /* Enables receiving of broadcast packets in PS mode */
- u8 rx_broadcast_in_ps;
-
- /* Consecutive PS Poll failures before updating the host */
- u8 ps_poll_threshold;
- u8 pad[2];
-} __packed;
-
-struct acx_event_mask {
- struct acx_header header;
-
- u32 event_mask;
- u32 high_event_mask; /* Unused */
-} __packed;
-
-#define CFG_RX_FCS BIT(2)
-#define CFG_RX_ALL_GOOD BIT(3)
-#define CFG_UNI_FILTER_EN BIT(4)
-#define CFG_BSSID_FILTER_EN BIT(5)
-#define CFG_MC_FILTER_EN BIT(6)
-#define CFG_MC_ADDR0_EN BIT(7)
-#define CFG_MC_ADDR1_EN BIT(8)
-#define CFG_BC_REJECT_EN BIT(9)
-#define CFG_SSID_FILTER_EN BIT(10)
-#define CFG_RX_INT_FCS_ERROR BIT(11)
-#define CFG_RX_INT_ENCRYPTED BIT(12)
-#define CFG_RX_WR_RX_STATUS BIT(13)
-#define CFG_RX_FILTER_NULTI BIT(14)
-#define CFG_RX_RESERVE BIT(15)
-#define CFG_RX_TIMESTAMP_TSF BIT(16)
-
-#define CFG_RX_RSV_EN BIT(0)
-#define CFG_RX_RCTS_ACK BIT(1)
-#define CFG_RX_PRSP_EN BIT(2)
-#define CFG_RX_PREQ_EN BIT(3)
-#define CFG_RX_MGMT_EN BIT(4)
-#define CFG_RX_FCS_ERROR BIT(5)
-#define CFG_RX_DATA_EN BIT(6)
-#define CFG_RX_CTL_EN BIT(7)
-#define CFG_RX_CF_EN BIT(8)
-#define CFG_RX_BCN_EN BIT(9)
-#define CFG_RX_AUTH_EN BIT(10)
-#define CFG_RX_ASSOC_EN BIT(11)
-
-#define SCAN_PASSIVE BIT(0)
-#define SCAN_5GHZ_BAND BIT(1)
-#define SCAN_TRIGGERED BIT(2)
-#define SCAN_PRIORITY_HIGH BIT(3)
-
-struct acx_fw_gen_frame_rates {
- struct acx_header header;
-
- u8 tx_ctrl_frame_rate; /* RATE_* */
- u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
- u8 tx_mgt_frame_rate;
- u8 tx_mgt_frame_mod;
-} __packed;
-
-/* STA MAC */
-struct acx_dot11_station_id {
- struct acx_header header;
-
- u8 mac[ETH_ALEN];
- u8 pad[2];
-} __packed;
-
-struct acx_feature_config {
- struct acx_header header;
-
- u32 options;
- u32 data_flow_options;
-} __packed;
-
-struct acx_current_tx_power {
- struct acx_header header;
-
- u8 current_tx_power;
- u8 padding[3];
-} __packed;
-
-struct acx_dot11_default_key {
- struct acx_header header;
-
- u8 id;
- u8 pad[3];
-} __packed;
-
-struct acx_tsf_info {
- struct acx_header header;
-
- u32 current_tsf_msb;
- u32 current_tsf_lsb;
- u32 last_TBTT_msb;
- u32 last_TBTT_lsb;
- u8 last_dtim_count;
- u8 pad[3];
-} __packed;
-
-enum acx_wake_up_event {
- WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/
- WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/
- WAKE_UP_EVENT_N_DTIM_BITMAP = 0x04, /* Wake on every Nth DTIM */
- WAKE_UP_EVENT_N_BEACONS_BITMAP = 0x08, /* Wake on every Nth Beacon */
- WAKE_UP_EVENT_BITS_MASK = 0x0F
-};
-
-struct acx_wake_up_condition {
- struct acx_header header;
-
- u8 wake_up_event; /* Only one bit can be set */
- u8 listen_interval;
- u8 pad[2];
-} __packed;
-
-struct acx_aid {
- struct acx_header header;
-
- /*
- * To be set when associated with an AP.
- */
- u16 aid;
- u8 pad[2];
-} __packed;
-
-enum acx_preamble_type {
- ACX_PREAMBLE_LONG = 0,
- ACX_PREAMBLE_SHORT = 1
-};
-
-struct acx_preamble {
- struct acx_header header;
-
- /*
- * When set, the WiLink transmits the frames with a short preamble and
- * when cleared, the WiLink transmits the frames with a long preamble.
- */
- u8 preamble;
- u8 padding[3];
-} __packed;
-
-enum acx_ctsprotect_type {
- CTSPROTECT_DISABLE = 0,
- CTSPROTECT_ENABLE = 1
-};
-
-struct acx_ctsprotect {
- struct acx_header header;
- u8 ctsprotect;
- u8 padding[3];
-} __packed;
-
-struct acx_tx_statistics {
- u32 internal_desc_overflow;
-} __packed;
-
-struct acx_rx_statistics {
- u32 out_of_mem;
- u32 hdr_overflow;
- u32 hw_stuck;
- u32 dropped;
- u32 fcs_err;
- u32 xfr_hint_trig;
- u32 path_reset;
- u32 reset_counter;
-} __packed;
-
-struct acx_dma_statistics {
- u32 rx_requested;
- u32 rx_errors;
- u32 tx_requested;
- u32 tx_errors;
-} __packed;
-
-struct acx_isr_statistics {
- /* host command complete */
- u32 cmd_cmplt;
-
- /* fiqisr() */
- u32 fiqs;
-
- /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
- u32 rx_headers;
-
- /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
- u32 rx_completes;
-
- /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
- u32 rx_mem_overflow;
-
- /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
- u32 rx_rdys;
-
- /* irqisr() */
- u32 irqs;
-
- /* (INT_STS_ND & INT_TRIG_TX_PROC) */
- u32 tx_procs;
-
- /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
- u32 decrypt_done;
-
- /* (INT_STS_ND & INT_TRIG_DMA0) */
- u32 dma0_done;
-
- /* (INT_STS_ND & INT_TRIG_DMA1) */
- u32 dma1_done;
-
- /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
- u32 tx_exch_complete;
-
- /* (INT_STS_ND & INT_TRIG_COMMAND) */
- u32 commands;
-
- /* (INT_STS_ND & INT_TRIG_RX_PROC) */
- u32 rx_procs;
-
- /* (INT_STS_ND & INT_TRIG_PM_802) */
- u32 hw_pm_mode_changes;
-
- /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
- u32 host_acknowledges;
-
- /* (INT_STS_ND & INT_TRIG_PM_PCI) */
- u32 pci_pm;
-
- /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
- u32 wakeups;
-
- /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
- u32 low_rssi;
-} __packed;
-
-struct acx_wep_statistics {
- /* WEP address keys configured */
- u32 addr_key_count;
-
- /* default keys configured */
- u32 default_key_count;
-
- u32 reserved;
-
- /* number of times that WEP key not found on lookup */
- u32 key_not_found;
-
- /* number of times that WEP key decryption failed */
- u32 decrypt_fail;
-
- /* WEP packets decrypted */
- u32 packets;
-
- /* WEP decrypt interrupts */
- u32 interrupt;
-} __packed;
-
-#define ACX_MISSED_BEACONS_SPREAD 10
-
-struct acx_pwr_statistics {
- /* the amount of enters into power save mode (both PD & ELP) */
- u32 ps_enter;
-
- /* the amount of enters into ELP mode */
- u32 elp_enter;
-
- /* the amount of missing beacon interrupts to the host */
- u32 missing_bcns;
-
- /* the amount of wake on host-access times */
- u32 wake_on_host;
-
- /* the amount of wake on timer-expire */
- u32 wake_on_timer_exp;
-
- /* the number of packets that were transmitted with PS bit set */
- u32 tx_with_ps;
-
- /* the number of packets that were transmitted with PS bit clear */
- u32 tx_without_ps;
-
- /* the number of received beacons */
- u32 rcvd_beacons;
-
- /* the number of entering into PowerOn (power save off) */
- u32 power_save_off;
-
- /* the number of entries into power save mode */
- u16 enable_ps;
-
- /*
- * the number of exits from power save, not including failed PS
- * transitions
- */
- u16 disable_ps;
-
- /*
- * the number of times the TSF counter was adjusted because
- * of drift
- */
- u32 fix_tsf_ps;
-
- /* Gives statistics about the spread continuous missed beacons.
- * The 16 LSB are dedicated for the PS mode.
- * The 16 MSB are dedicated for the PS mode.
- * cont_miss_bcns_spread[0] - single missed beacon.
- * cont_miss_bcns_spread[1] - two continuous missed beacons.
- * cont_miss_bcns_spread[2] - three continuous missed beacons.
- * ...
- * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
- */
- u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
-
- /* the number of beacons in awake mode */
- u32 rcvd_awake_beacons;
-} __packed;
-
-struct acx_mic_statistics {
- u32 rx_pkts;
- u32 calc_failure;
-} __packed;
-
-struct acx_aes_statistics {
- u32 encrypt_fail;
- u32 decrypt_fail;
- u32 encrypt_packets;
- u32 decrypt_packets;
- u32 encrypt_interrupt;
- u32 decrypt_interrupt;
-} __packed;
-
-struct acx_event_statistics {
- u32 heart_beat;
- u32 calibration;
- u32 rx_mismatch;
- u32 rx_mem_empty;
- u32 rx_pool;
- u32 oom_late;
- u32 phy_transmit_error;
- u32 tx_stuck;
-} __packed;
-
-struct acx_ps_statistics {
- u32 pspoll_timeouts;
- u32 upsd_timeouts;
- u32 upsd_max_sptime;
- u32 upsd_max_apturn;
- u32 pspoll_max_apturn;
- u32 pspoll_utilization;
- u32 upsd_utilization;
-} __packed;
-
-struct acx_rxpipe_statistics {
- u32 rx_prep_beacon_drop;
- u32 descr_host_int_trig_rx_data;
- u32 beacon_buffer_thres_host_int_trig_rx_data;
- u32 missed_beacon_host_int_trig_rx_data;
- u32 tx_xfr_host_int_trig_rx_data;
-} __packed;
-
-struct acx_statistics {
- struct acx_header header;
-
- struct acx_tx_statistics tx;
- struct acx_rx_statistics rx;
- struct acx_dma_statistics dma;
- struct acx_isr_statistics isr;
- struct acx_wep_statistics wep;
- struct acx_pwr_statistics pwr;
- struct acx_aes_statistics aes;
- struct acx_mic_statistics mic;
- struct acx_event_statistics event;
- struct acx_ps_statistics ps;
- struct acx_rxpipe_statistics rxpipe;
-} __packed;
-
-#define ACX_MAX_RATE_CLASSES 8
-#define ACX_RATE_MASK_UNSPECIFIED 0
-#define ACX_RATE_RETRY_LIMIT 10
-
-struct acx_rate_class {
- u32 enabled_rates;
- u8 short_retry_limit;
- u8 long_retry_limit;
- u8 aflags;
- u8 reserved;
-};
-
-struct acx_rate_policy {
- struct acx_header header;
-
- u32 rate_class_cnt;
- struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES];
-} __packed;
-
-struct wl1251_acx_memory {
- __le16 num_stations; /* number of STAs to be supported. */
- u16 reserved_1;
-
- /*
- * Nmber of memory buffers for the RX mem pool.
- * The actual number may be less if there are
- * not enough blocks left for the minimum num
- * of TX ones.
- */
- u8 rx_mem_block_num;
- u8 reserved_2;
- u8 num_tx_queues; /* From 1 to 16 */
- u8 host_if_options; /* HOST_IF* */
- u8 tx_min_mem_block_num;
- u8 num_ssid_profiles;
- __le16 debug_buffer_size;
-} __packed;
-
-
-#define ACX_RX_DESC_MIN 1
-#define ACX_RX_DESC_MAX 127
-#define ACX_RX_DESC_DEF 32
-struct wl1251_acx_rx_queue_config {
- u8 num_descs;
- u8 pad;
- u8 type;
- u8 priority;
- __le32 dma_address;
-} __packed;
-
-#define ACX_TX_DESC_MIN 1
-#define ACX_TX_DESC_MAX 127
-#define ACX_TX_DESC_DEF 16
-struct wl1251_acx_tx_queue_config {
- u8 num_descs;
- u8 pad[2];
- u8 attributes;
-} __packed;
-
-#define MAX_TX_QUEUE_CONFIGS 5
-#define MAX_TX_QUEUES 4
-struct wl1251_acx_config_memory {
- struct acx_header header;
-
- struct wl1251_acx_memory mem_config;
- struct wl1251_acx_rx_queue_config rx_queue_config;
- struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
-} __packed;
-
-struct wl1251_acx_mem_map {
- struct acx_header header;
-
- void *code_start;
- void *code_end;
-
- void *wep_defkey_start;
- void *wep_defkey_end;
-
- void *sta_table_start;
- void *sta_table_end;
-
- void *packet_template_start;
- void *packet_template_end;
-
- void *queue_memory_start;
- void *queue_memory_end;
-
- void *packet_memory_pool_start;
- void *packet_memory_pool_end;
-
- void *debug_buffer1_start;
- void *debug_buffer1_end;
-
- void *debug_buffer2_start;
- void *debug_buffer2_end;
-
- /* Number of blocks FW allocated for TX packets */
- u32 num_tx_mem_blocks;
-
- /* Number of blocks FW allocated for RX packets */
- u32 num_rx_mem_blocks;
-} __packed;
-
-
-struct wl1251_acx_wr_tbtt_and_dtim {
-
- struct acx_header header;
-
- /* Time in TUs between two consecutive beacons */
- u16 tbtt;
-
- /*
- * DTIM period
- * For BSS: Number of TBTTs in a DTIM period (range: 1-10)
- * For IBSS: value shall be set to 1
- */
- u8 dtim;
- u8 padding;
-} __packed;
-
-struct wl1251_acx_ac_cfg {
- struct acx_header header;
-
- /*
- * Access Category - The TX queue's access category
- * (refer to AccessCategory_enum)
- */
- u8 ac;
-
- /*
- * The contention window minimum size (in slots) for
- * the access class.
- */
- u8 cw_min;
-
- /*
- * The contention window maximum size (in slots) for
- * the access class.
- */
- u16 cw_max;
-
- /* The AIF value (in slots) for the access class. */
- u8 aifsn;
-
- u8 reserved;
-
- /* The TX Op Limit (in microseconds) for the access class. */
- u16 txop_limit;
-} __packed;
-
-
-enum wl1251_acx_channel_type {
- CHANNEL_TYPE_DCF = 0,
- CHANNEL_TYPE_EDCF = 1,
- CHANNEL_TYPE_HCCA = 2,
-};
-
-enum wl1251_acx_ps_scheme {
- /* regular ps: simple sending of packets */
- WL1251_ACX_PS_SCHEME_LEGACY = 0,
-
- /* sending a packet triggers a unscheduled apsd downstream */
- WL1251_ACX_PS_SCHEME_UPSD_TRIGGER = 1,
-
- /* a pspoll packet will be sent before every data packet */
- WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL = 2,
-
- /* scheduled apsd mode */
- WL1251_ACX_PS_SCHEME_SAPSD = 3,
-};
-
-enum wl1251_acx_ack_policy {
- WL1251_ACX_ACK_POLICY_LEGACY = 0,
- WL1251_ACX_ACK_POLICY_NO_ACK = 1,
- WL1251_ACX_ACK_POLICY_BLOCK = 2,
-};
-
-struct wl1251_acx_tid_cfg {
- struct acx_header header;
-
- /* tx queue id number (0-7) */
- u8 queue;
-
- /* channel access type for the queue, enum wl1251_acx_channel_type */
- u8 type;
-
- /* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */
- u8 tsid;
-
- /* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */
- u8 ps_scheme;
-
- /* the tx queue ack policy, enum wl1251_acx_ack_policy */
- u8 ack_policy;
-
- u8 padding[3];
-
- /* not supported */
- u32 apsdconf[2];
-} __packed;
-
-/*************************************************************************
-
- Host Interrupt Register (WiLink -> Host)
-
-**************************************************************************/
-
-/* RX packet is ready in Xfer buffer #0 */
-#define WL1251_ACX_INTR_RX0_DATA BIT(0)
-
-/* TX result(s) are in the TX complete buffer */
-#define WL1251_ACX_INTR_TX_RESULT BIT(1)
-
-/* OBSOLETE */
-#define WL1251_ACX_INTR_TX_XFR BIT(2)
-
-/* RX packet is ready in Xfer buffer #1 */
-#define WL1251_ACX_INTR_RX1_DATA BIT(3)
-
-/* Event was entered to Event MBOX #A */
-#define WL1251_ACX_INTR_EVENT_A BIT(4)
-
-/* Event was entered to Event MBOX #B */
-#define WL1251_ACX_INTR_EVENT_B BIT(5)
-
-/* OBSOLETE */
-#define WL1251_ACX_INTR_WAKE_ON_HOST BIT(6)
-
-/* Trace meassge on MBOX #A */
-#define WL1251_ACX_INTR_TRACE_A BIT(7)
-
-/* Trace meassge on MBOX #B */
-#define WL1251_ACX_INTR_TRACE_B BIT(8)
-
-/* Command processing completion */
-#define WL1251_ACX_INTR_CMD_COMPLETE BIT(9)
-
-/* Init sequence is done */
-#define WL1251_ACX_INTR_INIT_COMPLETE BIT(14)
-
-#define WL1251_ACX_INTR_ALL 0xFFFFFFFF
-
-enum {
- ACX_WAKE_UP_CONDITIONS = 0x0002,
- ACX_MEM_CFG = 0x0003,
- ACX_SLOT = 0x0004,
- ACX_QUEUE_HEAD = 0x0005, /* for MASTER mode only */
- ACX_AC_CFG = 0x0007,
- ACX_MEM_MAP = 0x0008,
- ACX_AID = 0x000A,
- ACX_RADIO_PARAM = 0x000B, /* Not used */
- ACX_CFG = 0x000C, /* Not used */
- ACX_FW_REV = 0x000D,
- ACX_MEDIUM_USAGE = 0x000F,
- ACX_RX_CFG = 0x0010,
- ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */
- ACX_BSS_IN_PS = 0x0012, /* for AP only */
- ACX_STATISTICS = 0x0013, /* Debug API */
- ACX_FEATURE_CFG = 0x0015,
- ACX_MISC_CFG = 0x0017, /* Not used */
- ACX_TID_CFG = 0x001A,
- ACX_BEACON_FILTER_OPT = 0x001F,
- ACX_LOW_RSSI = 0x0020,
- ACX_NOISE_HIST = 0x0021,
- ACX_HDK_VERSION = 0x0022, /* ??? */
- ACX_PD_THRESHOLD = 0x0023,
- ACX_DATA_PATH_PARAMS = 0x0024, /* WO */
- ACX_DATA_PATH_RESP_PARAMS = 0x0024, /* RO */
- ACX_CCA_THRESHOLD = 0x0025,
- ACX_EVENT_MBOX_MASK = 0x0026,
-#ifdef FW_RUNNING_AS_AP
- ACX_DTIM_PERIOD = 0x0027, /* for AP only */
-#else
- ACX_WR_TBTT_AND_DTIM = 0x0027, /* STA only */
-#endif
- ACX_ACI_OPTION_CFG = 0x0029, /* OBSOLETE (for 1251)*/
- ACX_GPIO_CFG = 0x002A, /* Not used */
- ACX_GPIO_SET = 0x002B, /* Not used */
- ACX_PM_CFG = 0x002C, /* To Be Documented */
- ACX_CONN_MONIT_PARAMS = 0x002D,
- ACX_AVERAGE_RSSI = 0x002E, /* Not used */
- ACX_CONS_TX_FAILURE = 0x002F,
- ACX_BCN_DTIM_OPTIONS = 0x0031,
- ACX_SG_ENABLE = 0x0032,
- ACX_SG_CFG = 0x0033,
- ACX_ANTENNA_DIVERSITY_CFG = 0x0035, /* To Be Documented */
- ACX_LOW_SNR = 0x0037, /* To Be Documented */
- ACX_BEACON_FILTER_TABLE = 0x0038,
- ACX_ARP_IP_FILTER = 0x0039,
- ACX_ROAMING_STATISTICS_TBL = 0x003B,
- ACX_RATE_POLICY = 0x003D,
- ACX_CTS_PROTECTION = 0x003E,
- ACX_SLEEP_AUTH = 0x003F,
- ACX_PREAMBLE_TYPE = 0x0040,
- ACX_ERROR_CNT = 0x0041,
- ACX_FW_GEN_FRAME_RATES = 0x0042,
- ACX_IBSS_FILTER = 0x0044,
- ACX_SERVICE_PERIOD_TIMEOUT = 0x0045,
- ACX_TSF_INFO = 0x0046,
- ACX_CONFIG_PS_WMM = 0x0049,
- ACX_ENABLE_RX_DATA_FILTER = 0x004A,
- ACX_SET_RX_DATA_FILTER = 0x004B,
- ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
- ACX_POWER_LEVEL_TABLE = 0x004D,
- ACX_BET_ENABLE = 0x0050,
- DOT11_STATION_ID = 0x1001,
- DOT11_RX_MSDU_LIFE_TIME = 0x1004,
- DOT11_CUR_TX_PWR = 0x100D,
- DOT11_DEFAULT_KEY = 0x1010,
- DOT11_RX_DOT11_MODE = 0x1012,
- DOT11_RTS_THRESHOLD = 0x1013,
- DOT11_GROUP_ADDRESS_TBL = 0x1014,
-
- MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
-
- MAX_IE = 0xFFFF
-};
-
-
-int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
- u8 mgt_rate, u8 mgt_mod);
-int wl1251_acx_station_id(struct wl1251 *wl);
-int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id);
-int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
- u8 listen_interval);
-int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth);
-int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len);
-int wl1251_acx_tx_power(struct wl1251 *wl, int power);
-int wl1251_acx_feature_cfg(struct wl1251 *wl);
-int wl1251_acx_mem_map(struct wl1251 *wl,
- struct acx_header *mem_map, size_t len);
-int wl1251_acx_data_path_params(struct wl1251 *wl,
- struct acx_data_path_params_resp *data_path);
-int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time);
-int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter);
-int wl1251_acx_pd_threshold(struct wl1251 *wl);
-int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time);
-int wl1251_acx_group_address_tbl(struct wl1251 *wl);
-int wl1251_acx_service_period_timeout(struct wl1251 *wl);
-int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold);
-int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter);
-int wl1251_acx_beacon_filter_table(struct wl1251 *wl);
-int wl1251_acx_conn_monit_params(struct wl1251 *wl);
-int wl1251_acx_sg_enable(struct wl1251 *wl);
-int wl1251_acx_sg_cfg(struct wl1251 *wl);
-int wl1251_acx_cca_threshold(struct wl1251 *wl);
-int wl1251_acx_bcn_dtim_options(struct wl1251 *wl);
-int wl1251_acx_aid(struct wl1251 *wl, u16 aid);
-int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask);
-int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble);
-int wl1251_acx_cts_protect(struct wl1251 *wl,
- enum acx_ctsprotect_type ctsprotect);
-int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats);
-int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
-int wl1251_acx_rate_policies(struct wl1251 *wl);
-int wl1251_acx_mem_cfg(struct wl1251 *wl);
-int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
-int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
- u8 aifs, u16 txop);
-int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
- enum wl1251_acx_channel_type type,
- u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
- enum wl1251_acx_ack_policy ack_policy);
-
-#endif /* __WL1251_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
deleted file mode 100644
index 65e0416be5b6..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/gpio.h>
-#include <linux/slab.h>
-
-#include "wl1251_reg.h"
-#include "wl1251_boot.h"
-#include "wl1251_io.h"
-#include "wl1251_spi.h"
-#include "wl1251_event.h"
-#include "wl1251_acx.h"
-
-void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
-{
- wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
- wl1251_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
-}
-
-int wl1251_boot_soft_reset(struct wl1251 *wl)
-{
- unsigned long timeout;
- u32 boot_data;
-
- /* perform soft reset */
- wl1251_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
-
- /* SOFT_RESET is self clearing */
- timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
- while (1) {
- boot_data = wl1251_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
- wl1251_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
- if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
- break;
-
- if (time_after(jiffies, timeout)) {
- /* 1.2 check pWhalBus->uSelfClearTime if the
- * timeout was reached */
- wl1251_error("soft reset timeout");
- return -1;
- }
-
- udelay(SOFT_RESET_STALL_TIME);
- }
-
- /* disable Rx/Tx */
- wl1251_reg_write32(wl, ENABLE, 0x0);
-
- /* disable auto calibration on start*/
- wl1251_reg_write32(wl, SPARE_A2, 0xffff);
-
- return 0;
-}
-
-int wl1251_boot_init_seq(struct wl1251 *wl)
-{
- u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
-
- /*
- * col #1: INTEGER_DIVIDER
- * col #2: FRACTIONAL_DIVIDER
- * col #3: ATTN_BB
- * col #4: ALPHA_BB
- * col #5: STOP_TIME_BB
- * col #6: BB_PLL_LOOP_FILTER
- */
- static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
-
- { 83, 87381, 0xB, 5, 0xF00, 3}, /* REF_FREQ_19_2*/
- { 61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
- { 41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
- { 40, 0, 0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
- { 47, 162280, 0xC, 6, 0x2760, 1} /* REF_FREQ_33_6 */
- };
-
- /* read NVS params */
- scr_pad6 = wl1251_reg_read32(wl, SCR_PAD6);
- wl1251_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
-
- /* read ELP_CMD */
- elp_cmd = wl1251_reg_read32(wl, ELP_CMD);
- wl1251_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
-
- /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
- ref_freq = scr_pad6 & 0x000000FF;
- wl1251_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
-
- wl1251_reg_write32(wl, PLL_CAL_TIME, 0x9);
-
- /*
- * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
- */
- wl1251_reg_write32(wl, CLK_BUF_TIME, 0x6);
-
- /*
- * set the clock detect feature to work in the restart wu procedure
- * (ELP_CFG_MODE[14]) and Select the clock source type
- * (ELP_CFG_MODE[13:12])
- */
- tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
- wl1251_reg_write32(wl, ELP_CFG_MODE, tmp);
-
- /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
- elp_cmd |= 0x00000040;
- wl1251_reg_write32(wl, ELP_CMD, elp_cmd);
-
- /* PG 1.2: Set the BB PLL stable time to be 1000usec
- * (PLL_STABLE_TIME) */
- wl1251_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
-
- /* PG 1.2: read clock request time */
- init_data = wl1251_reg_read32(wl, CLK_REQ_TIME);
-
- /*
- * PG 1.2: set the clock request time to be ref_clk_settling_time -
- * 1ms = 4ms
- */
- if (init_data > 0x21)
- tmp = init_data - 0x21;
- else
- tmp = 0;
- wl1251_reg_write32(wl, CLK_REQ_TIME, tmp);
-
- /* set BB PLL configurations in RF AFE */
- wl1251_reg_write32(wl, 0x003058cc, 0x4B5);
-
- /* set RF_AFE_REG_5 */
- wl1251_reg_write32(wl, 0x003058d4, 0x50);
-
- /* set RF_AFE_CTRL_REG_2 */
- wl1251_reg_write32(wl, 0x00305948, 0x11c001);
-
- /*
- * change RF PLL and BB PLL divider for VCO clock and adjust VCO
- * bais current(RF_AFE_REG_13)
- */
- wl1251_reg_write32(wl, 0x003058f4, 0x1e);
-
- /* set BB PLL configurations */
- tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
- wl1251_reg_write32(wl, 0x00305840, tmp);
-
- /* set fractional divider according to Appendix C-BB PLL
- * Calculations
- */
- tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
- wl1251_reg_write32(wl, 0x00305844, tmp);
-
- /* set the initial data for the sigma delta */
- wl1251_reg_write32(wl, 0x00305848, 0x3039);
-
- /*
- * set the accumulator attenuation value, calibration loop1
- * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
- * the VCO gain
- */
- tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
- (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
- wl1251_reg_write32(wl, 0x00305854, tmp);
-
- /*
- * set the calibration stop time after holdoff time expires and set
- * settling time HOLD_OFF_TIME_BB
- */
- tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
- wl1251_reg_write32(wl, 0x00305858, tmp);
-
- /*
- * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
- * constant leakage current to linearize PFD to 0uA -
- * BB_ILOOPF[7:3]
- */
- tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
- wl1251_reg_write32(wl, 0x003058f8, tmp);
-
- /*
- * set regulator output voltage for n divider to
- * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
- * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
- * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
- */
- wl1251_reg_write32(wl, 0x003058f0, 0x29);
-
- /* enable restart wakeup sequence (ELP_CMD[0]) */
- wl1251_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
-
- /* restart sequence completed */
- udelay(2000);
-
- return 0;
-}
-
-static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag)
-{
- u32 cpu_ctrl;
-
- /* 10.5.0 run the firmware (I) */
- cpu_ctrl = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
-
- /* 10.5.1 run the firmware (II) */
- cpu_ctrl &= ~flag;
- wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
-}
-
-int wl1251_boot_run_firmware(struct wl1251 *wl)
-{
- int loop, ret;
- u32 chip_id, acx_intr;
-
- wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
-
- chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
-
- wl1251_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
-
- if (chip_id != wl->chip_id) {
- wl1251_error("chip id doesn't match after firmware boot");
- return -EIO;
- }
-
- /* wait for init to complete */
- loop = 0;
- while (loop++ < INIT_LOOP) {
- udelay(INIT_LOOP_DELAY);
- acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
-
- if (acx_intr == 0xffffffff) {
- wl1251_error("error reading hardware complete "
- "init indication");
- return -EIO;
- }
- /* check that ACX_INTR_INIT_COMPLETE is enabled */
- else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) {
- wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
- WL1251_ACX_INTR_INIT_COMPLETE);
- break;
- }
- }
-
- if (loop > INIT_LOOP) {
- wl1251_error("timeout waiting for the hardware to "
- "complete initialization");
- return -EIO;
- }
-
- /* get hardware config command mail box */
- wl->cmd_box_addr = wl1251_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
-
- /* get hardware config event mail box */
- wl->event_box_addr = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
-
- /* set the working partition to its "running" mode offset */
- wl1251_set_partition(wl, WL1251_PART_WORK_MEM_START,
- WL1251_PART_WORK_MEM_SIZE,
- WL1251_PART_WORK_REG_START,
- WL1251_PART_WORK_REG_SIZE);
-
- wl1251_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
- wl->cmd_box_addr, wl->event_box_addr);
-
- wl1251_acx_fw_version(wl, wl->fw_ver, sizeof(wl->fw_ver));
-
- /*
- * in case of full asynchronous mode the firmware event must be
- * ready to receive event from the command mailbox
- */
-
- /* enable gpio interrupts */
- wl1251_enable_interrupts(wl);
-
- /* Enable target's interrupts */
- wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
- WL1251_ACX_INTR_RX1_DATA |
- WL1251_ACX_INTR_TX_RESULT |
- WL1251_ACX_INTR_EVENT_A |
- WL1251_ACX_INTR_EVENT_B |
- WL1251_ACX_INTR_INIT_COMPLETE;
- wl1251_boot_target_enable_interrupts(wl);
-
- wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID |
- SYNCHRONIZATION_TIMEOUT_EVENT_ID |
- ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
- ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
- REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
- BT_PTA_PREDICTION_EVENT_ID;
-
- ret = wl1251_event_unmask(wl);
- if (ret < 0) {
- wl1251_error("EVENT mask setting failed");
- return ret;
- }
-
- wl1251_event_mbox_config(wl);
-
- /* firmware startup completed */
- return 0;
-}
-
-static int wl1251_boot_upload_firmware(struct wl1251 *wl)
-{
- int addr, chunk_num, partition_limit;
- size_t fw_data_len, len;
- u8 *p, *buf;
-
- /* whal_FwCtrl_LoadFwImageSm() */
-
- wl1251_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
- wl1251_reg_read32(wl, CHIP_ID_B));
-
- /* 10.0 check firmware length and set partition */
- fw_data_len = (wl->fw[4] << 24) | (wl->fw[5] << 16) |
- (wl->fw[6] << 8) | (wl->fw[7]);
-
- wl1251_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
- CHUNK_SIZE);
-
- if ((fw_data_len % 4) != 0) {
- wl1251_error("firmware length not multiple of four");
- return -EIO;
- }
-
- buf = kmalloc(CHUNK_SIZE, GFP_KERNEL);
- if (!buf) {
- wl1251_error("allocation for firmware upload chunk failed");
- return -ENOMEM;
- }
-
- wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
- WL1251_PART_DOWN_MEM_SIZE,
- WL1251_PART_DOWN_REG_START,
- WL1251_PART_DOWN_REG_SIZE);
-
- /* 10.1 set partition limit and chunk num */
- chunk_num = 0;
- partition_limit = WL1251_PART_DOWN_MEM_SIZE;
-
- while (chunk_num < fw_data_len / CHUNK_SIZE) {
- /* 10.2 update partition, if needed */
- addr = WL1251_PART_DOWN_MEM_START +
- (chunk_num + 2) * CHUNK_SIZE;
- if (addr > partition_limit) {
- addr = WL1251_PART_DOWN_MEM_START +
- chunk_num * CHUNK_SIZE;
- partition_limit = chunk_num * CHUNK_SIZE +
- WL1251_PART_DOWN_MEM_SIZE;
- wl1251_set_partition(wl,
- addr,
- WL1251_PART_DOWN_MEM_SIZE,
- WL1251_PART_DOWN_REG_START,
- WL1251_PART_DOWN_REG_SIZE);
- }
-
- /* 10.3 upload the chunk */
- addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
- p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
- wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
- p, addr);
-
- /* need to copy the chunk for dma */
- len = CHUNK_SIZE;
- memcpy(buf, p, len);
- wl1251_mem_write(wl, addr, buf, len);
-
- chunk_num++;
- }
-
- /* 10.4 upload the last chunk */
- addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
- p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
-
- /* need to copy the chunk for dma */
- len = fw_data_len % CHUNK_SIZE;
- memcpy(buf, p, len);
-
- wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
- len, p, addr);
- wl1251_mem_write(wl, addr, buf, len);
-
- kfree(buf);
-
- return 0;
-}
-
-static int wl1251_boot_upload_nvs(struct wl1251 *wl)
-{
- size_t nvs_len, nvs_bytes_written, burst_len;
- int nvs_start, i;
- u32 dest_addr, val;
- u8 *nvs_ptr, *nvs;
-
- nvs = wl->nvs;
- if (nvs == NULL)
- return -ENODEV;
-
- nvs_ptr = nvs;
-
- nvs_len = wl->nvs_len;
- nvs_start = wl->fw_len;
-
- /*
- * Layout before the actual NVS tables:
- * 1 byte : burst length.
- * 2 bytes: destination address.
- * n bytes: data to burst copy.
- *
- * This is ended by a 0 length, then the NVS tables.
- */
-
- while (nvs_ptr[0]) {
- burst_len = nvs_ptr[0];
- dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
-
- /* We move our pointer to the data */
- nvs_ptr += 3;
-
- for (i = 0; i < burst_len; i++) {
- val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
- | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
-
- wl1251_debug(DEBUG_BOOT,
- "nvs burst write 0x%x: 0x%x",
- dest_addr, val);
- wl1251_mem_write32(wl, dest_addr, val);
-
- nvs_ptr += 4;
- dest_addr += 4;
- }
- }
-
- /*
- * We've reached the first zero length, the first NVS table
- * is 7 bytes further.
- */
- nvs_ptr += 7;
- nvs_len -= nvs_ptr - nvs;
- nvs_len = ALIGN(nvs_len, 4);
-
- /* Now we must set the partition correctly */
- wl1251_set_partition(wl, nvs_start,
- WL1251_PART_DOWN_MEM_SIZE,
- WL1251_PART_DOWN_REG_START,
- WL1251_PART_DOWN_REG_SIZE);
-
- /* And finally we upload the NVS tables */
- nvs_bytes_written = 0;
- while (nvs_bytes_written < nvs_len) {
- val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
- | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
-
- val = cpu_to_le32(val);
-
- wl1251_debug(DEBUG_BOOT,
- "nvs write table 0x%x: 0x%x",
- nvs_start, val);
- wl1251_mem_write32(wl, nvs_start, val);
-
- nvs_ptr += 4;
- nvs_bytes_written += 4;
- nvs_start += 4;
- }
-
- return 0;
-}
-
-int wl1251_boot(struct wl1251 *wl)
-{
- int ret = 0, minor_minor_e2_ver;
- u32 tmp, boot_data;
-
- /* halt embedded ARM CPU while loading firmware */
- wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, ECPU_CONTROL_HALT);
-
- ret = wl1251_boot_soft_reset(wl);
- if (ret < 0)
- goto out;
-
- /* 2. start processing NVS file */
- if (wl->use_eeprom) {
- wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
- /* Wait for EEPROM NVS burst read to complete */
- msleep(40);
- wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
- } else {
- ret = wl1251_boot_upload_nvs(wl);
- if (ret < 0)
- goto out;
-
- /* write firmware's last address (ie. it's length) to
- * ACX_EEPROMLESS_IND_REG */
- wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
- }
-
- /* 6. read the EEPROM parameters */
- tmp = wl1251_reg_read32(wl, SCR_PAD2);
-
- /* 7. read bootdata */
- wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
- wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
- tmp = wl1251_reg_read32(wl, SCR_PAD3);
-
- /* 8. check bootdata and call restart sequence */
- wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
- minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
-
- wl1251_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
- "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
- wl->boot_attr.radio_type, wl->boot_attr.major,
- wl->boot_attr.minor, minor_minor_e2_ver);
-
- ret = wl1251_boot_init_seq(wl);
- if (ret < 0)
- goto out;
-
- /* 9. NVS processing done */
- boot_data = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
-
- wl1251_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
-
- /* 10. check that ECPU_CONTROL_HALT bits are set in
- * pWhalBus->uBootData and start uploading firmware
- */
- if ((boot_data & ECPU_CONTROL_HALT) == 0) {
- wl1251_error("boot failed, ECPU_CONTROL_HALT not set");
- ret = -EIO;
- goto out;
- }
-
- ret = wl1251_boot_upload_firmware(wl);
- if (ret < 0)
- goto out;
-
- /* 10.5 start firmware */
- ret = wl1251_boot_run_firmware(wl);
- if (ret < 0)
- goto out;
-
-out:
- return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl12xx/wl1251_boot.h
deleted file mode 100644
index 90063697e8f2..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_boot.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __BOOT_H__
-#define __BOOT_H__
-
-#include "wl1251.h"
-
-int wl1251_boot_soft_reset(struct wl1251 *wl);
-int wl1251_boot_init_seq(struct wl1251 *wl);
-int wl1251_boot_run_firmware(struct wl1251 *wl);
-void wl1251_boot_target_enable_interrupts(struct wl1251 *wl);
-int wl1251_boot(struct wl1251 *wl);
-
-/* number of times we try to read the INIT interrupt */
-#define INIT_LOOP 20000
-
-/* delay between retries */
-#define INIT_LOOP_DELAY 50
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
deleted file mode 100644
index ce3722f4c3e3..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ /dev/null
@@ -1,496 +0,0 @@
-#include "wl1251_cmd.h"
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/crc7.h>
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_ps.h"
-#include "wl1251_acx.h"
-
-/**
- * send command to firmware
- *
- * @wl: wl struct
- * @id: command id
- * @buf: buffer containing the command, must work with dma
- * @len: length of the buffer
- */
-int wl1251_cmd_send(struct wl1251 *wl, u16 id, void *buf, size_t len)
-{
- struct wl1251_cmd_header *cmd;
- unsigned long timeout;
- u32 intr;
- int ret = 0;
-
- cmd = buf;
- cmd->id = id;
- cmd->status = 0;
-
- WARN_ON(len % 4 != 0);
-
- wl1251_mem_write(wl, wl->cmd_box_addr, buf, len);
-
- wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
-
- timeout = jiffies + msecs_to_jiffies(WL1251_COMMAND_TIMEOUT);
-
- intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
- while (!(intr & WL1251_ACX_INTR_CMD_COMPLETE)) {
- if (time_after(jiffies, timeout)) {
- wl1251_error("command complete timeout");
- ret = -ETIMEDOUT;
- goto out;
- }
-
- msleep(1);
-
- intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
- }
-
- wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
- WL1251_ACX_INTR_CMD_COMPLETE);
-
-out:
- return ret;
-}
-
-/**
- * send test command to firmware
- *
- * @wl: wl struct
- * @buf: buffer containing the command, with all headers, must work with dma
- * @len: length of the buffer
- * @answer: is answer needed
- */
-int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer)
-{
- int ret;
-
- wl1251_debug(DEBUG_CMD, "cmd test");
-
- ret = wl1251_cmd_send(wl, CMD_TEST, buf, buf_len);
-
- if (ret < 0) {
- wl1251_warning("TEST command failed");
- return ret;
- }
-
- if (answer) {
- struct wl1251_command *cmd_answer;
-
- /*
- * The test command got in, we can read the answer.
- * The answer would be a wl1251_command, where the
- * parameter array contains the actual answer.
- */
- wl1251_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
-
- cmd_answer = buf;
-
- if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
- wl1251_error("TEST command answer error: %d",
- cmd_answer->header.status);
- }
-
- return 0;
-}
-
-/**
- * read acx from firmware
- *
- * @wl: wl struct
- * @id: acx id
- * @buf: buffer for the response, including all headers, must work with dma
- * @len: lenght of buf
- */
-int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len)
-{
- struct acx_header *acx = buf;
- int ret;
-
- wl1251_debug(DEBUG_CMD, "cmd interrogate");
-
- acx->id = id;
-
- /* payload length, does not include any headers */
- acx->len = len - sizeof(*acx);
-
- ret = wl1251_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
- if (ret < 0) {
- wl1251_error("INTERROGATE command failed");
- goto out;
- }
-
- /* the interrogate command got in, we can read the answer */
- wl1251_mem_read(wl, wl->cmd_box_addr, buf, len);
-
- acx = buf;
- if (acx->cmd.status != CMD_STATUS_SUCCESS)
- wl1251_error("INTERROGATE command error: %d",
- acx->cmd.status);
-
-out:
- return ret;
-}
-
-/**
- * write acx value to firmware
- *
- * @wl: wl struct
- * @id: acx id
- * @buf: buffer containing acx, including all headers, must work with dma
- * @len: length of buf
- */
-int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len)
-{
- struct acx_header *acx = buf;
- int ret;
-
- wl1251_debug(DEBUG_CMD, "cmd configure");
-
- acx->id = id;
-
- /* payload length, does not include any headers */
- acx->len = len - sizeof(*acx);
-
- ret = wl1251_cmd_send(wl, CMD_CONFIGURE, acx, len);
- if (ret < 0) {
- wl1251_warning("CONFIGURE command NOK");
- return ret;
- }
-
- return 0;
-}
-
-int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
- void *bitmap, u16 bitmap_len, u8 bitmap_control)
-{
- struct wl1251_cmd_vbm_update *vbm;
- int ret;
-
- wl1251_debug(DEBUG_CMD, "cmd vbm");
-
- vbm = kzalloc(sizeof(*vbm), GFP_KERNEL);
- if (!vbm) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* Count and period will be filled by the target */
- vbm->tim.bitmap_ctrl = bitmap_control;
- if (bitmap_len > PARTIAL_VBM_MAX) {
- wl1251_warning("cmd vbm len is %d B, truncating to %d",
- bitmap_len, PARTIAL_VBM_MAX);
- bitmap_len = PARTIAL_VBM_MAX;
- }
- memcpy(vbm->tim.pvb_field, bitmap, bitmap_len);
- vbm->tim.identity = identity;
- vbm->tim.length = bitmap_len + 3;
-
- vbm->len = cpu_to_le16(bitmap_len + 5);
-
- ret = wl1251_cmd_send(wl, CMD_VBM, vbm, sizeof(*vbm));
- if (ret < 0) {
- wl1251_error("VBM command failed");
- goto out;
- }
-
-out:
- kfree(vbm);
- return 0;
-}
-
-int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
-{
- struct cmd_enabledisable_path *cmd;
- int ret;
- u16 cmd_rx, cmd_tx;
-
- wl1251_debug(DEBUG_CMD, "cmd data path");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->channel = channel;
-
- if (enable) {
- cmd_rx = CMD_ENABLE_RX;
- cmd_tx = CMD_ENABLE_TX;
- } else {
- cmd_rx = CMD_DISABLE_RX;
- cmd_tx = CMD_DISABLE_TX;
- }
-
- ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
- if (ret < 0) {
- wl1251_error("rx %s cmd for channel %d failed",
- enable ? "start" : "stop", channel);
- goto out;
- }
-
- wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d",
- enable ? "start" : "stop", channel);
-
- ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
- if (ret < 0) {
- wl1251_error("tx %s cmd for channel %d failed",
- enable ? "start" : "stop", channel);
- return ret;
- }
-
- wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d",
- enable ? "start" : "stop", channel);
-
-out:
- kfree(cmd);
- return ret;
-}
-
-int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
- u16 beacon_interval, u8 dtim_interval)
-{
- struct cmd_join *join;
- int ret, i;
- u8 *bssid;
-
- join = kzalloc(sizeof(*join), GFP_KERNEL);
- if (!join) {
- ret = -ENOMEM;
- goto out;
- }
-
- wl1251_debug(DEBUG_CMD, "cmd join%s ch %d %d/%d",
- bss_type == BSS_TYPE_IBSS ? " ibss" : "",
- channel, beacon_interval, dtim_interval);
-
- /* Reverse order BSSID */
- bssid = (u8 *) &join->bssid_lsb;
- for (i = 0; i < ETH_ALEN; i++)
- bssid[i] = wl->bssid[ETH_ALEN - i - 1];
-
- join->rx_config_options = wl->rx_config;
- join->rx_filter_options = wl->rx_filter;
-
- /*
- * FIXME: disable temporarily all filters because after commit
- * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
- * association. The filter logic needs to be implemented properly
- * and once that is done, this hack can be removed.
- */
- join->rx_config_options = 0;
- join->rx_filter_options = WL1251_DEFAULT_RX_FILTER;
-
- join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
- RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
-
- join->beacon_interval = beacon_interval;
- join->dtim_interval = dtim_interval;
- join->bss_type = bss_type;
- join->channel = channel;
- join->ctrl = JOIN_CMD_CTRL_TX_FLUSH;
-
- ret = wl1251_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
- if (ret < 0) {
- wl1251_error("failed to initiate cmd join");
- goto out;
- }
-
-out:
- kfree(join);
- return ret;
-}
-
-int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode)
-{
- struct wl1251_cmd_ps_params *ps_params = NULL;
- int ret = 0;
-
- wl1251_debug(DEBUG_CMD, "cmd set ps mode");
-
- ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
- if (!ps_params) {
- ret = -ENOMEM;
- goto out;
- }
-
- ps_params->ps_mode = ps_mode;
- ps_params->send_null_data = 1;
- ps_params->retries = 5;
- ps_params->hang_over_period = 128;
- ps_params->null_data_rate = 1; /* 1 Mbps */
-
- ret = wl1251_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
- sizeof(*ps_params));
- if (ret < 0) {
- wl1251_error("cmd set_ps_mode failed");
- goto out;
- }
-
-out:
- kfree(ps_params);
- return ret;
-}
-
-int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
- size_t len)
-{
- struct cmd_read_write_memory *cmd;
- int ret = 0;
-
- wl1251_debug(DEBUG_CMD, "cmd read memory");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- WARN_ON(len > MAX_READ_SIZE);
- len = min_t(size_t, len, MAX_READ_SIZE);
-
- cmd->addr = addr;
- cmd->size = len;
-
- ret = wl1251_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
- if (ret < 0) {
- wl1251_error("read memory command failed: %d", ret);
- goto out;
- }
-
- /* the read command got in, we can now read the answer */
- wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
-
- if (cmd->header.status != CMD_STATUS_SUCCESS)
- wl1251_error("error in read command result: %d",
- cmd->header.status);
-
- memcpy(answer, cmd->value, len);
-
-out:
- kfree(cmd);
- return ret;
-}
-
-int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
- void *buf, size_t buf_len)
-{
- struct wl1251_cmd_packet_template *cmd;
- size_t cmd_len;
- int ret = 0;
-
- wl1251_debug(DEBUG_CMD, "cmd template %d", cmd_id);
-
- WARN_ON(buf_len > WL1251_MAX_TEMPLATE_SIZE);
- buf_len = min_t(size_t, buf_len, WL1251_MAX_TEMPLATE_SIZE);
- cmd_len = ALIGN(sizeof(*cmd) + buf_len, 4);
-
- cmd = kzalloc(cmd_len, GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- cmd->size = cpu_to_le16(buf_len);
-
- if (buf)
- memcpy(cmd->data, buf, buf_len);
-
- ret = wl1251_cmd_send(wl, cmd_id, cmd, cmd_len);
- if (ret < 0) {
- wl1251_warning("cmd set_template failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(cmd);
- return ret;
-}
-
-int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
- struct ieee80211_channel *channels[],
- unsigned int n_channels, unsigned int n_probes)
-{
- struct wl1251_cmd_scan *cmd;
- int i, ret = 0;
-
- wl1251_debug(DEBUG_CMD, "cmd scan");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd)
- return -ENOMEM;
-
- cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
- cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN |
- CFG_RX_MGMT_EN |
- CFG_RX_BCN_EN);
- cmd->params.scan_options = 0;
- cmd->params.num_channels = n_channels;
- cmd->params.num_probe_requests = n_probes;
- cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
- cmd->params.tid_trigger = 0;
-
- for (i = 0; i < n_channels; i++) {
- cmd->channels[i].min_duration =
- cpu_to_le32(WL1251_SCAN_MIN_DURATION);
- cmd->channels[i].max_duration =
- cpu_to_le32(WL1251_SCAN_MAX_DURATION);
- memset(&cmd->channels[i].bssid_lsb, 0xff, 4);
- memset(&cmd->channels[i].bssid_msb, 0xff, 2);
- cmd->channels[i].early_termination = 0;
- cmd->channels[i].tx_power_att = 0;
- cmd->channels[i].channel = channels[i]->hw_value;
- }
-
- cmd->params.ssid_len = ssid_len;
- if (ssid)
- memcpy(cmd->params.ssid, ssid, ssid_len);
-
- ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
- if (ret < 0) {
- wl1251_error("cmd scan failed: %d", ret);
- goto out;
- }
-
- wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
-
- if (cmd->header.status != CMD_STATUS_SUCCESS) {
- wl1251_error("cmd scan status wasn't success: %d",
- cmd->header.status);
- ret = -EIO;
- goto out;
- }
-
-out:
- kfree(cmd);
- return ret;
-}
-
-int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
-{
- struct wl1251_cmd_trigger_scan_to *cmd;
- int ret;
-
- wl1251_debug(DEBUG_CMD, "cmd trigger scan to");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd)
- return -ENOMEM;
-
- cmd->timeout = timeout;
-
- ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd));
- if (ret < 0) {
- wl1251_error("cmd trigger scan to failed: %d", ret);
- goto out;
- }
-
-out:
- kfree(cmd);
- return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h
deleted file mode 100644
index a9e4991369be..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.h
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_CMD_H__
-#define __WL1251_CMD_H__
-
-#include "wl1251.h"
-
-#include <net/cfg80211.h>
-
-struct acx_header;
-
-int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len);
-int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer);
-int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len);
-int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len);
-int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
- void *bitmap, u16 bitmap_len, u8 bitmap_control);
-int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable);
-int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
- u16 beacon_interval, u8 dtim_interval);
-int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode);
-int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
- size_t len);
-int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
- void *buf, size_t buf_len);
-int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
- struct ieee80211_channel *channels[],
- unsigned int n_channels, unsigned int n_probes);
-int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout);
-
-/* unit ms */
-#define WL1251_COMMAND_TIMEOUT 2000
-
-enum wl1251_commands {
- CMD_RESET = 0,
- CMD_INTERROGATE = 1, /*use this to read information elements*/
- CMD_CONFIGURE = 2, /*use this to write information elements*/
- CMD_ENABLE_RX = 3,
- CMD_ENABLE_TX = 4,
- CMD_DISABLE_RX = 5,
- CMD_DISABLE_TX = 6,
- CMD_SCAN = 8,
- CMD_STOP_SCAN = 9,
- CMD_VBM = 10,
- CMD_START_JOIN = 11,
- CMD_SET_KEYS = 12,
- CMD_READ_MEMORY = 13,
- CMD_WRITE_MEMORY = 14,
- CMD_BEACON = 19,
- CMD_PROBE_RESP = 20,
- CMD_NULL_DATA = 21,
- CMD_PROBE_REQ = 22,
- CMD_TEST = 23,
- CMD_RADIO_CALIBRATE = 25, /* OBSOLETE */
- CMD_ENABLE_RX_PATH = 27, /* OBSOLETE */
- CMD_NOISE_HIST = 28,
- CMD_RX_RESET = 29,
- CMD_PS_POLL = 30,
- CMD_QOS_NULL_DATA = 31,
- CMD_LNA_CONTROL = 32,
- CMD_SET_BCN_MODE = 33,
- CMD_MEASUREMENT = 34,
- CMD_STOP_MEASUREMENT = 35,
- CMD_DISCONNECT = 36,
- CMD_SET_PS_MODE = 37,
- CMD_CHANNEL_SWITCH = 38,
- CMD_STOP_CHANNEL_SWICTH = 39,
- CMD_AP_DISCOVERY = 40,
- CMD_STOP_AP_DISCOVERY = 41,
- CMD_SPS_SCAN = 42,
- CMD_STOP_SPS_SCAN = 43,
- CMD_HEALTH_CHECK = 45,
- CMD_DEBUG = 46,
- CMD_TRIGGER_SCAN_TO = 47,
-
- NUM_COMMANDS,
- MAX_COMMAND_ID = 0xFFFF,
-};
-
-#define MAX_CMD_PARAMS 572
-
-struct wl1251_cmd_header {
- u16 id;
- u16 status;
- /* payload */
- u8 data[0];
-} __packed;
-
-struct wl1251_command {
- struct wl1251_cmd_header header;
- u8 parameters[MAX_CMD_PARAMS];
-};
-
-enum {
- CMD_MAILBOX_IDLE = 0,
- CMD_STATUS_SUCCESS = 1,
- CMD_STATUS_UNKNOWN_CMD = 2,
- CMD_STATUS_UNKNOWN_IE = 3,
- CMD_STATUS_REJECT_MEAS_SG_ACTIVE = 11,
- CMD_STATUS_RX_BUSY = 13,
- CMD_STATUS_INVALID_PARAM = 14,
- CMD_STATUS_TEMPLATE_TOO_LARGE = 15,
- CMD_STATUS_OUT_OF_MEMORY = 16,
- CMD_STATUS_STA_TABLE_FULL = 17,
- CMD_STATUS_RADIO_ERROR = 18,
- CMD_STATUS_WRONG_NESTING = 19,
- CMD_STATUS_TIMEOUT = 21, /* Driver internal use.*/
- CMD_STATUS_FW_RESET = 22, /* Driver internal use.*/
- MAX_COMMAND_STATUS = 0xff
-};
-
-
-/*
- * CMD_READ_MEMORY
- *
- * The host issues this command to read the WiLink device memory/registers.
- *
- * Note: The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-/*
- * CMD_WRITE_MEMORY
- *
- * The host issues this command to write the WiLink device memory/registers.
- *
- * The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-#define MAX_READ_SIZE 256
-
-struct cmd_read_write_memory {
- struct wl1251_cmd_header header;
-
- /* The address of the memory to read from or write to.*/
- u32 addr;
-
- /* The amount of data in bytes to read from or write to the WiLink
- * device.*/
- u32 size;
-
- /* The actual value read from or written to the Wilink. The source
- of this field is the Host in WRITE command or the Wilink in READ
- command. */
- u8 value[MAX_READ_SIZE];
-};
-
-#define CMDMBOX_HEADER_LEN 4
-#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
-
-#define WL1251_SCAN_MIN_DURATION 30000
-#define WL1251_SCAN_MAX_DURATION 60000
-
-#define WL1251_SCAN_NUM_PROBES 3
-
-struct wl1251_scan_parameters {
- __le32 rx_config_options;
- __le32 rx_filter_options;
-
- /*
- * Scan options:
- * bit 0: When this bit is set, passive scan.
- * bit 1: Band, when this bit is set we scan
- * in the 5Ghz band.
- * bit 2: voice mode, 0 for normal scan.
- * bit 3: scan priority, 1 for high priority.
- */
- __le16 scan_options;
-
- /* Number of channels to scan */
- u8 num_channels;
-
- /* Number opf probe requests to send, per channel */
- u8 num_probe_requests;
-
- /* Rate and modulation for probe requests */
- __le16 tx_rate;
-
- u8 tid_trigger;
- u8 ssid_len;
- u8 ssid[32];
-
-} __packed;
-
-struct wl1251_scan_ch_parameters {
- __le32 min_duration; /* in TU */
- __le32 max_duration; /* in TU */
- u32 bssid_lsb;
- u16 bssid_msb;
-
- /*
- * bits 0-3: Early termination count.
- * bits 4-5: Early termination condition.
- */
- u8 early_termination;
-
- u8 tx_power_att;
- u8 channel;
- u8 pad[3];
-} __packed;
-
-/* SCAN parameters */
-#define SCAN_MAX_NUM_OF_CHANNELS 16
-
-struct wl1251_cmd_scan {
- struct wl1251_cmd_header header;
-
- struct wl1251_scan_parameters params;
- struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
-} __packed;
-
-enum {
- BSS_TYPE_IBSS = 0,
- BSS_TYPE_STA_BSS = 2,
- BSS_TYPE_AP_BSS = 3,
- MAX_BSS_TYPE = 0xFF
-};
-
-#define JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */
-#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE 0x01 /* Early wakeup time */
-
-
-struct cmd_join {
- struct wl1251_cmd_header header;
-
- u32 bssid_lsb;
- u16 bssid_msb;
- u16 beacon_interval; /* in TBTTs */
- u32 rx_config_options;
- u32 rx_filter_options;
-
- /*
- * The target uses this field to determine the rate at
- * which to transmit control frame responses (such as
- * ACK or CTS frames).
- */
- u16 basic_rate_set;
- u8 dtim_interval;
- u8 tx_ctrl_frame_rate; /* OBSOLETE */
- u8 tx_ctrl_frame_mod; /* OBSOLETE */
- /*
- * bits 0-2: This bitwise field specifies the type
- * of BSS to start or join (BSS_TYPE_*).
- * bit 4: Band - The radio band in which to join
- * or start.
- * 0 - 2.4GHz band
- * 1 - 5GHz band
- * bits 3, 5-7: Reserved
- */
- u8 bss_type;
- u8 channel;
- u8 ssid_len;
- u8 ssid[IW_ESSID_MAX_SIZE];
- u8 ctrl; /* JOIN_CMD_CTRL_* */
- u8 tx_mgt_frame_rate; /* OBSOLETE */
- u8 tx_mgt_frame_mod; /* OBSOLETE */
- u8 reserved;
-} __packed;
-
-struct cmd_enabledisable_path {
- struct wl1251_cmd_header header;
-
- u8 channel;
- u8 padding[3];
-} __packed;
-
-#define WL1251_MAX_TEMPLATE_SIZE 300
-
-struct wl1251_cmd_packet_template {
- struct wl1251_cmd_header header;
-
- __le16 size;
- u8 data[0];
-} __packed;
-
-#define TIM_ELE_ID 5
-#define PARTIAL_VBM_MAX 251
-
-struct wl1251_tim {
- u8 identity;
- u8 length;
- u8 dtim_count;
- u8 dtim_period;
- u8 bitmap_ctrl;
- u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
-} __packed;
-
-/* Virtual Bit Map update */
-struct wl1251_cmd_vbm_update {
- struct wl1251_cmd_header header;
- __le16 len;
- u8 padding[2];
- struct wl1251_tim tim;
-} __packed;
-
-enum wl1251_cmd_ps_mode {
- STATION_ACTIVE_MODE,
- STATION_POWER_SAVE_MODE
-};
-
-struct wl1251_cmd_ps_params {
- struct wl1251_cmd_header header;
-
- u8 ps_mode; /* STATION_* */
- u8 send_null_data; /* Do we have to send NULL data packet ? */
- u8 retries; /* Number of retires for the initial NULL data packet */
-
- /*
- * TUs during which the target stays awake after switching
- * to power save mode.
- */
- u8 hang_over_period;
- u16 null_data_rate;
- u8 pad[2];
-} __packed;
-
-struct wl1251_cmd_trigger_scan_to {
- struct wl1251_cmd_header header;
-
- u32 timeout;
-};
-
-/* HW encryption keys */
-#define NUM_ACCESS_CATEGORIES_COPY 4
-#define MAX_KEY_SIZE 32
-
-/* When set, disable HW encryption */
-#define DF_ENCRYPTION_DISABLE 0x01
-/* When set, disable HW decryption */
-#define DF_SNIFF_MODE_ENABLE 0x80
-
-enum wl1251_cmd_key_action {
- KEY_ADD_OR_REPLACE = 1,
- KEY_REMOVE = 2,
- KEY_SET_ID = 3,
- MAX_KEY_ACTION = 0xffff,
-};
-
-enum wl1251_cmd_key_type {
- KEY_WEP_DEFAULT = 0,
- KEY_WEP_ADDR = 1,
- KEY_AES_GROUP = 4,
- KEY_AES_PAIRWISE = 5,
- KEY_WEP_GROUP = 6,
- KEY_TKIP_MIC_GROUP = 10,
- KEY_TKIP_MIC_PAIRWISE = 11,
-};
-
-/*
- *
- * key_type_e key size key format
- * ---------- --------- ----------
- * 0x00 5, 13, 29 Key data
- * 0x01 5, 13, 29 Key data
- * 0x04 16 16 bytes of key data
- * 0x05 16 16 bytes of key data
- * 0x0a 32 16 bytes of TKIP key data
- * 8 bytes of RX MIC key data
- * 8 bytes of TX MIC key data
- * 0x0b 32 16 bytes of TKIP key data
- * 8 bytes of RX MIC key data
- * 8 bytes of TX MIC key data
- *
- */
-
-struct wl1251_cmd_set_keys {
- struct wl1251_cmd_header header;
-
- /* Ignored for default WEP key */
- u8 addr[ETH_ALEN];
-
- /* key_action_e */
- u16 key_action;
-
- u16 reserved_1;
-
- /* key size in bytes */
- u8 key_size;
-
- /* key_type_e */
- u8 key_type;
- u8 ssid_profile;
-
- /*
- * TKIP, AES: frame's key id field.
- * For WEP default key: key id;
- */
- u8 id;
- u8 reserved_2[6];
- u8 key[MAX_KEY_SIZE];
- u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
- u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
-} __packed;
-
-
-#endif /* __WL1251_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
deleted file mode 100644
index 5e4465ac08fa..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251_debugfs.h"
-
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-
-#include "wl1251.h"
-#include "wl1251_acx.h"
-#include "wl1251_ps.h"
-
-/* ms */
-#define WL1251_DEBUGFS_STATS_LIFETIME 1000
-
-/* debugfs macros idea from mac80211 */
-
-#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
-static ssize_t name## _read(struct file *file, char __user *userbuf, \
- size_t count, loff_t *ppos) \
-{ \
- struct wl1251 *wl = file->private_data; \
- char buf[buflen]; \
- int res; \
- \
- res = scnprintf(buf, buflen, fmt "\n", ##value); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-} \
- \
-static const struct file_operations name## _ops = { \
- .read = name## _read, \
- .open = wl1251_open_file_generic, \
-};
-
-#define DEBUGFS_ADD(name, parent) \
- wl->debugfs.name = debugfs_create_file(#name, 0400, parent, \
- wl, &name## _ops); \
- if (IS_ERR(wl->debugfs.name)) { \
- ret = PTR_ERR(wl->debugfs.name); \
- wl->debugfs.name = NULL; \
- goto out; \
- }
-
-#define DEBUGFS_DEL(name) \
- do { \
- debugfs_remove(wl->debugfs.name); \
- wl->debugfs.name = NULL; \
- } while (0)
-
-#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt) \
-static ssize_t sub## _ ##name## _read(struct file *file, \
- char __user *userbuf, \
- size_t count, loff_t *ppos) \
-{ \
- struct wl1251 *wl = file->private_data; \
- char buf[buflen]; \
- int res; \
- \
- wl1251_debugfs_update_stats(wl); \
- \
- res = scnprintf(buf, buflen, fmt "\n", \
- wl->stats.fw_stats->sub.name); \
- return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
-} \
- \
-static const struct file_operations sub## _ ##name## _ops = { \
- .read = sub## _ ##name## _read, \
- .open = wl1251_open_file_generic, \
-};
-
-#define DEBUGFS_FWSTATS_ADD(sub, name) \
- DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
-
-#define DEBUGFS_FWSTATS_DEL(sub, name) \
- DEBUGFS_DEL(sub## _ ##name)
-
-static void wl1251_debugfs_update_stats(struct wl1251 *wl)
-{
- int ret;
-
- mutex_lock(&wl->mutex);
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- if (wl->state == WL1251_STATE_ON &&
- time_after(jiffies, wl->stats.fw_stats_update +
- msecs_to_jiffies(WL1251_DEBUGFS_STATS_LIFETIME))) {
- wl1251_acx_statistics(wl, wl->stats.fw_stats);
- wl->stats.fw_stats_update = jiffies;
- }
-
- wl1251_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
-/* skipping wep.reserved */
-DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
-/* skipping cont_miss_bcns_spread for now */
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
- 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
-
-DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
-DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
- wl->stats.excessive_retries);
-
-static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct wl1251 *wl = file->private_data;
- u32 queue_len;
- char buf[20];
- int res;
-
- queue_len = skb_queue_len(&wl->tx_queue);
-
- res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
- return simple_read_from_buffer(userbuf, count, ppos, buf, res);
-}
-
-static const struct file_operations tx_queue_len_ops = {
- .read = tx_queue_len_read,
- .open = wl1251_open_file_generic,
-};
-
-static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct wl1251 *wl = file->private_data;
- char buf[3], status;
- int len;
-
- if (wl->tx_queue_stopped)
- status = 's';
- else
- status = 'r';
-
- len = scnprintf(buf, sizeof(buf), "%c\n", status);
- return simple_read_from_buffer(userbuf, count, ppos, buf, len);
-}
-
-static const struct file_operations tx_queue_status_ops = {
- .read = tx_queue_status_read,
- .open = wl1251_open_file_generic,
-};
-
-static void wl1251_debugfs_delete_files(struct wl1251 *wl)
-{
- DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
-
- DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
- DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
- DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
- DEBUGFS_FWSTATS_DEL(rx, dropped);
- DEBUGFS_FWSTATS_DEL(rx, fcs_err);
- DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
- DEBUGFS_FWSTATS_DEL(rx, path_reset);
- DEBUGFS_FWSTATS_DEL(rx, reset_counter);
-
- DEBUGFS_FWSTATS_DEL(dma, rx_requested);
- DEBUGFS_FWSTATS_DEL(dma, rx_errors);
- DEBUGFS_FWSTATS_DEL(dma, tx_requested);
- DEBUGFS_FWSTATS_DEL(dma, tx_errors);
-
- DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
- DEBUGFS_FWSTATS_DEL(isr, fiqs);
- DEBUGFS_FWSTATS_DEL(isr, rx_headers);
- DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
- DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
- DEBUGFS_FWSTATS_DEL(isr, irqs);
- DEBUGFS_FWSTATS_DEL(isr, tx_procs);
- DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
- DEBUGFS_FWSTATS_DEL(isr, dma0_done);
- DEBUGFS_FWSTATS_DEL(isr, dma1_done);
- DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
- DEBUGFS_FWSTATS_DEL(isr, commands);
- DEBUGFS_FWSTATS_DEL(isr, rx_procs);
- DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
- DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
- DEBUGFS_FWSTATS_DEL(isr, pci_pm);
- DEBUGFS_FWSTATS_DEL(isr, wakeups);
- DEBUGFS_FWSTATS_DEL(isr, low_rssi);
-
- DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
- DEBUGFS_FWSTATS_DEL(wep, default_key_count);
- /* skipping wep.reserved */
- DEBUGFS_FWSTATS_DEL(wep, key_not_found);
- DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
- DEBUGFS_FWSTATS_DEL(wep, packets);
- DEBUGFS_FWSTATS_DEL(wep, interrupt);
-
- DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
- DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
- DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
- DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
- DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
- DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
- DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
- DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
- DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
- DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
- DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
- DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
- /* skipping cont_miss_bcns_spread for now */
- DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
-
- DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
- DEBUGFS_FWSTATS_DEL(mic, calc_failure);
-
- DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
- DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
- DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
- DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
- DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
- DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
-
- DEBUGFS_FWSTATS_DEL(event, heart_beat);
- DEBUGFS_FWSTATS_DEL(event, calibration);
- DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
- DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
- DEBUGFS_FWSTATS_DEL(event, rx_pool);
- DEBUGFS_FWSTATS_DEL(event, oom_late);
- DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
- DEBUGFS_FWSTATS_DEL(event, tx_stuck);
-
- DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
- DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
- DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
- DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
- DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
- DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
- DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
-
- DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
- DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
-
- DEBUGFS_DEL(tx_queue_len);
- DEBUGFS_DEL(tx_queue_status);
- DEBUGFS_DEL(retry_count);
- DEBUGFS_DEL(excessive_retries);
-}
-
-static int wl1251_debugfs_add_files(struct wl1251 *wl)
-{
- int ret = 0;
-
- DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
-
- DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
- DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
- DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
- DEBUGFS_FWSTATS_ADD(rx, dropped);
- DEBUGFS_FWSTATS_ADD(rx, fcs_err);
- DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
- DEBUGFS_FWSTATS_ADD(rx, path_reset);
- DEBUGFS_FWSTATS_ADD(rx, reset_counter);
-
- DEBUGFS_FWSTATS_ADD(dma, rx_requested);
- DEBUGFS_FWSTATS_ADD(dma, rx_errors);
- DEBUGFS_FWSTATS_ADD(dma, tx_requested);
- DEBUGFS_FWSTATS_ADD(dma, tx_errors);
-
- DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
- DEBUGFS_FWSTATS_ADD(isr, fiqs);
- DEBUGFS_FWSTATS_ADD(isr, rx_headers);
- DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
- DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
- DEBUGFS_FWSTATS_ADD(isr, irqs);
- DEBUGFS_FWSTATS_ADD(isr, tx_procs);
- DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
- DEBUGFS_FWSTATS_ADD(isr, dma0_done);
- DEBUGFS_FWSTATS_ADD(isr, dma1_done);
- DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
- DEBUGFS_FWSTATS_ADD(isr, commands);
- DEBUGFS_FWSTATS_ADD(isr, rx_procs);
- DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
- DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
- DEBUGFS_FWSTATS_ADD(isr, pci_pm);
- DEBUGFS_FWSTATS_ADD(isr, wakeups);
- DEBUGFS_FWSTATS_ADD(isr, low_rssi);
-
- DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
- DEBUGFS_FWSTATS_ADD(wep, default_key_count);
- /* skipping wep.reserved */
- DEBUGFS_FWSTATS_ADD(wep, key_not_found);
- DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
- DEBUGFS_FWSTATS_ADD(wep, packets);
- DEBUGFS_FWSTATS_ADD(wep, interrupt);
-
- DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
- DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
- DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
- DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
- DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
- DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
- DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
- DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
- DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
- DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
- DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
- DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
- /* skipping cont_miss_bcns_spread for now */
- DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
-
- DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
- DEBUGFS_FWSTATS_ADD(mic, calc_failure);
-
- DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
- DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
- DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
- DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
-
- DEBUGFS_FWSTATS_ADD(event, heart_beat);
- DEBUGFS_FWSTATS_ADD(event, calibration);
- DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
- DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
- DEBUGFS_FWSTATS_ADD(event, rx_pool);
- DEBUGFS_FWSTATS_ADD(event, oom_late);
- DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
- DEBUGFS_FWSTATS_ADD(event, tx_stuck);
-
- DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
- DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
- DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
- DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
- DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
- DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
- DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
-
- DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
- DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
- DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
-
- DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
- DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
- DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
- DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
-
-out:
- if (ret < 0)
- wl1251_debugfs_delete_files(wl);
-
- return ret;
-}
-
-void wl1251_debugfs_reset(struct wl1251 *wl)
-{
- if (wl->stats.fw_stats != NULL)
- memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
- wl->stats.retry_count = 0;
- wl->stats.excessive_retries = 0;
-}
-
-int wl1251_debugfs_init(struct wl1251 *wl)
-{
- int ret;
-
- wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
-
- if (IS_ERR(wl->debugfs.rootdir)) {
- ret = PTR_ERR(wl->debugfs.rootdir);
- wl->debugfs.rootdir = NULL;
- goto err;
- }
-
- wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
- wl->debugfs.rootdir);
-
- if (IS_ERR(wl->debugfs.fw_statistics)) {
- ret = PTR_ERR(wl->debugfs.fw_statistics);
- wl->debugfs.fw_statistics = NULL;
- goto err_root;
- }
-
- wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
- GFP_KERNEL);
-
- if (!wl->stats.fw_stats) {
- ret = -ENOMEM;
- goto err_fw;
- }
-
- wl->stats.fw_stats_update = jiffies;
-
- ret = wl1251_debugfs_add_files(wl);
-
- if (ret < 0)
- goto err_file;
-
- return 0;
-
-err_file:
- kfree(wl->stats.fw_stats);
- wl->stats.fw_stats = NULL;
-
-err_fw:
- debugfs_remove(wl->debugfs.fw_statistics);
- wl->debugfs.fw_statistics = NULL;
-
-err_root:
- debugfs_remove(wl->debugfs.rootdir);
- wl->debugfs.rootdir = NULL;
-
-err:
- return ret;
-}
-
-void wl1251_debugfs_exit(struct wl1251 *wl)
-{
- wl1251_debugfs_delete_files(wl);
-
- kfree(wl->stats.fw_stats);
- wl->stats.fw_stats = NULL;
-
- debugfs_remove(wl->debugfs.fw_statistics);
- wl->debugfs.fw_statistics = NULL;
-
- debugfs_remove(wl->debugfs.rootdir);
- wl->debugfs.rootdir = NULL;
-
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl12xx/wl1251_debugfs.h
deleted file mode 100644
index 6dc3d080853c..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef WL1251_DEBUGFS_H
-#define WL1251_DEBUGFS_H
-
-#include "wl1251.h"
-
-int wl1251_debugfs_init(struct wl1251 *wl);
-void wl1251_debugfs_exit(struct wl1251 *wl);
-void wl1251_debugfs_reset(struct wl1251 *wl);
-
-#endif /* WL1251_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c
deleted file mode 100644
index 020d764f9c13..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_event.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_event.h"
-#include "wl1251_ps.h"
-
-static int wl1251_event_scan_complete(struct wl1251 *wl,
- struct event_mailbox *mbox)
-{
- wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
- mbox->scheduled_scan_status,
- mbox->scheduled_scan_channels);
-
- if (wl->scanning) {
- mutex_unlock(&wl->mutex);
- ieee80211_scan_completed(wl->hw, false);
- mutex_lock(&wl->mutex);
- wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
- wl->scanning = false;
- }
-
- return 0;
-}
-
-static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
-{
- wl1251_debug(DEBUG_EVENT, "MBOX DUMP:");
- wl1251_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
- wl1251_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
-}
-
-static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
-{
- int ret;
- u32 vector;
-
- wl1251_event_mbox_dump(mbox);
-
- vector = mbox->events_vector & ~(mbox->events_mask);
- wl1251_debug(DEBUG_EVENT, "vector: 0x%x", vector);
-
- if (vector & SCAN_COMPLETE_EVENT_ID) {
- ret = wl1251_event_scan_complete(wl, mbox);
- if (ret < 0)
- return ret;
- }
-
- if (vector & BSS_LOSE_EVENT_ID) {
- wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
-
- if (wl->psm_requested && wl->psm) {
- ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
- if (ret < 0)
- return ret;
- }
- }
-
- if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) {
- wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
-
- /* indicate to the stack, that beacons have been lost */
- ieee80211_beacon_loss(wl->vif);
- }
-
- if (vector & REGAINED_BSS_EVENT_ID) {
- if (wl->psm_requested) {
- ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
- if (ret < 0)
- return ret;
- }
- }
-
- return 0;
-}
-
-int wl1251_event_unmask(struct wl1251 *wl)
-{
- int ret;
-
- ret = wl1251_acx_event_mbox_mask(wl, ~(wl->event_mask));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-void wl1251_event_mbox_config(struct wl1251 *wl)
-{
- wl->mbox_ptr[0] = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
- wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
-
- wl1251_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
- wl->mbox_ptr[0], wl->mbox_ptr[1]);
-}
-
-int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num)
-{
- struct event_mailbox mbox;
- int ret;
-
- wl1251_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
-
- if (mbox_num > 1)
- return -EINVAL;
-
- /* first we read the mbox descriptor */
- wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
- sizeof(struct event_mailbox));
-
- /* process the descriptor */
- ret = wl1251_event_process(wl, &mbox);
- if (ret < 0)
- return ret;
-
- /* then we let the firmware know it can go on...*/
- wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
-
- return 0;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl12xx/wl1251_event.h
deleted file mode 100644
index f48a2b66bc5a..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_event.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_EVENT_H__
-#define __WL1251_EVENT_H__
-
-/*
- * Mbox events
- *
- * The event mechanism is based on a pair of event buffers (buffers A and
- * B) at fixed locations in the target's memory. The host processes one
- * buffer while the other buffer continues to collect events. If the host
- * is not processing events, an interrupt is issued to signal that a buffer
- * is ready. Once the host is done with processing events from one buffer,
- * it signals the target (with an ACK interrupt) that the event buffer is
- * free.
- */
-
-enum {
- RESERVED1_EVENT_ID = BIT(0),
- RESERVED2_EVENT_ID = BIT(1),
- MEASUREMENT_START_EVENT_ID = BIT(2),
- SCAN_COMPLETE_EVENT_ID = BIT(3),
- CALIBRATION_COMPLETE_EVENT_ID = BIT(4),
- ROAMING_TRIGGER_LOW_RSSI_EVENT_ID = BIT(5),
- PS_REPORT_EVENT_ID = BIT(6),
- SYNCHRONIZATION_TIMEOUT_EVENT_ID = BIT(7),
- HEALTH_REPORT_EVENT_ID = BIT(8),
- ACI_DETECTION_EVENT_ID = BIT(9),
- DEBUG_REPORT_EVENT_ID = BIT(10),
- MAC_STATUS_EVENT_ID = BIT(11),
- DISCONNECT_EVENT_COMPLETE_ID = BIT(12),
- JOIN_EVENT_COMPLETE_ID = BIT(13),
- CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(14),
- BSS_LOSE_EVENT_ID = BIT(15),
- ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(16),
- MEASUREMENT_COMPLETE_EVENT_ID = BIT(17),
- AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(18),
- SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(19),
- PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(20),
- RESET_BSS_EVENT_ID = BIT(21),
- REGAINED_BSS_EVENT_ID = BIT(22),
- ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID = BIT(23),
- ROAMING_TRIGGER_LOW_SNR_EVENT_ID = BIT(24),
- ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID = BIT(25),
-
- DBG_EVENT_ID = BIT(26),
- BT_PTA_SENSE_EVENT_ID = BIT(27),
- BT_PTA_PREDICTION_EVENT_ID = BIT(28),
- BT_PTA_AVALANCHE_EVENT_ID = BIT(29),
-
- PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(30),
-
- EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff,
-};
-
-struct event_debug_report {
- u8 debug_event_id;
- u8 num_params;
- u16 pad;
- u32 report_1;
- u32 report_2;
- u32 report_3;
-} __packed;
-
-struct event_mailbox {
- u32 events_vector;
- u32 events_mask;
- u32 reserved_1;
- u32 reserved_2;
-
- char average_rssi_level;
- u8 ps_status;
- u8 channel_switch_status;
- u8 scheduled_scan_status;
-
- /* Channels scanned by the scheduled scan */
- u16 scheduled_scan_channels;
-
- /* If bit 0 is set -> target's fatal error */
- u16 health_report;
- u16 bad_fft_counter;
- u8 bt_pta_sense_info;
- u8 bt_pta_protective_info;
- u32 reserved;
- u32 debug_report[2];
-
- /* Number of FCS errors since last event */
- u32 fcs_err_counter;
-
- struct event_debug_report report;
- u8 average_snr_level;
- u8 padding[19];
-} __packed;
-
-int wl1251_event_unmask(struct wl1251 *wl);
-void wl1251_event_mbox_config(struct wl1251 *wl);
-int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c
deleted file mode 100644
index b538bdd7b320..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "wl1251_init.h"
-#include "wl12xx_80211.h"
-#include "wl1251_acx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_reg.h"
-
-int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
-{
- int ret;
-
- ret = wl1251_acx_feature_cfg(wl);
- if (ret < 0) {
- wl1251_warning("couldn't set feature config");
- return ret;
- }
-
- ret = wl1251_acx_default_key(wl, wl->default_key);
- if (ret < 0) {
- wl1251_warning("couldn't set default key");
- return ret;
- }
-
- return 0;
-}
-
-int wl1251_hw_init_templates_config(struct wl1251 *wl)
-{
- int ret;
- u8 partial_vbm[PARTIAL_VBM_MAX];
-
- /* send empty templates for fw memory reservation */
- ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
- sizeof(struct wl12xx_probe_req_template));
- if (ret < 0)
- return ret;
-
- ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, NULL,
- sizeof(struct wl12xx_null_data_template));
- if (ret < 0)
- return ret;
-
- ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, NULL,
- sizeof(struct wl12xx_ps_poll_template));
- if (ret < 0)
- return ret;
-
- ret = wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
- sizeof
- (struct wl12xx_qos_null_data_template));
- if (ret < 0)
- return ret;
-
- ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
- sizeof
- (struct wl12xx_probe_resp_template));
- if (ret < 0)
- return ret;
-
- ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL,
- sizeof
- (struct wl12xx_beacon_template));
- if (ret < 0)
- return ret;
-
- /* tim templates, first reserve space then allocate an empty one */
- memset(partial_vbm, 0, PARTIAL_VBM_MAX);
- ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
- if (ret < 0)
- return ret;
-
- ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter)
-{
- int ret;
-
- ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_rx_config(wl, config, filter);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1251_hw_init_phy_config(struct wl1251 *wl)
-{
- int ret;
-
- ret = wl1251_acx_pd_threshold(wl);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_group_address_tbl(wl);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_service_period_timeout(wl);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1251_hw_init_beacon_filter(struct wl1251 *wl)
-{
- int ret;
-
- /* disable beacon filtering at this stage */
- ret = wl1251_acx_beacon_filter_opt(wl, false);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_beacon_filter_table(wl);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1251_hw_init_pta(struct wl1251 *wl)
-{
- int ret;
-
- ret = wl1251_acx_sg_enable(wl);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_sg_cfg(wl);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1251_hw_init_energy_detection(struct wl1251 *wl)
-{
- int ret;
-
- ret = wl1251_acx_cca_threshold(wl);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl)
-{
- int ret;
-
- ret = wl1251_acx_bcn_dtim_options(wl);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-int wl1251_hw_init_power_auth(struct wl1251 *wl)
-{
- return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
-}
-
-int wl1251_hw_init_mem_config(struct wl1251 *wl)
-{
- int ret;
-
- ret = wl1251_acx_mem_cfg(wl);
- if (ret < 0)
- return ret;
-
- wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
- GFP_KERNEL);
- if (!wl->target_mem_map) {
- wl1251_error("couldn't allocate target memory map");
- return -ENOMEM;
- }
-
- /* we now ask for the firmware built memory map */
- ret = wl1251_acx_mem_map(wl, wl->target_mem_map,
- sizeof(struct wl1251_acx_mem_map));
- if (ret < 0) {
- wl1251_error("couldn't retrieve firmware memory map");
- kfree(wl->target_mem_map);
- wl->target_mem_map = NULL;
- return ret;
- }
-
- return 0;
-}
-
-static int wl1251_hw_init_txq_fill(u8 qid,
- struct acx_tx_queue_qos_config *config,
- u32 num_blocks)
-{
- config->qid = qid;
-
- switch (qid) {
- case QOS_AC_BE:
- config->high_threshold =
- (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
- config->low_threshold =
- (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
- break;
- case QOS_AC_BK:
- config->high_threshold =
- (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
- config->low_threshold =
- (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
- break;
- case QOS_AC_VI:
- config->high_threshold =
- (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
- config->low_threshold =
- (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
- break;
- case QOS_AC_VO:
- config->high_threshold =
- (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
- config->low_threshold =
- (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
- break;
- default:
- wl1251_error("Invalid TX queue id: %d", qid);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
-{
- struct acx_tx_queue_qos_config *config;
- struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
- int ret, i;
-
- wl1251_debug(DEBUG_ACX, "acx tx queue config");
-
- config = kzalloc(sizeof(*config), GFP_KERNEL);
- if (!config) {
- ret = -ENOMEM;
- goto out;
- }
-
- for (i = 0; i < MAX_NUM_OF_AC; i++) {
- ret = wl1251_hw_init_txq_fill(i, config,
- wl_mem_map->num_tx_mem_blocks);
- if (ret < 0)
- goto out;
-
- ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG,
- config, sizeof(*config));
- if (ret < 0)
- goto out;
- }
-
- wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
- wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
- wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
- wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
-
-out:
- kfree(config);
- return ret;
-}
-
-static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
-{
- int ret;
-
- /* asking for the data path parameters */
- wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
- GFP_KERNEL);
- if (!wl->data_path) {
- wl1251_error("Couldnt allocate data path parameters");
- return -ENOMEM;
- }
-
- ret = wl1251_acx_data_path_params(wl, wl->data_path);
- if (ret < 0) {
- kfree(wl->data_path);
- wl->data_path = NULL;
- return ret;
- }
-
- return 0;
-}
-
-
-int wl1251_hw_init(struct wl1251 *wl)
-{
- struct wl1251_acx_mem_map *wl_mem_map;
- int ret;
-
- ret = wl1251_hw_init_hwenc_config(wl);
- if (ret < 0)
- return ret;
-
- /* Template settings */
- ret = wl1251_hw_init_templates_config(wl);
- if (ret < 0)
- return ret;
-
- /* Default memory configuration */
- ret = wl1251_hw_init_mem_config(wl);
- if (ret < 0)
- return ret;
-
- /* Default data path configuration */
- ret = wl1251_hw_init_data_path_config(wl);
- if (ret < 0)
- goto out_free_memmap;
-
- /* RX config */
- ret = wl1251_hw_init_rx_config(wl,
- RX_CFG_PROMISCUOUS | RX_CFG_TSF,
- RX_FILTER_OPTION_DEF);
- /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
- RX_FILTER_OPTION_FILTER_ALL); */
- if (ret < 0)
- goto out_free_data_path;
-
- /* TX queues config */
- ret = wl1251_hw_init_tx_queue_config(wl);
- if (ret < 0)
- goto out_free_data_path;
-
- /* PHY layer config */
- ret = wl1251_hw_init_phy_config(wl);
- if (ret < 0)
- goto out_free_data_path;
-
- /* Initialize connection monitoring thresholds */
- ret = wl1251_acx_conn_monit_params(wl);
- if (ret < 0)
- goto out_free_data_path;
-
- /* Beacon filtering */
- ret = wl1251_hw_init_beacon_filter(wl);
- if (ret < 0)
- goto out_free_data_path;
-
- /* Bluetooth WLAN coexistence */
- ret = wl1251_hw_init_pta(wl);
- if (ret < 0)
- goto out_free_data_path;
-
- /* Energy detection */
- ret = wl1251_hw_init_energy_detection(wl);
- if (ret < 0)
- goto out_free_data_path;
-
- /* Beacons and boradcast settings */
- ret = wl1251_hw_init_beacon_broadcast(wl);
- if (ret < 0)
- goto out_free_data_path;
-
- /* Enable data path */
- ret = wl1251_cmd_data_path(wl, wl->channel, 1);
- if (ret < 0)
- goto out_free_data_path;
-
- /* Default power state */
- ret = wl1251_hw_init_power_auth(wl);
- if (ret < 0)
- goto out_free_data_path;
-
- wl_mem_map = wl->target_mem_map;
- wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
- wl_mem_map->num_tx_mem_blocks,
- wl->data_path->tx_control_addr,
- wl_mem_map->num_rx_mem_blocks,
- wl->data_path->rx_control_addr);
-
- return 0;
-
- out_free_data_path:
- kfree(wl->data_path);
-
- out_free_memmap:
- kfree(wl->target_mem_map);
-
- return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h
deleted file mode 100644
index 269cefb3e7d4..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_init.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_INIT_H__
-#define __WL1251_INIT_H__
-
-#include "wl1251.h"
-
-enum {
- /* best effort/legacy */
- AC_BE = 0,
-
- /* background */
- AC_BK = 1,
-
- /* video */
- AC_VI = 2,
-
- /* voice */
- AC_VO = 3,
-
- /* broadcast dummy access category */
- AC_BCAST = 4,
-
- NUM_ACCESS_CATEGORIES = 4
-};
-
-/* following are defult values for the IE fields*/
-#define CWMIN_BK 15
-#define CWMIN_BE 15
-#define CWMIN_VI 7
-#define CWMIN_VO 3
-#define CWMAX_BK 1023
-#define CWMAX_BE 63
-#define CWMAX_VI 15
-#define CWMAX_VO 7
-
-/* slot number setting to start transmission at PIFS interval */
-#define AIFS_PIFS 1
-
-/*
- * slot number setting to start transmission at DIFS interval - normal DCF
- * access
- */
-#define AIFS_DIFS 2
-
-#define AIFSN_BK 7
-#define AIFSN_BE 3
-#define AIFSN_VI AIFS_PIFS
-#define AIFSN_VO AIFS_PIFS
-#define TXOP_BK 0
-#define TXOP_BE 0
-#define TXOP_VI 3008
-#define TXOP_VO 1504
-
-int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
-int wl1251_hw_init_templates_config(struct wl1251 *wl);
-int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
-int wl1251_hw_init_phy_config(struct wl1251 *wl);
-int wl1251_hw_init_beacon_filter(struct wl1251 *wl);
-int wl1251_hw_init_pta(struct wl1251 *wl);
-int wl1251_hw_init_energy_detection(struct wl1251 *wl);
-int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl);
-int wl1251_hw_init_power_auth(struct wl1251 *wl);
-int wl1251_hw_init_mem_config(struct wl1251 *wl);
-int wl1251_hw_init(struct wl1251 *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c
deleted file mode 100644
index f1c232e0887f..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_io.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-
-/* FIXME: this is static data nowadays and the table can be removed */
-static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = {
- [ACX_REG_INTERRUPT_TRIG] = (REGISTERS_BASE + 0x0474),
- [ACX_REG_INTERRUPT_TRIG_H] = (REGISTERS_BASE + 0x0478),
- [ACX_REG_INTERRUPT_MASK] = (REGISTERS_BASE + 0x0494),
- [ACX_REG_HINT_MASK_SET] = (REGISTERS_BASE + 0x0498),
- [ACX_REG_HINT_MASK_CLR] = (REGISTERS_BASE + 0x049C),
- [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
- [ACX_REG_INTERRUPT_CLEAR] = (REGISTERS_BASE + 0x04A4),
- [ACX_REG_INTERRUPT_ACK] = (REGISTERS_BASE + 0x04A8),
- [ACX_REG_SLV_SOFT_RESET] = (REGISTERS_BASE + 0x0000),
- [ACX_REG_EE_START] = (REGISTERS_BASE + 0x080C),
- [ACX_REG_ECPU_CONTROL] = (REGISTERS_BASE + 0x0804)
-};
-
-static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr)
-{
- /* If the address is lower than REGISTERS_BASE, it means that this is
- * a chip-specific register address, so look it up in the registers
- * table */
- if (addr < REGISTERS_BASE) {
- /* Make sure we don't go over the table */
- if (addr >= ACX_REG_TABLE_LEN) {
- wl1251_error("address out of range (%d)", addr);
- return -EINVAL;
- }
- addr = wl1251_io_reg_table[addr];
- }
-
- return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
-}
-
-static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr)
-{
- return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
-}
-
-void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len)
-{
- int physical;
-
- physical = wl1251_translate_mem_addr(wl, addr);
-
- wl->if_ops->read(wl, physical, buf, len);
-}
-
-void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
-{
- int physical;
-
- physical = wl1251_translate_mem_addr(wl, addr);
-
- wl->if_ops->write(wl, physical, buf, len);
-}
-
-u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
-{
- return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr));
-}
-
-void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val)
-{
- wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val);
-}
-
-u32 wl1251_reg_read32(struct wl1251 *wl, int addr)
-{
- return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr));
-}
-
-void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
-{
- wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
-}
-
-/* Set the partitions to access the chip addresses.
- *
- * There are two VIRTUAL partitions (the memory partition and the
- * registers partition), which are mapped to two different areas of the
- * PHYSICAL (hardware) memory. This function also makes other checks to
- * ensure that the partitions are not overlapping. In the diagram below, the
- * memory partition comes before the register partition, but the opposite is
- * also supported.
- *
- * PHYSICAL address
- * space
- *
- * | |
- * ...+----+--> mem_start
- * VIRTUAL address ... | |
- * space ... | | [PART_0]
- * ... | |
- * 0x00000000 <--+----+... ...+----+--> mem_start + mem_size
- * | | ... | |
- * |MEM | ... | |
- * | | ... | |
- * part_size <--+----+... | | {unused area)
- * | | ... | |
- * |REG | ... | |
- * part_size | | ... | |
- * + <--+----+... ...+----+--> reg_start
- * reg_size ... | |
- * ... | | [PART_1]
- * ... | |
- * ...+----+--> reg_start + reg_size
- * | |
- *
- */
-void wl1251_set_partition(struct wl1251 *wl,
- u32 mem_start, u32 mem_size,
- u32 reg_start, u32 reg_size)
-{
- struct wl1251_partition partition[2];
-
- wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- mem_start, mem_size);
- wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
- reg_start, reg_size);
-
- /* Make sure that the two partitions together don't exceed the
- * address range */
- if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
- wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
- " address range. Truncating partition[0].");
- mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
- wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- mem_start, mem_size);
- wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
- reg_start, reg_size);
- }
-
- if ((mem_start < reg_start) &&
- ((mem_start + mem_size) > reg_start)) {
- /* Guarantee that the memory partition doesn't overlap the
- * registers partition */
- wl1251_debug(DEBUG_SPI, "End of partition[0] is "
- "overlapping partition[1]. Adjusted.");
- mem_size = reg_start - mem_start;
- wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- mem_start, mem_size);
- wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
- reg_start, reg_size);
- } else if ((reg_start < mem_start) &&
- ((reg_start + reg_size) > mem_start)) {
- /* Guarantee that the register partition doesn't overlap the
- * memory partition */
- wl1251_debug(DEBUG_SPI, "End of partition[1] is"
- " overlapping partition[0]. Adjusted.");
- reg_size = mem_start - reg_start;
- wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
- mem_start, mem_size);
- wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
- reg_start, reg_size);
- }
-
- partition[0].start = mem_start;
- partition[0].size = mem_size;
- partition[1].start = reg_start;
- partition[1].size = reg_size;
-
- wl->physical_mem_addr = mem_start;
- wl->physical_reg_addr = reg_start;
-
- wl->virtual_mem_addr = 0;
- wl->virtual_reg_addr = mem_size;
-
- wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition,
- sizeof(partition));
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
deleted file mode 100644
index c545e9d5f512..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_io.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __WL1251_IO_H__
-#define __WL1251_IO_H__
-
-#include "wl1251.h"
-
-#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
-
-#define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0
-#define HW_ACCESS_PART0_START_ADDR 0x1FFC4
-#define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8
-#define HW_ACCESS_PART1_START_ADDR 0x1FFCC
-
-#define HW_ACCESS_REGISTER_SIZE 4
-
-#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
-
-static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
-{
- u32 response;
-
- wl->if_ops->read(wl, addr, &response, sizeof(u32));
-
- return response;
-}
-
-static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
-{
- wl->if_ops->write(wl, addr, &val, sizeof(u32));
-}
-
-static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr)
-{
- u32 response;
-
- if (wl->if_ops->read_elp)
- wl->if_ops->read_elp(wl, addr, &response);
- else
- wl->if_ops->read(wl, addr, &response, sizeof(u32));
-
- return response;
-}
-
-static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val)
-{
- if (wl->if_ops->write_elp)
- wl->if_ops->write_elp(wl, addr, val);
- else
- wl->if_ops->write(wl, addr, &val, sizeof(u32));
-}
-
-/* Memory target IO, address is translated to partition 0 */
-void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
-void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len);
-u32 wl1251_mem_read32(struct wl1251 *wl, int addr);
-void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
-/* Registers IO */
-u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
-void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
-
-void wl1251_set_partition(struct wl1251 *wl,
- u32 part_start, u32 part_size,
- u32 reg_start, u32 reg_size);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
deleted file mode 100644
index 861a5f33761e..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ /dev/null
@@ -1,1442 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/crc32.h>
-#include <linux/etherdevice.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-
-#include "wl1251.h"
-#include "wl12xx_80211.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_cmd.h"
-#include "wl1251_event.h"
-#include "wl1251_tx.h"
-#include "wl1251_rx.h"
-#include "wl1251_ps.h"
-#include "wl1251_init.h"
-#include "wl1251_debugfs.h"
-#include "wl1251_boot.h"
-
-void wl1251_enable_interrupts(struct wl1251 *wl)
-{
- wl->if_ops->enable_irq(wl);
-}
-
-void wl1251_disable_interrupts(struct wl1251 *wl)
-{
- wl->if_ops->disable_irq(wl);
-}
-
-static void wl1251_power_off(struct wl1251 *wl)
-{
- wl->set_power(false);
-}
-
-static void wl1251_power_on(struct wl1251 *wl)
-{
- wl->set_power(true);
-}
-
-static int wl1251_fetch_firmware(struct wl1251 *wl)
-{
- const struct firmware *fw;
- struct device *dev = wiphy_dev(wl->hw->wiphy);
- int ret;
-
- ret = request_firmware(&fw, WL1251_FW_NAME, dev);
-
- if (ret < 0) {
- wl1251_error("could not get firmware: %d", ret);
- return ret;
- }
-
- if (fw->size % 4) {
- wl1251_error("firmware size is not multiple of 32 bits: %zu",
- fw->size);
- ret = -EILSEQ;
- goto out;
- }
-
- wl->fw_len = fw->size;
- wl->fw = vmalloc(wl->fw_len);
-
- if (!wl->fw) {
- wl1251_error("could not allocate memory for the firmware");
- ret = -ENOMEM;
- goto out;
- }
-
- memcpy(wl->fw, fw->data, wl->fw_len);
-
- ret = 0;
-
-out:
- release_firmware(fw);
-
- return ret;
-}
-
-static int wl1251_fetch_nvs(struct wl1251 *wl)
-{
- const struct firmware *fw;
- struct device *dev = wiphy_dev(wl->hw->wiphy);
- int ret;
-
- ret = request_firmware(&fw, WL1251_NVS_NAME, dev);
-
- if (ret < 0) {
- wl1251_error("could not get nvs file: %d", ret);
- return ret;
- }
-
- if (fw->size % 4) {
- wl1251_error("nvs size is not multiple of 32 bits: %zu",
- fw->size);
- ret = -EILSEQ;
- goto out;
- }
-
- wl->nvs_len = fw->size;
- wl->nvs = kmemdup(fw->data, wl->nvs_len, GFP_KERNEL);
-
- if (!wl->nvs) {
- wl1251_error("could not allocate memory for the nvs file");
- ret = -ENOMEM;
- goto out;
- }
-
- ret = 0;
-
-out:
- release_firmware(fw);
-
- return ret;
-}
-
-static void wl1251_fw_wakeup(struct wl1251 *wl)
-{
- u32 elp_reg;
-
- elp_reg = ELPCTRL_WAKE_UP;
- wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
- elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
-
- if (!(elp_reg & ELPCTRL_WLAN_READY))
- wl1251_warning("WLAN not ready");
-}
-
-static int wl1251_chip_wakeup(struct wl1251 *wl)
-{
- int ret = 0;
-
- wl1251_power_on(wl);
- msleep(WL1251_POWER_ON_SLEEP);
- wl->if_ops->reset(wl);
-
- /* We don't need a real memory partition here, because we only want
- * to use the registers at this point. */
- wl1251_set_partition(wl,
- 0x00000000,
- 0x00000000,
- REGISTERS_BASE,
- REGISTERS_DOWN_SIZE);
-
- /* ELP module wake up */
- wl1251_fw_wakeup(wl);
-
- /* whal_FwCtrl_BootSm() */
-
- /* 0. read chip id from CHIP_ID */
- wl->chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
-
- /* 1. check if chip id is valid */
-
- switch (wl->chip_id) {
- case CHIP_ID_1251_PG12:
- wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
- wl->chip_id);
- break;
- case CHIP_ID_1251_PG11:
- wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG11)",
- wl->chip_id);
- break;
- case CHIP_ID_1251_PG10:
- default:
- wl1251_error("unsupported chip id: 0x%x", wl->chip_id);
- ret = -ENODEV;
- goto out;
- }
-
- if (wl->fw == NULL) {
- ret = wl1251_fetch_firmware(wl);
- if (ret < 0)
- goto out;
- }
-
- if (wl->nvs == NULL && !wl->use_eeprom) {
- /* No NVS from netlink, try to get it from the filesystem */
- ret = wl1251_fetch_nvs(wl);
- if (ret < 0)
- goto out;
- }
-
-out:
- return ret;
-}
-
-#define WL1251_IRQ_LOOP_COUNT 10
-static void wl1251_irq_work(struct work_struct *work)
-{
- u32 intr, ctr = WL1251_IRQ_LOOP_COUNT;
- struct wl1251 *wl =
- container_of(work, struct wl1251, irq_work);
- int ret;
-
- mutex_lock(&wl->mutex);
-
- wl1251_debug(DEBUG_IRQ, "IRQ work");
-
- if (wl->state == WL1251_STATE_OFF)
- goto out;
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
-
- intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
- wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr);
-
- do {
- if (wl->data_path) {
- wl->rx_counter = wl1251_mem_read32(
- wl, wl->data_path->rx_control_addr);
-
- /* We handle a frmware bug here */
- switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
- case 0:
- wl1251_debug(DEBUG_IRQ,
- "RX: FW and host in sync");
- intr &= ~WL1251_ACX_INTR_RX0_DATA;
- intr &= ~WL1251_ACX_INTR_RX1_DATA;
- break;
- case 1:
- wl1251_debug(DEBUG_IRQ, "RX: FW +1");
- intr |= WL1251_ACX_INTR_RX0_DATA;
- intr &= ~WL1251_ACX_INTR_RX1_DATA;
- break;
- case 2:
- wl1251_debug(DEBUG_IRQ, "RX: FW +2");
- intr |= WL1251_ACX_INTR_RX0_DATA;
- intr |= WL1251_ACX_INTR_RX1_DATA;
- break;
- default:
- wl1251_warning(
- "RX: FW and host out of sync: %d",
- wl->rx_counter - wl->rx_handled);
- break;
- }
-
- wl->rx_handled = wl->rx_counter;
-
- wl1251_debug(DEBUG_IRQ, "RX counter: %d",
- wl->rx_counter);
- }
-
- intr &= wl->intr_mask;
-
- if (intr == 0) {
- wl1251_debug(DEBUG_IRQ, "INTR is 0");
- goto out_sleep;
- }
-
- if (intr & WL1251_ACX_INTR_RX0_DATA) {
- wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
- wl1251_rx(wl);
- }
-
- if (intr & WL1251_ACX_INTR_RX1_DATA) {
- wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
- wl1251_rx(wl);
- }
-
- if (intr & WL1251_ACX_INTR_TX_RESULT) {
- wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
- wl1251_tx_complete(wl);
- }
-
- if (intr & (WL1251_ACX_INTR_EVENT_A |
- WL1251_ACX_INTR_EVENT_B)) {
- wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)",
- intr);
- if (intr & WL1251_ACX_INTR_EVENT_A)
- wl1251_event_handle(wl, 0);
- else
- wl1251_event_handle(wl, 1);
- }
-
- if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
- wl1251_debug(DEBUG_IRQ,
- "WL1251_ACX_INTR_INIT_COMPLETE");
-
- if (--ctr == 0)
- break;
-
- intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
- } while (intr);
-
-out_sleep:
- wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
- wl1251_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
- u16 beacon_interval, u8 dtim_period)
-{
- int ret;
-
- ret = wl1251_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
- DEFAULT_HW_GEN_MODULATION_TYPE,
- wl->tx_mgmt_frm_rate,
- wl->tx_mgmt_frm_mod);
- if (ret < 0)
- goto out;
-
-
- ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval,
- dtim_period);
- if (ret < 0)
- goto out;
-
- /*
- * FIXME: we should wait for JOIN_EVENT_COMPLETE_ID but to simplify
- * locking we just sleep instead, for now
- */
- msleep(10);
-
-out:
- return ret;
-}
-
-static void wl1251_filter_work(struct work_struct *work)
-{
- struct wl1251 *wl =
- container_of(work, struct wl1251, filter_work);
- int ret;
-
- mutex_lock(&wl->mutex);
-
- if (wl->state == WL1251_STATE_OFF)
- goto out;
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int,
- wl->dtim_period);
- if (ret < 0)
- goto out_sleep;
-
-out_sleep:
- wl1251_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct wl1251 *wl = hw->priv;
-
- skb_queue_tail(&wl->tx_queue, skb);
-
- /*
- * The chip specific setup must run before the first TX packet -
- * before that, the tx_work will not be initialized!
- */
-
- ieee80211_queue_work(wl->hw, &wl->tx_work);
-
- /*
- * The workqueue is slow to process the tx_queue and we need stop
- * the queue here, otherwise the queue will get too long.
- */
- if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
- wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
- ieee80211_stop_queues(wl->hw);
-
- /*
- * FIXME: this is racy, the variable is not properly
- * protected. Maybe fix this by removing the stupid
- * variable altogether and checking the real queue state?
- */
- wl->tx_queue_stopped = true;
- }
-
- return NETDEV_TX_OK;
-}
-
-static int wl1251_op_start(struct ieee80211_hw *hw)
-{
- struct wl1251 *wl = hw->priv;
- struct wiphy *wiphy = hw->wiphy;
- int ret = 0;
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 start");
-
- mutex_lock(&wl->mutex);
-
- if (wl->state != WL1251_STATE_OFF) {
- wl1251_error("cannot start because not in off state: %d",
- wl->state);
- ret = -EBUSY;
- goto out;
- }
-
- ret = wl1251_chip_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1251_boot(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1251_hw_init(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1251_acx_station_id(wl);
- if (ret < 0)
- goto out;
-
- wl->state = WL1251_STATE_ON;
-
- wl1251_info("firmware booted (%s)", wl->fw_ver);
-
- /* update hw/fw version info in wiphy struct */
- wiphy->hw_version = wl->chip_id;
- strncpy(wiphy->fw_version, wl->fw_ver, sizeof(wiphy->fw_version));
-
-out:
- if (ret < 0)
- wl1251_power_off(wl);
-
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static void wl1251_op_stop(struct ieee80211_hw *hw)
-{
- struct wl1251 *wl = hw->priv;
-
- wl1251_info("down");
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 stop");
-
- mutex_lock(&wl->mutex);
-
- WARN_ON(wl->state != WL1251_STATE_ON);
-
- if (wl->scanning) {
- mutex_unlock(&wl->mutex);
- ieee80211_scan_completed(wl->hw, true);
- mutex_lock(&wl->mutex);
- wl->scanning = false;
- }
-
- wl->state = WL1251_STATE_OFF;
-
- wl1251_disable_interrupts(wl);
-
- mutex_unlock(&wl->mutex);
-
- cancel_work_sync(&wl->irq_work);
- cancel_work_sync(&wl->tx_work);
- cancel_work_sync(&wl->filter_work);
-
- mutex_lock(&wl->mutex);
-
- /* let's notify MAC80211 about the remaining pending TX frames */
- wl1251_tx_flush(wl);
- wl1251_power_off(wl);
-
- memset(wl->bssid, 0, ETH_ALEN);
- wl->listen_int = 1;
- wl->bss_type = MAX_BSS_TYPE;
-
- wl->data_in_count = 0;
- wl->rx_counter = 0;
- wl->rx_handled = 0;
- wl->rx_current_buffer = 0;
- wl->rx_last_id = 0;
- wl->next_tx_complete = 0;
- wl->elp = false;
- wl->psm = 0;
- wl->tx_queue_stopped = false;
- wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
- wl->channel = WL1251_DEFAULT_CHANNEL;
-
- wl1251_debugfs_reset(wl);
-
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_op_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct wl1251 *wl = hw->priv;
- int ret = 0;
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
- vif->type, vif->addr);
-
- mutex_lock(&wl->mutex);
- if (wl->vif) {
- ret = -EBUSY;
- goto out;
- }
-
- wl->vif = vif;
-
- switch (vif->type) {
- case NL80211_IFTYPE_STATION:
- wl->bss_type = BSS_TYPE_STA_BSS;
- break;
- case NL80211_IFTYPE_ADHOC:
- wl->bss_type = BSS_TYPE_IBSS;
- break;
- default:
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) {
- memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
- SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
- ret = wl1251_acx_station_id(wl);
- if (ret < 0)
- goto out;
- }
-
-out:
- mutex_unlock(&wl->mutex);
- return ret;
-}
-
-static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
-{
- struct wl1251 *wl = hw->priv;
-
- mutex_lock(&wl->mutex);
- wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
- wl->vif = NULL;
- mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_build_qos_null_data(struct wl1251 *wl)
-{
- struct ieee80211_qos_hdr template;
-
- memset(&template, 0, sizeof(template));
-
- memcpy(template.addr1, wl->bssid, ETH_ALEN);
- memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
- memcpy(template.addr3, wl->bssid, ETH_ALEN);
-
- template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_QOS_NULLFUNC |
- IEEE80211_FCTL_TODS);
-
- /* FIXME: not sure what priority to use here */
- template.qos_ctrl = cpu_to_le16(0);
-
- return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
- sizeof(template));
-}
-
-static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct wl1251 *wl = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
- int channel, ret = 0;
-
- channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
- channel,
- conf->flags & IEEE80211_CONF_PS ? "on" : "off",
- conf->power_level);
-
- mutex_lock(&wl->mutex);
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- if (channel != wl->channel) {
- wl->channel = channel;
-
- ret = wl1251_join(wl, wl->bss_type, wl->channel,
- wl->beacon_int, wl->dtim_period);
- if (ret < 0)
- goto out_sleep;
- }
-
- if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
- wl1251_debug(DEBUG_PSM, "psm enabled");
-
- wl->psm_requested = true;
-
- wl->dtim_period = conf->ps_dtim_period;
-
- ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
- wl->dtim_period);
-
- /*
- * mac80211 enables PSM only if we're already associated.
- */
- ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
- if (ret < 0)
- goto out_sleep;
- } else if (!(conf->flags & IEEE80211_CONF_PS) &&
- wl->psm_requested) {
- wl1251_debug(DEBUG_PSM, "psm disabled");
-
- wl->psm_requested = false;
-
- if (wl->psm) {
- ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
- if (ret < 0)
- goto out_sleep;
- }
- }
-
- if (conf->power_level != wl->power_level) {
- ret = wl1251_acx_tx_power(wl, conf->power_level);
- if (ret < 0)
- goto out_sleep;
-
- wl->power_level = conf->power_level;
- }
-
-out_sleep:
- wl1251_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
- FIF_ALLMULTI | \
- FIF_FCSFAIL | \
- FIF_BCN_PRBRESP_PROMISC | \
- FIF_CONTROL | \
- FIF_OTHER_BSS)
-
-static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed,
- unsigned int *total,u64 multicast)
-{
- struct wl1251 *wl = hw->priv;
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter");
-
- *total &= WL1251_SUPPORTED_FILTERS;
- changed &= WL1251_SUPPORTED_FILTERS;
-
- if (changed == 0)
- /* no filters which we support changed */
- return;
-
- /* FIXME: wl->rx_config and wl->rx_filter are not protected */
-
- wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
- wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
-
- if (*total & FIF_PROMISC_IN_BSS) {
- wl->rx_config |= CFG_BSSID_FILTER_EN;
- wl->rx_config |= CFG_RX_ALL_GOOD;
- }
- if (*total & FIF_ALLMULTI)
- /*
- * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
- * all multicast frames
- */
- wl->rx_config &= ~CFG_MC_FILTER_EN;
- if (*total & FIF_FCSFAIL)
- wl->rx_filter |= CFG_RX_FCS_ERROR;
- if (*total & FIF_BCN_PRBRESP_PROMISC) {
- wl->rx_config &= ~CFG_BSSID_FILTER_EN;
- wl->rx_config &= ~CFG_SSID_FILTER_EN;
- }
- if (*total & FIF_CONTROL)
- wl->rx_filter |= CFG_RX_CTL_EN;
- if (*total & FIF_OTHER_BSS)
- wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
-
- /*
- * FIXME: workqueues need to be properly cancelled on stop(), for
- * now let's just disable changing the filter settings. They will
- * be updated any on config().
- */
- /* schedule_work(&wl->filter_work); */
-}
-
-/* HW encryption */
-static int wl1251_set_key_type(struct wl1251 *wl,
- struct wl1251_cmd_set_keys *key,
- enum set_key_cmd cmd,
- struct ieee80211_key_conf *mac80211_key,
- const u8 *addr)
-{
- switch (mac80211_key->alg) {
- case ALG_WEP:
- if (is_broadcast_ether_addr(addr))
- key->key_type = KEY_WEP_DEFAULT;
- else
- key->key_type = KEY_WEP_ADDR;
-
- mac80211_key->hw_key_idx = mac80211_key->keyidx;
- break;
- case ALG_TKIP:
- if (is_broadcast_ether_addr(addr))
- key->key_type = KEY_TKIP_MIC_GROUP;
- else
- key->key_type = KEY_TKIP_MIC_PAIRWISE;
-
- mac80211_key->hw_key_idx = mac80211_key->keyidx;
- break;
- case ALG_CCMP:
- if (is_broadcast_ether_addr(addr))
- key->key_type = KEY_AES_GROUP;
- else
- key->key_type = KEY_AES_PAIRWISE;
- mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- break;
- default:
- wl1251_error("Unknown key algo 0x%x", mac80211_key->alg);
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
-{
- struct wl1251 *wl = hw->priv;
- struct wl1251_cmd_set_keys *wl_cmd;
- const u8 *addr;
- int ret;
-
- static const u8 bcast_addr[ETH_ALEN] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 set key");
-
- wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
- if (!wl_cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- addr = sta ? sta->addr : bcast_addr;
-
- wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
- wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
- wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
- key->alg, key->keyidx, key->keylen, key->flags);
- wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
-
- if (is_zero_ether_addr(addr)) {
- /* We dont support TX only encryption */
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- mutex_lock(&wl->mutex);
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out_unlock;
-
- switch (cmd) {
- case SET_KEY:
- wl_cmd->key_action = KEY_ADD_OR_REPLACE;
- break;
- case DISABLE_KEY:
- wl_cmd->key_action = KEY_REMOVE;
- break;
- default:
- wl1251_error("Unsupported key cmd 0x%x", cmd);
- break;
- }
-
- ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
- if (ret < 0) {
- wl1251_error("Set KEY type failed");
- goto out_sleep;
- }
-
- if (wl_cmd->key_type != KEY_WEP_DEFAULT)
- memcpy(wl_cmd->addr, addr, ETH_ALEN);
-
- if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
- (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
- /*
- * We get the key in the following form:
- * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
- * but the target is expecting:
- * TKIP - RX MIC - TX MIC
- */
- memcpy(wl_cmd->key, key->key, 16);
- memcpy(wl_cmd->key + 16, key->key + 24, 8);
- memcpy(wl_cmd->key + 24, key->key + 16, 8);
-
- } else {
- memcpy(wl_cmd->key, key->key, key->keylen);
- }
- wl_cmd->key_size = key->keylen;
-
- wl_cmd->id = key->keyidx;
- wl_cmd->ssid_profile = 0;
-
- wl1251_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd));
-
- ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
- if (ret < 0) {
- wl1251_warning("could not set keys");
- goto out_sleep;
- }
-
-out_sleep:
- wl1251_ps_elp_sleep(wl);
-
-out_unlock:
- mutex_unlock(&wl->mutex);
-
-out:
- kfree(wl_cmd);
-
- return ret;
-}
-
-static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
-{
- struct wl1251 *wl = hw->priv;
- struct sk_buff *skb;
- size_t ssid_len = 0;
- u8 *ssid = NULL;
- int ret;
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
-
- if (req->n_ssids) {
- ssid = req->ssids[0].ssid;
- ssid_len = req->ssids[0].ssid_len;
- }
-
- mutex_lock(&wl->mutex);
-
- if (wl->scanning) {
- wl1251_debug(DEBUG_SCAN, "scan already in progress");
- ret = -EINVAL;
- goto out;
- }
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
- req->ie, req->ie_len);
- if (!skb) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
- skb->len);
- dev_kfree_skb(skb);
- if (ret < 0)
- goto out_sleep;
-
- ret = wl1251_cmd_trigger_scan_to(wl, 0);
- if (ret < 0)
- goto out_sleep;
-
- wl->scanning = true;
-
- ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
- req->n_channels, WL1251_SCAN_NUM_PROBES);
- if (ret < 0) {
- wl->scanning = false;
- goto out_sleep;
- }
-
-out_sleep:
- wl1251_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
-{
- struct wl1251 *wl = hw->priv;
- int ret;
-
- mutex_lock(&wl->mutex);
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- ret = wl1251_acx_rts_threshold(wl, (u16) value);
- if (ret < 0)
- wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret);
-
- wl1251_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changed)
-{
- struct wl1251 *wl = hw->priv;
- struct sk_buff *beacon, *skb;
- int ret;
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
-
- mutex_lock(&wl->mutex);
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- if (changed & BSS_CHANGED_BSSID) {
- memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
-
- skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
- if (!skb)
- goto out_sleep;
-
- ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
- skb->data, skb->len);
- dev_kfree_skb(skb);
- if (ret < 0)
- goto out_sleep;
-
- ret = wl1251_build_qos_null_data(wl);
- if (ret < 0)
- goto out;
-
- if (wl->bss_type != BSS_TYPE_IBSS) {
- ret = wl1251_join(wl, wl->bss_type, wl->channel,
- wl->beacon_int, wl->dtim_period);
- if (ret < 0)
- goto out_sleep;
- }
- }
-
- if (changed & BSS_CHANGED_ASSOC) {
- if (bss_conf->assoc) {
- wl->beacon_int = bss_conf->beacon_int;
-
- skb = ieee80211_pspoll_get(wl->hw, wl->vif);
- if (!skb)
- goto out_sleep;
-
- ret = wl1251_cmd_template_set(wl, CMD_PS_POLL,
- skb->data,
- skb->len);
- dev_kfree_skb(skb);
- if (ret < 0)
- goto out_sleep;
-
- ret = wl1251_acx_aid(wl, bss_conf->aid);
- if (ret < 0)
- goto out_sleep;
- } else {
- /* use defaults when not associated */
- wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
- wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
- }
- }
- if (changed & BSS_CHANGED_ERP_SLOT) {
- if (bss_conf->use_short_slot)
- ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT);
- else
- ret = wl1251_acx_slot(wl, SLOT_TIME_LONG);
- if (ret < 0) {
- wl1251_warning("Set slot time failed %d", ret);
- goto out_sleep;
- }
- }
-
- if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- if (bss_conf->use_short_preamble)
- wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
- else
- wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
- }
-
- if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- if (bss_conf->use_cts_prot)
- ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE);
- else
- ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
- if (ret < 0) {
- wl1251_warning("Set ctsprotect failed %d", ret);
- goto out_sleep;
- }
- }
-
- if (changed & BSS_CHANGED_BEACON) {
- beacon = ieee80211_beacon_get(hw, vif);
- ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
- beacon->len);
-
- if (ret < 0) {
- dev_kfree_skb(beacon);
- goto out_sleep;
- }
-
- ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
- beacon->len);
-
- dev_kfree_skb(beacon);
-
- if (ret < 0)
- goto out_sleep;
-
- ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
- wl->channel, wl->dtim_period);
-
- if (ret < 0)
- goto out_sleep;
- }
-
-out_sleep:
- wl1251_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_rate wl1251_rates[] = {
- { .bitrate = 10,
- .hw_value = 0x1,
- .hw_value_short = 0x1, },
- { .bitrate = 20,
- .hw_value = 0x2,
- .hw_value_short = 0x2,
- .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 55,
- .hw_value = 0x4,
- .hw_value_short = 0x4,
- .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 110,
- .hw_value = 0x20,
- .hw_value_short = 0x20,
- .flags = IEEE80211_RATE_SHORT_PREAMBLE },
- { .bitrate = 60,
- .hw_value = 0x8,
- .hw_value_short = 0x8, },
- { .bitrate = 90,
- .hw_value = 0x10,
- .hw_value_short = 0x10, },
- { .bitrate = 120,
- .hw_value = 0x40,
- .hw_value_short = 0x40, },
- { .bitrate = 180,
- .hw_value = 0x80,
- .hw_value_short = 0x80, },
- { .bitrate = 240,
- .hw_value = 0x200,
- .hw_value_short = 0x200, },
- { .bitrate = 360,
- .hw_value = 0x400,
- .hw_value_short = 0x400, },
- { .bitrate = 480,
- .hw_value = 0x800,
- .hw_value_short = 0x800, },
- { .bitrate = 540,
- .hw_value = 0x1000,
- .hw_value_short = 0x1000, },
-};
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_channel wl1251_channels[] = {
- { .hw_value = 1, .center_freq = 2412},
- { .hw_value = 2, .center_freq = 2417},
- { .hw_value = 3, .center_freq = 2422},
- { .hw_value = 4, .center_freq = 2427},
- { .hw_value = 5, .center_freq = 2432},
- { .hw_value = 6, .center_freq = 2437},
- { .hw_value = 7, .center_freq = 2442},
- { .hw_value = 8, .center_freq = 2447},
- { .hw_value = 9, .center_freq = 2452},
- { .hw_value = 10, .center_freq = 2457},
- { .hw_value = 11, .center_freq = 2462},
- { .hw_value = 12, .center_freq = 2467},
- { .hw_value = 13, .center_freq = 2472},
-};
-
-static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- enum wl1251_acx_ps_scheme ps_scheme;
- struct wl1251 *wl = hw->priv;
- int ret;
-
- mutex_lock(&wl->mutex);
-
- wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
-
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
-
- /* mac80211 uses units of 32 usec */
- ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
- params->cw_min, params->cw_max,
- params->aifs, params->txop * 32);
- if (ret < 0)
- goto out_sleep;
-
- if (params->uapsd)
- ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
- else
- ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;
-
- ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
- CHANNEL_TYPE_EDCF,
- wl1251_tx_get_queue(queue), ps_scheme,
- WL1251_ACX_ACK_POLICY_LEGACY);
- if (ret < 0)
- goto out_sleep;
-
-out_sleep:
- wl1251_ps_elp_sleep(wl);
-
-out:
- mutex_unlock(&wl->mutex);
-
- return ret;
-}
-
-static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx,
- struct survey_info *survey)
-{
- struct wl1251 *wl = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
-
- if (idx != 0)
- return -ENOENT;
-
- survey->channel = conf->channel;
- survey->filled = SURVEY_INFO_NOISE_DBM;
- survey->noise = wl->noise;
-
- return 0;
-}
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_supported_band wl1251_band_2ghz = {
- .channels = wl1251_channels,
- .n_channels = ARRAY_SIZE(wl1251_channels),
- .bitrates = wl1251_rates,
- .n_bitrates = ARRAY_SIZE(wl1251_rates),
-};
-
-static const struct ieee80211_ops wl1251_ops = {
- .start = wl1251_op_start,
- .stop = wl1251_op_stop,
- .add_interface = wl1251_op_add_interface,
- .remove_interface = wl1251_op_remove_interface,
- .config = wl1251_op_config,
- .configure_filter = wl1251_op_configure_filter,
- .tx = wl1251_op_tx,
- .set_key = wl1251_op_set_key,
- .hw_scan = wl1251_op_hw_scan,
- .bss_info_changed = wl1251_op_bss_info_changed,
- .set_rts_threshold = wl1251_op_set_rts_threshold,
- .conf_tx = wl1251_op_conf_tx,
- .get_survey = wl1251_op_get_survey,
-};
-
-static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data)
-{
- unsigned long timeout;
-
- wl1251_reg_write32(wl, EE_ADDR, offset);
- wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ);
-
- /* EE_CTL_READ clears when data is ready */
- timeout = jiffies + msecs_to_jiffies(100);
- while (1) {
- if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ))
- break;
-
- if (time_after(jiffies, timeout))
- return -ETIMEDOUT;
-
- msleep(1);
- }
-
- *data = wl1251_reg_read32(wl, EE_DATA);
- return 0;
-}
-
-static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset,
- u8 *data, size_t len)
-{
- size_t i;
- int ret;
-
- wl1251_reg_write32(wl, EE_START, 0);
-
- for (i = 0; i < len; i++) {
- ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-static int wl1251_read_eeprom_mac(struct wl1251 *wl)
-{
- u8 mac[ETH_ALEN];
- int i, ret;
-
- wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE);
-
- ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac));
- if (ret < 0) {
- wl1251_warning("failed to read MAC address from EEPROM");
- return ret;
- }
-
- /* MAC is stored in reverse order */
- for (i = 0; i < ETH_ALEN; i++)
- wl->mac_addr[i] = mac[ETH_ALEN - i - 1];
-
- return 0;
-}
-
-static int wl1251_register_hw(struct wl1251 *wl)
-{
- int ret;
-
- if (wl->mac80211_registered)
- return 0;
-
- SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
-
- ret = ieee80211_register_hw(wl->hw);
- if (ret < 0) {
- wl1251_error("unable to register mac80211 hw: %d", ret);
- return ret;
- }
-
- wl->mac80211_registered = true;
-
- wl1251_notice("loaded");
-
- return 0;
-}
-
-int wl1251_init_ieee80211(struct wl1251 *wl)
-{
- int ret;
-
- /* The tx descriptor buffer and the TKIP space */
- wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
- + WL1251_TKIP_IV_SPACE;
-
- /* unit us */
- /* FIXME: find a proper value */
- wl->hw->channel_change_time = 10000;
-
- wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
- IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_BEACON_FILTER |
- IEEE80211_HW_SUPPORTS_UAPSD;
-
- wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
- wl->hw->wiphy->max_scan_ssids = 1;
- wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
-
- wl->hw->queues = 4;
-
- if (wl->use_eeprom)
- wl1251_read_eeprom_mac(wl);
-
- ret = wl1251_register_hw(wl);
- if (ret)
- goto out;
-
- wl1251_debugfs_init(wl);
- wl1251_notice("initialized");
-
- ret = 0;
-
-out:
- return ret;
-}
-EXPORT_SYMBOL_GPL(wl1251_init_ieee80211);
-
-struct ieee80211_hw *wl1251_alloc_hw(void)
-{
- struct ieee80211_hw *hw;
- struct wl1251 *wl;
- int i;
- static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
-
- hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
- if (!hw) {
- wl1251_error("could not alloc ieee80211_hw");
- return ERR_PTR(-ENOMEM);
- }
-
- wl = hw->priv;
- memset(wl, 0, sizeof(*wl));
-
- wl->hw = hw;
-
- wl->data_in_count = 0;
-
- skb_queue_head_init(&wl->tx_queue);
-
- INIT_WORK(&wl->filter_work, wl1251_filter_work);
- INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
- wl->channel = WL1251_DEFAULT_CHANNEL;
- wl->scanning = false;
- wl->default_key = 0;
- wl->listen_int = 1;
- wl->rx_counter = 0;
- wl->rx_handled = 0;
- wl->rx_current_buffer = 0;
- wl->rx_last_id = 0;
- wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
- wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
- wl->elp = false;
- wl->psm = 0;
- wl->psm_requested = false;
- wl->tx_queue_stopped = false;
- wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
- wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
- wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
- wl->vif = NULL;
-
- for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
- wl->tx_frames[i] = NULL;
-
- wl->next_tx_complete = 0;
-
- INIT_WORK(&wl->irq_work, wl1251_irq_work);
- INIT_WORK(&wl->tx_work, wl1251_tx_work);
-
- /*
- * In case our MAC address is not correctly set,
- * we use a random but Nokia MAC.
- */
- memcpy(wl->mac_addr, nokia_oui, 3);
- get_random_bytes(wl->mac_addr + 3, 3);
-
- wl->state = WL1251_STATE_OFF;
- mutex_init(&wl->mutex);
-
- wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
- wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
-
- wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
- if (!wl->rx_descriptor) {
- wl1251_error("could not allocate memory for rx descriptor");
- ieee80211_free_hw(hw);
- return ERR_PTR(-ENOMEM);
- }
-
- return hw;
-}
-EXPORT_SYMBOL_GPL(wl1251_alloc_hw);
-
-int wl1251_free_hw(struct wl1251 *wl)
-{
- ieee80211_unregister_hw(wl->hw);
-
- wl1251_debugfs_exit(wl);
-
- kfree(wl->target_mem_map);
- kfree(wl->data_path);
- vfree(wl->fw);
- wl->fw = NULL;
- kfree(wl->nvs);
- wl->nvs = NULL;
-
- kfree(wl->rx_descriptor);
- wl->rx_descriptor = NULL;
-
- ieee80211_free_hw(wl->hw);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(wl1251_free_hw);
-
-MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
-MODULE_FIRMWARE(WL1251_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
deleted file mode 100644
index b55cb2bd459a..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251_reg.h"
-#include "wl1251_ps.h"
-#include "wl1251_cmd.h"
-#include "wl1251_io.h"
-
-/* in ms */
-#define WL1251_WAKEUP_TIMEOUT 100
-
-void wl1251_elp_work(struct work_struct *work)
-{
- struct delayed_work *dwork;
- struct wl1251 *wl;
-
- dwork = container_of(work, struct delayed_work, work);
- wl = container_of(dwork, struct wl1251, elp_work);
-
- wl1251_debug(DEBUG_PSM, "elp work");
-
- mutex_lock(&wl->mutex);
-
- if (wl->elp || !wl->psm)
- goto out;
-
- wl1251_debug(DEBUG_PSM, "chip to elp");
- wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
- wl->elp = true;
-
-out:
- mutex_unlock(&wl->mutex);
-}
-
-#define ELP_ENTRY_DELAY 5
-
-/* Routines to toggle sleep mode while in ELP */
-void wl1251_ps_elp_sleep(struct wl1251 *wl)
-{
- unsigned long delay;
-
- if (wl->psm) {
- cancel_delayed_work(&wl->elp_work);
- delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
- ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
- }
-}
-
-int wl1251_ps_elp_wakeup(struct wl1251 *wl)
-{
- unsigned long timeout, start;
- u32 elp_reg;
-
- if (!wl->elp)
- return 0;
-
- wl1251_debug(DEBUG_PSM, "waking up chip from elp");
-
- start = jiffies;
- timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
-
- wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
-
- elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
-
- /*
- * FIXME: we should wait for irq from chip but, as a temporary
- * solution to simplify locking, let's poll instead
- */
- while (!(elp_reg & ELPCTRL_WLAN_READY)) {
- if (time_after(jiffies, timeout)) {
- wl1251_error("elp wakeup timeout");
- return -ETIMEDOUT;
- }
- msleep(1);
- elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
- }
-
- wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
- jiffies_to_msecs(jiffies - start));
-
- wl->elp = false;
-
- return 0;
-}
-
-static int wl1251_ps_set_elp(struct wl1251 *wl, bool enable)
-{
- int ret;
-
- if (enable) {
- wl1251_debug(DEBUG_PSM, "sleep auth psm/elp");
-
- ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
- if (ret < 0)
- return ret;
-
- wl1251_ps_elp_sleep(wl);
- } else {
- wl1251_debug(DEBUG_PSM, "sleep auth cam");
-
- /*
- * When the target is in ELP, we can only
- * access the ELP control register. Thus,
- * we have to wake the target up before
- * changing the power authorization.
- */
-
- wl1251_ps_elp_wakeup(wl);
-
- ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
-{
- int ret;
-
- switch (mode) {
- case STATION_POWER_SAVE_MODE:
- wl1251_debug(DEBUG_PSM, "entering psm");
-
- /* enable beacon filtering */
- ret = wl1251_acx_beacon_filter_opt(wl, true);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_wake_up_conditions(wl,
- WAKE_UP_EVENT_DTIM_BITMAP,
- wl->listen_int);
- if (ret < 0)
- return ret;
-
- ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
- if (ret < 0)
- return ret;
-
- ret = wl1251_ps_set_elp(wl, true);
- if (ret < 0)
- return ret;
-
- wl->psm = 1;
- break;
- case STATION_ACTIVE_MODE:
- default:
- wl1251_debug(DEBUG_PSM, "leaving psm");
- ret = wl1251_ps_set_elp(wl, false);
- if (ret < 0)
- return ret;
-
- /* disable beacon filtering */
- ret = wl1251_acx_beacon_filter_opt(wl, false);
- if (ret < 0)
- return ret;
-
- ret = wl1251_acx_wake_up_conditions(wl,
- WAKE_UP_EVENT_DTIM_BITMAP,
- wl->listen_int);
- if (ret < 0)
- return ret;
-
- ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
- if (ret < 0)
- return ret;
-
- wl->psm = 0;
- break;
- }
-
- return ret;
-}
-
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h
deleted file mode 100644
index c688ac57aee4..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_ps.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __WL1251_PS_H__
-#define __WL1251_PS_H__
-
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include "wl1251.h"
-#include "wl1251_acx.h"
-
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
-void wl1251_ps_elp_sleep(struct wl1251 *wl);
-int wl1251_ps_elp_wakeup(struct wl1251 *wl);
-void wl1251_elp_work(struct work_struct *work);
-
-
-#endif /* __WL1251_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h
deleted file mode 100644
index d16edd9bf06c..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_reg.h
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __REG_H__
-#define __REG_H__
-
-#include <linux/bitops.h>
-
-#define REGISTERS_BASE 0x00300000
-#define DRPW_BASE 0x00310000
-
-#define REGISTERS_DOWN_SIZE 0x00008800
-#define REGISTERS_WORK_SIZE 0x0000b000
-
-#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
-
-/* ELP register commands */
-#define ELPCTRL_WAKE_UP 0x1
-#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
-#define ELPCTRL_SLEEP 0x0
-/* ELP WLAN_READY bit */
-#define ELPCTRL_WLAN_READY 0x2
-
-/* Device Configuration registers*/
-#define SOR_CFG (REGISTERS_BASE + 0x0800)
-#define ECPU_CTRL (REGISTERS_BASE + 0x0804)
-#define HI_CFG (REGISTERS_BASE + 0x0808)
-
-/* EEPROM registers */
-#define EE_START (REGISTERS_BASE + 0x080C)
-#define EE_CTL (REGISTERS_BASE + 0x2000)
-#define EE_DATA (REGISTERS_BASE + 0x2004)
-#define EE_ADDR (REGISTERS_BASE + 0x2008)
-
-#define EE_CTL_READ 2
-
-#define CHIP_ID_B (REGISTERS_BASE + 0x5674)
-
-#define CHIP_ID_1251_PG10 (0x7010101)
-#define CHIP_ID_1251_PG11 (0x7020101)
-#define CHIP_ID_1251_PG12 (0x7030101)
-
-#define ENABLE (REGISTERS_BASE + 0x5450)
-
-/* Power Management registers */
-#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804)
-#define ELP_CMD (REGISTERS_BASE + 0x5808)
-#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810)
-#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814)
-#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818)
-
-#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820)
-
-/* Scratch Pad registers*/
-#define SCR_PAD0 (REGISTERS_BASE + 0x5608)
-#define SCR_PAD1 (REGISTERS_BASE + 0x560C)
-#define SCR_PAD2 (REGISTERS_BASE + 0x5610)
-#define SCR_PAD3 (REGISTERS_BASE + 0x5614)
-#define SCR_PAD4 (REGISTERS_BASE + 0x5618)
-#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C)
-#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620)
-#define SCR_PAD5 (REGISTERS_BASE + 0x5624)
-#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628)
-#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C)
-#define SCR_PAD6 (REGISTERS_BASE + 0x5630)
-#define SCR_PAD7 (REGISTERS_BASE + 0x5634)
-#define SCR_PAD8 (REGISTERS_BASE + 0x5638)
-#define SCR_PAD9 (REGISTERS_BASE + 0x563C)
-
-/* Spare registers*/
-#define SPARE_A1 (REGISTERS_BASE + 0x0994)
-#define SPARE_A2 (REGISTERS_BASE + 0x0998)
-#define SPARE_A3 (REGISTERS_BASE + 0x099C)
-#define SPARE_A4 (REGISTERS_BASE + 0x09A0)
-#define SPARE_A5 (REGISTERS_BASE + 0x09A4)
-#define SPARE_A6 (REGISTERS_BASE + 0x09A8)
-#define SPARE_A7 (REGISTERS_BASE + 0x09AC)
-#define SPARE_A8 (REGISTERS_BASE + 0x09B0)
-#define SPARE_B1 (REGISTERS_BASE + 0x5420)
-#define SPARE_B2 (REGISTERS_BASE + 0x5424)
-#define SPARE_B3 (REGISTERS_BASE + 0x5428)
-#define SPARE_B4 (REGISTERS_BASE + 0x542C)
-#define SPARE_B5 (REGISTERS_BASE + 0x5430)
-#define SPARE_B6 (REGISTERS_BASE + 0x5434)
-#define SPARE_B7 (REGISTERS_BASE + 0x5438)
-#define SPARE_B8 (REGISTERS_BASE + 0x543C)
-
-enum wl12xx_acx_int_reg {
- ACX_REG_INTERRUPT_TRIG,
- ACX_REG_INTERRUPT_TRIG_H,
-
-/*=============================================
- Host Interrupt Mask Register - 32bit (RW)
- ------------------------------------------
- Setting a bit in this register masks the
- corresponding interrupt to the host.
- 0 - RX0 - Rx first dubble buffer Data Interrupt
- 1 - TXD - Tx Data Interrupt
- 2 - TXXFR - Tx Transfer Interrupt
- 3 - RX1 - Rx second dubble buffer Data Interrupt
- 4 - RXXFR - Rx Transfer Interrupt
- 5 - EVENT_A - Event Mailbox interrupt
- 6 - EVENT_B - Event Mailbox interrupt
- 7 - WNONHST - Wake On Host Interrupt
- 8 - TRACE_A - Debug Trace interrupt
- 9 - TRACE_B - Debug Trace interrupt
- 10 - CDCMP - Command Complete Interrupt
- 11 -
- 12 -
- 13 -
- 14 - ICOMP - Initialization Complete Interrupt
- 16 - SG SE - Soft Gemini - Sense enable interrupt
- 17 - SG SD - Soft Gemini - Sense disable interrupt
- 18 - -
- 19 - -
- 20 - -
- 21- -
- Default: 0x0001
-*==============================================*/
- ACX_REG_INTERRUPT_MASK,
-
-/*=============================================
- Host Interrupt Mask Set 16bit, (Write only)
- ------------------------------------------
- Setting a bit in this register sets
- the corresponding bin in ACX_HINT_MASK register
- without effecting the mask
- state of other bits (0 = no effect).
-==============================================*/
- ACX_REG_HINT_MASK_SET,
-
-/*=============================================
- Host Interrupt Mask Clear 16bit,(Write only)
- ------------------------------------------
- Setting a bit in this register clears
- the corresponding bin in ACX_HINT_MASK register
- without effecting the mask
- state of other bits (0 = no effect).
-=============================================*/
- ACX_REG_HINT_MASK_CLR,
-
-/*=============================================
- Host Interrupt Status Nondestructive Read
- 16bit,(Read only)
- ------------------------------------------
- The host can read this register to determine
- which interrupts are active.
- Reading this register doesn't
- effect its content.
-=============================================*/
- ACX_REG_INTERRUPT_NO_CLEAR,
-
-/*=============================================
- Host Interrupt Status Clear on Read Register
- 16bit,(Read only)
- ------------------------------------------
- The host can read this register to determine
- which interrupts are active.
- Reading this register clears it,
- thus making all interrupts inactive.
-==============================================*/
- ACX_REG_INTERRUPT_CLEAR,
-
-/*=============================================
- Host Interrupt Acknowledge Register
- 16bit,(Write only)
- ------------------------------------------
- The host can set individual bits in this
- register to clear (acknowledge) the corresp.
- interrupt status bits in the HINT_STS_CLR and
- HINT_STS_ND registers, thus making the
- assotiated interrupt inactive. (0-no effect)
-==============================================*/
- ACX_REG_INTERRUPT_ACK,
-
-/*===============================================
- Host Software Reset - 32bit RW
- ------------------------------------------
- [31:1] Reserved
- 0 SOFT_RESET Soft Reset - When this bit is set,
- it holds the Wlan hardware in a soft reset state.
- This reset disables all MAC and baseband processor
- clocks except the CardBus/PCI interface clock.
- It also initializes all MAC state machines except
- the host interface. It does not reload the
- contents of the EEPROM. When this bit is cleared
- (not self-clearing), the Wlan hardware
- exits the software reset state.
-===============================================*/
- ACX_REG_SLV_SOFT_RESET,
-
-/*===============================================
- EEPROM Burst Read Start - 32bit RW
- ------------------------------------------
- [31:1] Reserved
- 0 ACX_EE_START - EEPROM Burst Read Start 0
- Setting this bit starts a burst read from
- the external EEPROM.
- If this bit is set (after reset) before an EEPROM read/write,
- the burst read starts at EEPROM address 0.
- Otherwise, it starts at the address
- following the address of the previous access.
- TheWlan hardware hardware clears this bit automatically.
-
- Default: 0x00000000
-*================================================*/
- ACX_REG_EE_START,
-
-/* Embedded ARM CPU Control */
-
-/*===============================================
- Halt eCPU - 32bit RW
- ------------------------------------------
- 0 HALT_ECPU Halt Embedded CPU - This bit is the
- compliment of bit 1 (MDATA2) in the SOR_CFG register.
- During a hardware reset, this bit holds
- the inverse of MDATA2.
- When downloading firmware from the host,
- set this bit (pull down MDATA2).
- The host clears this bit after downloading the firmware into
- zero-wait-state SSRAM.
- When loading firmware from Flash, clear this bit (pull up MDATA2)
- so that the eCPU can run the bootloader code in Flash
- HALT_ECPU eCPU State
- --------------------
- 1 halt eCPU
- 0 enable eCPU
- ===============================================*/
- ACX_REG_ECPU_CONTROL,
-
- ACX_REG_TABLE_LEN
-};
-
-#define ACX_SLV_SOFT_RESET_BIT BIT(0)
-#define ACX_REG_EEPROM_START_BIT BIT(0)
-
-/* Command/Information Mailbox Pointers */
-
-/*===============================================
- Command Mailbox Pointer - 32bit RW
- ------------------------------------------
- This register holds the start address of
- the command mailbox located in the Wlan hardware memory.
- The host must read this pointer after a reset to
- find the location of the command mailbox.
- The Wlan hardware initializes the command mailbox
- pointer with the default address of the command mailbox.
- The command mailbox pointer is not valid until after
- the host receives the Init Complete interrupt from
- the Wlan hardware.
- ===============================================*/
-#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0)
-
-/*===============================================
- Information Mailbox Pointer - 32bit RW
- ------------------------------------------
- This register holds the start address of
- the information mailbox located in the Wlan hardware memory.
- The host must read this pointer after a reset to find
- the location of the information mailbox.
- The Wlan hardware initializes the information mailbox pointer
- with the default address of the information mailbox.
- The information mailbox pointer is not valid
- until after the host receives the Init Complete interrupt from
- the Wlan hardware.
- ===============================================*/
-#define REG_EVENT_MAILBOX_PTR (SCR_PAD1)
-
-
-/* Misc */
-
-#define REG_ENABLE_TX_RX (ENABLE)
-/*
- * Rx configuration (filter) information element
- * ---------------------------------------------
- */
-#define REG_RX_CONFIG (RX_CFG)
-#define REG_RX_FILTER (RX_FILTER_CFG)
-
-
-#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002
-
-/* promiscuous - receives all valid frames */
-#define RX_CFG_PROMISCUOUS 0x0008
-
-/* receives frames from any BSSID */
-#define RX_CFG_BSSID 0x0020
-
-/* receives frames destined to any MAC address */
-#define RX_CFG_MAC 0x0010
-
-#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010
-#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000
-#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020
-#define RX_CFG_ENABLE_ANY_BSSID 0x0000
-
-/* discards all broadcast frames */
-#define RX_CFG_DISABLE_BCAST 0x0200
-
-#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400
-#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
-#define RX_CFG_COPY_RX_STATUS 0x2000
-#define RX_CFG_TSF 0x10000
-
-#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
- RX_CFG_ENABLE_ONLY_MY_BSSID)
-
-#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
- | RX_CFG_ENABLE_ANY_BSSID)
-
-#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
- RX_CFG_ENABLE_ANY_BSSID)
-
-#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
- | RX_CFG_ENABLE_ONLY_MY_BSSID)
-
-#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \
- | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
- | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
-
-#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
-
-#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \
- RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
-
-#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \
- RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
-
-#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
- | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
- | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
-
-#define RX_FILTER_OPTION_FILTER_ALL 0
-
-#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
- | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
-
-#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
- | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
- | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
- | CFG_RX_PRSP_EN)
-
-
-/*===============================================
- EEPROM Read/Write Request 32bit RW
- ------------------------------------------
- 1 EE_READ - EEPROM Read Request 1 - Setting this bit
- loads a single byte of data into the EE_DATA
- register from the EEPROM location specified in
- the EE_ADDR register.
- The Wlan hardware hardware clears this bit automatically.
- EE_DATA is valid when this bit is cleared.
-
- 0 EE_WRITE - EEPROM Write Request - Setting this bit
- writes a single byte of data from the EE_DATA register into the
- EEPROM location specified in the EE_ADDR register.
- The Wlan hardware hardware clears this bit automatically.
-*===============================================*/
-#define EE_CTL (REGISTERS_BASE + 0x2000)
-#define ACX_EE_CTL_REG EE_CTL
-#define EE_WRITE 0x00000001ul
-#define EE_READ 0x00000002ul
-
-/*===============================================
- EEPROM Address - 32bit RW
- ------------------------------------------
- This register specifies the address
- within the EEPROM from/to which to read/write data.
- ===============================================*/
-#define EE_ADDR (REGISTERS_BASE + 0x2008)
-#define ACX_EE_ADDR_REG EE_ADDR
-
-/*===============================================
- EEPROM Data - 32bit RW
- ------------------------------------------
- This register either holds the read 8 bits of
- data from the EEPROM or the write data
- to be written to the EEPROM.
- ===============================================*/
-#define EE_DATA (REGISTERS_BASE + 0x2004)
-#define ACX_EE_DATA_REG EE_DATA
-
-#define EEPROM_ACCESS_TO 10000 /* timeout counter */
-#define START_EEPROM_MGR 0x00000001
-
-/*===============================================
- EEPROM Base Address - 32bit RW
- ------------------------------------------
- This register holds the upper nine bits
- [23:15] of the 24-bit Wlan hardware memory
- address for burst reads from EEPROM accesses.
- The EEPROM provides the lower 15 bits of this address.
- The MSB of the address from the EEPROM is ignored.
- ===============================================*/
-#define ACX_EE_CFG EE_CFG
-
-/*===============================================
- GPIO Output Values -32bit, RW
- ------------------------------------------
- [31:16] Reserved
- [15: 0] Specify the output values (at the output driver inputs) for
- GPIO[15:0], respectively.
- ===============================================*/
-#define ACX_GPIO_OUT_REG GPIO_OUT
-#define ACX_MAX_GPIO_LINES 15
-
-/*===============================================
- Contention window -32bit, RW
- ------------------------------------------
- [31:26] Reserved
- [25:16] Max (0x3ff)
- [15:07] Reserved
- [06:00] Current contention window value - default is 0x1F
- ===============================================*/
-#define ACX_CONT_WIND_CFG_REG CONT_WIND_CFG
-#define ACX_CONT_WIND_MIN_MASK 0x0000007f
-#define ACX_CONT_WIND_MAX 0x03ff0000
-
-/*===============================================
- HI_CFG Interface Configuration Register Values
- ------------------------------------------
- ===============================================*/
-#define HI_CFG_UART_ENABLE 0x00000004
-#define HI_CFG_RST232_ENABLE 0x00000008
-#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
-#define HI_CFG_HOST_INT_ENABLE 0x00000020
-#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
-#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
-#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
-#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
-#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
-
-/*
- * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
- * for platforms using active high interrupt level
- */
-#ifdef USE_ACTIVE_HIGH
-#define HI_CFG_DEF_VAL \
- (HI_CFG_UART_ENABLE | \
- HI_CFG_RST232_ENABLE | \
- HI_CFG_CLOCK_REQ_SELECT | \
- HI_CFG_HOST_INT_ENABLE)
-#else
-#define HI_CFG_DEF_VAL \
- (HI_CFG_UART_ENABLE | \
- HI_CFG_RST232_ENABLE | \
- HI_CFG_CLOCK_REQ_SELECT | \
- HI_CFG_HOST_INT_ENABLE)
-
-#endif
-
-#define REF_FREQ_19_2 0
-#define REF_FREQ_26_0 1
-#define REF_FREQ_38_4 2
-#define REF_FREQ_40_0 3
-#define REF_FREQ_33_6 4
-#define REF_FREQ_NUM 5
-
-#define LUT_PARAM_INTEGER_DIVIDER 0
-#define LUT_PARAM_FRACTIONAL_DIVIDER 1
-#define LUT_PARAM_ATTN_BB 2
-#define LUT_PARAM_ALPHA_BB 3
-#define LUT_PARAM_STOP_TIME_BB 4
-#define LUT_PARAM_BB_PLL_LOOP_FILTER 5
-#define LUT_PARAM_NUM 6
-
-#define ACX_EEPROMLESS_IND_REG (SCR_PAD4)
-#define USE_EEPROM 0
-#define SOFT_RESET_MAX_TIME 1000000
-#define SOFT_RESET_STALL_TIME 1000
-#define NVS_DATA_BUNDARY_ALIGNMENT 4
-
-
-/* Firmware image load chunk size */
-#define CHUNK_SIZE 512
-
-/* Firmware image header size */
-#define FW_HDR_SIZE 8
-
-#define ECPU_CONTROL_HALT 0x00000101
-
-
-/******************************************************************************
-
- CHANNELS, BAND & REG DOMAINS definitions
-
-******************************************************************************/
-
-
-enum {
- RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */
- RADIO_BAND_5GHZ = 1, /* 5 Ghz band */
- RADIO_BAND_JAPAN_4_9_GHZ = 2,
- DEFAULT_BAND = RADIO_BAND_2_4GHZ,
- INVALID_BAND = 0xFE,
- MAX_RADIO_BANDS = 0xFF
-};
-
-enum {
- NO_RATE = 0,
- RATE_1MBPS = 0x0A,
- RATE_2MBPS = 0x14,
- RATE_5_5MBPS = 0x37,
- RATE_6MBPS = 0x0B,
- RATE_9MBPS = 0x0F,
- RATE_11MBPS = 0x6E,
- RATE_12MBPS = 0x0A,
- RATE_18MBPS = 0x0E,
- RATE_22MBPS = 0xDC,
- RATE_24MBPS = 0x09,
- RATE_36MBPS = 0x0D,
- RATE_48MBPS = 0x08,
- RATE_54MBPS = 0x0C
-};
-
-enum {
- RATE_INDEX_1MBPS = 0,
- RATE_INDEX_2MBPS = 1,
- RATE_INDEX_5_5MBPS = 2,
- RATE_INDEX_6MBPS = 3,
- RATE_INDEX_9MBPS = 4,
- RATE_INDEX_11MBPS = 5,
- RATE_INDEX_12MBPS = 6,
- RATE_INDEX_18MBPS = 7,
- RATE_INDEX_22MBPS = 8,
- RATE_INDEX_24MBPS = 9,
- RATE_INDEX_36MBPS = 10,
- RATE_INDEX_48MBPS = 11,
- RATE_INDEX_54MBPS = 12,
- RATE_INDEX_MAX = RATE_INDEX_54MBPS,
- MAX_RATE_INDEX,
- INVALID_RATE_INDEX = MAX_RATE_INDEX,
- RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
-};
-
-enum {
- RATE_MASK_1MBPS = 0x1,
- RATE_MASK_2MBPS = 0x2,
- RATE_MASK_5_5MBPS = 0x4,
- RATE_MASK_11MBPS = 0x20,
-};
-
-#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */
-#define OFDM_RATE_BIT BIT(6)
-#define PBCC_RATE_BIT BIT(7)
-
-enum {
- CCK_LONG = 0,
- CCK_SHORT = SHORT_PREAMBLE_BIT,
- PBCC_LONG = PBCC_RATE_BIT,
- PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
- OFDM = OFDM_RATE_BIT
-};
-
-/******************************************************************************
-
-Transmit-Descriptor RATE-SET field definitions...
-
-Define a new "Rate-Set" for TX path that incorporates the
-Rate & Modulation info into a single 16-bit field.
-
-TxdRateSet_t:
-b15 - Indicates Preamble type (1=SHORT, 0=LONG).
- Notes:
- Must be LONG (0) for 1Mbps rate.
- Does not apply (set to 0) for RevG-OFDM rates.
-b14 - Indicates PBCC encoding (1=PBCC, 0=not).
- Notes:
- Does not apply (set to 0) for rates 1 and 2 Mbps.
- Does not apply (set to 0) for RevG-OFDM rates.
-b13 - Unused (set to 0).
-b12-b0 - Supported Rate indicator bits as defined below.
-
-******************************************************************************/
-
-
-/*************************************************************************
-
- Interrupt Trigger Register (Host -> WiLink)
-
-**************************************************************************/
-
-/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
-
-/*
- * Host Command Interrupt. Setting this bit masks
- * the interrupt that the host issues to inform
- * the FW that it has sent a command
- * to the Wlan hardware Command Mailbox.
- */
-#define INTR_TRIG_CMD BIT(0)
-
-/*
- * Host Event Acknowlegde Interrupt. The host
- * sets this bit to acknowledge that it received
- * the unsolicited information from the event
- * mailbox.
- */
-#define INTR_TRIG_EVENT_ACK BIT(1)
-
-/*
- * The host sets this bit to inform the Wlan
- * FW that a TX packet is in the XFER
- * Buffer #0.
- */
-#define INTR_TRIG_TX_PROC0 BIT(2)
-
-/*
- * The host sets this bit to inform the FW
- * that it read a packet from RX XFER
- * Buffer #0.
- */
-#define INTR_TRIG_RX_PROC0 BIT(3)
-
-#define INTR_TRIG_DEBUG_ACK BIT(4)
-
-#define INTR_TRIG_STATE_CHANGED BIT(5)
-
-
-/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
-
-/*
- * The host sets this bit to inform the FW
- * that it read a packet from RX XFER
- * Buffer #1.
- */
-#define INTR_TRIG_RX_PROC1 BIT(17)
-
-/*
- * The host sets this bit to inform the Wlan
- * hardware that a TX packet is in the XFER
- * Buffer #1.
- */
-#define INTR_TRIG_TX_PROC1 BIT(18)
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
deleted file mode 100644
index 1b6294b3b996..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/skbuff.h>
-#include <linux/gfp.h>
-#include <net/mac80211.h>
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_io.h"
-#include "wl1251_rx.h"
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
-
-static void wl1251_rx_header(struct wl1251 *wl,
- struct wl1251_rx_descriptor *desc)
-{
- u32 rx_packet_ring_addr;
-
- rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
- if (wl->rx_current_buffer)
- rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
-
- wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc));
-}
-
-static void wl1251_rx_status(struct wl1251 *wl,
- struct wl1251_rx_descriptor *desc,
- struct ieee80211_rx_status *status,
- u8 beacon)
-{
- u64 mactime;
- int ret;
-
- memset(status, 0, sizeof(struct ieee80211_rx_status));
-
- status->band = IEEE80211_BAND_2GHZ;
- status->mactime = desc->timestamp;
-
- /*
- * The rx status timestamp is a 32 bits value while the TSF is a
- * 64 bits one.
- * For IBSS merging, TSF is mandatory, so we have to get it
- * somehow, so we ask for ACX_TSF_INFO.
- * That could be moved to the get_tsf() hook, but unfortunately,
- * this one must be atomic, while our SPI routines can sleep.
- */
- if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
- ret = wl1251_acx_tsf_info(wl, &mactime);
- if (ret == 0)
- status->mactime = mactime;
- }
-
- status->signal = desc->rssi;
-
- /*
- * FIXME: guessing that snr needs to be divided by two, otherwise
- * the values don't make any sense
- */
- wl->noise = desc->rssi - desc->snr / 2;
-
- status->freq = ieee80211_channel_to_frequency(desc->channel);
-
- status->flag |= RX_FLAG_TSFT;
-
- if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
- status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
-
- if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
- status->flag |= RX_FLAG_DECRYPTED;
-
- if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
- status->flag |= RX_FLAG_MMIC_ERROR;
- }
-
- if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
- status->flag |= RX_FLAG_FAILED_FCS_CRC;
-
-
- /* FIXME: set status->rate_idx */
-}
-
-static void wl1251_rx_body(struct wl1251 *wl,
- struct wl1251_rx_descriptor *desc)
-{
- struct sk_buff *skb;
- struct ieee80211_rx_status status;
- u8 *rx_buffer, beacon = 0;
- u16 length, *fc;
- u32 curr_id, last_id_inc, rx_packet_ring_addr;
-
- length = WL1251_RX_ALIGN(desc->length - PLCP_HEADER_LENGTH);
- curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
- last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
-
- if (last_id_inc != curr_id) {
- wl1251_warning("curr ID:%d, last ID inc:%d",
- curr_id, last_id_inc);
- wl->rx_last_id = curr_id;
- } else {
- wl->rx_last_id = last_id_inc;
- }
-
- rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
- sizeof(struct wl1251_rx_descriptor) + 20;
- if (wl->rx_current_buffer)
- rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
-
- skb = __dev_alloc_skb(length, GFP_KERNEL);
- if (!skb) {
- wl1251_error("Couldn't allocate RX frame");
- return;
- }
-
- rx_buffer = skb_put(skb, length);
- wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
-
- /* The actual lenght doesn't include the target's alignment */
- skb->len = desc->length - PLCP_HEADER_LENGTH;
-
- fc = (u16 *)skb->data;
-
- if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
- beacon = 1;
-
- wl1251_rx_status(wl, desc, &status, beacon);
-
- wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
- beacon ? "beacon" : "");
-
- memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
- ieee80211_rx_ni(wl->hw, skb);
-}
-
-static void wl1251_rx_ack(struct wl1251 *wl)
-{
- u32 data, addr;
-
- if (wl->rx_current_buffer) {
- addr = ACX_REG_INTERRUPT_TRIG_H;
- data = INTR_TRIG_RX_PROC1;
- } else {
- addr = ACX_REG_INTERRUPT_TRIG;
- data = INTR_TRIG_RX_PROC0;
- }
-
- wl1251_reg_write32(wl, addr, data);
-
- /* Toggle buffer ring */
- wl->rx_current_buffer = !wl->rx_current_buffer;
-}
-
-
-void wl1251_rx(struct wl1251 *wl)
-{
- struct wl1251_rx_descriptor *rx_desc;
-
- if (wl->state != WL1251_STATE_ON)
- return;
-
- rx_desc = wl->rx_descriptor;
-
- /* We first read the frame's header */
- wl1251_rx_header(wl, rx_desc);
-
- /* Now we can read the body */
- wl1251_rx_body(wl, rx_desc);
-
- /* Finally, we need to ACK the RX */
- wl1251_rx_ack(wl);
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl12xx/wl1251_rx.h
deleted file mode 100644
index da4e53406a0e..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_rx.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_RX_H__
-#define __WL1251_RX_H__
-
-#include <linux/bitops.h>
-
-#include "wl1251.h"
-
-/*
- * RX PATH
- *
- * The Rx path uses a double buffer and an rx_contro structure, each located
- * at a fixed address in the device memory. The host keeps track of which
- * buffer is available and alternates between them on a per packet basis.
- * The size of each of the two buffers is large enough to hold the longest
- * 802.3 packet.
- * The RX path goes like that:
- * 1) The target generates an interrupt each time a new packet is received.
- * There are 2 RX interrupts, one for each buffer.
- * 2) The host reads the received packet from one of the double buffers.
- * 3) The host triggers a target interrupt.
- * 4) The target prepares the next RX packet.
- */
-
-#define WL1251_RX_MAX_RSSI -30
-#define WL1251_RX_MIN_RSSI -95
-
-#define WL1251_RX_ALIGN_TO 4
-#define WL1251_RX_ALIGN(len) (((len) + WL1251_RX_ALIGN_TO - 1) & \
- ~(WL1251_RX_ALIGN_TO - 1))
-
-#define SHORT_PREAMBLE_BIT BIT(0)
-#define OFDM_RATE_BIT BIT(6)
-#define PBCC_RATE_BIT BIT(7)
-
-#define PLCP_HEADER_LENGTH 8
-#define RX_DESC_PACKETID_SHIFT 11
-#define RX_MAX_PACKET_ID 3
-
-#define RX_DESC_VALID_FCS 0x0001
-#define RX_DESC_MATCH_RXADDR1 0x0002
-#define RX_DESC_MCAST 0x0004
-#define RX_DESC_STAINTIM 0x0008
-#define RX_DESC_VIRTUAL_BM 0x0010
-#define RX_DESC_BCAST 0x0020
-#define RX_DESC_MATCH_SSID 0x0040
-#define RX_DESC_MATCH_BSSID 0x0080
-#define RX_DESC_ENCRYPTION_MASK 0x0300
-#define RX_DESC_MEASURMENT 0x0400
-#define RX_DESC_SEQNUM_MASK 0x1800
-#define RX_DESC_MIC_FAIL 0x2000
-#define RX_DESC_DECRYPT_FAIL 0x4000
-
-struct wl1251_rx_descriptor {
- u32 timestamp; /* In microseconds */
- u16 length; /* Paylod length, including headers */
- u16 flags;
-
- /*
- * 0 - 802.11
- * 1 - 802.3
- * 2 - IP
- * 3 - Raw Codec
- */
- u8 type;
-
- /*
- * Received Rate:
- * 0x0A - 1MBPS
- * 0x14 - 2MBPS
- * 0x37 - 5_5MBPS
- * 0x0B - 6MBPS
- * 0x0F - 9MBPS
- * 0x6E - 11MBPS
- * 0x0A - 12MBPS
- * 0x0E - 18MBPS
- * 0xDC - 22MBPS
- * 0x09 - 24MBPS
- * 0x0D - 36MBPS
- * 0x08 - 48MBPS
- * 0x0C - 54MBPS
- */
- u8 rate;
-
- u8 mod_pre; /* Modulation and preamble */
- u8 channel;
-
- /*
- * 0 - 2.4 Ghz
- * 1 - 5 Ghz
- */
- u8 band;
-
- s8 rssi; /* in dB */
- u8 rcpi; /* in dB */
- u8 snr; /* in dB */
-} __packed;
-
-void wl1251_rx(struct wl1251 *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
deleted file mode 100644
index b901b6135654..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_sdio.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * wl12xx SDIO routines
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- * Copyright (C) 2005 Texas Instruments Incorporated
- * Copyright (C) 2008 Google Inc
- * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
- */
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/platform_device.h>
-#include <linux/spi/wl12xx.h>
-#include <linux/irq.h>
-
-#include "wl1251.h"
-
-#ifndef SDIO_VENDOR_ID_TI
-#define SDIO_VENDOR_ID_TI 0x104c
-#endif
-
-#ifndef SDIO_DEVICE_ID_TI_WL1251
-#define SDIO_DEVICE_ID_TI_WL1251 0x9066
-#endif
-
-struct wl1251_sdio {
- struct sdio_func *func;
- u32 elp_val;
-};
-
-static struct wl12xx_platform_data *wl12xx_board_data;
-
-static struct sdio_func *wl_to_func(struct wl1251 *wl)
-{
- struct wl1251_sdio *wl_sdio = wl->if_priv;
- return wl_sdio->func;
-}
-
-static void wl1251_sdio_interrupt(struct sdio_func *func)
-{
- struct wl1251 *wl = sdio_get_drvdata(func);
-
- wl1251_debug(DEBUG_IRQ, "IRQ");
-
- /* FIXME should be synchronous for sdio */
- ieee80211_queue_work(wl->hw, &wl->irq_work);
-}
-
-static const struct sdio_device_id wl1251_devices[] = {
- { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) },
- {}
-};
-MODULE_DEVICE_TABLE(sdio, wl1251_devices);
-
-
-static void wl1251_sdio_read(struct wl1251 *wl, int addr,
- void *buf, size_t len)
-{
- int ret;
- struct sdio_func *func = wl_to_func(wl);
-
- sdio_claim_host(func);
- ret = sdio_memcpy_fromio(func, buf, addr, len);
- if (ret)
- wl1251_error("sdio read failed (%d)", ret);
- sdio_release_host(func);
-}
-
-static void wl1251_sdio_write(struct wl1251 *wl, int addr,
- void *buf, size_t len)
-{
- int ret;
- struct sdio_func *func = wl_to_func(wl);
-
- sdio_claim_host(func);
- ret = sdio_memcpy_toio(func, addr, buf, len);
- if (ret)
- wl1251_error("sdio write failed (%d)", ret);
- sdio_release_host(func);
-}
-
-static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
-{
- int ret = 0;
- struct wl1251_sdio *wl_sdio = wl->if_priv;
- struct sdio_func *func = wl_sdio->func;
-
- /*
- * The hardware only supports RAW (read after write) access for
- * reading, regular sdio_readb won't work here (it interprets
- * the unused bits of CMD52 as write data even if we send read
- * request).
- */
- sdio_claim_host(func);
- *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret);
- sdio_release_host(func);
-
- if (ret)
- wl1251_error("sdio_readb failed (%d)", ret);
-}
-
-static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
-{
- int ret = 0;
- struct wl1251_sdio *wl_sdio = wl->if_priv;
- struct sdio_func *func = wl_sdio->func;
-
- sdio_claim_host(func);
- sdio_writeb(func, val, addr, &ret);
- sdio_release_host(func);
-
- if (ret)
- wl1251_error("sdio_writeb failed (%d)", ret);
- else
- wl_sdio->elp_val = val;
-}
-
-static void wl1251_sdio_reset(struct wl1251 *wl)
-{
-}
-
-static void wl1251_sdio_enable_irq(struct wl1251 *wl)
-{
- struct sdio_func *func = wl_to_func(wl);
-
- sdio_claim_host(func);
- sdio_claim_irq(func, wl1251_sdio_interrupt);
- sdio_release_host(func);
-}
-
-static void wl1251_sdio_disable_irq(struct wl1251 *wl)
-{
- struct sdio_func *func = wl_to_func(wl);
-
- sdio_claim_host(func);
- sdio_release_irq(func);
- sdio_release_host(func);
-}
-
-/* Interrupts when using dedicated WLAN_IRQ pin */
-static irqreturn_t wl1251_line_irq(int irq, void *cookie)
-{
- struct wl1251 *wl = cookie;
-
- ieee80211_queue_work(wl->hw, &wl->irq_work);
-
- return IRQ_HANDLED;
-}
-
-static void wl1251_enable_line_irq(struct wl1251 *wl)
-{
- return enable_irq(wl->irq);
-}
-
-static void wl1251_disable_line_irq(struct wl1251 *wl)
-{
- return disable_irq(wl->irq);
-}
-
-static void wl1251_sdio_set_power(bool enable)
-{
-}
-
-static struct wl1251_if_operations wl1251_sdio_ops = {
- .read = wl1251_sdio_read,
- .write = wl1251_sdio_write,
- .write_elp = wl1251_sdio_write_elp,
- .read_elp = wl1251_sdio_read_elp,
- .reset = wl1251_sdio_reset,
-};
-
-static int wl1251_platform_probe(struct platform_device *pdev)
-{
- if (pdev->id != -1) {
- wl1251_error("can only handle single device");
- return -ENODEV;
- }
-
- wl12xx_board_data = pdev->dev.platform_data;
- return 0;
-}
-
-/*
- * Dummy platform_driver for passing platform_data to this driver,
- * until we have a way to pass this through SDIO subsystem or
- * some other way.
- */
-static struct platform_driver wl1251_platform_driver = {
- .driver = {
- .name = "wl1251_data",
- .owner = THIS_MODULE,
- },
- .probe = wl1251_platform_probe,
-};
-
-static int wl1251_sdio_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
-{
- int ret;
- struct wl1251 *wl;
- struct ieee80211_hw *hw;
- struct wl1251_sdio *wl_sdio;
-
- hw = wl1251_alloc_hw();
- if (IS_ERR(hw))
- return PTR_ERR(hw);
-
- wl = hw->priv;
-
- wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL);
- if (wl_sdio == NULL) {
- ret = -ENOMEM;
- goto out_free_hw;
- }
-
- sdio_claim_host(func);
- ret = sdio_enable_func(func);
- if (ret)
- goto release;
-
- sdio_set_block_size(func, 512);
- sdio_release_host(func);
-
- SET_IEEE80211_DEV(hw, &func->dev);
- wl_sdio->func = func;
- wl->if_priv = wl_sdio;
- wl->if_ops = &wl1251_sdio_ops;
- wl->set_power = wl1251_sdio_set_power;
-
- if (wl12xx_board_data != NULL) {
- wl->set_power = wl12xx_board_data->set_power;
- wl->irq = wl12xx_board_data->irq;
- wl->use_eeprom = wl12xx_board_data->use_eeprom;
- }
-
- if (wl->irq) {
- ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
- if (ret < 0) {
- wl1251_error("request_irq() failed: %d", ret);
- goto disable;
- }
-
- set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
- disable_irq(wl->irq);
-
- wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
- wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
-
- wl1251_info("using dedicated interrupt line");
- } else {
- wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
- wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
-
- wl1251_info("using SDIO interrupt");
- }
-
- ret = wl1251_init_ieee80211(wl);
- if (ret)
- goto out_free_irq;
-
- sdio_set_drvdata(func, wl);
- return ret;
-
-out_free_irq:
- if (wl->irq)
- free_irq(wl->irq, wl);
-disable:
- sdio_claim_host(func);
- sdio_disable_func(func);
-release:
- sdio_release_host(func);
- kfree(wl_sdio);
-out_free_hw:
- wl1251_free_hw(wl);
- return ret;
-}
-
-static void __devexit wl1251_sdio_remove(struct sdio_func *func)
-{
- struct wl1251 *wl = sdio_get_drvdata(func);
- struct wl1251_sdio *wl_sdio = wl->if_priv;
-
- if (wl->irq)
- free_irq(wl->irq, wl);
- kfree(wl_sdio);
- wl1251_free_hw(wl);
-
- sdio_claim_host(func);
- sdio_release_irq(func);
- sdio_disable_func(func);
- sdio_release_host(func);
-}
-
-static struct sdio_driver wl1251_sdio_driver = {
- .name = "wl1251_sdio",
- .id_table = wl1251_devices,
- .probe = wl1251_sdio_probe,
- .remove = __devexit_p(wl1251_sdio_remove),
-};
-
-static int __init wl1251_sdio_init(void)
-{
- int err;
-
- err = platform_driver_register(&wl1251_platform_driver);
- if (err) {
- wl1251_error("failed to register platform driver: %d", err);
- return err;
- }
-
- err = sdio_register_driver(&wl1251_sdio_driver);
- if (err)
- wl1251_error("failed to register sdio driver: %d", err);
- return err;
-}
-
-static void __exit wl1251_sdio_exit(void)
-{
- sdio_unregister_driver(&wl1251_sdio_driver);
- platform_driver_unregister(&wl1251_platform_driver);
- wl1251_notice("unloaded");
-}
-
-module_init(wl1251_sdio_init);
-module_exit(wl1251_sdio_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
deleted file mode 100644
index 27fdfaaeb074..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_spi.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/crc7.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/wl12xx.h>
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_spi.h"
-
-static irqreturn_t wl1251_irq(int irq, void *cookie)
-{
- struct wl1251 *wl;
-
- wl1251_debug(DEBUG_IRQ, "IRQ");
-
- wl = cookie;
-
- ieee80211_queue_work(wl->hw, &wl->irq_work);
-
- return IRQ_HANDLED;
-}
-
-static struct spi_device *wl_to_spi(struct wl1251 *wl)
-{
- return wl->if_priv;
-}
-
-static void wl1251_spi_reset(struct wl1251 *wl)
-{
- u8 *cmd;
- struct spi_transfer t;
- struct spi_message m;
-
- cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
- if (!cmd) {
- wl1251_error("could not allocate cmd for spi reset");
- return;
- }
-
- memset(&t, 0, sizeof(t));
- spi_message_init(&m);
-
- memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
-
- t.tx_buf = cmd;
- t.len = WSPI_INIT_CMD_LEN;
- spi_message_add_tail(&t, &m);
-
- spi_sync(wl_to_spi(wl), &m);
-
- wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
-}
-
-static void wl1251_spi_wake(struct wl1251 *wl)
-{
- u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
- struct spi_transfer t;
- struct spi_message m;
-
- cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
- if (!cmd) {
- wl1251_error("could not allocate cmd for spi init");
- return;
- }
-
- memset(crc, 0, sizeof(crc));
- memset(&t, 0, sizeof(t));
- spi_message_init(&m);
-
- /*
- * Set WSPI_INIT_COMMAND
- * the data is being send from the MSB to LSB
- */
- cmd[2] = 0xff;
- cmd[3] = 0xff;
- cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
- cmd[0] = 0;
- cmd[7] = 0;
- cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
- cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
-
- if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
- cmd[5] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
- else
- cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
-
- cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
- | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
-
- crc[0] = cmd[1];
- crc[1] = cmd[0];
- crc[2] = cmd[7];
- crc[3] = cmd[6];
- crc[4] = cmd[5];
-
- cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
- cmd[4] |= WSPI_INIT_CMD_END;
-
- t.tx_buf = cmd;
- t.len = WSPI_INIT_CMD_LEN;
- spi_message_add_tail(&t, &m);
-
- spi_sync(wl_to_spi(wl), &m);
-
- wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
-}
-
-static void wl1251_spi_reset_wake(struct wl1251 *wl)
-{
- wl1251_spi_reset(wl);
- wl1251_spi_wake(wl);
-}
-
-static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
- size_t len)
-{
- struct spi_transfer t[3];
- struct spi_message m;
- u8 *busy_buf;
- u32 *cmd;
-
- cmd = &wl->buffer_cmd;
- busy_buf = wl->buffer_busyword;
-
- *cmd = 0;
- *cmd |= WSPI_CMD_READ;
- *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- t[0].tx_buf = cmd;
- t[0].len = 4;
- spi_message_add_tail(&t[0], &m);
-
- /* Busy and non busy words read */
- t[1].rx_buf = busy_buf;
- t[1].len = WL1251_BUSY_WORD_LEN;
- spi_message_add_tail(&t[1], &m);
-
- t[2].rx_buf = buf;
- t[2].len = len;
- spi_message_add_tail(&t[2], &m);
-
- spi_sync(wl_to_spi(wl), &m);
-
- /* FIXME: check busy words */
-
- wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
- wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
-}
-
-static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
- size_t len)
-{
- struct spi_transfer t[2];
- struct spi_message m;
- u32 *cmd;
-
- cmd = &wl->buffer_cmd;
-
- *cmd = 0;
- *cmd |= WSPI_CMD_WRITE;
- *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- t[0].tx_buf = cmd;
- t[0].len = sizeof(*cmd);
- spi_message_add_tail(&t[0], &m);
-
- t[1].tx_buf = buf;
- t[1].len = len;
- spi_message_add_tail(&t[1], &m);
-
- spi_sync(wl_to_spi(wl), &m);
-
- wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
- wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
-}
-
-static void wl1251_spi_enable_irq(struct wl1251 *wl)
-{
- return enable_irq(wl->irq);
-}
-
-static void wl1251_spi_disable_irq(struct wl1251 *wl)
-{
- return disable_irq(wl->irq);
-}
-
-static const struct wl1251_if_operations wl1251_spi_ops = {
- .read = wl1251_spi_read,
- .write = wl1251_spi_write,
- .reset = wl1251_spi_reset_wake,
- .enable_irq = wl1251_spi_enable_irq,
- .disable_irq = wl1251_spi_disable_irq,
-};
-
-static int __devinit wl1251_spi_probe(struct spi_device *spi)
-{
- struct wl12xx_platform_data *pdata;
- struct ieee80211_hw *hw;
- struct wl1251 *wl;
- int ret;
-
- pdata = spi->dev.platform_data;
- if (!pdata) {
- wl1251_error("no platform data");
- return -ENODEV;
- }
-
- hw = wl1251_alloc_hw();
- if (IS_ERR(hw))
- return PTR_ERR(hw);
-
- wl = hw->priv;
-
- SET_IEEE80211_DEV(hw, &spi->dev);
- dev_set_drvdata(&spi->dev, wl);
- wl->if_priv = spi;
- wl->if_ops = &wl1251_spi_ops;
-
- /* This is the only SPI value that we need to set here, the rest
- * comes from the board-peripherals file */
- spi->bits_per_word = 32;
-
- ret = spi_setup(spi);
- if (ret < 0) {
- wl1251_error("spi_setup failed");
- goto out_free;
- }
-
- wl->set_power = pdata->set_power;
- if (!wl->set_power) {
- wl1251_error("set power function missing in platform data");
- return -ENODEV;
- }
-
- wl->irq = spi->irq;
- if (wl->irq < 0) {
- wl1251_error("irq missing in platform data");
- return -ENODEV;
- }
-
- wl->use_eeprom = pdata->use_eeprom;
-
- ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
- if (ret < 0) {
- wl1251_error("request_irq() failed: %d", ret);
- goto out_free;
- }
-
- set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
-
- disable_irq(wl->irq);
-
- ret = wl1251_init_ieee80211(wl);
- if (ret)
- goto out_irq;
-
- return 0;
-
- out_irq:
- free_irq(wl->irq, wl);
-
- out_free:
- ieee80211_free_hw(hw);
-
- return ret;
-}
-
-static int __devexit wl1251_spi_remove(struct spi_device *spi)
-{
- struct wl1251 *wl = dev_get_drvdata(&spi->dev);
-
- free_irq(wl->irq, wl);
- wl1251_free_hw(wl);
-
- return 0;
-}
-
-static struct spi_driver wl1251_spi_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
- },
-
- .probe = wl1251_spi_probe,
- .remove = __devexit_p(wl1251_spi_remove),
-};
-
-static int __init wl1251_spi_init(void)
-{
- int ret;
-
- ret = spi_register_driver(&wl1251_spi_driver);
- if (ret < 0) {
- wl1251_error("failed to register spi driver: %d", ret);
- goto out;
- }
-
-out:
- return ret;
-}
-
-static void __exit wl1251_spi_exit(void)
-{
- spi_unregister_driver(&wl1251_spi_driver);
-
- wl1251_notice("unloaded");
-}
-
-module_init(wl1251_spi_init);
-module_exit(wl1251_spi_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
-MODULE_ALIAS("spi:wl1251");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
deleted file mode 100644
index 2e273a97e7f3..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_spi.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_SPI_H__
-#define __WL1251_SPI_H__
-
-#include "wl1251_cmd.h"
-#include "wl1251_acx.h"
-#include "wl1251_reg.h"
-
-#define WSPI_CMD_READ 0x40000000
-#define WSPI_CMD_WRITE 0x00000000
-#define WSPI_CMD_FIXED 0x20000000
-#define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
-#define WSPI_CMD_BYTE_LENGTH_OFFSET 17
-#define WSPI_CMD_BYTE_ADDR 0x0001FFFF
-
-#define WSPI_INIT_CMD_CRC_LEN 5
-
-#define WSPI_INIT_CMD_START 0x00
-#define WSPI_INIT_CMD_TX 0x40
-/* the extra bypass bit is sampled by the TNET as '1' */
-#define WSPI_INIT_CMD_BYPASS_BIT 0x80
-#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
-#define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
-#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
-#define WSPI_INIT_CMD_IOD 0x40
-#define WSPI_INIT_CMD_IP 0x20
-#define WSPI_INIT_CMD_CS 0x10
-#define WSPI_INIT_CMD_WS 0x08
-#define WSPI_INIT_CMD_WSPI 0x01
-#define WSPI_INIT_CMD_END 0x01
-
-#define WSPI_INIT_CMD_LEN 8
-
-#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
- ((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32))
-#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
-
-#endif /* __WL1251_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
deleted file mode 100644
index a38ec199187a..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "wl1251.h"
-#include "wl1251_reg.h"
-#include "wl1251_tx.h"
-#include "wl1251_ps.h"
-#include "wl1251_io.h"
-
-static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
-{
- int used, data_in_count;
-
- data_in_count = wl->data_in_count;
-
- if (data_in_count < data_out_count)
- /* data_in_count has wrapped */
- data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
-
- used = data_in_count - data_out_count;
-
- WARN_ON(used < 0);
- WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
-
- if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
- return true;
- else
- return false;
-}
-
-static int wl1251_tx_path_status(struct wl1251 *wl)
-{
- u32 status, addr, data_out_count;
- bool busy;
-
- addr = wl->data_path->tx_control_addr;
- status = wl1251_mem_read32(wl, addr);
- data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
- busy = wl1251_tx_double_buffer_busy(wl, data_out_count);
-
- if (busy)
- return -EBUSY;
-
- return 0;
-}
-
-static int wl1251_tx_id(struct wl1251 *wl, struct sk_buff *skb)
-{
- int i;
-
- for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
- if (wl->tx_frames[i] == NULL) {
- wl->tx_frames[i] = skb;
- return i;
- }
-
- return -EBUSY;
-}
-
-static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr,
- struct ieee80211_tx_info *control, u16 fc)
-{
- *(u16 *)&tx_hdr->control = 0;
-
- tx_hdr->control.rate_policy = 0;
-
- /* 802.11 packets */
- tx_hdr->control.packet_type = 0;
-
- if (control->flags & IEEE80211_TX_CTL_NO_ACK)
- tx_hdr->control.ack_policy = 1;
-
- tx_hdr->control.tx_complete = 1;
-
- if ((fc & IEEE80211_FTYPE_DATA) &&
- ((fc & IEEE80211_STYPE_QOS_DATA) ||
- (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
- tx_hdr->control.qos = 1;
-}
-
-/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
-#define MAX_MSDU_SECURITY_LENGTH 16
-#define MAX_MPDU_SECURITY_LENGTH 16
-#define WLAN_QOS_HDR_LEN 26
-#define MAX_MPDU_HEADER_AND_SECURITY (MAX_MPDU_SECURITY_LENGTH + \
- WLAN_QOS_HDR_LEN)
-#define HW_BLOCK_SIZE 252
-static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
-{
- u16 payload_len, frag_threshold, mem_blocks;
- u16 num_mpdus, mem_blocks_per_frag;
-
- frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
- tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
-
- payload_len = le16_to_cpu(tx_hdr->length) + MAX_MSDU_SECURITY_LENGTH;
-
- if (payload_len > frag_threshold) {
- mem_blocks_per_frag =
- ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
- HW_BLOCK_SIZE) + 1;
- num_mpdus = payload_len / frag_threshold;
- mem_blocks = num_mpdus * mem_blocks_per_frag;
- payload_len -= num_mpdus * frag_threshold;
- num_mpdus++;
-
- } else {
- mem_blocks_per_frag = 0;
- mem_blocks = 0;
- num_mpdus = 1;
- }
-
- mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
-
- if (num_mpdus > 1)
- mem_blocks += min(num_mpdus, mem_blocks_per_frag);
-
- tx_hdr->num_mem_blocks = mem_blocks;
-}
-
-static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb,
- struct ieee80211_tx_info *control)
-{
- struct tx_double_buffer_desc *tx_hdr;
- struct ieee80211_rate *rate;
- int id;
- u16 fc;
-
- if (!skb)
- return -EINVAL;
-
- id = wl1251_tx_id(wl, skb);
- if (id < 0)
- return id;
-
- fc = *(u16 *)skb->data;
- tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
- sizeof(*tx_hdr));
-
- tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
- rate = ieee80211_get_tx_rate(wl->hw, control);
- tx_hdr->rate = cpu_to_le16(rate->hw_value);
- tx_hdr->expiry_time = cpu_to_le32(1 << 16);
- tx_hdr->id = id;
-
- tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb));
-
- wl1251_tx_control(tx_hdr, control, fc);
- wl1251_tx_frag_block_num(tx_hdr);
-
- return 0;
-}
-
-/* We copy the packet to the target */
-static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
- struct ieee80211_tx_info *control)
-{
- struct tx_double_buffer_desc *tx_hdr;
- int len;
- u32 addr;
-
- if (!skb)
- return -EINVAL;
-
- tx_hdr = (struct tx_double_buffer_desc *) skb->data;
-
- if (control->control.hw_key &&
- control->control.hw_key->alg == ALG_TKIP) {
- int hdrlen;
- __le16 fc;
- u16 length;
- u8 *pos;
-
- fc = *(__le16 *)(skb->data + sizeof(*tx_hdr));
- length = le16_to_cpu(tx_hdr->length) + WL1251_TKIP_IV_SPACE;
- tx_hdr->length = cpu_to_le16(length);
-
- hdrlen = ieee80211_hdrlen(fc);
-
- pos = skb_push(skb, WL1251_TKIP_IV_SPACE);
- memmove(pos, pos + WL1251_TKIP_IV_SPACE,
- sizeof(*tx_hdr) + hdrlen);
- }
-
- /* Revisit. This is a workaround for getting non-aligned packets.
- This happens at least with EAPOL packets from the user space.
- Our DMA requires packets to be aligned on a 4-byte boundary.
- */
- if (unlikely((long)skb->data & 0x03)) {
- int offset = (4 - (long)skb->data) & 0x03;
- wl1251_debug(DEBUG_TX, "skb offset %d", offset);
-
- /* check whether the current skb can be used */
- if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
- unsigned char *src = skb->data;
-
- /* align the buffer on a 4-byte boundary */
- skb_reserve(skb, offset);
- memmove(skb->data, src, skb->len);
- tx_hdr = (struct tx_double_buffer_desc *) skb->data;
- } else {
- wl1251_info("No handler, fixme!");
- return -EINVAL;
- }
- }
-
- /* Our skb->data at this point includes the HW header */
- len = WL1251_TX_ALIGN(skb->len);
-
- if (wl->data_in_count & 0x1)
- addr = wl->data_path->tx_packet_ring_addr +
- wl->data_path->tx_packet_ring_chunk_size;
- else
- addr = wl->data_path->tx_packet_ring_addr;
-
- wl1251_mem_write(wl, addr, skb->data, len);
-
- wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x "
- "queue %d", tx_hdr->id, skb, tx_hdr->length,
- tx_hdr->rate, tx_hdr->xmit_queue);
-
- return 0;
-}
-
-static void wl1251_tx_trigger(struct wl1251 *wl)
-{
- u32 data, addr;
-
- if (wl->data_in_count & 0x1) {
- addr = ACX_REG_INTERRUPT_TRIG_H;
- data = INTR_TRIG_TX_PROC1;
- } else {
- addr = ACX_REG_INTERRUPT_TRIG;
- data = INTR_TRIG_TX_PROC0;
- }
-
- wl1251_reg_write32(wl, addr, data);
-
- /* Bumping data in */
- wl->data_in_count = (wl->data_in_count + 1) &
- TX_STATUS_DATA_OUT_COUNT_MASK;
-}
-
-/* caller must hold wl->mutex */
-static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
-{
- struct ieee80211_tx_info *info;
- int ret = 0;
- u8 idx;
-
- info = IEEE80211_SKB_CB(skb);
-
- if (info->control.hw_key) {
- idx = info->control.hw_key->hw_key_idx;
- if (unlikely(wl->default_key != idx)) {
- ret = wl1251_acx_default_key(wl, idx);
- if (ret < 0)
- return ret;
- }
- }
-
- ret = wl1251_tx_path_status(wl);
- if (ret < 0)
- return ret;
-
- ret = wl1251_tx_fill_hdr(wl, skb, info);
- if (ret < 0)
- return ret;
-
- ret = wl1251_tx_send_packet(wl, skb, info);
- if (ret < 0)
- return ret;
-
- wl1251_tx_trigger(wl);
-
- return ret;
-}
-
-void wl1251_tx_work(struct work_struct *work)
-{
- struct wl1251 *wl = container_of(work, struct wl1251, tx_work);
- struct sk_buff *skb;
- bool woken_up = false;
- int ret;
-
- mutex_lock(&wl->mutex);
-
- if (unlikely(wl->state == WL1251_STATE_OFF))
- goto out;
-
- while ((skb = skb_dequeue(&wl->tx_queue))) {
- if (!woken_up) {
- ret = wl1251_ps_elp_wakeup(wl);
- if (ret < 0)
- goto out;
- woken_up = true;
- }
-
- ret = wl1251_tx_frame(wl, skb);
- if (ret == -EBUSY) {
- /* firmware buffer is full, stop queues */
- wl1251_debug(DEBUG_TX, "tx_work: fw buffer full, "
- "stop queues");
- ieee80211_stop_queues(wl->hw);
- wl->tx_queue_stopped = true;
- skb_queue_head(&wl->tx_queue, skb);
- goto out;
- } else if (ret < 0) {
- dev_kfree_skb(skb);
- goto out;
- }
- }
-
-out:
- if (woken_up)
- wl1251_ps_elp_sleep(wl);
-
- mutex_unlock(&wl->mutex);
-}
-
-static const char *wl1251_tx_parse_status(u8 status)
-{
- /* 8 bit status field, one character per bit plus null */
- static char buf[9];
- int i = 0;
-
- memset(buf, 0, sizeof(buf));
-
- if (status & TX_DMA_ERROR)
- buf[i++] = 'm';
- if (status & TX_DISABLED)
- buf[i++] = 'd';
- if (status & TX_RETRY_EXCEEDED)
- buf[i++] = 'r';
- if (status & TX_TIMEOUT)
- buf[i++] = 't';
- if (status & TX_KEY_NOT_FOUND)
- buf[i++] = 'k';
- if (status & TX_ENCRYPT_FAIL)
- buf[i++] = 'e';
- if (status & TX_UNAVAILABLE_PRIORITY)
- buf[i++] = 'p';
-
- /* bit 0 is unused apparently */
-
- return buf;
-}
-
-static void wl1251_tx_packet_cb(struct wl1251 *wl,
- struct tx_result *result)
-{
- struct ieee80211_tx_info *info;
- struct sk_buff *skb;
- int hdrlen, ret;
- u8 *frame;
-
- skb = wl->tx_frames[result->id];
- if (skb == NULL) {
- wl1251_error("SKB for packet %d is NULL", result->id);
- return;
- }
-
- info = IEEE80211_SKB_CB(skb);
-
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- (result->status == TX_SUCCESS))
- info->flags |= IEEE80211_TX_STAT_ACK;
-
- info->status.rates[0].count = result->ack_failures + 1;
- wl->stats.retry_count += result->ack_failures;
-
- /*
- * We have to remove our private TX header before pushing
- * the skb back to mac80211.
- */
- frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
- if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP) {
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen);
- skb_pull(skb, WL1251_TKIP_IV_SPACE);
- }
-
- wl1251_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
- " status 0x%x (%s)",
- result->id, skb, result->ack_failures, result->rate,
- result->status, wl1251_tx_parse_status(result->status));
-
-
- ieee80211_tx_status(wl->hw, skb);
-
- wl->tx_frames[result->id] = NULL;
-
- if (wl->tx_queue_stopped) {
- wl1251_debug(DEBUG_TX, "cb: queue was stopped");
-
- skb = skb_dequeue(&wl->tx_queue);
-
- /* The skb can be NULL because tx_work might have been
- scheduled before the queue was stopped making the
- queue empty */
-
- if (skb) {
- ret = wl1251_tx_frame(wl, skb);
- if (ret == -EBUSY) {
- /* firmware buffer is still full */
- wl1251_debug(DEBUG_TX, "cb: fw buffer "
- "still full");
- skb_queue_head(&wl->tx_queue, skb);
- return;
- } else if (ret < 0) {
- dev_kfree_skb(skb);
- return;
- }
- }
-
- wl1251_debug(DEBUG_TX, "cb: waking queues");
- ieee80211_wake_queues(wl->hw);
- wl->tx_queue_stopped = false;
- }
-}
-
-/* Called upon reception of a TX complete interrupt */
-void wl1251_tx_complete(struct wl1251 *wl)
-{
- int i, result_index, num_complete = 0;
- struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
-
- if (unlikely(wl->state != WL1251_STATE_ON))
- return;
-
- /* First we read the result */
- wl1251_mem_read(wl, wl->data_path->tx_complete_addr,
- result, sizeof(result));
-
- result_index = wl->next_tx_complete;
-
- for (i = 0; i < ARRAY_SIZE(result); i++) {
- result_ptr = &result[result_index];
-
- if (result_ptr->done_1 == 1 &&
- result_ptr->done_2 == 1) {
- wl1251_tx_packet_cb(wl, result_ptr);
-
- result_ptr->done_1 = 0;
- result_ptr->done_2 = 0;
-
- result_index = (result_index + 1) &
- (FW_TX_CMPLT_BLOCK_SIZE - 1);
- num_complete++;
- } else {
- break;
- }
- }
-
- /* Every completed frame needs to be acknowledged */
- if (num_complete) {
- /*
- * If we've wrapped, we have to clear
- * the results in 2 steps.
- */
- if (result_index > wl->next_tx_complete) {
- /* Only 1 write is needed */
- wl1251_mem_write(wl,
- wl->data_path->tx_complete_addr +
- (wl->next_tx_complete *
- sizeof(struct tx_result)),
- &result[wl->next_tx_complete],
- num_complete *
- sizeof(struct tx_result));
-
-
- } else if (result_index < wl->next_tx_complete) {
- /* 2 writes are needed */
- wl1251_mem_write(wl,
- wl->data_path->tx_complete_addr +
- (wl->next_tx_complete *
- sizeof(struct tx_result)),
- &result[wl->next_tx_complete],
- (FW_TX_CMPLT_BLOCK_SIZE -
- wl->next_tx_complete) *
- sizeof(struct tx_result));
-
- wl1251_mem_write(wl,
- wl->data_path->tx_complete_addr,
- result,
- (num_complete -
- FW_TX_CMPLT_BLOCK_SIZE +
- wl->next_tx_complete) *
- sizeof(struct tx_result));
-
- } else {
- /* We have to write the whole array */
- wl1251_mem_write(wl,
- wl->data_path->tx_complete_addr,
- result,
- FW_TX_CMPLT_BLOCK_SIZE *
- sizeof(struct tx_result));
- }
-
- }
-
- wl->next_tx_complete = result_index;
-}
-
-/* caller must hold wl->mutex */
-void wl1251_tx_flush(struct wl1251 *wl)
-{
- int i;
- struct sk_buff *skb;
- struct ieee80211_tx_info *info;
-
- /* TX failure */
-/* control->flags = 0; FIXME */
-
- while ((skb = skb_dequeue(&wl->tx_queue))) {
- info = IEEE80211_SKB_CB(skb);
-
- wl1251_debug(DEBUG_TX, "flushing skb 0x%p", skb);
-
- if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
- continue;
-
- ieee80211_tx_status(wl->hw, skb);
- }
-
- for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
- if (wl->tx_frames[i] != NULL) {
- skb = wl->tx_frames[i];
- info = IEEE80211_SKB_CB(skb);
-
- if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
- continue;
-
- ieee80211_tx_status(wl->hw, skb);
- wl->tx_frames[i] = NULL;
- }
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
deleted file mode 100644
index f40eeb37f5aa..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * This file is part of wl1251
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * Contact: Kalle Valo <kalle.valo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __WL1251_TX_H__
-#define __WL1251_TX_H__
-
-#include <linux/bitops.h>
-#include "wl1251_acx.h"
-
-/*
- *
- * TX PATH
- *
- * The Tx path uses a double buffer and a tx_control structure, each located
- * at a fixed address in the device's memory. On startup, the host retrieves
- * the pointers to these addresses. A double buffer allows for continuous data
- * flow towards the device. The host keeps track of which buffer is available
- * and alternates between these two buffers on a per packet basis.
- *
- * The size of each of the two buffers is large enough to hold the longest
- * 802.3 packet - maximum size Ethernet packet + header + descriptor.
- * TX complete indication will be received a-synchronously in a TX done cyclic
- * buffer which is composed of 16 tx_result descriptors structures and is used
- * in a cyclic manner.
- *
- * The TX (HOST) procedure is as follows:
- * 1. Read the Tx path status, that will give the data_out_count.
- * 2. goto 1, if not possible.
- * i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
- * buffer).
- * 3. Copy the packet (preceded by double_buffer_desc), if possible.
- * i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
- * buffer).
- * 4. increment data_in_count.
- * 5. Inform the firmware by generating a firmware internal interrupt.
- * 6. FW will increment data_out_count after it reads the buffer.
- *
- * The TX Complete procedure:
- * 1. To get a TX complete indication the host enables the tx_complete flag in
- * the TX descriptor Structure.
- * 2. For each packet with a Tx Complete field set, the firmware adds the
- * transmit results to the cyclic buffer (txDoneRing) and sets both done_1
- * and done_2 to 1 to indicate driver ownership.
- * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
- * host to process the new data. Note: interrupt will be send per packet if
- * TX complete indication was requested in tx_control or per crossing
- * aggregation threshold.
- * 4. After receiving the Tx Complete interrupt, the host reads the
- * TxDescriptorDone information in a cyclic manner and clears both done_1
- * and done_2 fields.
- *
- */
-
-#define TX_COMPLETE_REQUIRED_BIT 0x80
-#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf
-
-#define WL1251_TX_ALIGN_TO 4
-#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \
- ~(WL1251_TX_ALIGN_TO - 1))
-#define WL1251_TKIP_IV_SPACE 4
-
-struct tx_control {
- /* Rate Policy (class) index */
- unsigned rate_policy:3;
-
- /* When set, no ack policy is expected */
- unsigned ack_policy:1;
-
- /*
- * Packet type:
- * 0 -> 802.11
- * 1 -> 802.3
- * 2 -> IP
- * 3 -> raw codec
- */
- unsigned packet_type:2;
-
- /* If set, this is a QoS-Null or QoS-Data frame */
- unsigned qos:1;
-
- /*
- * If set, the target triggers the tx complete INT
- * upon frame sending completion.
- */
- unsigned tx_complete:1;
-
- /* 2 bytes padding before packet header */
- unsigned xfer_pad:1;
-
- unsigned reserved:7;
-} __packed;
-
-
-struct tx_double_buffer_desc {
- /* Length of payload, including headers. */
- __le16 length;
-
- /*
- * A bit mask that specifies the initial rate to be used
- * Possible values are:
- * 0x0001 - 1Mbits
- * 0x0002 - 2Mbits
- * 0x0004 - 5.5Mbits
- * 0x0008 - 6Mbits
- * 0x0010 - 9Mbits
- * 0x0020 - 11Mbits
- * 0x0040 - 12Mbits
- * 0x0080 - 18Mbits
- * 0x0100 - 22Mbits
- * 0x0200 - 24Mbits
- * 0x0400 - 36Mbits
- * 0x0800 - 48Mbits
- * 0x1000 - 54Mbits
- */
- __le16 rate;
-
- /* Time in us that a packet can spend in the target */
- __le32 expiry_time;
-
- /* index of the TX queue used for this packet */
- u8 xmit_queue;
-
- /* Used to identify a packet */
- u8 id;
-
- struct tx_control control;
-
- /*
- * The FW should cut the packet into fragments
- * of this size.
- */
- __le16 frag_threshold;
-
- /* Numbers of HW queue blocks to be allocated */
- u8 num_mem_blocks;
-
- u8 reserved;
-} __packed;
-
-enum {
- TX_SUCCESS = 0,
- TX_DMA_ERROR = BIT(7),
- TX_DISABLED = BIT(6),
- TX_RETRY_EXCEEDED = BIT(5),
- TX_TIMEOUT = BIT(4),
- TX_KEY_NOT_FOUND = BIT(3),
- TX_ENCRYPT_FAIL = BIT(2),
- TX_UNAVAILABLE_PRIORITY = BIT(1),
-};
-
-struct tx_result {
- /*
- * Ownership synchronization between the host and
- * the firmware. If done_1 and done_2 are cleared,
- * owned by the FW (no info ready).
- */
- u8 done_1;
-
- /* same as double_buffer_desc->id */
- u8 id;
-
- /*
- * Total air access duration consumed by this
- * packet, including all retries and overheads.
- */
- u16 medium_usage;
-
- /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
- u32 medium_delay;
-
- /* Time between host xfer and tx complete */
- u32 fw_hnadling_time;
-
- /* The LS-byte of the last TKIP sequence number. */
- u8 lsb_seq_num;
-
- /* Retry count */
- u8 ack_failures;
-
- /* At which rate we got a ACK */
- u16 rate;
-
- u16 reserved;
-
- /* TX_* */
- u8 status;
-
- /* See done_1 */
- u8 done_2;
-} __packed;
-
-static inline int wl1251_tx_get_queue(int queue)
-{
- switch (queue) {
- case 0:
- return QOS_AC_VO;
- case 1:
- return QOS_AC_VI;
- case 2:
- return QOS_AC_BE;
- case 3:
- return QOS_AC_BK;
- default:
- return QOS_AC_BE;
- }
-}
-
-void wl1251_tx_work(struct work_struct *work);
-void wl1251_tx_complete(struct wl1251 *wl);
-void wl1251_tx_flush(struct wl1251 *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index dd3cee6ea5bb..8a4cd763e5a2 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -117,10 +117,7 @@ enum {
#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
-/*
- * Enable/disable 802.11a support for WL1273
- */
-#undef WL1271_80211A_ENABLED
+#define WL1271_CIPHER_SUITE_GEM 0x00147201
#define WL1271_BUSY_WORD_CNT 1
#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
@@ -133,6 +130,8 @@ enum {
#define ACX_TX_DESCRIPTORS 32
+#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
+
enum wl1271_state {
WL1271_STATE_OFF,
WL1271_STATE_ON,
@@ -301,6 +300,7 @@ struct wl1271_rx_mem_pool_addr {
struct wl1271_scan {
struct cfg80211_scan_request *req;
bool *scanned_ch;
+ bool failed;
u8 state;
u8 ssid[IW_ESSID_MAX_SIZE+1];
size_t ssid_len;
@@ -313,7 +313,7 @@ struct wl1271_if_operations {
bool fixed);
void (*reset)(struct wl1271 *wl);
void (*init)(struct wl1271 *wl);
- void (*power)(struct wl1271 *wl, bool enable);
+ int (*power)(struct wl1271 *wl, bool enable);
struct device* (*dev)(struct wl1271 *wl);
void (*enable_irq)(struct wl1271 *wl);
void (*disable_irq)(struct wl1271 *wl);
@@ -330,6 +330,7 @@ struct wl1271 {
void (*set_power)(bool enable);
int irq;
+ int ref_clock;
spinlock_t wl_lock;
@@ -349,6 +350,7 @@ struct wl1271 {
#define WL1271_FLAG_IDLE (10)
#define WL1271_FLAG_IDLE_REQUESTED (11)
#define WL1271_FLAG_PSPOLL_FAILURE (12)
+#define WL1271_FLAG_STA_STATE_SENT (13)
unsigned long flags;
struct wl1271_partition_set part;
@@ -361,6 +363,7 @@ struct wl1271 {
u8 *fw;
size_t fw_len;
struct wl1271_nvs_file *nvs;
+ size_t nvs_len;
s8 hw_pg_ver;
@@ -407,9 +410,15 @@ struct wl1271 {
/* Rx memory pool address */
struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
+ /* Intermediate buffer, used for packet aggregation */
+ u8 *aggr_buf;
+
/* The target interrupt mask */
struct work_struct irq_work;
+ /* Hardware recovery work */
+ struct work_struct recovery_work;
+
/* The mbox event mask */
u32 event_mask;
@@ -418,6 +427,7 @@ struct wl1271 {
/* Are we currently scanning */
struct wl1271_scan scan;
+ struct delayed_work scan_complete_work;
/* Our association ID */
u16 aid;
@@ -474,6 +484,8 @@ struct wl1271 {
bool sg_enabled;
+ bool enable_11a;
+
struct list_head list;
/* Most recently reported noise in dBm */
@@ -497,14 +509,4 @@ int wl1271_plt_stop(struct wl1271 *wl);
#define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */
#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
-static inline bool wl1271_11a_enabled(void)
-{
- /* FIXME: this could be determined based on the NVS-INI file */
-#ifdef WL1271_80211A_ENABLED
- return true;
-#else
- return false;
-#endif
-}
-
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index bb245f05af49..618993405262 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -86,40 +86,6 @@ out:
return ret;
}
-int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len)
-{
- struct acx_revision *rev;
- int ret;
-
- wl1271_debug(DEBUG_ACX, "acx fw rev");
-
- rev = kzalloc(sizeof(*rev), GFP_KERNEL);
- if (!rev) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
- if (ret < 0) {
- wl1271_warning("ACX_FW_REV interrogate failed");
- goto out;
- }
-
- /* be careful with the buffer sizes */
- strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
-
- /*
- * if the firmware version string is exactly
- * sizeof(rev->fw_version) long or fw_len is less than
- * sizeof(rev->fw_version) it won't be null terminated
- */
- buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
-
-out:
- kfree(rev);
- return ret;
-}
-
int wl1271_acx_tx_power(struct wl1271 *wl, int power)
{
struct acx_current_tx_power *acx;
@@ -269,7 +235,7 @@ int wl1271_acx_pd_threshold(struct wl1271 *wl)
out:
kfree(pd);
- return 0;
+ return ret;
}
int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 4235bc56f750..ebb341d36e8c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -100,35 +100,6 @@ struct acx_error_counter {
__le32 seq_num_miss;
} __packed;
-struct acx_revision {
- struct acx_header header;
-
- /*
- * The WiLink firmware version, an ASCII string x.x.x.x,
- * that uniquely identifies the current firmware.
- * The left most digit is incremented each time a
- * significant change is made to the firmware, such as
- * code redesign or new platform support.
- * The second digit is incremented when major enhancements
- * are added or major fixes are made.
- * The third digit is incremented for each GA release.
- * The fourth digit is incremented for each build.
- * The first two digits identify a firmware release version,
- * in other words, a unique set of features.
- * The first three digits identify a GA release.
- */
- char fw_version[20];
-
- /*
- * This 4 byte field specifies the WiLink hardware version.
- * bits 0 - 15: Reserved.
- * bits 16 - 23: Version ID - The WiLink version ID
- * (1 = first spin, 2 = second spin, and so on).
- * bits 24 - 31: Chip ID - The WiLink chip ID.
- */
- __le32 hw_version;
-} __packed;
-
enum wl1271_psm_mode {
/* Active mode */
WL1271_PSM_CAM = 0,
@@ -1060,7 +1031,6 @@ enum {
ACX_PEER_HT_CAP = 0x0057,
ACX_HT_BSS_OPERATION = 0x0058,
ACX_COEX_ACTIVITY = 0x0059,
- ACX_SET_SMART_REFLEX_DEBUG = 0x005A,
ACX_SET_DCO_ITRIM_PARAMS = 0x0061,
DOT11_RX_MSDU_LIFE_TIME = 0x1004,
DOT11_CUR_TX_PWR = 0x100D,
@@ -1077,7 +1047,6 @@ enum {
int wl1271_acx_wake_up_conditions(struct wl1271 *wl);
int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
-int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len);
int wl1271_acx_tx_power(struct wl1271 *wl, int power);
int wl1271_acx_feature_cfg(struct wl1271 *wl);
int wl1271_acx_mem_map(struct wl1271 *wl,
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index f36430b0336d..b91021242098 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -225,6 +225,28 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
if (wl->nvs == NULL)
return -ENODEV;
+ /*
+ * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
+ * configurations) can be removed when those NVS files stop floating
+ * around.
+ */
+ if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
+ wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
+ if (wl->nvs->general_params.dual_mode_select)
+ wl->enable_11a = true;
+ }
+
+ if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
+ (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
+ wl->enable_11a)) {
+ wl1271_error("nvs size is not as expected: %zu != %zu",
+ wl->nvs_len, sizeof(struct wl1271_nvs_file));
+ kfree(wl->nvs);
+ wl->nvs = NULL;
+ wl->nvs_len = 0;
+ return -EILSEQ;
+ }
+
/* only the first part of the NVS needs to be uploaded */
nvs_len = sizeof(wl->nvs->nvs);
nvs_ptr = (u8 *)wl->nvs->nvs;
@@ -251,8 +273,10 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
burst_len = nvs_ptr[0];
dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
- /* FIXME: Due to our new wl1271_translate_reg_addr function,
- we need to add the REGISTER_BASE to the destination */
+ /*
+ * Due to our new wl1271_translate_reg_addr function,
+ * we need to add the REGISTER_BASE to the destination
+ */
dest_addr += REGISTERS_BASE;
/* We move our pointer to the data */
@@ -274,31 +298,21 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
/*
* We've reached the first zero length, the first NVS table
- * is 7 bytes further.
+ * is located at an aligned offset which is at least 7 bytes further.
*/
- nvs_ptr += 7;
+ nvs_ptr = (u8 *)wl->nvs->nvs +
+ ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4);
nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
- nvs_len = ALIGN(nvs_len, 4);
- /* FIXME: The driver sets the partition here, but this is not needed,
- since it sets to the same one as currently in use */
/* Now we must set the partition correctly */
wl1271_set_partition(wl, &part_table[PART_WORK]);
/* Copy the NVS tables to a new block to ensure alignment */
- /* FIXME: We jump 3 more bytes before uploading the NVS. It seems
- that our NVS files have three extra zeros here. I'm not sure whether
- the problem is in our NVS generation or we should really jumpt these
- 3 bytes here */
- nvs_ptr += 3;
-
- nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); if
- (!nvs_aligned) return -ENOMEM;
+ nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
+ if (!nvs_aligned)
+ return -ENOMEM;
/* And finally we upload the NVS tables */
- /* FIXME: In wl1271, we upload everything at once.
- No endianness handling needed here?! The ref driver doesn't do
- anything about it at this point */
wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
kfree(nvs_aligned);
@@ -457,17 +471,20 @@ int wl1271_boot(struct wl1271 *wl)
{
int ret = 0;
u32 tmp, clk, pause;
+ int ref_clock = wl->ref_clock;
wl1271_boot_hw_version(wl);
- if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4)
+ if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4)
/* ref clk: 19.2/38.4/38.4-XTAL */
clk = 0x3;
- else if (REF_CLOCK == 1 || REF_CLOCK == 3)
+ else if (ref_clock == 1 || ref_clock == 3)
/* ref clk: 26/52 */
clk = 0x5;
+ else
+ return -EINVAL;
- if (REF_CLOCK != 0) {
+ if (ref_clock != 0) {
u16 val;
/* Set clock type (open drain) */
val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -493,10 +510,7 @@ int wl1271_boot(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
- pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be
- * WU_COUNTER_PAUSE_VAL instead of
- * 0x3ff (magic number ). How does
- * this work?! */
+ pause &= ~(WU_COUNTER_PAUSE_VAL);
pause |= WU_COUNTER_PAUSE_VAL;
wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
@@ -516,7 +530,7 @@ int wl1271_boot(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
/* 2 */
- clk |= (REF_CLOCK << 1) << 4;
+ clk |= (ref_clock << 1) << 4;
wl1271_write32(wl, DRPW_SCRATCH_START, clk);
wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -550,7 +564,6 @@ int wl1271_boot(struct wl1271 *wl)
if (ret < 0)
goto out;
- /* FIXME: Need to check whether this is really what we want */
wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
WL1271_ACX_ALL_EVENTS_VECTOR);
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
index f829699d597e..f73b0b15a280 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.h
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -46,7 +46,6 @@ struct wl1271_static_data {
/* delay between retries */
#define INIT_LOOP_DELAY 50
-#define REF_CLOCK 2
#define WU_COUNTER_PAUSE_VAL 0x3FF
#define WELP_ARM_COMMAND_VAL 0x4
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index ce503ddd5a41..5d3e8485ea4e 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -94,6 +94,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
status = le16_to_cpu(cmd->status);
if (status != CMD_STATUS_SUCCESS) {
wl1271_error("command execute failure %d", status);
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
ret = -EIO;
}
@@ -107,6 +108,8 @@ out:
int wl1271_cmd_general_parms(struct wl1271 *wl)
{
struct wl1271_general_parms_cmd *gen_parms;
+ struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
+ bool answer = false;
int ret;
if (!wl->nvs)
@@ -118,13 +121,24 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
- memcpy(&gen_parms->general_params, &wl->nvs->general_params,
- sizeof(struct wl1271_ini_general_params));
+ memcpy(&gen_parms->general_params, gp, sizeof(*gp));
- ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
- if (ret < 0)
+ if (gp->tx_bip_fem_auto_detect)
+ answer = true;
+
+ ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
+ if (ret < 0) {
wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
+ goto out;
+ }
+
+ gp->tx_bip_fem_manufacturer =
+ gen_parms->general_params.tx_bip_fem_manufacturer;
+
+ wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
+ answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
+out:
kfree(gen_parms);
return ret;
}
@@ -170,6 +184,39 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
return ret;
}
+int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
+{
+ struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
+ struct conf_rf_settings *rf = &wl->conf.rf;
+ int ret;
+
+ if (!wl->nvs)
+ return -ENODEV;
+
+ ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
+ if (!ext_radio_parms)
+ return -ENOMEM;
+
+ ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
+
+ memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
+ rf->tx_per_channel_power_compensation_2,
+ CONF_TX_PWR_COMPENSATION_LEN_2);
+ memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
+ rf->tx_per_channel_power_compensation_5,
+ CONF_TX_PWR_COMPENSATION_LEN_5);
+
+ wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
+ ext_radio_parms, sizeof(*ext_radio_parms));
+
+ ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
+ if (ret < 0)
+ wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
+
+ kfree(ext_radio_parms);
+ return ret;
+}
+
/*
* Poll the mailbox event field until any of the bits in the mask is set or a
* timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
@@ -182,8 +229,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
do {
- if (time_after(jiffies, timeout))
+ if (time_after(jiffies, timeout)) {
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
return -ETIMEDOUT;
+ }
msleep(1);
@@ -390,18 +439,11 @@ out:
return ret;
}
-int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
+int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send)
{
struct wl1271_cmd_ps_params *ps_params = NULL;
int ret = 0;
- /* FIXME: this should be in ps.c */
- ret = wl1271_acx_wake_up_conditions(wl);
- if (ret < 0) {
- wl1271_error("couldn't set wake up conditions");
- goto out;
- }
-
wl1271_debug(DEBUG_CMD, "cmd set ps mode");
ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
@@ -412,9 +454,9 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
ps_params->ps_mode = ps_mode;
ps_params->send_null_data = send;
- ps_params->retries = 5;
- ps_params->hang_over_period = 1;
- ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set);
+ ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries;
+ ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period;
+ ps_params->null_data_rate = cpu_to_le32(rates);
ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
sizeof(*ps_params), 0);
@@ -428,41 +470,6 @@ out:
return ret;
}
-int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
- size_t len)
-{
- struct cmd_read_write_memory *cmd;
- int ret = 0;
-
- wl1271_debug(DEBUG_CMD, "cmd read memory");
-
- cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
- if (!cmd) {
- ret = -ENOMEM;
- goto out;
- }
-
- WARN_ON(len > MAX_READ_SIZE);
- len = min_t(size_t, len, MAX_READ_SIZE);
-
- cmd->addr = cpu_to_le32(addr);
- cmd->size = cpu_to_le32(len);
-
- ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd),
- sizeof(*cmd));
- if (ret < 0) {
- wl1271_error("read memory command failed: %d", ret);
- goto out;
- }
-
- /* the read command got in */
- memcpy(answer, cmd->value, len);
-
-out:
- kfree(cmd);
- return ret;
-}
-
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
void *buf, size_t buf_len, int index, u32 rates)
{
@@ -523,7 +530,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
}
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
- WL1271_RATE_AUTOMATIC);
+ wl->basic_rate);
out:
dev_kfree_skb(skb);
@@ -546,7 +553,7 @@ int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
skb->data, skb->len,
CMD_TEMPL_KLV_IDX_NULL_DATA,
- WL1271_RATE_AUTOMATIC);
+ wl->basic_rate);
out:
dev_kfree_skb(skb);
@@ -623,7 +630,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
sizeof(template), 0,
- WL1271_RATE_AUTOMATIC);
+ wl->basic_rate);
}
int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
@@ -746,3 +753,31 @@ out_free:
out:
return ret;
}
+
+int wl1271_cmd_set_sta_state(struct wl1271 *wl)
+{
+ struct wl1271_cmd_set_sta_state *cmd;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_CMD, "cmd set sta state");
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (!cmd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
+
+ ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0);
+ if (ret < 0) {
+ wl1271_error("failed to send set STA state command");
+ goto out_free;
+ }
+
+out_free:
+ kfree(cmd);
+
+out:
+ return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index af577ee8eb02..a0caf4fc37b1 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -33,12 +33,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
size_t res_len);
int wl1271_cmd_general_parms(struct wl1271 *wl);
int wl1271_cmd_radio_parms(struct wl1271 *wl);
+int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type);
int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
-int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
+int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send);
int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
size_t len);
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
@@ -55,6 +56,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
u8 key_size, const u8 *key, const u8 *addr,
u32 tx_seq_32, u16 tx_seq_16);
int wl1271_cmd_disconnect(struct wl1271 *wl);
+int wl1271_cmd_set_sta_state(struct wl1271 *wl);
enum wl1271_commands {
CMD_INTERROGATE = 1, /*use this to read information elements*/
@@ -160,41 +162,6 @@ enum {
MAX_COMMAND_STATUS = 0xff
};
-
-/*
- * CMD_READ_MEMORY
- *
- * The host issues this command to read the WiLink device memory/registers.
- *
- * Note: The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-/*
- * CMD_WRITE_MEMORY
- *
- * The host issues this command to write the WiLink device memory/registers.
- *
- * The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-#define MAX_READ_SIZE 256
-
-struct cmd_read_write_memory {
- struct wl1271_cmd_header header;
-
- /* The address of the memory to read from or write to.*/
- __le32 addr;
-
- /* The amount of data in bytes to read from or write to the WiLink
- * device.*/
- __le32 size;
-
- /* The actual value read from or written to the Wilink. The source
- of this field is the Host in WRITE command or the Wilink in READ
- command. */
- u8 value[MAX_READ_SIZE];
-} __packed;
-
#define CMDMBOX_HEADER_LEN 4
#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
@@ -313,7 +280,7 @@ enum wl1271_cmd_key_type {
KEY_WEP = 1,
KEY_TKIP = 2,
KEY_AES = 3,
- KEY_GEM = 4
+ KEY_GEM = 4,
};
/* FIXME: Add description for key-types */
@@ -358,13 +325,14 @@ enum wl1271_channel_tune_bands {
WL1271_CHANNEL_TUNE_BAND_4_9
};
-#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
+#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
-#define TEST_CMD_P2G_CAL 0x02
-#define TEST_CMD_CHANNEL_TUNE 0x0d
-#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
-#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
-#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
+#define TEST_CMD_P2G_CAL 0x02
+#define TEST_CMD_CHANNEL_TUNE 0x0d
+#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
+#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
+#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
+#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
struct wl1271_general_parms_cmd {
struct wl1271_cmd_header header;
@@ -397,6 +365,16 @@ struct wl1271_radio_parms_cmd {
u8 padding3[2];
} __packed;
+struct wl1271_ext_radio_parms_cmd {
+ struct wl1271_cmd_header header;
+
+ struct wl1271_cmd_test_header test;
+
+ u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
+ u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
+ u8 padding[3];
+} __packed;
+
struct wl1271_cmd_cal_channel_tune {
struct wl1271_cmd_header header;
@@ -469,4 +447,13 @@ struct wl1271_cmd_disconnect {
u8 padding;
} __packed;
+#define WL1271_CMD_STA_STATE_CONNECTED 1
+
+struct wl1271_cmd_set_sta_state {
+ struct wl1271_cmd_header header;
+
+ u8 state;
+ u8 padding[3];
+} __packed;
+
#endif /* __WL1271_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 0435ffda8f73..5f78a6cb1433 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -595,7 +595,7 @@ struct conf_tx_ac_category {
u16 tx_op_limit;
};
-#define CONF_TX_MAX_TID_COUNT 7
+#define CONF_TX_MAX_TID_COUNT 8
enum {
CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/
@@ -912,6 +912,22 @@ struct conf_conn_settings {
u8 psm_entry_retries;
/*
+ * Specifies the maximum number of times to try transmit the PSM entry
+ * null-func frame for each PSM entry attempt
+ *
+ * Range 0 - 255
+ */
+ u8 psm_entry_nullfunc_retries;
+
+ /*
+ * Specifies the time to linger in active mode after successfully
+ * transmitting the PSM entry null-func frame.
+ *
+ * Range 0 - 255 TU's
+ */
+ u8 psm_entry_hangover_period;
+
+ /*
*
* Specifies the interval of the connection keep-alive null-func
* frame in ms.
@@ -1016,6 +1032,64 @@ struct conf_roam_trigger_settings {
u8 avg_weight_snr_data;
};
+struct conf_scan_settings {
+ /*
+ * The minimum time to wait on each channel for active scans
+ *
+ * Range: 0 - 65536 tu
+ */
+ u16 min_dwell_time_active;
+
+ /*
+ * The maximum time to wait on each channel for active scans
+ *
+ * Range: 0 - 65536 tu
+ */
+ u16 max_dwell_time_active;
+
+ /*
+ * The maximum time to wait on each channel for passive scans
+ *
+ * Range: 0 - 65536 tu
+ */
+ u16 min_dwell_time_passive;
+
+ /*
+ * The maximum time to wait on each channel for passive scans
+ *
+ * Range: 0 - 65536 tu
+ */
+ u16 max_dwell_time_passive;
+
+ /*
+ * Number of probe requests to transmit on each active scan channel
+ *
+ * Range: u8
+ */
+ u16 num_probe_reqs;
+
+};
+
+/* these are number of channels on the band divided by two, rounded up */
+#define CONF_TX_PWR_COMPENSATION_LEN_2 7
+#define CONF_TX_PWR_COMPENSATION_LEN_5 18
+
+struct conf_rf_settings {
+ /*
+ * Per channel power compensation for 2.4GHz
+ *
+ * Range: s8
+ */
+ u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
+
+ /*
+ * Per channel power compensation for 5GHz
+ *
+ * Range: s8
+ */
+ u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
+};
+
struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
@@ -1024,6 +1098,8 @@ struct conf_drv_settings {
struct conf_itrim_settings itrim;
struct conf_pm_config_settings pm_config;
struct conf_roam_trigger_settings roam_trigger;
+ struct conf_scan_settings scan;
+ struct conf_rf_settings rf;
};
#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index c239ef4d0b8d..66c2b90ddfd4 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -51,6 +51,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \
static const struct file_operations name## _ops = { \
.read = name## _read, \
.open = wl1271_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_ADD(name, parent) \
@@ -87,6 +88,7 @@ static ssize_t sub## _ ##name## _read(struct file *file, \
static const struct file_operations sub## _ ##name## _ops = { \
.read = sub## _ ##name## _read, \
.open = wl1271_open_file_generic, \
+ .llseek = generic_file_llseek, \
};
#define DEBUGFS_FWSTATS_ADD(sub, name) \
@@ -237,6 +239,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
static const struct file_operations tx_queue_len_ops = {
.read = tx_queue_len_read,
.open = wl1271_open_file_generic,
+ .llseek = default_llseek,
};
static ssize_t gpio_power_read(struct file *file, char __user *user_buf,
@@ -291,7 +294,8 @@ out:
static const struct file_operations gpio_power_ops = {
.read = gpio_power_read,
.write = gpio_power_write,
- .open = wl1271_open_file_generic
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
};
static void wl1271_debugfs_delete_files(struct wl1271 *wl)
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 25ce2cd5e3f3..7b3f50382963 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -41,6 +41,9 @@ void wl1271_pspoll_work(struct work_struct *work)
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ goto out;
+
if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags))
goto out;
@@ -52,7 +55,7 @@ void wl1271_pspoll_work(struct work_struct *work)
* delivery failure occurred, and no-one changed state since, so
* we should go back to powersave.
*/
- wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true);
+ wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true);
out:
mutex_unlock(&wl->mutex);
@@ -70,7 +73,8 @@ static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl)
/* force active mode receive data from the AP */
if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
- ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true);
+ ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+ wl->basic_rate, true);
if (ret < 0)
return;
set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags);
@@ -91,6 +95,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
bool *beacon_loss)
{
int ret = 0;
+ u32 total_retries = wl->conf.conn.psm_entry_retries;
wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
@@ -104,10 +109,10 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
break;
}
- if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
+ if (wl->psm_entry_retry < total_retries) {
wl->psm_entry_retry++;
ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
- true);
+ wl->basic_rate, true);
} else {
wl1271_info("No ack to nullfunc from AP.");
wl->psm_entry_retry = 0;
@@ -143,7 +148,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
/* make sure the firmware goes to active mode - the frame to
be sent next will indicate to the AP, that we are active. */
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
- false);
+ wl->basic_rate, false);
break;
case EVENT_EXIT_POWER_SAVE_SUCCESS:
default:
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 4447af1557f5..8044bba70ee7 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -53,6 +53,7 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
int wl1271_init_templates_config(struct wl1271 *wl)
{
int ret, i;
+ size_t size;
/* send empty templates for fw memory reservation */
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
@@ -61,14 +62,12 @@ int wl1271_init_templates_config(struct wl1271 *wl)
if (ret < 0)
return ret;
- if (wl1271_11a_enabled()) {
- size_t size = sizeof(struct wl12xx_probe_req_template);
- ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
- NULL, size, 0,
- WL1271_RATE_AUTOMATIC);
- if (ret < 0)
- return ret;
- }
+ size = sizeof(struct wl12xx_probe_req_template);
+ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+ NULL, size, 0,
+ WL1271_RATE_AUTOMATIC);
+ if (ret < 0)
+ return ret;
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
sizeof(struct wl12xx_null_data_template),
@@ -223,6 +222,10 @@ int wl1271_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;
+ ret = wl1271_cmd_ext_radio_parms(wl);
+ if (ret < 0)
+ return ret;
+
/* Template settings */
ret = wl1271_init_templates_config(wl);
if (ret < 0)
@@ -291,8 +294,16 @@ int wl1271_hw_init(struct wl1271 *wl)
if (ret < 0)
goto out_free_memmap;
- /* Default TID configuration */
+ /* Default TID/AC configuration */
+ BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
+ conf_ac = &wl->conf.tx.ac_conf[i];
+ ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
+ conf_ac->cw_max, conf_ac->aifsn,
+ conf_ac->tx_op_limit);
+ if (ret < 0)
+ goto out_free_memmap;
+
conf_tid = &wl->conf.tx.tid_conf[i];
ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
conf_tid->channel_type,
@@ -305,16 +316,6 @@ int wl1271_hw_init(struct wl1271 *wl)
goto out_free_memmap;
}
- /* Default AC configuration */
- for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
- conf_ac = &wl->conf.tx.ac_conf[i];
- ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
- conf_ac->cw_max, conf_ac->aifsn,
- conf_ac->tx_op_limit);
- if (ret < 0)
- goto out_free_memmap;
- }
-
/* Configure TX rate classes */
ret = wl1271_acx_rate_policies(wl);
if (ret < 0)
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h
index bc806c74c63a..c1f92e65ded0 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/wl1271_io.h
@@ -144,10 +144,13 @@ static inline void wl1271_power_off(struct wl1271 *wl)
clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
}
-static inline void wl1271_power_on(struct wl1271 *wl)
+static inline int wl1271_power_on(struct wl1271 *wl)
{
- wl->if_ops->power(wl, true);
- set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+ int ret = wl->if_ops->power(wl, true);
+ if (ret == 0)
+ set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+
+ return ret;
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 9d68f0012f05..48a4b9961ae6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -124,28 +124,28 @@ static struct conf_drv_settings default_conf = {
},
.ac_conf_count = 4,
.ac_conf = {
- [0] = {
+ [CONF_TX_AC_BE] = {
.ac = CONF_TX_AC_BE,
.cw_min = 15,
.cw_max = 63,
.aifsn = 3,
.tx_op_limit = 0,
},
- [1] = {
+ [CONF_TX_AC_BK] = {
.ac = CONF_TX_AC_BK,
.cw_min = 15,
.cw_max = 63,
.aifsn = 7,
.tx_op_limit = 0,
},
- [2] = {
+ [CONF_TX_AC_VI] = {
.ac = CONF_TX_AC_VI,
.cw_min = 15,
.cw_max = 63,
.aifsn = CONF_TX_AIFS_PIFS,
.tx_op_limit = 3008,
},
- [3] = {
+ [CONF_TX_AC_VO] = {
.ac = CONF_TX_AC_VO,
.cw_min = 15,
.cw_max = 63,
@@ -153,64 +153,40 @@ static struct conf_drv_settings default_conf = {
.tx_op_limit = 1504,
},
},
- .tid_conf_count = 7,
+ .tid_conf_count = 4,
.tid_conf = {
- [0] = {
- .queue_id = 0,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- },
- [1] = {
- .queue_id = 1,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
+ [CONF_TX_AC_BE] = {
+ .queue_id = CONF_TX_AC_BE,
+ .channel_type = CONF_CHANNEL_TYPE_EDCF,
.tsid = CONF_TX_AC_BE,
.ps_scheme = CONF_PS_SCHEME_LEGACY,
.ack_policy = CONF_ACK_POLICY_LEGACY,
.apsd_conf = {0, 0},
},
- [2] = {
- .queue_id = 2,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
+ [CONF_TX_AC_BK] = {
+ .queue_id = CONF_TX_AC_BK,
+ .channel_type = CONF_CHANNEL_TYPE_EDCF,
+ .tsid = CONF_TX_AC_BK,
.ps_scheme = CONF_PS_SCHEME_LEGACY,
.ack_policy = CONF_ACK_POLICY_LEGACY,
.apsd_conf = {0, 0},
},
- [3] = {
- .queue_id = 3,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- },
- [4] = {
- .queue_id = 4,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
+ [CONF_TX_AC_VI] = {
+ .queue_id = CONF_TX_AC_VI,
+ .channel_type = CONF_CHANNEL_TYPE_EDCF,
+ .tsid = CONF_TX_AC_VI,
.ps_scheme = CONF_PS_SCHEME_LEGACY,
.ack_policy = CONF_ACK_POLICY_LEGACY,
.apsd_conf = {0, 0},
},
- [5] = {
- .queue_id = 5,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
+ [CONF_TX_AC_VO] = {
+ .queue_id = CONF_TX_AC_VO,
+ .channel_type = CONF_CHANNEL_TYPE_EDCF,
+ .tsid = CONF_TX_AC_VO,
.ps_scheme = CONF_PS_SCHEME_LEGACY,
.ack_policy = CONF_ACK_POLICY_LEGACY,
.apsd_conf = {0, 0},
},
- [6] = {
- .queue_id = 6,
- .channel_type = CONF_CHANNEL_TYPE_DCF,
- .tsid = CONF_TX_AC_BE,
- .ps_scheme = CONF_PS_SCHEME_LEGACY,
- .ack_policy = CONF_ACK_POLICY_LEGACY,
- .apsd_conf = {0, 0},
- }
},
.frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
.tx_compl_timeout = 700,
@@ -238,7 +214,9 @@ static struct conf_drv_settings default_conf = {
.ps_poll_recovery_period = 700,
.bet_enable = CONF_BET_MODE_ENABLE,
.bet_max_consecutive = 10,
- .psm_entry_retries = 3,
+ .psm_entry_retries = 5,
+ .psm_entry_nullfunc_retries = 3,
+ .psm_entry_hangover_period = 1,
.keep_alive_interval = 55000,
.max_listen_interval = 20,
},
@@ -251,15 +229,34 @@ static struct conf_drv_settings default_conf = {
.host_fast_wakeup_support = false
},
.roam_trigger = {
- /* FIXME: due to firmware bug, must use value 1 for now */
.trigger_pacing = 1,
.avg_weight_rssi_beacon = 20,
.avg_weight_rssi_data = 10,
.avg_weight_snr_beacon = 20,
.avg_weight_snr_data = 10
- }
+ },
+ .scan = {
+ .min_dwell_time_active = 7500,
+ .max_dwell_time_active = 30000,
+ .min_dwell_time_passive = 30000,
+ .max_dwell_time_passive = 60000,
+ .num_probe_reqs = 2,
+ },
+ .rf = {
+ .tx_per_channel_power_compensation_2 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ .tx_per_channel_power_compensation_5 = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ },
};
+static void __wl1271_op_remove_interface(struct wl1271 *wl);
+
+
static void wl1271_device_release(struct device *dev)
{
@@ -277,6 +274,67 @@ static struct platform_device wl1271_device = {
static LIST_HEAD(wl_list);
+static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
+ void *arg)
+{
+ struct net_device *dev = arg;
+ struct wireless_dev *wdev;
+ struct wiphy *wiphy;
+ struct ieee80211_hw *hw;
+ struct wl1271 *wl;
+ struct wl1271 *wl_temp;
+ int ret = 0;
+
+ /* Check that this notification is for us. */
+ if (what != NETDEV_CHANGE)
+ return NOTIFY_DONE;
+
+ wdev = dev->ieee80211_ptr;
+ if (wdev == NULL)
+ return NOTIFY_DONE;
+
+ wiphy = wdev->wiphy;
+ if (wiphy == NULL)
+ return NOTIFY_DONE;
+
+ hw = wiphy_priv(wiphy);
+ if (hw == NULL)
+ return NOTIFY_DONE;
+
+ wl_temp = hw->priv;
+ list_for_each_entry(wl, &wl_list, list) {
+ if (wl == wl_temp)
+ break;
+ }
+ if (wl != wl_temp)
+ return NOTIFY_DONE;
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->state == WL1271_STATE_OFF)
+ goto out;
+
+ if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
+ goto out;
+
+ ret = wl1271_ps_elp_wakeup(wl, false);
+ if (ret < 0)
+ goto out;
+
+ if ((dev->operstate == IF_OPER_UP) &&
+ !test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) {
+ wl1271_cmd_set_sta_state(wl);
+ wl1271_info("Association completed.");
+ }
+
+ wl1271_ps_elp_sleep(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+
+ return NOTIFY_OK;
+}
+
static void wl1271_conf_init(struct wl1271 *wl)
{
@@ -309,6 +367,10 @@ static int wl1271_plt_init(struct wl1271 *wl)
if (ret < 0)
return ret;
+ ret = wl1271_cmd_ext_radio_parms(wl);
+ if (ret < 0)
+ return ret;
+
ret = wl1271_init_templates_config(wl);
if (ret < 0)
return ret;
@@ -346,8 +408,16 @@ static int wl1271_plt_init(struct wl1271 *wl)
if (ret < 0)
goto out_free_memmap;
- /* Default TID configuration */
+ /* Default TID/AC configuration */
+ BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count);
for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {
+ conf_ac = &wl->conf.tx.ac_conf[i];
+ ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
+ conf_ac->cw_max, conf_ac->aifsn,
+ conf_ac->tx_op_limit);
+ if (ret < 0)
+ goto out_free_memmap;
+
conf_tid = &wl->conf.tx.tid_conf[i];
ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,
conf_tid->channel_type,
@@ -360,16 +430,6 @@ static int wl1271_plt_init(struct wl1271 *wl)
goto out_free_memmap;
}
- /* Default AC configuration */
- for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
- conf_ac = &wl->conf.tx.ac_conf[i];
- ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,
- conf_ac->cw_max, conf_ac->aifsn,
- conf_ac->tx_op_limit);
- if (ret < 0)
- goto out_free_memmap;
- }
-
/* Enable data path */
ret = wl1271_cmd_data_path(wl, 1);
if (ret < 0)
@@ -562,20 +622,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
return ret;
}
- /*
- * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
- * configurations) can be removed when those NVS files stop floating
- * around.
- */
- if (fw->size != sizeof(struct wl1271_nvs_file) &&
- (fw->size != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
- wl1271_11a_enabled())) {
- wl1271_error("nvs size is not as expected: %zu != %zu",
- fw->size, sizeof(struct wl1271_nvs_file));
- ret = -EILSEQ;
- goto out;
- }
-
wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
if (!wl->nvs) {
@@ -584,12 +630,37 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
goto out;
}
+ wl->nvs_len = fw->size;
+
out:
release_firmware(fw);
return ret;
}
+static void wl1271_recovery_work(struct work_struct *work)
+{
+ struct wl1271 *wl =
+ container_of(work, struct wl1271, recovery_work);
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->state != WL1271_STATE_ON)
+ goto out;
+
+ wl1271_info("Hardware recovery in progress.");
+
+ if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
+ ieee80211_connection_loss(wl->vif);
+
+ /* reboot the chipset */
+ __wl1271_op_remove_interface(wl);
+ ieee80211_restart_hw(wl->hw);
+
+out:
+ mutex_unlock(&wl->mutex);
+}
+
static void wl1271_fw_wakeup(struct wl1271 *wl)
{
u32 elp_reg;
@@ -610,8 +681,6 @@ static int wl1271_setup(struct wl1271 *wl)
return -ENOMEM;
}
- INIT_WORK(&wl->irq_work, wl1271_irq_work);
- INIT_WORK(&wl->tx_work, wl1271_tx_work);
return 0;
}
@@ -621,7 +690,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
int ret = 0;
msleep(WL1271_PRE_POWER_ON_SLEEP);
- wl1271_power_on(wl);
+ ret = wl1271_power_on(wl);
+ if (ret < 0)
+ goto out;
msleep(WL1271_POWER_ON_SLEEP);
wl1271_io_reset(wl);
wl1271_io_init(wl);
@@ -766,10 +837,12 @@ int wl1271_plt_stop(struct wl1271 *wl)
out:
mutex_unlock(&wl->mutex);
+ cancel_work_sync(&wl->irq_work);
+ cancel_work_sync(&wl->recovery_work);
+
return ret;
}
-
static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct wl1271 *wl = hw->priv;
@@ -812,6 +885,10 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
+static struct notifier_block wl1271_dev_notifier = {
+ .notifier_call = wl1271_dev_notify,
+};
+
static int wl1271_op_start(struct ieee80211_hw *hw)
{
wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -928,13 +1005,10 @@ out:
return ret;
}
-static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static void __wl1271_op_remove_interface(struct wl1271 *wl)
{
- struct wl1271 *wl = hw->priv;
int i;
- mutex_lock(&wl->mutex);
wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
wl1271_info("down");
@@ -948,12 +1022,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
ieee80211_enable_dyn_ps(wl->vif);
if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
- mutex_unlock(&wl->mutex);
- ieee80211_scan_completed(wl->hw, true);
- mutex_lock(&wl->mutex);
wl->scan.state = WL1271_SCAN_STATE_IDLE;
kfree(wl->scan.scanned_ch);
wl->scan.scanned_ch = NULL;
+ ieee80211_scan_completed(wl->hw, true);
}
wl->state = WL1271_STATE_OFF;
@@ -962,9 +1034,11 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
mutex_unlock(&wl->mutex);
+ cancel_delayed_work_sync(&wl->scan_complete_work);
cancel_work_sync(&wl->irq_work);
cancel_work_sync(&wl->tx_work);
cancel_delayed_work_sync(&wl->pspoll_work);
+ cancel_delayed_work_sync(&wl->elp_work);
mutex_lock(&wl->mutex);
@@ -1006,8 +1080,19 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
wl->tx_res_if = NULL;
kfree(wl->target_mem_map);
wl->target_mem_map = NULL;
+}
+static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct wl1271 *wl = hw->priv;
+
+ mutex_lock(&wl->mutex);
+ WARN_ON(wl->vif != vif);
+ __wl1271_op_remove_interface(wl);
mutex_unlock(&wl->mutex);
+
+ cancel_work_sync(&wl->recovery_work);
}
static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
@@ -1289,7 +1374,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
wl1271_debug(DEBUG_PSM, "psm enabled");
ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
- true);
+ wl->basic_rate, true);
}
} else if (!(conf->flags & IEEE80211_CONF_PS) &&
test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
@@ -1299,7 +1384,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
if (test_bit(WL1271_FLAG_PSM, &wl->flags))
ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
- true);
+ wl->basic_rate, true);
}
if (conf->power_level != wl->power_level) {
@@ -1439,7 +1524,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
- key_conf->alg, key_conf->keyidx,
+ key_conf->cipher, key_conf->keyidx,
key_conf->keylen, key_conf->flags);
wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
@@ -1455,28 +1540,34 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (ret < 0)
goto out_unlock;
- switch (key_conf->alg) {
- case ALG_WEP:
+ switch (key_conf->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
key_type = KEY_WEP;
key_conf->hw_key_idx = key_conf->keyidx;
break;
- case ALG_TKIP:
+ case WLAN_CIPHER_SUITE_TKIP:
key_type = KEY_TKIP;
key_conf->hw_key_idx = key_conf->keyidx;
tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
break;
- case ALG_CCMP:
+ case WLAN_CIPHER_SUITE_CCMP:
key_type = KEY_AES;
key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
break;
+ case WL1271_CIPHER_SUITE_GEM:
+ key_type = KEY_GEM;
+ tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq);
+ tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq);
+ break;
default:
- wl1271_error("Unknown key algo 0x%x", key_conf->alg);
+ wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
ret = -EOPNOTSUPP;
goto out_sleep;
@@ -1558,10 +1649,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
if (ret < 0)
goto out;
- if (wl1271_11a_enabled())
- ret = wl1271_scan(hw->priv, ssid, len, req);
- else
- ret = wl1271_scan(hw->priv, ssid, len, req);
+ ret = wl1271_scan(hw->priv, ssid, len, req);
wl1271_ps_elp_sleep(wl);
@@ -1633,7 +1721,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if (ret < 0)
goto out;
- if ((changed && BSS_CHANGED_BEACON_INT) &&
+ if ((changed & BSS_CHANGED_BEACON_INT) &&
(wl->bss_type == BSS_TYPE_IBSS)) {
wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d",
bss_conf->beacon_int);
@@ -1642,7 +1730,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
do_join = true;
}
- if ((changed && BSS_CHANGED_BEACON) &&
+ if ((changed & BSS_CHANGED_BEACON) &&
(wl->bss_type == BSS_TYPE_IBSS)) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
@@ -1776,12 +1864,15 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
mode = STATION_POWER_SAVE_MODE;
- ret = wl1271_ps_set_mode(wl, mode, true);
+ ret = wl1271_ps_set_mode(wl, mode,
+ wl->basic_rate,
+ true);
if (ret < 0)
goto out_sleep;
}
} else {
/* use defaults when not associated */
+ clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags);
clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
wl->aid = 0;
@@ -1993,21 +2084,24 @@ static struct ieee80211_rate wl1271_rates[] = {
.hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};
-/* can't be const, mac80211 writes to this */
+/*
+ * Can't be const, mac80211 writes to this. The order of the channels here
+ * is designed to improve scanning.
+ */
static struct ieee80211_channel wl1271_channels[] = {
{ .hw_value = 1, .center_freq = 2412, .max_power = 25 },
- { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
- { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
- { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
{ .hw_value = 5, .center_freq = 2432, .max_power = 25 },
- { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
- { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
- { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
{ .hw_value = 9, .center_freq = 2452, .max_power = 25 },
- { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
- { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
- { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
{ .hw_value = 13, .center_freq = 2472, .max_power = 25 },
+ { .hw_value = 4, .center_freq = 2427, .max_power = 25 },
+ { .hw_value = 8, .center_freq = 2447, .max_power = 25 },
+ { .hw_value = 12, .center_freq = 2467, .max_power = 25 },
+ { .hw_value = 3, .center_freq = 2422, .max_power = 25 },
+ { .hw_value = 7, .center_freq = 2442, .max_power = 25 },
+ { .hw_value = 11, .center_freq = 2462, .max_power = 25 },
+ { .hw_value = 2, .center_freq = 2417, .max_power = 25 },
+ { .hw_value = 6, .center_freq = 2437, .max_power = 25 },
+ { .hw_value = 10, .center_freq = 2457, .max_power = 25 },
};
/* mapping to indexes for wl1271_rates */
@@ -2076,49 +2170,52 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
.hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};
-/* 5 GHz band channels for WL1273 */
+/*
+ * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this.
+ * The order of the channels here is designed to improve scanning.
+ */
static struct ieee80211_channel wl1271_channels_5ghz[] = {
{ .hw_value = 183, .center_freq = 4915},
- { .hw_value = 184, .center_freq = 4920},
- { .hw_value = 185, .center_freq = 4925},
- { .hw_value = 187, .center_freq = 4935},
{ .hw_value = 188, .center_freq = 4940},
- { .hw_value = 189, .center_freq = 4945},
- { .hw_value = 192, .center_freq = 4960},
- { .hw_value = 196, .center_freq = 4980},
- { .hw_value = 7, .center_freq = 5035},
{ .hw_value = 8, .center_freq = 5040},
- { .hw_value = 9, .center_freq = 5045},
- { .hw_value = 11, .center_freq = 5055},
- { .hw_value = 12, .center_freq = 5060},
- { .hw_value = 16, .center_freq = 5080},
{ .hw_value = 34, .center_freq = 5170},
- { .hw_value = 36, .center_freq = 5180},
- { .hw_value = 38, .center_freq = 5190},
- { .hw_value = 40, .center_freq = 5200},
- { .hw_value = 42, .center_freq = 5210},
{ .hw_value = 44, .center_freq = 5220},
- { .hw_value = 46, .center_freq = 5230},
- { .hw_value = 48, .center_freq = 5240},
- { .hw_value = 52, .center_freq = 5260},
- { .hw_value = 56, .center_freq = 5280},
{ .hw_value = 60, .center_freq = 5300},
- { .hw_value = 64, .center_freq = 5320},
- { .hw_value = 100, .center_freq = 5500},
- { .hw_value = 104, .center_freq = 5520},
- { .hw_value = 108, .center_freq = 5540},
{ .hw_value = 112, .center_freq = 5560},
- { .hw_value = 116, .center_freq = 5580},
- { .hw_value = 120, .center_freq = 5600},
- { .hw_value = 124, .center_freq = 5620},
- { .hw_value = 128, .center_freq = 5640},
{ .hw_value = 132, .center_freq = 5660},
+ { .hw_value = 157, .center_freq = 5785},
+ { .hw_value = 184, .center_freq = 4920},
+ { .hw_value = 189, .center_freq = 4945},
+ { .hw_value = 9, .center_freq = 5045},
+ { .hw_value = 36, .center_freq = 5180},
+ { .hw_value = 46, .center_freq = 5230},
+ { .hw_value = 64, .center_freq = 5320},
+ { .hw_value = 116, .center_freq = 5580},
{ .hw_value = 136, .center_freq = 5680},
+ { .hw_value = 192, .center_freq = 4960},
+ { .hw_value = 11, .center_freq = 5055},
+ { .hw_value = 38, .center_freq = 5190},
+ { .hw_value = 48, .center_freq = 5240},
+ { .hw_value = 100, .center_freq = 5500},
+ { .hw_value = 120, .center_freq = 5600},
{ .hw_value = 140, .center_freq = 5700},
+ { .hw_value = 185, .center_freq = 4925},
+ { .hw_value = 196, .center_freq = 4980},
+ { .hw_value = 12, .center_freq = 5060},
+ { .hw_value = 40, .center_freq = 5200},
+ { .hw_value = 52, .center_freq = 5260},
+ { .hw_value = 104, .center_freq = 5520},
+ { .hw_value = 124, .center_freq = 5620},
{ .hw_value = 149, .center_freq = 5745},
- { .hw_value = 153, .center_freq = 5765},
- { .hw_value = 157, .center_freq = 5785},
{ .hw_value = 161, .center_freq = 5805},
+ { .hw_value = 187, .center_freq = 4935},
+ { .hw_value = 7, .center_freq = 5035},
+ { .hw_value = 16, .center_freq = 5080},
+ { .hw_value = 42, .center_freq = 5210},
+ { .hw_value = 56, .center_freq = 5280},
+ { .hw_value = 108, .center_freq = 5540},
+ { .hw_value = 128, .center_freq = 5640},
+ { .hw_value = 153, .center_freq = 5765},
{ .hw_value = 165, .center_freq = 5825},
};
@@ -2211,8 +2308,7 @@ static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
struct wl1271 *wl = dev_get_drvdata(dev);
ssize_t len;
- /* FIXME: what's the maximum length of buf? page size?*/
- len = 500;
+ len = PAGE_SIZE;
mutex_lock(&wl->mutex);
len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
@@ -2273,8 +2369,7 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
struct wl1271 *wl = dev_get_drvdata(dev);
ssize_t len;
- /* FIXME: what's the maximum length of buf? page size?*/
- len = 500;
+ len = PAGE_SIZE;
mutex_lock(&wl->mutex);
if (wl->hw_pg_ver >= 0)
@@ -2306,6 +2401,8 @@ int wl1271_register_hw(struct wl1271 *wl)
wl->mac80211_registered = true;
+ register_netdevice_notifier(&wl1271_dev_notifier);
+
wl1271_notice("loaded");
return 0;
@@ -2314,6 +2411,7 @@ EXPORT_SYMBOL_GPL(wl1271_register_hw);
void wl1271_unregister_hw(struct wl1271 *wl)
{
+ unregister_netdevice_notifier(&wl1271_dev_notifier);
ieee80211_unregister_hw(wl->hw);
wl->mac80211_registered = false;
@@ -2322,6 +2420,14 @@ EXPORT_SYMBOL_GPL(wl1271_unregister_hw);
int wl1271_init_ieee80211(struct wl1271 *wl)
{
+ static const u32 cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+ WL1271_CIPHER_SUITE_GEM,
+ };
+
/* The tx descriptor buffer and the TKIP space. */
wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
sizeof(struct wl1271_tx_hw_descr);
@@ -2339,13 +2445,14 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
IEEE80211_HW_CONNECTION_MONITOR |
IEEE80211_HW_SUPPORTS_CQM_RSSI;
+ wl->hw->wiphy->cipher_suites = cipher_suites;
+ wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
wl->hw->wiphy->max_scan_ssids = 1;
wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
-
- if (wl1271_11a_enabled())
- wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
+ wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
wl->hw->queues = 4;
wl->hw->max_rates = 1;
@@ -2364,6 +2471,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
struct platform_device *plat_dev = NULL;
struct wl1271 *wl;
int i, ret;
+ unsigned int order;
hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
if (!hw) {
@@ -2391,6 +2499,10 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
+ INIT_WORK(&wl->irq_work, wl1271_irq_work);
+ INIT_WORK(&wl->tx_work, wl1271_tx_work);
+ INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
+ INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
wl->channel = WL1271_DEFAULT_CHANNEL;
wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
wl->default_key = 0;
@@ -2422,11 +2534,18 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl1271_debugfs_init(wl);
+ order = get_order(WL1271_AGGR_BUFFER_SIZE);
+ wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
+ if (!wl->aggr_buf) {
+ ret = -ENOMEM;
+ goto err_hw;
+ }
+
/* Register platform device */
ret = platform_device_register(wl->plat_dev);
if (ret) {
wl1271_error("couldn't register platform device");
- goto err_hw;
+ goto err_aggr;
}
dev_set_drvdata(&wl->plat_dev->dev, wl);
@@ -2452,6 +2571,9 @@ err_bt_coex_state:
err_platform:
platform_device_unregister(wl->plat_dev);
+err_aggr:
+ free_pages((unsigned long)wl->aggr_buf, order);
+
err_hw:
wl1271_debugfs_exit(wl);
kfree(plat_dev);
@@ -2468,6 +2590,8 @@ EXPORT_SYMBOL_GPL(wl1271_alloc_hw);
int wl1271_free_hw(struct wl1271 *wl)
{
platform_device_unregister(wl->plat_dev);
+ free_pages((unsigned long)wl->aggr_buf,
+ get_order(WL1271_AGGR_BUFFER_SIZE));
kfree(wl->plat_dev);
wl1271_debugfs_exit(wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index a5e60e0403e5..e3c332e2f97c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -39,6 +39,9 @@ void wl1271_elp_work(struct work_struct *work)
mutex_lock(&wl->mutex);
+ if (unlikely(wl->state == WL1271_STATE_OFF))
+ goto out;
+
if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
(!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
!test_bit(WL1271_FLAG_IDLE, &wl->flags)))
@@ -61,7 +64,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
test_bit(WL1271_FLAG_IDLE, &wl->flags)) {
cancel_delayed_work(&wl->elp_work);
ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
- msecs_to_jiffies(ELP_ENTRY_DELAY));
+ msecs_to_jiffies(ELP_ENTRY_DELAY));
}
}
@@ -96,6 +99,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
&compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
if (ret == 0) {
wl1271_error("ELP wakeup timeout!");
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
ret = -ETIMEDOUT;
goto err;
} else if (ret < 0) {
@@ -121,7 +125,7 @@ out:
}
int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
- bool send)
+ u32 rates, bool send)
{
int ret;
@@ -129,7 +133,14 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
case STATION_POWER_SAVE_MODE:
wl1271_debug(DEBUG_PSM, "entering psm");
- ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send);
+ ret = wl1271_acx_wake_up_conditions(wl);
+ if (ret < 0) {
+ wl1271_error("couldn't set wake up conditions");
+ return ret;
+ }
+
+ ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE,
+ rates, send);
if (ret < 0)
return ret;
@@ -152,7 +163,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
if (ret < 0)
return ret;
- ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send);
+ ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE,
+ rates, send);
if (ret < 0)
return ret;
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h
index 940276f517a4..6ba7b032736f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.h
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.h
@@ -28,7 +28,7 @@
#include "wl1271_acx.h"
int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
- bool send);
+ u32 rates, bool send);
void wl1271_ps_elp_sleep(struct wl1271 *wl);
int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
void wl1271_elp_work(struct work_struct *work);
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index 019aa79cd9df..bea133b6e489 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -74,9 +74,8 @@ static void wl1271_rx_status(struct wl1271 *wl,
}
}
-static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
+static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
{
- struct ieee80211_rx_status rx_status;
struct wl1271_rx_descriptor *desc;
struct sk_buff *skb;
u16 *fc;
@@ -88,16 +87,16 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
* workaround this by not retrieving them at all.
*/
if (unlikely(wl->state == WL1271_STATE_PLT))
- return;
+ return -EINVAL;
skb = __dev_alloc_skb(length, GFP_KERNEL);
if (!skb) {
wl1271_error("Couldn't allocate RX frame");
- return;
+ return -ENOMEM;
}
buf = skb_put(skb, length);
- wl1271_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
+ memcpy(buf, data, length);
/* the data read starts with the descriptor */
desc = (struct wl1271_rx_descriptor *) buf;
@@ -109,15 +108,16 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
beacon = 1;
- wl1271_rx_status(wl, desc, &rx_status, beacon);
+ wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
beacon ? "beacon" : "");
skb_trim(skb, skb->len - desc->pad_len);
- memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
ieee80211_rx_ni(wl->hw, skb);
+
+ return 0;
}
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
@@ -126,31 +126,60 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
u32 buf_size;
u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
+ u32 rx_counter;
u32 mem_block;
+ u32 pkt_length;
+ u32 pkt_offset;
while (drv_rx_counter != fw_rx_counter) {
- mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
- buf_size = wl1271_rx_get_buf_size(status, drv_rx_counter);
+ buf_size = 0;
+ rx_counter = drv_rx_counter;
+ while (rx_counter != fw_rx_counter) {
+ pkt_length = wl1271_rx_get_buf_size(status, rx_counter);
+ if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE)
+ break;
+ buf_size += pkt_length;
+ rx_counter++;
+ rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
+ }
if (buf_size == 0) {
wl1271_warning("received empty data");
break;
}
+ /*
+ * Choose the block we want to read
+ * For aggregated packets, only the first memory block should
+ * be retrieved. The FW takes care of the rest.
+ */
+ mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
wl->rx_mem_pool_addr.addr = (mem_block << 8) +
le32_to_cpu(wl_mem_map->packet_memory_pool_start);
wl->rx_mem_pool_addr.addr_extra =
wl->rx_mem_pool_addr.addr + 4;
-
- /* Choose the block we want to read */
wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr,
- sizeof(wl->rx_mem_pool_addr), false);
-
- wl1271_rx_handle_data(wl, buf_size);
-
- wl->rx_counter++;
- drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
+ sizeof(wl->rx_mem_pool_addr), false);
+
+ /* Read all available packets at once */
+ wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
+ buf_size, true);
+
+ /* Split data into separate packets */
+ pkt_offset = 0;
+ while (pkt_offset < buf_size) {
+ pkt_length = wl1271_rx_get_buf_size(status,
+ drv_rx_counter);
+ if (wl1271_rx_handle_data(wl,
+ wl->aggr_buf + pkt_offset,
+ pkt_length) < 0)
+ break;
+ wl->rx_counter++;
+ drv_rx_counter++;
+ drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
+ pkt_offset += pkt_length;
+ }
}
-
- wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
+ wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS,
+ cpu_to_le32(wl->rx_counter));
}
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c
index fec43eed8c55..909bb47995b6 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.c
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.c
@@ -28,11 +28,43 @@
#include "wl1271_scan.h"
#include "wl1271_acx.h"
+void wl1271_scan_complete_work(struct work_struct *work)
+{
+ struct delayed_work *dwork;
+ struct wl1271 *wl;
+
+ dwork = container_of(work, struct delayed_work, work);
+ wl = container_of(dwork, struct wl1271, scan_complete_work);
+
+ wl1271_debug(DEBUG_SCAN, "Scanning complete");
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->scan.state == WL1271_SCAN_STATE_IDLE) {
+ mutex_unlock(&wl->mutex);
+ return;
+ }
+
+ wl->scan.state = WL1271_SCAN_STATE_IDLE;
+ kfree(wl->scan.scanned_ch);
+ wl->scan.scanned_ch = NULL;
+ mutex_unlock(&wl->mutex);
+
+ ieee80211_scan_completed(wl->hw, false);
+
+ if (wl->scan.failed) {
+ wl1271_info("Scan completed due to error.");
+ ieee80211_queue_work(wl->hw, &wl->recovery_work);
+ }
+}
+
+
static int wl1271_get_scan_channels(struct wl1271 *wl,
struct cfg80211_scan_request *req,
struct basic_scan_channel_params *channels,
enum ieee80211_band band, bool passive)
{
+ struct conf_scan_settings *c = &wl->conf.scan;
int i, j;
u32 flags;
@@ -60,10 +92,17 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
wl1271_debug(DEBUG_SCAN, "beacon_found %d",
req->channels[i]->beacon_found);
- channels[j].min_duration =
- cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION);
- channels[j].max_duration =
- cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION);
+ if (!passive) {
+ channels[j].min_duration =
+ cpu_to_le32(c->min_dwell_time_active);
+ channels[j].max_duration =
+ cpu_to_le32(c->max_dwell_time_active);
+ } else {
+ channels[j].min_duration =
+ cpu_to_le32(c->min_dwell_time_passive);
+ channels[j].max_duration =
+ cpu_to_le32(c->max_dwell_time_passive);
+ }
channels[j].early_termination = 0;
channels[j].tx_power_att = req->channels[i]->max_power;
channels[j].channel = req->channels[i]->hw_value;
@@ -100,8 +139,11 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
/* We always use high priority scans */
scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH;
- if(passive)
+
+ /* No SSIDs means that we have a forced passive scan */
+ if (passive || wl->scan.req->n_ssids == 0)
scan_options |= WL1271_SCAN_OPT_PASSIVE;
+
cmd->params.scan_options = cpu_to_le16(scan_options);
cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req,
@@ -117,7 +159,7 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
cmd->params.rx_filter_options =
cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
- cmd->params.n_probe_reqs = WL1271_SCAN_PROBE_REQS;
+ cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs;
cmd->params.tx_rate = cpu_to_le32(basic_rate);
cmd->params.tid_trigger = 0;
cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
@@ -165,7 +207,7 @@ out:
void wl1271_scan_stm(struct wl1271 *wl)
{
- int ret;
+ int ret = 0;
switch (wl->scan.state) {
case WL1271_SCAN_STATE_IDLE:
@@ -185,7 +227,7 @@ void wl1271_scan_stm(struct wl1271 *wl)
ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true,
wl->conf.tx.basic_rate);
if (ret == WL1271_NOTHING_TO_SCAN) {
- if (wl1271_11a_enabled())
+ if (wl->enable_11a)
wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE;
else
wl->scan.state = WL1271_SCAN_STATE_DONE;
@@ -215,20 +257,22 @@ void wl1271_scan_stm(struct wl1271 *wl)
break;
case WL1271_SCAN_STATE_DONE:
- mutex_unlock(&wl->mutex);
- ieee80211_scan_completed(wl->hw, false);
- mutex_lock(&wl->mutex);
-
- kfree(wl->scan.scanned_ch);
- wl->scan.scanned_ch = NULL;
-
- wl->scan.state = WL1271_SCAN_STATE_IDLE;
+ wl->scan.failed = false;
+ cancel_delayed_work(&wl->scan_complete_work);
+ ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
+ msecs_to_jiffies(0));
break;
default:
wl1271_error("invalid scan state");
break;
}
+
+ if (ret < 0) {
+ cancel_delayed_work(&wl->scan_complete_work);
+ ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
+ msecs_to_jiffies(0));
+ }
}
int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
@@ -248,9 +292,14 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
wl->scan.req = req;
- wl->scan.scanned_ch = kzalloc(req->n_channels *
+ wl->scan.scanned_ch = kcalloc(req->n_channels,
sizeof(*wl->scan.scanned_ch),
GFP_KERNEL);
+ /* we assume failure so that timeout scenarios are handled correctly */
+ wl->scan.failed = true;
+ ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
+ msecs_to_jiffies(WL1271_SCAN_TIMEOUT));
+
wl1271_scan_stm(wl);
return 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h
index f1815700f5f9..6d57127b5e6b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_scan.h
+++ b/drivers/net/wireless/wl12xx/wl1271_scan.h
@@ -32,6 +32,7 @@ int wl1271_scan_build_probe_req(struct wl1271 *wl,
const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len, u8 band);
void wl1271_scan_stm(struct wl1271 *wl);
+void wl1271_scan_complete_work(struct work_struct *work);
#define WL1271_SCAN_MAX_CHANNELS 24
#define WL1271_SCAN_DEFAULT_TAG 1
@@ -39,11 +40,10 @@ void wl1271_scan_stm(struct wl1271 *wl);
#define WL1271_SCAN_OPT_ACTIVE 0
#define WL1271_SCAN_OPT_PASSIVE 1
#define WL1271_SCAN_OPT_PRIORITY_HIGH 4
-#define WL1271_SCAN_CHAN_MIN_DURATION 30000 /* TU */
-#define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */
#define WL1271_SCAN_BAND_2_4_GHZ 0
#define WL1271_SCAN_BAND_5_GHZ 1
-#define WL1271_SCAN_PROBE_REQS 3
+
+#define WL1271_SCAN_TIMEOUT 10000 /* msec */
enum {
WL1271_SCAN_STATE_IDLE,
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 7059b5cccf0f..784ef3432641 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -29,14 +29,13 @@
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/card.h>
#include <linux/gpio.h>
+#include <linux/wl12xx.h>
+#include <linux/pm_runtime.h>
#include "wl1271.h"
#include "wl12xx_80211.h"
#include "wl1271_io.h"
-
-#define RX71_WL1271_IRQ_GPIO 42
-
#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI 0x0097
#endif
@@ -107,6 +106,8 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
int ret;
struct sdio_func *func = wl_to_func(wl);
+ sdio_claim_host(func);
+
if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
@@ -122,9 +123,10 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
}
+ sdio_release_host(func);
+
if (ret)
wl1271_error("sdio read failed (%d)", ret);
-
}
static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
@@ -133,6 +135,8 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
int ret;
struct sdio_func *func = wl_to_func(wl);
+ sdio_claim_host(func);
+
if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
@@ -147,26 +151,49 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
else
ret = sdio_memcpy_toio(func, addr, buf, len);
}
+
+ sdio_release_host(func);
+
if (ret)
wl1271_error("sdio write failed (%d)", ret);
+}
+static int wl1271_sdio_power_on(struct wl1271 *wl)
+{
+ struct sdio_func *func = wl_to_func(wl);
+ int ret;
+
+ /* Power up the card */
+ ret = pm_runtime_get_sync(&func->dev);
+ if (ret < 0)
+ goto out;
+
+ sdio_claim_host(func);
+ sdio_enable_func(func);
+ sdio_release_host(func);
+
+out:
+ return ret;
}
-static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+static int wl1271_sdio_power_off(struct wl1271 *wl)
{
struct sdio_func *func = wl_to_func(wl);
- /* Let the SDIO stack handle wlan_enable control, so we
- * keep host claimed while wlan is in use to keep wl1271
- * alive.
- */
- if (enable) {
- sdio_claim_host(func);
- sdio_enable_func(func);
- } else {
- sdio_disable_func(func);
- sdio_release_host(func);
- }
+ sdio_claim_host(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ /* Power down the card */
+ return pm_runtime_put_sync(&func->dev);
+}
+
+static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
+{
+ if (enable)
+ return wl1271_sdio_power_on(wl);
+ else
+ return wl1271_sdio_power_off(wl);
}
static struct wl1271_if_operations sdio_ops = {
@@ -184,6 +211,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
struct ieee80211_hw *hw;
+ const struct wl12xx_platform_data *wlan_data;
struct wl1271 *wl;
int ret;
@@ -203,13 +231,16 @@ static int __devinit wl1271_probe(struct sdio_func *func,
/* Grab access to FN0 for ELP reg. */
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
- wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO);
- if (wl->irq < 0) {
- ret = wl->irq;
- wl1271_error("could not get irq!");
+ wlan_data = wl12xx_get_platform_data();
+ if (IS_ERR(wlan_data)) {
+ ret = PTR_ERR(wlan_data);
+ wl1271_error("missing wlan platform data: %d", ret);
goto out_free;
}
+ wl->irq = wlan_data->irq;
+ wl->ref_clock = wlan_data->board_ref_clock;
+
ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
if (ret < 0) {
wl1271_error("request_irq() failed: %d", ret);
@@ -230,6 +261,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
sdio_set_drvdata(func, wl);
+ /* Tell PM core that we don't need the card to be powered now */
+ pm_runtime_put_noidle(&func->dev);
+
wl1271_notice("initialized");
return 0;
@@ -248,17 +282,39 @@ static void __devexit wl1271_remove(struct sdio_func *func)
{
struct wl1271 *wl = sdio_get_drvdata(func);
- free_irq(wl->irq, wl);
+ /* Undo decrement done above in wl1271_probe */
+ pm_runtime_get_noresume(&func->dev);
wl1271_unregister_hw(wl);
+ free_irq(wl->irq, wl);
wl1271_free_hw(wl);
}
+static int wl1271_suspend(struct device *dev)
+{
+ /* Tell MMC/SDIO core it's OK to power down the card
+ * (if it isn't already), but not to remove it completely */
+ return 0;
+}
+
+static int wl1271_resume(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops wl1271_sdio_pm_ops = {
+ .suspend = wl1271_suspend,
+ .resume = wl1271_resume,
+};
+
static struct sdio_driver wl1271_sdio_driver = {
.name = "wl1271_sdio",
.id_table = wl1271_devices,
.probe = wl1271_probe,
.remove = __devexit_p(wl1271_remove),
+ .drv = {
+ .pm = &wl1271_sdio_pm_ops,
+ },
};
static int __init wl1271_init(void)
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 4cb99c541e2a..ef801680773f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/crc7.h>
#include <linux/spi/spi.h>
-#include <linux/spi/wl12xx.h>
+#include <linux/wl12xx.h>
#include <linux/slab.h>
#include "wl1271.h"
@@ -63,6 +63,11 @@
((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
#define HW_ACCESS_WSPI_INIT_CMD_MASK 0
+/* HW limitation: maximum possible chunk size is 4095 bytes */
+#define WSPI_MAX_CHUNK_SIZE 4092
+
+#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
+
static inline struct spi_device *wl_to_spi(struct wl1271 *wl)
{
return wl->if_priv;
@@ -202,90 +207,117 @@ static int wl1271_spi_read_busy(struct wl1271 *wl)
static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
size_t len, bool fixed)
{
- struct spi_transfer t[3];
+ struct spi_transfer t[2];
struct spi_message m;
u32 *busy_buf;
u32 *cmd;
+ u32 chunk_len;
- cmd = &wl->buffer_cmd;
- busy_buf = wl->buffer_busyword;
+ while (len > 0) {
+ chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len);
- *cmd = 0;
- *cmd |= WSPI_CMD_READ;
- *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
+ cmd = &wl->buffer_cmd;
+ busy_buf = wl->buffer_busyword;
- if (fixed)
- *cmd |= WSPI_CMD_FIXED;
+ *cmd = 0;
+ *cmd |= WSPI_CMD_READ;
+ *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
+ WSPI_CMD_BYTE_LENGTH;
+ *cmd |= addr & WSPI_CMD_BYTE_ADDR;
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
+ if (fixed)
+ *cmd |= WSPI_CMD_FIXED;
- t[0].tx_buf = cmd;
- t[0].len = 4;
- t[0].cs_change = true;
- spi_message_add_tail(&t[0], &m);
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
- /* Busy and non busy words read */
- t[1].rx_buf = busy_buf;
- t[1].len = WL1271_BUSY_WORD_LEN;
- t[1].cs_change = true;
- spi_message_add_tail(&t[1], &m);
+ t[0].tx_buf = cmd;
+ t[0].len = 4;
+ t[0].cs_change = true;
+ spi_message_add_tail(&t[0], &m);
- spi_sync(wl_to_spi(wl), &m);
+ /* Busy and non busy words read */
+ t[1].rx_buf = busy_buf;
+ t[1].len = WL1271_BUSY_WORD_LEN;
+ t[1].cs_change = true;
+ spi_message_add_tail(&t[1], &m);
- if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
- wl1271_spi_read_busy(wl)) {
- memset(buf, 0, len);
- return;
- }
+ spi_sync(wl_to_spi(wl), &m);
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
+ if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
+ wl1271_spi_read_busy(wl)) {
+ memset(buf, 0, chunk_len);
+ return;
+ }
- t[0].rx_buf = buf;
- t[0].len = len;
- t[0].cs_change = true;
- spi_message_add_tail(&t[0], &m);
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
- spi_sync(wl_to_spi(wl), &m);
+ t[0].rx_buf = buf;
+ t[0].len = chunk_len;
+ t[0].cs_change = true;
+ spi_message_add_tail(&t[0], &m);
- wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
- wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
+ spi_sync(wl_to_spi(wl), &m);
+
+ wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
+ wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len);
+
+ if (!fixed)
+ addr += chunk_len;
+ buf += chunk_len;
+ len -= chunk_len;
+ }
}
static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
size_t len, bool fixed)
{
- struct spi_transfer t[2];
+ struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
struct spi_message m;
+ u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
u32 *cmd;
+ u32 chunk_len;
+ int i;
- cmd = &wl->buffer_cmd;
-
- *cmd = 0;
- *cmd |= WSPI_CMD_WRITE;
- *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
- *cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
- if (fixed)
- *cmd |= WSPI_CMD_FIXED;
+ WARN_ON(len > WL1271_AGGR_BUFFER_SIZE);
spi_message_init(&m);
memset(t, 0, sizeof(t));
- t[0].tx_buf = cmd;
- t[0].len = sizeof(*cmd);
- spi_message_add_tail(&t[0], &m);
+ cmd = &commands[0];
+ i = 0;
+ while (len > 0) {
+ chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len);
- t[1].tx_buf = buf;
- t[1].len = len;
- spi_message_add_tail(&t[1], &m);
+ *cmd = 0;
+ *cmd |= WSPI_CMD_WRITE;
+ *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
+ WSPI_CMD_BYTE_LENGTH;
+ *cmd |= addr & WSPI_CMD_BYTE_ADDR;
- spi_sync(wl_to_spi(wl), &m);
+ if (fixed)
+ *cmd |= WSPI_CMD_FIXED;
+
+ t[i].tx_buf = cmd;
+ t[i].len = sizeof(*cmd);
+ spi_message_add_tail(&t[i++], &m);
+
+ t[i].tx_buf = buf;
+ t[i].len = chunk_len;
+ spi_message_add_tail(&t[i++], &m);
- wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
- wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
+ wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
+ wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, chunk_len);
+
+ if (!fixed)
+ addr += chunk_len;
+ buf += chunk_len;
+ len -= chunk_len;
+ cmd++;
+ }
+
+ spi_sync(wl_to_spi(wl), &m);
}
static irqreturn_t wl1271_irq(int irq, void *cookie)
@@ -312,10 +344,12 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
return IRQ_HANDLED;
}
-static void wl1271_spi_set_power(struct wl1271 *wl, bool enable)
+static int wl1271_spi_set_power(struct wl1271 *wl, bool enable)
{
if (wl->set_power)
wl->set_power(enable);
+
+ return 0;
}
static struct wl1271_if_operations spi_ops = {
@@ -370,6 +404,8 @@ static int __devinit wl1271_probe(struct spi_device *spi)
goto out_free;
}
+ wl->ref_clock = pdata->board_ref_clock;
+
wl->irq = spi->irq;
if (wl->irq < 0) {
wl1271_error("irq missing in platform data");
@@ -412,9 +448,8 @@ static int __devexit wl1271_remove(struct spi_device *spi)
{
struct wl1271 *wl = dev_get_drvdata(&spi->dev);
- free_irq(wl->irq, wl);
-
wl1271_unregister_hw(wl);
+ free_irq(wl->irq, wl);
wl1271_free_hw(wl);
return 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c
index 6e0952f79e9a..a3aa84386c88 100644
--- a/drivers/net/wireless/wl12xx/wl1271_testmode.c
+++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c
@@ -199,19 +199,6 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
buf = nla_data(tb[WL1271_TM_ATTR_DATA]);
len = nla_len(tb[WL1271_TM_ATTR_DATA]);
- /*
- * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
- * configurations) can be removed when those NVS files stop floating
- * around.
- */
- if (len != sizeof(struct wl1271_nvs_file) &&
- (len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
- wl1271_11a_enabled())) {
- wl1271_error("nvs size is not as expected: %zu != %zu",
- len, sizeof(struct wl1271_nvs_file));
- return -EMSGSIZE;
- }
-
mutex_lock(&wl->mutex);
kfree(wl->nvs);
@@ -224,6 +211,7 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
}
memcpy(wl->nvs, buf, len);
+ wl->nvs_len = len;
wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index c592cc2e9fe8..e3dc13c4d01a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -43,13 +43,17 @@ static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
return -EBUSY;
}
-static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
+static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
+ u32 buf_offset)
{
struct wl1271_tx_hw_descr *desc;
u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
u32 total_blocks;
int id, ret = -EBUSY;
+ if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
+ return -EBUSY;
+
/* allocate free identifier for the packet */
id = wl1271_tx_id(wl, skb);
if (id < 0)
@@ -82,7 +86,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
return ret;
}
-static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
+static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
u32 extra, struct ieee80211_tx_info *control)
{
struct timespec ts;
@@ -110,9 +114,9 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
/* configure the tx attributes */
tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
- /* queue */
+ /* queue (we use same identifiers for tid's and ac's */
ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
- desc->tid = wl1271_tx_ac_to_tid(ac);
+ desc->tid = ac;
desc->aid = TX_HW_DEFAULT_AID;
desc->reserved = 0;
@@ -133,59 +137,17 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
desc->tx_attr = cpu_to_le16(tx_attr);
wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
- return 0;
-}
-
-static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
- struct ieee80211_tx_info *control)
-{
-
- struct wl1271_tx_hw_descr *desc;
- int len;
-
- /* FIXME: This is a workaround for getting non-aligned packets.
- This happens at least with EAPOL packets from the user space.
- Our DMA requires packets to be aligned on a 4-byte boundary.
- */
- if (unlikely((long)skb->data & 0x03)) {
- int offset = (4 - (long)skb->data) & 0x03;
- wl1271_debug(DEBUG_TX, "skb offset %d", offset);
-
- /* check whether the current skb can be used */
- if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
- unsigned char *src = skb->data;
-
- /* align the buffer on a 4-byte boundary */
- skb_reserve(skb, offset);
- memmove(skb->data, src, skb->len);
- } else {
- wl1271_info("No handler, fixme!");
- return -EINVAL;
- }
- }
-
- len = WL1271_TX_ALIGN(skb->len);
-
- /* perform a fixed address block write with the packet */
- wl1271_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
-
- /* write packet new counter into the write access register */
- wl->tx_packets_count++;
-
- desc = (struct wl1271_tx_hw_descr *) skb->data;
- wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
- desc->id, skb, len, desc->length);
-
- return 0;
}
/* caller must hold wl->mutex */
-static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
+static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
+ u32 buf_offset)
{
struct ieee80211_tx_info *info;
u32 extra = 0;
int ret = 0;
u8 idx;
+ u32 total_len;
if (!skb)
return -EINVAL;
@@ -193,7 +155,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
info = IEEE80211_SKB_CB(skb);
if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP)
+ info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
extra = WL1271_TKIP_IV_SPACE;
if (info->control.hw_key) {
@@ -208,19 +170,22 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
}
}
- ret = wl1271_tx_allocate(wl, skb, extra);
+ ret = wl1271_tx_allocate(wl, skb, extra, buf_offset);
if (ret < 0)
return ret;
- ret = wl1271_tx_fill_hdr(wl, skb, extra, info);
- if (ret < 0)
- return ret;
+ wl1271_tx_fill_hdr(wl, skb, extra, info);
- ret = wl1271_tx_send_packet(wl, skb, info);
- if (ret < 0)
- return ret;
+ /*
+ * The length of each packet is stored in terms of words. Thus, we must
+ * pad the skb data to make sure its length is aligned.
+ * The number of padding bytes is computed and set in wl1271_tx_fill_hdr
+ */
+ total_len = WL1271_TX_ALIGN(skb->len);
+ memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
+ memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
- return ret;
+ return total_len;
}
u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
@@ -245,7 +210,7 @@ void wl1271_tx_work(struct work_struct *work)
struct sk_buff *skb;
bool woken_up = false;
u32 sta_rates = 0;
- u32 prev_tx_packets_count;
+ u32 buf_offset;
int ret;
/* check if the rates supported by the AP have changed */
@@ -262,14 +227,15 @@ void wl1271_tx_work(struct work_struct *work)
if (unlikely(wl->state == WL1271_STATE_OFF))
goto out;
- prev_tx_packets_count = wl->tx_packets_count;
-
/* if rates have changed, re-configure the rate policy */
if (unlikely(sta_rates)) {
wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
wl1271_acx_rate_policies(wl);
}
+ /* Prepare the transfer buffer, by aggregating all
+ * available packets */
+ buf_offset = 0;
while ((skb = skb_dequeue(&wl->tx_queue))) {
if (!woken_up) {
ret = wl1271_ps_elp_wakeup(wl, false);
@@ -278,21 +244,30 @@ void wl1271_tx_work(struct work_struct *work)
woken_up = true;
}
- ret = wl1271_tx_frame(wl, skb);
+ ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
if (ret == -EBUSY) {
- /* firmware buffer is full, lets stop transmitting. */
+ /*
+ * Either the firmware buffer is full, or the
+ * aggregation buffer is.
+ * Queue back last skb, and stop aggregating.
+ */
skb_queue_head(&wl->tx_queue, skb);
goto out_ack;
} else if (ret < 0) {
dev_kfree_skb(skb);
goto out_ack;
}
+ buf_offset += ret;
+ wl->tx_packets_count++;
}
out_ack:
- /* interrupt the firmware with the new packets */
- if (prev_tx_packets_count != wl->tx_packets_count)
+ if (buf_offset) {
+ wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
+ buf_offset, true);
+ /* interrupt the firmware with the new packets */
wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
+ }
out:
if (woken_up)
@@ -347,7 +322,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
/* remove TKIP header space if present */
if (info->control.hw_key &&
- info->control.hw_key->alg == ALG_TKIP) {
+ info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen);
skb_pull(skb, WL1271_TKIP_IV_SPACE);
@@ -422,8 +397,6 @@ void wl1271_tx_reset(struct wl1271 *wl)
struct sk_buff *skb;
/* TX failure */
-/* control->flags = 0; FIXME */
-
while ((skb = skb_dequeue(&wl->tx_queue))) {
wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
ieee80211_tx_status(wl->hw, skb);
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 48bf92621c03..d12a129ad11c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -139,23 +139,6 @@ static inline int wl1271_tx_get_queue(int queue)
}
}
-/* wl1271 tx descriptor needs the tid and we need to convert it from ac */
-static inline int wl1271_tx_ac_to_tid(int ac)
-{
- switch (ac) {
- case 0:
- return 0;
- case 1:
- return 2;
- case 2:
- return 4;
- case 3:
- return 6;
- default:
- return 0;
- }
-}
-
void wl1271_tx_work(struct work_struct *work);
void wl1271_tx_complete(struct wl1271 *wl);
void wl1271_tx_reset(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
new file mode 100644
index 000000000000..973b11060a8f
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
@@ -0,0 +1,28 @@
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/wl12xx.h>
+
+static const struct wl12xx_platform_data *platform_data;
+
+int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
+{
+ if (platform_data)
+ return -EBUSY;
+ if (!data)
+ return -EINVAL;
+
+ platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!platform_data)
+ return -ENOMEM;
+
+ return 0;
+}
+
+const struct wl12xx_platform_data *wl12xx_get_platform_data(void)
+{
+ if (!platform_data)
+ return ERR_PTR(-ENODEV);
+
+ return platform_data;
+}
+EXPORT_SYMBOL(wl12xx_get_platform_data);