diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx')
57 files changed, 0 insertions, 23497 deletions
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig deleted file mode 100644 index 337fc7bec5a..00000000000 --- a/drivers/net/wireless/wl12xx/Kconfig +++ /dev/null @@ -1,77 +0,0 @@ -menuconfig WL12XX - tristate "TI wl12xx driver support" - depends on MAC80211 && EXPERIMENTAL - ---help--- - 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 && SPI_MASTER && GENERIC_HARDIRQS - depends on INET - select FW_LOADER - select CRC7 - ---help--- - This module adds support for wireless adapters based on the - TI wl1271 chipset. - - If you choose to build a module, it'll be called wl1271. Say N if - unsure. - -config WL1271_SPI - tristate "TI wl1271 SPI support" - depends on WL1271 && SPI_MASTER - ---help--- - This module adds support for the SPI interface of adapters using - TI wl1271 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 WL1271_SDIO - tristate "TI wl1271 SDIO support" - depends on WL1271 && MMC && ARM - ---help--- - This module adds support for the SDIO interface of adapters using - TI wl1271 chipset. Select this if your platform is using - the SDIO bus. - - If you choose to build a module, it'll be called - wl1271_sdio. Say N if unsure. - - diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile deleted file mode 100644 index 27ddd2be0a9..00000000000 --- a/drivers/net/wireless/wl12xx/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -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 \ - wl1271_init.o wl1271_debugfs.o - -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 diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h deleted file mode 100644 index 4f5f02a26e6..00000000000 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ /dev/null @@ -1,429 +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]; -}; - -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 91891f92807..00000000000 --- 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 26160c45784..00000000000 --- 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; -} __attribute__ ((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; -} __attribute__ ((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]; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((packed)); - -struct acx_packet_detection { - struct acx_header header; - - u32 threshold; -} __attribute__ ((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]; -} __attribute__ ((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]; -} __attribute__ ((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; -} __attribute__ ((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]; -} __attribute__ ((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]; -} __attribute__ ((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]; -} __attribute__ ((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]; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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]; -} __attribute__ ((packed)); - -struct acx_event_mask { - struct acx_header header; - - u32 event_mask; - u32 high_event_mask; /* Unused */ -} __attribute__ ((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; -} __attribute__ ((packed)); - -/* STA MAC */ -struct acx_dot11_station_id { - struct acx_header header; - - u8 mac[ETH_ALEN]; - u8 pad[2]; -} __attribute__ ((packed)); - -struct acx_feature_config { - struct acx_header header; - - u32 options; - u32 data_flow_options; -} __attribute__ ((packed)); - -struct acx_current_tx_power { - struct acx_header header; - - u8 current_tx_power; - u8 padding[3]; -} __attribute__ ((packed)); - -struct acx_dot11_default_key { - struct acx_header header; - - u8 id; - u8 pad[3]; -} __attribute__ ((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]; -} __attribute__ ((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]; -} __attribute__ ((packed)); - -struct acx_aid { - struct acx_header header; - - /* - * To be set when associated with an AP. - */ - u16 aid; - u8 pad[2]; -} __attribute__ ((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]; -} __attribute__ ((packed)); - -enum acx_ctsprotect_type { - CTSPROTECT_DISABLE = 0, - CTSPROTECT_ENABLE = 1 -}; - -struct acx_ctsprotect { - struct acx_header header; - u8 ctsprotect; - u8 padding[3]; -} __attribute__ ((packed)); - -struct acx_tx_statistics { - u32 internal_desc_overflow; -} __attribute__ ((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; -} __attribute__ ((packed)); - -struct acx_dma_statistics { - u32 rx_requested; - u32 rx_errors; - u32 tx_requested; - u32 tx_errors; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((packed)); - -struct acx_mic_statistics { - u32 rx_pkts; - u32 calc_failure; -} __attribute__ ((packed)); - -struct acx_aes_statistics { - u32 encrypt_fail; - u32 decrypt_fail; - u32 encrypt_packets; - u32 decrypt_packets; - u32 encrypt_interrupt; - u32 decrypt_interrupt; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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]; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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]; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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; -} __attribute__ ((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]; -} __attribute__ ((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 2545123931e..00000000000 --- 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, interrupt; - - 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); - interrupt = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - - if (interrupt == 0xffffffff) { - wl1251_error("error reading hardware complete " - "init indication"); - return -EIO; - } - /* check that ACX_INTR_INIT_COMPLETE is enabled */ - else if (interrupt & 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 90063697e8f..00000000000 --- 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 a37b30cef48..00000000000 --- 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_SCAN, 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 4ad67cae94d..00000000000 --- 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]; -} __attribute__ ((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 { - u32 rx_config_options; - u32 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. - */ - u16 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 */ - u16 tx_rate; - - u8 tid_trigger; - u8 ssid_len; - u8 ssid[32]; - -} __attribute__ ((packed)); - -struct wl1251_scan_ch_parameters { - u32 min_duration; /* in TU */ - u32 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]; -} __attribute__ ((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]; -} __attribute__ ((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; -} __attribute__ ((packed)); - -struct cmd_enabledisable_path { - struct wl1251_cmd_header header; - - u8 channel; - u8 padding[3]; -} __attribute__ ((packed)); - -#define WL1251_MAX_TEMPLATE_SIZE 300 - -struct wl1251_cmd_packet_template { - struct wl1251_cmd_header header; - - __le16 size; - u8 data[0]; -} __attribute__ ((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 */ -} __attribute__ ((packed)); - -/* Virtual Bit Map update */ -struct wl1251_cmd_vbm_update { - struct wl1251_cmd_header header; - __le16 len; - u8 padding[2]; - struct wl1251_tim tim; -} __attribute__ ((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]; -} __attribute__ ((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]; -} __attribute__ ((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 5e4465ac08f..00000000000 --- 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 6dc3d080853..00000000000 --- 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 020d764f9c1..00000000000 --- 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 be0ac54d624..00000000000 --- 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; -} __attribute__ ((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]; -} __attribute__ ((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 b538bdd7b32..00000000000 --- 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 269cefb3e7d..00000000000 --- 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 f1c232e0887..00000000000 --- 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 c545e9d5f51..00000000000 --- 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 00b24282fc7..00000000000 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ /dev/null @@ -1,1423 +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 = kmalloc(wl->nvs_len, GFP_KERNEL); - - if (!wl->nvs) { - wl1251_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->nvs, fw->data, wl->nvs_len); - - 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; - 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); - -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; -} - -/* 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, -}; - -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_ALIAS("spi:wl1251"); -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 b55cb2bd459..00000000000 --- 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 c688ac57aee..00000000000 --- 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 d16edd9bf06..00000000000 --- 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 851515836a7..00000000000 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ /dev/null @@ -1,186 +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; - - 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 563a3fde40f..00000000000 --- 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 */ -} __attribute__ ((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 c561332e700..00000000000 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ /dev/null @@ -1,314 +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 - -static struct wl12xx_platform_data *wl12xx_board_data; - -static struct sdio_func *wl_to_func(struct wl1251 *wl) -{ - return wl->if_priv; -} - -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 sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - *val = sdio_readb(func, 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 sdio_func *func = wl_to_func(wl); - - sdio_claim_host(func); - sdio_writeb(func, val, addr, &ret); - sdio_release_host(func); - - if (ret) - wl1251_error("sdio_writeb failed (%d)", ret); -} - -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; - - hw = wl1251_alloc_hw(); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - wl = hw->priv; - - 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->if_priv = func; - 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); - wl1251_free_hw(wl); - return ret; -} - -static void __devexit wl1251_sdio_remove(struct sdio_func *func) -{ - struct wl1251 *wl = sdio_get_drvdata(func); - - if (wl->irq) - free_irq(wl->irq, wl); - 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 e81474203a2..00000000000 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ /dev/null @@ -1,347 +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>"); diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h deleted file mode 100644 index 2e273a97e7f..00000000000 --- 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 c8223185efd..00000000000 --- a/drivers/net/wireless/wl12xx/wl1251_tx.c +++ /dev/null @@ -1,560 +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 = 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; - u16 fc; - u8 *pos; - - fc = *(u16 *)(skb->data + sizeof(*tx_hdr)); - tx_hdr->length += WL1251_TKIP_IV_SPACE; - - 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 55856c6bb97..00000000000 --- 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; -} __attribute__ ((packed)); - - -struct tx_double_buffer_desc { - /* Length of payload, including headers. */ - u16 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 - */ - u16 rate; - - /* Time in us that a packet can spend in the target */ - u32 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. - */ - u16 frag_threshold; - - /* Numbers of HW queue blocks to be allocated */ - u8 num_mem_blocks; - - u8 reserved; -} __attribute__ ((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; -} __attribute__ ((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 deleted file mode 100644 index 6f1b6b5640c..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ /dev/null @@ -1,528 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_H__ -#define __WL1271_H__ - -#include <linux/mutex.h> -#include <linux/completion.h> -#include <linux/spinlock.h> -#include <linux/list.h> -#include <linux/bitops.h> -#include <net/mac80211.h> - -#include "wl1271_conf.h" - -#define DRIVER_NAME "wl1271" -#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_TESTMODE = 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_SDIO = BIT(14), - DEBUG_FILTERS = BIT(15), - DEBUG_ADHOC = BIT(16), - DEBUG_ALL = ~0, -}; - -#define DEBUG_LEVEL (DEBUG_NONE) - -#define DEBUG_DUMP_LIMIT 1024 - -#define wl1271_error(fmt, arg...) \ - printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg) - -#define wl1271_warning(fmt, arg...) \ - printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg) - -#define wl1271_notice(fmt, arg...) \ - printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg) - -#define wl1271_info(fmt, arg...) \ - printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg) - -#define wl1271_debug(level, fmt, arg...) \ - do { \ - if (level & DEBUG_LEVEL) \ - printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \ - } while (0) - -#define wl1271_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 wl1271_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 WL1271_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ - CFG_BSSID_FILTER_EN | \ - CFG_MC_FILTER_EN) - -#define WL1271_DEFAULT_RX_FILTER (CFG_RX_RCTS_ACK | 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 WL1271_FW_NAME "wl1271-fw.bin" -#define WL1271_NVS_NAME "wl1271-nvs.bin" - -#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) -#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) - -/* NVS data structure */ -#define WL1271_NVS_SECTION_SIZE 468 - -#define WL1271_NVS_GENERAL_PARAMS_SIZE 57 -#define WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED \ - (WL1271_NVS_GENERAL_PARAMS_SIZE + 1) -#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE 17 -#define WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED \ - (WL1271_NVS_STAT_RADIO_PARAMS_SIZE + 1) -#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE 65 -#define WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED \ - (WL1271_NVS_DYN_RADIO_PARAMS_SIZE + 1) -#define WL1271_NVS_FEM_COUNT 2 -#define WL1271_NVS_INI_SPARE_SIZE 124 - -struct wl1271_nvs_file { - /* NVS section */ - u8 nvs[WL1271_NVS_SECTION_SIZE]; - - /* INI section */ - u8 general_params[WL1271_NVS_GENERAL_PARAMS_SIZE_PADDED]; - u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE_PADDED]; - u8 dyn_radio_params[WL1271_NVS_FEM_COUNT] - [WL1271_NVS_DYN_RADIO_PARAMS_SIZE_PADDED]; - u8 ini_spare[WL1271_NVS_INI_SPARE_SIZE]; -} __attribute__ ((packed)); - -/* - * Enable/disable 802.11a support for WL1273 - */ -#undef WL1271_80211A_ENABLED - -#define WL1271_BUSY_WORD_CNT 1 -#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) - -#define WL1271_ELP_HW_STATE_ASLEEP 0 -#define WL1271_ELP_HW_STATE_IRQ 1 - -#define WL1271_DEFAULT_BEACON_INT 100 -#define WL1271_DEFAULT_DTIM_PERIOD 1 - -#define ACX_TX_DESCRIPTORS 32 - -enum wl1271_state { - WL1271_STATE_OFF, - WL1271_STATE_ON, - WL1271_STATE_PLT, -}; - -enum wl1271_partition_type { - PART_DOWN, - PART_WORK, - PART_DRPW, - - PART_TABLE_LEN -}; - -struct wl1271_partition { - u32 size; - u32 start; -}; - -struct wl1271_partition_set { - struct wl1271_partition mem; - struct wl1271_partition reg; - struct wl1271_partition mem2; - struct wl1271_partition mem3; -}; - -struct wl1271; - -/* FIXME: I'm not sure about this structure name */ -struct wl1271_chip { - u32 id; - char fw_ver[21]; -}; - -struct wl1271_stats { - struct acx_statistics *fw_stats; - unsigned long fw_stats_update; - - unsigned int retry_count; - unsigned int excessive_retries; -}; - -struct wl1271_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 *retry_count; - struct dentry *excessive_retries; - struct dentry *gpio_power; -}; - -#define NUM_TX_QUEUES 4 -#define NUM_RX_PKT_DESC 8 - -/* FW status registers */ -struct wl1271_fw_status { - __le32 intr; - u8 fw_rx_counter; - u8 drv_rx_counter; - u8 reserved; - u8 tx_results_counter; - __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; - __le32 tx_released_blks[NUM_TX_QUEUES]; - __le32 fw_localtime; - __le32 padding[2]; -} __attribute__ ((packed)); - -struct wl1271_rx_mem_pool_addr { - u32 addr; - u32 addr_extra; -}; - -struct wl1271_scan { - u8 state; - u8 ssid[IW_ESSID_MAX_SIZE+1]; - size_t ssid_len; - u8 active; - u8 high_prio; - u8 probe_requests; -}; - -struct wl1271_if_operations { - void (*read)(struct wl1271 *wl, int addr, void *buf, size_t len, - bool fixed); - void (*write)(struct wl1271 *wl, int addr, void *buf, size_t len, - bool fixed); - void (*reset)(struct wl1271 *wl); - void (*init)(struct wl1271 *wl); - void (*power)(struct wl1271 *wl, bool enable); - struct device* (*dev)(struct wl1271 *wl); - void (*enable_irq)(struct wl1271 *wl); - void (*disable_irq)(struct wl1271 *wl); -}; - -struct wl1271 { - struct platform_device *plat_dev; - struct ieee80211_hw *hw; - bool mac80211_registered; - - void *if_priv; - - struct wl1271_if_operations *if_ops; - - void (*set_power)(bool enable); - int irq; - - spinlock_t wl_lock; - - enum wl1271_state state; - struct mutex mutex; - -#define WL1271_FLAG_STA_RATES_CHANGED (0) -#define WL1271_FLAG_STA_ASSOCIATED (1) -#define WL1271_FLAG_JOINED (2) -#define WL1271_FLAG_GPIO_POWER (3) -#define WL1271_FLAG_TX_QUEUE_STOPPED (4) -#define WL1271_FLAG_SCANNING (5) -#define WL1271_FLAG_IN_ELP (6) -#define WL1271_FLAG_PSM (7) -#define WL1271_FLAG_PSM_REQUESTED (8) -#define WL1271_FLAG_IRQ_PENDING (9) -#define WL1271_FLAG_IRQ_RUNNING (10) -#define WL1271_FLAG_IDLE (11) - unsigned long flags; - - struct wl1271_partition_set part; - - struct wl1271_chip chip; - - int cmd_box_addr; - int event_box_addr; - - u8 *fw; - size_t fw_len; - struct wl1271_nvs_file *nvs; - - s8 hw_pg_ver; - - u8 bssid[ETH_ALEN]; - u8 mac_addr[ETH_ALEN]; - u8 bss_type; - u8 set_bss_type; - u8 ssid[IW_ESSID_MAX_SIZE + 1]; - u8 ssid_len; - int channel; - - struct wl1271_acx_mem_map *target_mem_map; - - /* Accounting for allocated / available TX blocks on HW */ - u32 tx_blocks_freed[NUM_TX_QUEUES]; - u32 tx_blocks_available; - u32 tx_results_count; - - /* Transmitted TX packets counter for chipset interface */ - u32 tx_packets_count; - - /* Time-offset between host and chipset clocks */ - s64 time_offset; - - /* Session counter for the chipset */ - int session_counter; - - /* Frames scheduled for transmission, not handled yet */ - struct sk_buff_head tx_queue; - - struct work_struct tx_work; - - /* Pending TX frames */ - struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; - - /* Security sequence number counters */ - u8 tx_security_last_seq; - s64 tx_security_seq; - - /* FW Rx counter */ - u32 rx_counter; - - /* Rx memory pool address */ - struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; - - /* The target interrupt mask */ - struct work_struct irq_work; - - /* The mbox event mask */ - u32 event_mask; - - /* Mailbox pointers */ - u32 mbox_ptr[2]; - - /* Are we currently scanning */ - struct wl1271_scan scan; - - /* Our association ID */ - u16 aid; - - /* currently configured rate set */ - u32 sta_rate_set; - u32 basic_rate_set; - u32 basic_rate; - u32 rate_set; - - /* The current band */ - enum ieee80211_band band; - - /* Beaconing interval (needed for ad-hoc) */ - u32 beacon_int; - - /* Default key (for WEP) */ - u32 default_key; - - unsigned int filters; - unsigned int rx_config; - unsigned int rx_filter; - - struct completion *elp_compl; - struct delayed_work elp_work; - - /* retry counter for PSM entries */ - u8 psm_entry_retry; - - /* in dBm */ - int power_level; - - int rssi_thold; - int last_rssi_event; - - struct wl1271_stats stats; - struct wl1271_debugfs debugfs; - - __le32 buffer_32; - u32 buffer_cmd; - u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; - - struct wl1271_fw_status *fw_status; - struct wl1271_tx_hw_res_if *tx_res_if; - - struct ieee80211_vif *vif; - - /* Current chipset configuration */ - struct conf_drv_settings conf; - - bool sg_enabled; - - struct list_head list; -}; - -int wl1271_plt_start(struct wl1271 *wl); -int wl1271_plt_stop(struct wl1271 *wl); - -#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */ - -#define SESSION_COUNTER_MAX 7 /* maximum value for the session counter */ - -#define WL1271_DEFAULT_POWER_LEVEL 0 - -#define WL1271_TX_QUEUE_LOW_WATERMARK 10 -#define WL1271_TX_QUEUE_HIGH_WATERMARK 25 - -/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power - on in case is has been shut down shortly before */ -#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 deleted file mode 100644 index e19e2f8f1e5..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ /dev/null @@ -1,1268 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_acx.h" - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/crc7.h> -#include <linux/spi/spi.h> -#include <linux/slab.h> - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_reg.h" -#include "wl1271_ps.h" - -int wl1271_acx_wake_up_conditions(struct wl1271 *wl) -{ - struct acx_wake_up_condition *wake_up; - int ret; - - wl1271_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 = wl->conf.conn.wake_up_event; - wake_up->listen_interval = wl->conf.conn.listen_interval; - - ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS, - wake_up, sizeof(*wake_up)); - if (ret < 0) { - wl1271_warning("could not set wake up conditions: %d", ret); - goto out; - } - -out: - kfree(wake_up); - return ret; -} - -int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) -{ - struct acx_sleep_auth *auth; - int ret; - - wl1271_debug(DEBUG_ACX, "acx sleep auth"); - - auth = kzalloc(sizeof(*auth), GFP_KERNEL); - if (!auth) { - ret = -ENOMEM; - goto out; - } - - auth->sleep_auth = sleep_auth; - - ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); - if (ret < 0) - return ret; - -out: - kfree(auth); - 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; - int ret; - - wl1271_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 = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("configure of tx power failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_feature_cfg(struct wl1271 *wl) -{ - struct acx_feature_config *feature; - int ret; - - wl1271_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 = wl1271_cmd_configure(wl, ACX_FEATURE_CFG, - feature, sizeof(*feature)); - if (ret < 0) { - wl1271_error("Couldnt set HW encryption"); - goto out; - } - -out: - kfree(feature); - return ret; -} - -int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map, - size_t len) -{ - int ret; - - wl1271_debug(DEBUG_ACX, "acx mem map"); - - ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl) -{ - struct acx_rx_msdu_lifetime *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx rx msdu life time"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->lifetime = cpu_to_le32(wl->conf.rx.rx_msdu_life_time); - ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("failed to set rx msdu life time: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter) -{ - struct acx_rx_config *rx_config; - int ret; - - wl1271_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 = cpu_to_le32(config); - rx_config->filter_options = cpu_to_le32(filter); - - ret = wl1271_cmd_configure(wl, ACX_RX_CFG, - rx_config, sizeof(*rx_config)); - if (ret < 0) { - wl1271_warning("failed to set rx config: %d", ret); - goto out; - } - -out: - kfree(rx_config); - return ret; -} - -int wl1271_acx_pd_threshold(struct wl1271 *wl) -{ - struct acx_packet_detection *pd; - int ret; - - wl1271_debug(DEBUG_ACX, "acx data pd threshold"); - - pd = kzalloc(sizeof(*pd), GFP_KERNEL); - if (!pd) { - ret = -ENOMEM; - goto out; - } - - pd->threshold = cpu_to_le32(wl->conf.rx.packet_detection_threshold); - - ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd)); - if (ret < 0) { - wl1271_warning("failed to set pd threshold: %d", ret); - goto out; - } - -out: - kfree(pd); - return 0; -} - -int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time) -{ - struct acx_slot *slot; - int ret; - - wl1271_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 = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot)); - if (ret < 0) { - wl1271_warning("failed to set slot time: %d", ret); - goto out; - } - -out: - kfree(slot); - return ret; -} - -int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable, - void *mc_list, u32 mc_list_len) -{ - struct acx_dot11_grp_addr_tbl *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx group address tbl"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - /* MAC filtering */ - acx->enabled = enable; - acx->num_groups = mc_list_len; - memcpy(acx->mac_table, mc_list, mc_list_len * ETH_ALEN); - - ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("failed to set group addr table: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_service_period_timeout(struct wl1271 *wl) -{ - struct acx_rx_timeout *rx_timeout; - int ret; - - rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); - if (!rx_timeout) { - ret = -ENOMEM; - goto out; - } - - wl1271_debug(DEBUG_ACX, "acx service period timeout"); - - rx_timeout->ps_poll_timeout = cpu_to_le16(wl->conf.rx.ps_poll_timeout); - rx_timeout->upsd_timeout = cpu_to_le16(wl->conf.rx.upsd_timeout); - - ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT, - rx_timeout, sizeof(*rx_timeout)); - if (ret < 0) { - wl1271_warning("failed to set service period timeout: %d", - ret); - goto out; - } - -out: - kfree(rx_timeout); - return ret; -} - -int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold) -{ - struct acx_rts_threshold *rts; - int ret; - - wl1271_debug(DEBUG_ACX, "acx rts threshold"); - - rts = kzalloc(sizeof(*rts), GFP_KERNEL); - if (!rts) { - ret = -ENOMEM; - goto out; - } - - rts->threshold = cpu_to_le16(rts_threshold); - - ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts)); - if (ret < 0) { - wl1271_warning("failed to set rts threshold: %d", ret); - goto out; - } - -out: - kfree(rts); - return ret; -} - -int wl1271_acx_dco_itrim_params(struct wl1271 *wl) -{ - struct acx_dco_itrim_params *dco; - struct conf_itrim_settings *c = &wl->conf.itrim; - int ret; - - wl1271_debug(DEBUG_ACX, "acx dco itrim parameters"); - - dco = kzalloc(sizeof(*dco), GFP_KERNEL); - if (!dco) { - ret = -ENOMEM; - goto out; - } - - dco->enable = c->enable; - dco->timeout = cpu_to_le32(c->timeout); - - ret = wl1271_cmd_configure(wl, ACX_SET_DCO_ITRIM_PARAMS, - dco, sizeof(*dco)); - if (ret < 0) { - wl1271_warning("failed to set dco itrim parameters: %d", ret); - goto out; - } - -out: - kfree(dco); - return ret; -} - -int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter) -{ - struct acx_beacon_filter_option *beacon_filter = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx beacon filter opt"); - - if (enable_filter && - wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED) - goto out; - - beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); - if (!beacon_filter) { - ret = -ENOMEM; - goto out; - } - - beacon_filter->enable = enable_filter; - - /* - * When set to zero, and the filter is enabled, beacons - * without the unicast TIM bit set are dropped. - */ - beacon_filter->max_num_beacons = 0; - - ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT, - beacon_filter, sizeof(*beacon_filter)); - if (ret < 0) { - wl1271_warning("failed to set beacon filter opt: %d", ret); - goto out; - } - -out: - kfree(beacon_filter); - return ret; -} - -int wl1271_acx_beacon_filter_table(struct wl1271 *wl) -{ - struct acx_beacon_filter_ie_table *ie_table; - int i, idx = 0; - int ret; - bool vendor_spec = false; - - wl1271_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 = 0; - for (i = 0; i < wl->conf.conn.bcn_filt_ie_count; i++) { - struct conf_bcn_filt_rule *r = &(wl->conf.conn.bcn_filt_ie[i]); - ie_table->table[idx++] = r->ie; - ie_table->table[idx++] = r->rule; - - if (r->ie == WLAN_EID_VENDOR_SPECIFIC) { - /* only one vendor specific ie allowed */ - if (vendor_spec) - continue; - - /* for vendor specific rules configure the - additional fields */ - memcpy(&(ie_table->table[idx]), r->oui, - CONF_BCN_IE_OUI_LEN); - idx += CONF_BCN_IE_OUI_LEN; - ie_table->table[idx++] = r->type; - memcpy(&(ie_table->table[idx]), r->version, - CONF_BCN_IE_VER_LEN); - idx += CONF_BCN_IE_VER_LEN; - vendor_spec = true; - } - - ie_table->num_ie++; - } - - ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE, - ie_table, sizeof(*ie_table)); - if (ret < 0) { - wl1271_warning("failed to set beacon filter table: %d", ret); - goto out; - } - -out: - kfree(ie_table); - return ret; -} - -#define ACX_CONN_MONIT_DISABLE_VALUE 0xffffffff - -int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable) -{ - struct acx_conn_monit_params *acx; - u32 threshold = ACX_CONN_MONIT_DISABLE_VALUE; - u32 timeout = ACX_CONN_MONIT_DISABLE_VALUE; - int ret; - - wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s", - enable ? "enabled" : "disabled"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - if (enable) { - threshold = wl->conf.conn.synch_fail_thold; - timeout = wl->conf.conn.bss_lose_timeout; - } - - acx->synch_fail_thold = cpu_to_le32(threshold); - acx->bss_lose_timeout = cpu_to_le32(timeout); - - ret = wl1271_cmd_configure(wl, ACX_CONN_MONIT_PARAMS, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("failed to set connection monitor " - "parameters: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - - -int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable) -{ - struct acx_bt_wlan_coex *pta; - int ret; - - wl1271_debug(DEBUG_ACX, "acx sg enable"); - - pta = kzalloc(sizeof(*pta), GFP_KERNEL); - if (!pta) { - ret = -ENOMEM; - goto out; - } - - if (enable) - pta->enable = wl->conf.sg.state; - else - pta->enable = CONF_SG_DISABLE; - - ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); - if (ret < 0) { - wl1271_warning("failed to set softgemini enable: %d", ret); - goto out; - } - -out: - kfree(pta); - return ret; -} - -int wl1271_acx_sg_cfg(struct wl1271 *wl) -{ - struct acx_bt_wlan_coex_param *param; - struct conf_sg_settings *c = &wl->conf.sg; - int i, ret; - - wl1271_debug(DEBUG_ACX, "acx sg cfg"); - - param = kzalloc(sizeof(*param), GFP_KERNEL); - if (!param) { - ret = -ENOMEM; - goto out; - } - - /* BT-WLAN coext parameters */ - for (i = 0; i < CONF_SG_PARAMS_MAX; i++) - param->params[i] = cpu_to_le32(c->params[i]); - param->param_idx = CONF_SG_PARAMS_ALL; - - ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); - if (ret < 0) { - wl1271_warning("failed to set sg config: %d", ret); - goto out; - } - -out: - kfree(param); - return ret; -} - -int wl1271_acx_cca_threshold(struct wl1271 *wl) -{ - struct acx_energy_detection *detection; - int ret; - - wl1271_debug(DEBUG_ACX, "acx cca threshold"); - - detection = kzalloc(sizeof(*detection), GFP_KERNEL); - if (!detection) { - ret = -ENOMEM; - goto out; - } - - detection->rx_cca_threshold = cpu_to_le16(wl->conf.rx.rx_cca_threshold); - detection->tx_energy_detection = wl->conf.tx.tx_energy_detection; - - ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD, - detection, sizeof(*detection)); - if (ret < 0) { - wl1271_warning("failed to set cca threshold: %d", ret); - return ret; - } - -out: - kfree(detection); - return ret; -} - -int wl1271_acx_bcn_dtim_options(struct wl1271 *wl) -{ - struct acx_beacon_broadcast *bb; - int ret; - - wl1271_debug(DEBUG_ACX, "acx bcn dtim options"); - - bb = kzalloc(sizeof(*bb), GFP_KERNEL); - if (!bb) { - ret = -ENOMEM; - goto out; - } - - bb->beacon_rx_timeout = cpu_to_le16(wl->conf.conn.beacon_rx_timeout); - bb->broadcast_timeout = cpu_to_le16(wl->conf.conn.broadcast_timeout); - bb->rx_broadcast_in_ps = wl->conf.conn.rx_broadcast_in_ps; - bb->ps_poll_threshold = wl->conf.conn.ps_poll_threshold; - - ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb)); - if (ret < 0) { - wl1271_warning("failed to set rx config: %d", ret); - goto out; - } - -out: - kfree(bb); - return ret; -} - -int wl1271_acx_aid(struct wl1271 *wl, u16 aid) -{ - struct acx_aid *acx_aid; - int ret; - - wl1271_debug(DEBUG_ACX, "acx aid"); - - acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); - if (!acx_aid) { - ret = -ENOMEM; - goto out; - } - - acx_aid->aid = cpu_to_le16(aid); - - ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid)); - if (ret < 0) { - wl1271_warning("failed to set aid: %d", ret); - goto out; - } - -out: - kfree(acx_aid); - return ret; -} - -int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask) -{ - struct acx_event_mask *mask; - int ret; - - wl1271_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 = cpu_to_le32(0xffffffff); - mask->event_mask = cpu_to_le32(event_mask); - - ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK, - mask, sizeof(*mask)); - if (ret < 0) { - wl1271_warning("failed to set acx_event_mbox_mask: %d", ret); - goto out; - } - -out: - kfree(mask); - return ret; -} - -int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble) -{ - struct acx_preamble *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx_set_preamble"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->preamble = preamble; - - ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of preamble failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_cts_protect(struct wl1271 *wl, - enum acx_ctsprotect_type ctsprotect) -{ - struct acx_ctsprotect *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->ctsprotect = ctsprotect; - - ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of ctsprotect failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) -{ - int ret; - - wl1271_debug(DEBUG_ACX, "acx statistics"); - - ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, - sizeof(*stats)); - if (ret < 0) { - wl1271_warning("acx statistics failed: %d", ret); - return -ENOMEM; - } - - return 0; -} - -int wl1271_acx_rate_policies(struct wl1271 *wl) -{ - struct acx_rate_policy *acx; - struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf; - int idx = 0; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx rate policies"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - /* configure one basic rate class */ - idx = ACX_TX_BASIC_RATE; - acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate); - acx->rate_class[idx].short_retry_limit = c->short_retry_limit; - acx->rate_class[idx].long_retry_limit = c->long_retry_limit; - acx->rate_class[idx].aflags = c->aflags; - - /* configure one AP supported rate class */ - idx = ACX_TX_AP_FULL_RATE; - acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set); - acx->rate_class[idx].short_retry_limit = c->short_retry_limit; - acx->rate_class[idx].long_retry_limit = c->long_retry_limit; - acx->rate_class[idx].aflags = c->aflags; - - acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); - - ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of rate policies failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, - u8 aifsn, u16 txop) -{ - struct acx_ac_cfg *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d " - "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->ac = ac; - acx->cw_min = cw_min; - acx->cw_max = cpu_to_le16(cw_max); - acx->aifsn = aifsn; - acx->tx_op_limit = cpu_to_le16(txop); - - ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx ac cfg failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, - u8 tsid, u8 ps_scheme, u8 ack_policy, - u32 apsd_conf0, u32 apsd_conf1) -{ - struct acx_tid_config *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx tid config"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->queue_id = queue_id; - acx->channel_type = channel_type; - acx->tsid = tsid; - acx->ps_scheme = ps_scheme; - acx->ack_policy = ack_policy; - acx->apsd_conf[0] = cpu_to_le32(apsd_conf0); - acx->apsd_conf[1] = cpu_to_le32(apsd_conf1); - - ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of tid config failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_frag_threshold(struct wl1271 *wl) -{ - struct acx_frag_threshold *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx frag threshold"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->frag_threshold = cpu_to_le16(wl->conf.tx.frag_threshold); - ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of frag threshold failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_tx_config_options(struct wl1271 *wl) -{ - struct acx_tx_config_options *acx; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx tx config options"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->tx_compl_timeout = cpu_to_le16(wl->conf.tx.tx_compl_timeout); - acx->tx_compl_threshold = cpu_to_le16(wl->conf.tx.tx_compl_threshold); - ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("Setting of tx options failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_mem_cfg(struct wl1271 *wl) -{ - struct wl1271_acx_config_memory *mem_conf; - int ret; - - wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); - - mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); - if (!mem_conf) { - ret = -ENOMEM; - goto out; - } - - /* memory config */ - mem_conf->num_stations = DEFAULT_NUM_STATIONS; - mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; - mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; - mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; - mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); - - ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, - sizeof(*mem_conf)); - if (ret < 0) { - wl1271_warning("wl1271 mem config failed: %d", ret); - goto out; - } - -out: - kfree(mem_conf); - return ret; -} - -int wl1271_acx_init_mem_config(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_mem_cfg(wl); - if (ret < 0) - return ret; - - wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), - GFP_KERNEL); - if (!wl->target_mem_map) { - wl1271_error("couldn't allocate target memory map"); - return -ENOMEM; - } - - /* we now ask for the firmware built memory map */ - ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map, - sizeof(struct wl1271_acx_mem_map)); - if (ret < 0) { - wl1271_error("couldn't retrieve firmware memory map"); - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - return ret; - } - - /* initialize TX block book keeping */ - wl->tx_blocks_available = - le32_to_cpu(wl->target_mem_map->num_tx_mem_blocks); - wl1271_debug(DEBUG_TX, "available tx blocks: %d", - wl->tx_blocks_available); - - return 0; -} - -int wl1271_acx_init_rx_interrupt(struct wl1271 *wl) -{ - struct wl1271_acx_rx_config_opt *rx_conf; - int ret; - - wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config"); - - rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL); - if (!rx_conf) { - ret = -ENOMEM; - goto out; - } - - rx_conf->threshold = cpu_to_le16(wl->conf.rx.irq_pkt_threshold); - rx_conf->timeout = cpu_to_le16(wl->conf.rx.irq_timeout); - rx_conf->mblk_threshold = cpu_to_le16(wl->conf.rx.irq_blk_threshold); - rx_conf->queue_type = wl->conf.rx.queue_type; - - ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf, - sizeof(*rx_conf)); - if (ret < 0) { - wl1271_warning("wl1271 rx config opt failed: %d", ret); - goto out; - } - -out: - kfree(rx_conf); - return ret; -} - -int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable) -{ - struct wl1271_acx_bet_enable *acx = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx bet enable"); - - if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE) - goto out; - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->enable = enable ? CONF_BET_MODE_ENABLE : CONF_BET_MODE_DISABLE; - acx->max_consecutive = wl->conf.conn.bet_max_consecutive; - - ret = wl1271_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx bet enable failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, - u8 version) -{ - struct wl1271_acx_arp_filter *acx; - int ret; - - wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->version = version; - acx->enable = enable; - - if (enable == true) { - if (version == ACX_IPV4_VERSION) - memcpy(acx->address, address, ACX_IPV4_ADDR_SIZE); - else if (version == ACX_IPV6_VERSION) - memcpy(acx->address, address, sizeof(acx->address)); - else - wl1271_error("Invalid IP version"); - } - - ret = wl1271_cmd_configure(wl, ACX_ARP_IP_FILTER, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("failed to set arp ip filter: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_pm_config(struct wl1271 *wl) -{ - struct wl1271_acx_pm_config *acx = NULL; - struct conf_pm_config_settings *c = &wl->conf.pm_config; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx pm config"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->host_clk_settling_time = cpu_to_le32(c->host_clk_settling_time); - acx->host_fast_wakeup_support = c->host_fast_wakeup_support; - - ret = wl1271_cmd_configure(wl, ACX_PM_CONFIG, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx pm config failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable) -{ - struct wl1271_acx_keep_alive_mode *acx = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->enabled = enable; - - ret = wl1271_cmd_configure(wl, ACX_KEEP_ALIVE_MODE, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx keep alive mode failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid) -{ - struct wl1271_acx_keep_alive_config *acx = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx keep alive config"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->period = cpu_to_le32(wl->conf.conn.keep_alive_interval); - acx->index = index; - acx->tpl_validation = tpl_valid; - acx->trigger = ACX_KEEP_ALIVE_NO_TX; - - ret = wl1271_cmd_configure(wl, ACX_SET_KEEP_ALIVE_CONFIG, - acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx keep alive config failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, - s16 thold, u8 hyst) -{ - struct wl1271_acx_rssi_snr_trigger *acx = NULL; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx rssi snr trigger"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - wl->last_rssi_event = -1; - - acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing); - acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON; - acx->type = WL1271_ACX_TRIG_TYPE_EDGE; - if (enable) - acx->enable = WL1271_ACX_TRIG_ENABLE; - else - acx->enable = WL1271_ACX_TRIG_DISABLE; - - acx->index = WL1271_ACX_TRIG_IDX_RSSI; - acx->dir = WL1271_ACX_TRIG_DIR_BIDIR; - acx->threshold = cpu_to_le16(thold); - acx->hysteresis = hyst; - - ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx rssi snr trigger setting failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} - -int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl) -{ - struct wl1271_acx_rssi_snr_avg_weights *acx = NULL; - struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger; - int ret = 0; - - wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights"); - - acx = kzalloc(sizeof(*acx), GFP_KERNEL); - if (!acx) { - ret = -ENOMEM; - goto out; - } - - acx->rssi_beacon = c->avg_weight_rssi_beacon; - acx->rssi_data = c->avg_weight_rssi_data; - acx->snr_beacon = c->avg_weight_snr_beacon; - acx->snr_data = c->avg_weight_snr_data; - - ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx)); - if (ret < 0) { - wl1271_warning("acx rssi snr trigger weights failed: %d", ret); - goto out; - } - -out: - kfree(acx); - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h deleted file mode 100644 index 420e7e2fc02..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ /dev/null @@ -1,1118 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_ACX_H__ -#define __WL1271_ACX_H__ - -#include "wl1271.h" -#include "wl1271_cmd.h" - -/************************************************************************* - - Host Interrupt Register (WiLink -> Host) - -**************************************************************************/ -/* HW Initiated interrupt Watchdog timer expiration */ -#define WL1271_ACX_INTR_WATCHDOG BIT(0) -/* Init sequence is done (masked interrupt, detection through polling only ) */ -#define WL1271_ACX_INTR_INIT_COMPLETE BIT(1) -/* Event was entered to Event MBOX #A*/ -#define WL1271_ACX_INTR_EVENT_A BIT(2) -/* Event was entered to Event MBOX #B*/ -#define WL1271_ACX_INTR_EVENT_B BIT(3) -/* Command processing completion*/ -#define WL1271_ACX_INTR_CMD_COMPLETE BIT(4) -/* Signaling the host on HW wakeup */ -#define WL1271_ACX_INTR_HW_AVAILABLE BIT(5) -/* The MISC bit is used for aggregation of RX, TxComplete and TX rate update */ -#define WL1271_ACX_INTR_DATA BIT(6) -/* Trace meassge on MBOX #A */ -#define WL1271_ACX_INTR_TRACE_A BIT(7) -/* Trace meassge on MBOX #B */ -#define WL1271_ACX_INTR_TRACE_B BIT(8) - -#define WL1271_ACX_INTR_ALL 0xFFFFFFFF -#define WL1271_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_INIT_COMPLETE | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_CMD_COMPLETE | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA) - -#define WL1271_INTR_MASK (WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA) - -/* Target's information element */ -struct acx_header { - struct wl1271_cmd_header cmd; - - /* acx (or information element) header */ - __le16 id; - - /* payload length (not including headers */ - __le16 len; -} __attribute__ ((packed)); - -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.*/ - __le32 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.*/ - __le32 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.*/ - __le32 valid_frame; - - /* the number of missed sequence numbers in the squentially */ - /* values of frames seq numbers */ - __le32 seq_num_miss; -} __attribute__ ((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; -} __attribute__ ((packed)); - -enum wl1271_psm_mode { - /* Active mode */ - WL1271_PSM_CAM = 0, - - /* Power save mode */ - WL1271_PSM_PS = 1, - - /* Extreme low power */ - WL1271_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]; -} __attribute__ ((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 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. - */ - __le32 lifetime; -} __attribute__ ((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; - - __le32 config_options; - __le32 filter_options; -} __attribute__ ((packed)); - -struct acx_packet_detection { - struct acx_header header; - - __le32 threshold; -} __attribute__ ((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]; -} __attribute__ ((packed)); - - -#define ACX_MC_ADDRESS_GROUP_MAX (8) -#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ACX_MC_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]; -} __attribute__ ((packed)); - -struct acx_rx_timeout { - struct acx_header header; - - __le16 ps_poll_timeout; - __le16 upsd_timeout; -} __attribute__ ((packed)); - -struct acx_rts_threshold { - struct acx_header header; - - __le16 threshold; - u8 pad[2]; -} __attribute__ ((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]; -} __attribute__ ((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)) - -struct acx_beacon_filter_ie_table { - struct acx_header header; - - u8 num_ie; - u8 pad[3]; - u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; -} __attribute__ ((packed)); - -struct acx_conn_monit_params { - struct acx_header header; - - __le32 synch_fail_thold; /* number of beacons missed */ - __le32 bss_lose_timeout; /* number of TU's from synch fail */ -} __attribute__ ((packed)); - -struct acx_bt_wlan_coex { - struct acx_header header; - - u8 enable; - u8 pad[3]; -} __attribute__ ((packed)); - -struct acx_bt_wlan_coex_param { - struct acx_header header; - - __le32 params[CONF_SG_PARAMS_MAX]; - u8 param_idx; - u8 padding[3]; -} __attribute__ ((packed)); - -struct acx_dco_itrim_params { - struct acx_header header; - - u8 enable; - u8 padding[3]; - __le32 timeout; -} __attribute__ ((packed)); - -struct acx_energy_detection { - struct acx_header header; - - /* The RX Clear Channel Assessment threshold in the PHY */ - __le16 rx_cca_threshold; - u8 tx_energy_detection; - u8 pad; -} __attribute__ ((packed)); - -struct acx_beacon_broadcast { - struct acx_header header; - - __le16 beacon_rx_timeout; - __le16 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]; -} __attribute__ ((packed)); - -struct acx_event_mask { - struct acx_header header; - - __le32 event_mask; - __le32 high_event_mask; /* Unused */ -} __attribute__ ((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) - -/* When set, disable HW encryption */ -#define DF_ENCRYPTION_DISABLE 0x01 -#define DF_SNIFF_MODE_ENABLE 0x80 - -struct acx_feature_config { - struct acx_header header; - - __le32 options; - __le32 data_flow_options; -} __attribute__ ((packed)); - -struct acx_current_tx_power { - struct acx_header header; - - u8 current_tx_power; - u8 padding[3]; -} __attribute__ ((packed)); - -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]; -} __attribute__ ((packed)); - -struct acx_aid { - struct acx_header header; - - /* - * To be set when associated with an AP. - */ - __le16 aid; - u8 pad[2]; -} __attribute__ ((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]; -} __attribute__ ((packed)); - -enum acx_ctsprotect_type { - CTSPROTECT_DISABLE = 0, - CTSPROTECT_ENABLE = 1 -}; - -struct acx_ctsprotect { - struct acx_header header; - u8 ctsprotect; - u8 padding[3]; -} __attribute__ ((packed)); - -struct acx_tx_statistics { - __le32 internal_desc_overflow; -} __attribute__ ((packed)); - -struct acx_rx_statistics { - __le32 out_of_mem; - __le32 hdr_overflow; - __le32 hw_stuck; - __le32 dropped; - __le32 fcs_err; - __le32 xfr_hint_trig; - __le32 path_reset; - __le32 reset_counter; -} __attribute__ ((packed)); - -struct acx_dma_statistics { - __le32 rx_requested; - __le32 rx_errors; - __le32 tx_requested; - __le32 tx_errors; -} __attribute__ ((packed)); - -struct acx_isr_statistics { - /* host command complete */ - __le32 cmd_cmplt; - - /* fiqisr() */ - __le32 fiqs; - - /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ - __le32 rx_headers; - - /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ - __le32 rx_completes; - - /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ - __le32 rx_mem_overflow; - - /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ - __le32 rx_rdys; - - /* irqisr() */ - __le32 irqs; - - /* (INT_STS_ND & INT_TRIG_TX_PROC) */ - __le32 tx_procs; - - /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ - __le32 decrypt_done; - - /* (INT_STS_ND & INT_TRIG_DMA0) */ - __le32 dma0_done; - - /* (INT_STS_ND & INT_TRIG_DMA1) */ - __le32 dma1_done; - - /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ - __le32 tx_exch_complete; - - /* (INT_STS_ND & INT_TRIG_COMMAND) */ - __le32 commands; - - /* (INT_STS_ND & INT_TRIG_RX_PROC) */ - __le32 rx_procs; - - /* (INT_STS_ND & INT_TRIG_PM_802) */ - __le32 hw_pm_mode_changes; - - /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ - __le32 host_acknowledges; - - /* (INT_STS_ND & INT_TRIG_PM_PCI) */ - __le32 pci_pm; - - /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ - __le32 wakeups; - - /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ - __le32 low_rssi; -} __attribute__ ((packed)); - -struct acx_wep_statistics { - /* WEP address keys configured */ - __le32 addr_key_count; - - /* default keys configured */ - __le32 default_key_count; - - __le32 reserved; - - /* number of times that WEP key not found on lookup */ - __le32 key_not_found; - - /* number of times that WEP key decryption failed */ - __le32 decrypt_fail; - - /* WEP packets decrypted */ - __le32 packets; - - /* WEP decrypt interrupts */ - __le32 interrupt; -} __attribute__ ((packed)); - -#define ACX_MISSED_BEACONS_SPREAD 10 - -struct acx_pwr_statistics { - /* the amount of enters into power save mode (both PD & ELP) */ - __le32 ps_enter; - - /* the amount of enters into ELP mode */ - __le32 elp_enter; - - /* the amount of missing beacon interrupts to the host */ - __le32 missing_bcns; - - /* the amount of wake on host-access times */ - __le32 wake_on_host; - - /* the amount of wake on timer-expire */ - __le32 wake_on_timer_exp; - - /* the number of packets that were transmitted with PS bit set */ - __le32 tx_with_ps; - - /* the number of packets that were transmitted with PS bit clear */ - __le32 tx_without_ps; - - /* the number of received beacons */ - __le32 rcvd_beacons; - - /* the number of entering into PowerOn (power save off) */ - __le32 power_save_off; - - /* the number of entries into power save mode */ - __le16 enable_ps; - - /* - * the number of exits from power save, not including failed PS - * transitions - */ - __le16 disable_ps; - - /* - * the number of times the TSF counter was adjusted because - * of drift - */ - __le32 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. - */ - __le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; - - /* the number of beacons in awake mode */ - __le32 rcvd_awake_beacons; -} __attribute__ ((packed)); - -struct acx_mic_statistics { - __le32 rx_pkts; - __le32 calc_failure; -} __attribute__ ((packed)); - -struct acx_aes_statistics { - __le32 encrypt_fail; - __le32 decrypt_fail; - __le32 encrypt_packets; - __le32 decrypt_packets; - __le32 encrypt_interrupt; - __le32 decrypt_interrupt; -} __attribute__ ((packed)); - -struct acx_event_statistics { - __le32 heart_beat; - __le32 calibration; - __le32 rx_mismatch; - __le32 rx_mem_empty; - __le32 rx_pool; - __le32 oom_late; - __le32 phy_transmit_error; - __le32 tx_stuck; -} __attribute__ ((packed)); - -struct acx_ps_statistics { - __le32 pspoll_timeouts; - __le32 upsd_timeouts; - __le32 upsd_max_sptime; - __le32 upsd_max_apturn; - __le32 pspoll_max_apturn; - __le32 pspoll_utilization; - __le32 upsd_utilization; -} __attribute__ ((packed)); - -struct acx_rxpipe_statistics { - __le32 rx_prep_beacon_drop; - __le32 descr_host_int_trig_rx_data; - __le32 beacon_buffer_thres_host_int_trig_rx_data; - __le32 missed_beacon_host_int_trig_rx_data; - __le32 tx_xfr_host_int_trig_rx_data; -} __attribute__ ((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; -} __attribute__ ((packed)); - -struct acx_rate_class { - __le32 enabled_rates; - u8 short_retry_limit; - u8 long_retry_limit; - u8 aflags; - u8 reserved; -}; - -#define ACX_TX_BASIC_RATE 0 -#define ACX_TX_AP_FULL_RATE 1 -#define ACX_TX_RATE_POLICY_CNT 2 -struct acx_rate_policy { - struct acx_header header; - - __le32 rate_class_cnt; - struct acx_rate_class rate_class[CONF_TX_MAX_RATE_CLASSES]; -} __attribute__ ((packed)); - -struct acx_ac_cfg { - struct acx_header header; - u8 ac; - u8 cw_min; - __le16 cw_max; - u8 aifsn; - u8 reserved; - __le16 tx_op_limit; -} __attribute__ ((packed)); - -struct acx_tid_config { - struct acx_header header; - u8 queue_id; - u8 channel_type; - u8 tsid; - u8 ps_scheme; - u8 ack_policy; - u8 padding[3]; - __le32 apsd_conf[2]; -} __attribute__ ((packed)); - -struct acx_frag_threshold { - struct acx_header header; - __le16 frag_threshold; - u8 padding[2]; -} __attribute__ ((packed)); - -struct acx_tx_config_options { - struct acx_header header; - __le16 tx_compl_timeout; /* msec */ - __le16 tx_compl_threshold; /* number of packets */ -} __attribute__ ((packed)); - -#define ACX_RX_MEM_BLOCKS 70 -#define ACX_TX_MIN_MEM_BLOCKS 40 -#define ACX_TX_DESCRIPTORS 32 -#define ACX_NUM_SSID_PROFILES 1 - -struct wl1271_acx_config_memory { - struct acx_header header; - - u8 rx_mem_block_num; - u8 tx_min_mem_block_num; - u8 num_stations; - u8 num_ssid_profiles; - __le32 total_tx_descriptors; -} __attribute__ ((packed)); - -struct wl1271_acx_mem_map { - struct acx_header header; - - __le32 code_start; - __le32 code_end; - - __le32 wep_defkey_start; - __le32 wep_defkey_end; - - __le32 sta_table_start; - __le32 sta_table_end; - - __le32 packet_template_start; - __le32 packet_template_end; - - /* Address of the TX result interface (control block) */ - __le32 tx_result; - __le32 tx_result_queue_start; - - __le32 queue_memory_start; - __le32 queue_memory_end; - - __le32 packet_memory_pool_start; - __le32 packet_memory_pool_end; - - __le32 debug_buffer1_start; - __le32 debug_buffer1_end; - - __le32 debug_buffer2_start; - __le32 debug_buffer2_end; - - /* Number of blocks FW allocated for TX packets */ - __le32 num_tx_mem_blocks; - - /* Number of blocks FW allocated for RX packets */ - __le32 num_rx_mem_blocks; - - /* the following 4 fields are valid in SLAVE mode only */ - u8 *tx_cbuf; - u8 *rx_cbuf; - __le32 rx_ctrl; - __le32 tx_ctrl; -} __attribute__ ((packed)); - -struct wl1271_acx_rx_config_opt { - struct acx_header header; - - __le16 mblk_threshold; - __le16 threshold; - __le16 timeout; - u8 queue_type; - u8 reserved; -} __attribute__ ((packed)); - - -struct wl1271_acx_bet_enable { - struct acx_header header; - - u8 enable; - u8 max_consecutive; - u8 padding[2]; -} __attribute__ ((packed)); - -#define ACX_IPV4_VERSION 4 -#define ACX_IPV6_VERSION 6 -#define ACX_IPV4_ADDR_SIZE 4 -struct wl1271_acx_arp_filter { - struct acx_header header; - u8 version; /* ACX_IPV4_VERSION, ACX_IPV6_VERSION */ - u8 enable; /* 1 to enable ARP filtering, 0 to disable */ - u8 padding[2]; - u8 address[16]; /* The configured device IP address - all ARP - requests directed to this IP address will pass - through. For IPv4, the first four bytes are - used. */ -} __attribute__((packed)); - -struct wl1271_acx_pm_config { - struct acx_header header; - - __le32 host_clk_settling_time; - u8 host_fast_wakeup_support; - u8 padding[3]; -} __attribute__ ((packed)); - -struct wl1271_acx_keep_alive_mode { - struct acx_header header; - - u8 enabled; - u8 padding[3]; -} __attribute__ ((packed)); - -enum { - ACX_KEEP_ALIVE_NO_TX = 0, - ACX_KEEP_ALIVE_PERIOD_ONLY -}; - -enum { - ACX_KEEP_ALIVE_TPL_INVALID = 0, - ACX_KEEP_ALIVE_TPL_VALID -}; - -struct wl1271_acx_keep_alive_config { - struct acx_header header; - - __le32 period; - u8 index; - u8 tpl_validation; - u8 trigger; - u8 padding; -} __attribute__ ((packed)); - -enum { - WL1271_ACX_TRIG_TYPE_LEVEL = 0, - WL1271_ACX_TRIG_TYPE_EDGE, -}; - -enum { - WL1271_ACX_TRIG_DIR_LOW = 0, - WL1271_ACX_TRIG_DIR_HIGH, - WL1271_ACX_TRIG_DIR_BIDIR, -}; - -enum { - WL1271_ACX_TRIG_ENABLE = 1, - WL1271_ACX_TRIG_DISABLE, -}; - -enum { - WL1271_ACX_TRIG_METRIC_RSSI_BEACON = 0, - WL1271_ACX_TRIG_METRIC_RSSI_DATA, - WL1271_ACX_TRIG_METRIC_SNR_BEACON, - WL1271_ACX_TRIG_METRIC_SNR_DATA, -}; - -enum { - WL1271_ACX_TRIG_IDX_RSSI = 0, - WL1271_ACX_TRIG_COUNT = 8, -}; - -struct wl1271_acx_rssi_snr_trigger { - struct acx_header header; - - __le16 threshold; - __le16 pacing; /* 0 - 60000 ms */ - u8 metric; - u8 type; - u8 dir; - u8 hysteresis; - u8 index; - u8 enable; - u8 padding[2]; -}; - -struct wl1271_acx_rssi_snr_avg_weights { - struct acx_header header; - - u8 rssi_beacon; - u8 rssi_data; - u8 snr_beacon; - u8 snr_data; -}; - -enum { - ACX_WAKE_UP_CONDITIONS = 0x0002, - ACX_MEM_CFG = 0x0003, - ACX_SLOT = 0x0004, - ACX_AC_CFG = 0x0007, - ACX_MEM_MAP = 0x0008, - ACX_AID = 0x000A, - /* ACX_FW_REV is missing in the ref driver, but seems to work */ - ACX_FW_REV = 0x000D, - ACX_MEDIUM_USAGE = 0x000F, - ACX_RX_CFG = 0x0010, - ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */ - ACX_STATISTICS = 0x0013, /* Debug API */ - ACX_PWR_CONSUMPTION_STATISTICS = 0x0014, - ACX_FEATURE_CFG = 0x0015, - ACX_TID_CFG = 0x001A, - ACX_PS_RX_STREAMING = 0x001B, - ACX_BEACON_FILTER_OPT = 0x001F, - ACX_NOISE_HIST = 0x0021, - ACX_HDK_VERSION = 0x0022, /* ??? */ - ACX_PD_THRESHOLD = 0x0023, - ACX_TX_CONFIG_OPT = 0x0024, - ACX_CCA_THRESHOLD = 0x0025, - ACX_EVENT_MBOX_MASK = 0x0026, - ACX_CONN_MONIT_PARAMS = 0x002D, - ACX_CONS_TX_FAILURE = 0x002F, - ACX_BCN_DTIM_OPTIONS = 0x0031, - ACX_SG_ENABLE = 0x0032, - ACX_SG_CFG = 0x0033, - 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_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_RX_CONFIG_OPT = 0x004E, - ACX_FRAG_CFG = 0x004F, - ACX_BET_ENABLE = 0x0050, - ACX_RSSI_SNR_TRIGGER = 0x0051, - ACX_RSSI_SNR_WEIGHTS = 0x0052, - ACX_KEEP_ALIVE_MODE = 0x0053, - ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, - ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, - ACX_BA_SESSION_INITIATOR_POLICY = 0x0056, - 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, - DOT11_RX_DOT11_MODE = 0x1012, - DOT11_RTS_THRESHOLD = 0x1013, - DOT11_GROUP_ADDRESS_TBL = 0x1014, - ACX_PM_CONFIG = 0x1016, - - MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, - - MAX_IE = 0xFFFF -}; - - -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, - struct acx_header *mem_map, size_t len); -int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl); -int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter); -int wl1271_acx_pd_threshold(struct wl1271 *wl); -int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time); -int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable, - void *mc_list, u32 mc_list_len); -int wl1271_acx_service_period_timeout(struct wl1271 *wl); -int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold); -int wl1271_acx_dco_itrim_params(struct wl1271 *wl); -int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); -int wl1271_acx_beacon_filter_table(struct wl1271 *wl); -int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable); -int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable); -int wl1271_acx_sg_cfg(struct wl1271 *wl); -int wl1271_acx_cca_threshold(struct wl1271 *wl); -int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); -int wl1271_acx_aid(struct wl1271 *wl, u16 aid); -int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask); -int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble); -int wl1271_acx_cts_protect(struct wl1271 *wl, - enum acx_ctsprotect_type ctsprotect); -int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); -int wl1271_acx_rate_policies(struct wl1271 *wl); -int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, - u8 aifsn, u16 txop); -int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, - u8 tsid, u8 ps_scheme, u8 ack_policy, - u32 apsd_conf0, u32 apsd_conf1); -int wl1271_acx_frag_threshold(struct wl1271 *wl); -int wl1271_acx_tx_config_options(struct wl1271 *wl); -int wl1271_acx_mem_cfg(struct wl1271 *wl); -int wl1271_acx_init_mem_config(struct wl1271 *wl); -int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); -int wl1271_acx_smart_reflex(struct wl1271 *wl); -int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); -int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, - u8 version); -int wl1271_acx_pm_config(struct wl1271 *wl); -int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); -int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); -int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, - s16 thold, u8 hyst); -int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); - -#endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c deleted file mode 100644 index 1a36d8a2196..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_acx.h" -#include "wl1271_reg.h" -#include "wl1271_boot.h" -#include "wl1271_io.h" -#include "wl1271_event.h" - -static struct wl1271_partition_set part_table[PART_TABLE_LEN] = { - [PART_DOWN] = { - .mem = { - .start = 0x00000000, - .size = 0x000177c0 - }, - .reg = { - .start = REGISTERS_BASE, - .size = 0x00008800 - }, - .mem2 = { - .start = 0x00000000, - .size = 0x00000000 - }, - .mem3 = { - .start = 0x00000000, - .size = 0x00000000 - }, - }, - - [PART_WORK] = { - .mem = { - .start = 0x00040000, - .size = 0x00014fc0 - }, - .reg = { - .start = REGISTERS_BASE, - .size = 0x0000a000 - }, - .mem2 = { - .start = 0x003004f8, - .size = 0x00000004 - }, - .mem3 = { - .start = 0x00040404, - .size = 0x00000000 - }, - }, - - [PART_DRPW] = { - .mem = { - .start = 0x00040000, - .size = 0x00014fc0 - }, - .reg = { - .start = DRPW_BASE, - .size = 0x00006000 - }, - .mem2 = { - .start = 0x00000000, - .size = 0x00000000 - }, - .mem3 = { - .start = 0x00000000, - .size = 0x00000000 - } - } -}; - -static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) -{ - u32 cpu_ctrl; - - /* 10.5.0 run the firmware (I) */ - cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL); - - /* 10.5.1 run the firmware (II) */ - cpu_ctrl |= flag; - wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); -} - -static void wl1271_boot_fw_version(struct wl1271 *wl) -{ - struct wl1271_static_data static_data; - - wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data), - false); - - strncpy(wl->chip.fw_ver, static_data.fw_version, - sizeof(wl->chip.fw_ver)); - - /* make sure the string is NULL-terminated */ - wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0'; -} - -static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, - size_t fw_data_len, u32 dest) -{ - struct wl1271_partition_set partition; - int addr, chunk_num, partition_limit; - u8 *p, *chunk; - - /* whal_FwCtrl_LoadFwImageSm() */ - - wl1271_debug(DEBUG_BOOT, "starting firmware upload"); - - wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d", - fw_data_len, CHUNK_SIZE); - - if ((fw_data_len % 4) != 0) { - wl1271_error("firmware length not multiple of four"); - return -EIO; - } - - chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL); - if (!chunk) { - wl1271_error("allocation for firmware upload chunk failed"); - return -ENOMEM; - } - - memcpy(&partition, &part_table[PART_DOWN], sizeof(partition)); - partition.mem.start = dest; - wl1271_set_partition(wl, &partition); - - /* 10.1 set partition limit and chunk num */ - chunk_num = 0; - partition_limit = part_table[PART_DOWN].mem.size; - - while (chunk_num < fw_data_len / CHUNK_SIZE) { - /* 10.2 update partition, if needed */ - addr = dest + (chunk_num + 2) * CHUNK_SIZE; - if (addr > partition_limit) { - addr = dest + chunk_num * CHUNK_SIZE; - partition_limit = chunk_num * CHUNK_SIZE + - part_table[PART_DOWN].mem.size; - partition.mem.start = addr; - wl1271_set_partition(wl, &partition); - } - - /* 10.3 upload the chunk */ - addr = dest + chunk_num * CHUNK_SIZE; - p = buf + chunk_num * CHUNK_SIZE; - memcpy(chunk, p, CHUNK_SIZE); - wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", - p, addr); - wl1271_write(wl, addr, chunk, CHUNK_SIZE, false); - - chunk_num++; - } - - /* 10.4 upload the last chunk */ - addr = dest + chunk_num * CHUNK_SIZE; - p = buf + chunk_num * CHUNK_SIZE; - memcpy(chunk, p, fw_data_len % CHUNK_SIZE); - wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x", - fw_data_len % CHUNK_SIZE, p, addr); - wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false); - - kfree(chunk); - return 0; -} - -static int wl1271_boot_upload_firmware(struct wl1271 *wl) -{ - u32 chunks, addr, len; - int ret = 0; - u8 *fw; - - fw = wl->fw; - chunks = be32_to_cpup((__be32 *) fw); - fw += sizeof(u32); - - wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks); - - while (chunks--) { - addr = be32_to_cpup((__be32 *) fw); - fw += sizeof(u32); - len = be32_to_cpup((__be32 *) fw); - fw += sizeof(u32); - - if (len > 300000) { - wl1271_info("firmware chunk too long: %u", len); - return -EINVAL; - } - wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u", - chunks, addr, len); - ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr); - if (ret != 0) - break; - fw += len; - } - - return ret; -} - -static int wl1271_boot_upload_nvs(struct wl1271 *wl) -{ - size_t nvs_len, burst_len; - int i; - u32 dest_addr, val; - u8 *nvs_ptr, *nvs_aligned; - - if (wl->nvs == NULL) - return -ENODEV; - - /* only the first part of the NVS needs to be uploaded */ - nvs_len = sizeof(wl->nvs->nvs); - nvs_ptr = (u8 *)wl->nvs->nvs; - - /* update current MAC address to NVS */ - nvs_ptr[11] = wl->mac_addr[0]; - nvs_ptr[10] = wl->mac_addr[1]; - nvs_ptr[6] = wl->mac_addr[2]; - nvs_ptr[5] = wl->mac_addr[3]; - nvs_ptr[4] = wl->mac_addr[4]; - nvs_ptr[3] = wl->mac_addr[5]; - - /* - * 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. - */ - - /* FIXME: Do we need to check here whether the LSB is 1? */ - while (nvs_ptr[0]) { - 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 */ - dest_addr += REGISTERS_BASE; - - /* 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)); - - wl1271_debug(DEBUG_BOOT, - "nvs burst write 0x%x: 0x%x", - dest_addr, val); - wl1271_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 - (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; - - /* 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); - return 0; -} - -static void wl1271_boot_enable_interrupts(struct wl1271 *wl) -{ - wl1271_enable_interrupts(wl); - wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, - WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); - wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL); -} - -static int wl1271_boot_soft_reset(struct wl1271 *wl) -{ - unsigned long timeout; - u32 boot_data; - - /* perform soft reset */ - wl1271_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 = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET); - wl1271_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 */ - wl1271_error("soft reset timeout"); - return -1; - } - - udelay(SOFT_RESET_STALL_TIME); - } - - /* disable Rx/Tx */ - wl1271_write32(wl, ENABLE, 0x0); - - /* disable auto calibration on start*/ - wl1271_write32(wl, SPARE_A2, 0xffff); - - return 0; -} - -static int wl1271_boot_run_firmware(struct wl1271 *wl) -{ - int loop, ret; - u32 chip_id, intr; - - wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); - - chip_id = wl1271_read32(wl, CHIP_ID_B); - - wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id); - - if (chip_id != wl->chip.id) { - wl1271_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); - intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - - if (intr == 0xffffffff) { - wl1271_error("error reading hardware complete " - "init indication"); - return -EIO; - } - /* check that ACX_INTR_INIT_COMPLETE is enabled */ - else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) { - wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, - WL1271_ACX_INTR_INIT_COMPLETE); - break; - } - } - - if (loop > INIT_LOOP) { - wl1271_error("timeout waiting for the hardware to " - "complete initialization"); - return -EIO; - } - - /* get hardware config command mail box */ - wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR); - - /* get hardware config event mail box */ - wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR); - - /* set the working partition to its "running" mode offset */ - wl1271_set_partition(wl, &part_table[PART_WORK]); - - wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x", - wl->cmd_box_addr, wl->event_box_addr); - - wl1271_boot_fw_version(wl); - - /* - * in case of full asynchronous mode the firmware event must be - * ready to receive event from the command mailbox - */ - - /* unmask required mbox events */ - wl->event_mask = BSS_LOSE_EVENT_ID | - SCAN_COMPLETE_EVENT_ID | - PS_REPORT_EVENT_ID | - JOIN_EVENT_COMPLETE_ID | - DISCONNECT_EVENT_COMPLETE_ID | - RSSI_SNR_TRIGGER_0_EVENT_ID; - - ret = wl1271_event_unmask(wl); - if (ret < 0) { - wl1271_error("EVENT mask setting failed"); - return ret; - } - - wl1271_event_mbox_config(wl); - - /* firmware startup completed */ - return 0; -} - -static int wl1271_boot_write_irq_polarity(struct wl1271 *wl) -{ - u32 polarity; - - polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY); - - /* We use HIGH polarity, so unset the LOW bit */ - polarity &= ~POLARITY_LOW; - wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity); - - return 0; -} - -static void wl1271_boot_hw_version(struct wl1271 *wl) -{ - u32 fuse; - - fuse = wl1271_top_reg_read(wl, REG_FUSE_DATA_2_1); - fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; - - wl->hw_pg_ver = (s8)fuse; -} - -int wl1271_boot(struct wl1271 *wl) -{ - int ret = 0; - u32 tmp, clk, pause; - - wl1271_boot_hw_version(wl); - - 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) - /* ref clk: 26/52 */ - clk = 0x5; - - if (REF_CLOCK != 0) { - u16 val; - /* Set clock type (open drain) */ - val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); - val &= FREF_CLK_TYPE_BITS; - wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val); - - /* Set clock pull mode (no pull) */ - val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL); - val |= NO_PULL; - wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val); - } else { - u16 val; - /* Set clock polarity */ - val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY); - val &= FREF_CLK_POLARITY_BITS; - val |= CLK_REQ_OUTN_SEL; - wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); - } - - wl1271_write32(wl, PLL_PARAMETERS, clk); - - pause = wl1271_read32(wl, PLL_PARAMETERS); - - 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; - wl1271_write32(wl, WU_COUNTER_PAUSE, pause); - - /* Continue the ELP wake up sequence */ - wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); - udelay(500); - - wl1271_set_partition(wl, &part_table[PART_DRPW]); - - /* Read-modify-write DRPW_SCRATCH_START register (see next state) - to be used by DRPw FW. The RTRIM value will be added by the FW - before taking DRPw out of reset */ - - wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START); - clk = wl1271_read32(wl, DRPW_SCRATCH_START); - - wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); - - /* 2 */ - clk |= (REF_CLOCK << 1) << 4; - wl1271_write32(wl, DRPW_SCRATCH_START, clk); - - wl1271_set_partition(wl, &part_table[PART_WORK]); - - /* Disable interrupts */ - wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); - - ret = wl1271_boot_soft_reset(wl); - if (ret < 0) - goto out; - - /* 2. start processing NVS file */ - ret = wl1271_boot_upload_nvs(wl); - if (ret < 0) - goto out; - - /* write firmware's last address (ie. it's length) to - * ACX_EEPROMLESS_IND_REG */ - wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG"); - - wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG); - - tmp = wl1271_read32(wl, CHIP_ID_B); - - wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); - - /* 6. read the EEPROM parameters */ - tmp = wl1271_read32(wl, SCR_PAD2); - - ret = wl1271_boot_write_irq_polarity(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); - - /* WL1271: The reference driver skips steps 7 to 10 (jumps directly - * to upload_fw) */ - - ret = wl1271_boot_upload_firmware(wl); - if (ret < 0) - goto out; - - /* 10.5 start firmware */ - ret = wl1271_boot_run_firmware(wl); - if (ret < 0) - goto out; - - /* Enable firmware interrupts now */ - wl1271_boot_enable_interrupts(wl); - - /* set the wl1271 default filters */ - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; - - wl1271_event_mbox_config(wl); - -out: - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h deleted file mode 100644 index f829699d597..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_boot.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h" - -int wl1271_boot(struct wl1271 *wl); - -#define WL1271_NO_SUBBANDS 8 -#define WL1271_NO_POWER_LEVELS 4 -#define WL1271_FW_VERSION_MAX_LEN 20 - -struct wl1271_static_data { - u8 mac_address[ETH_ALEN]; - u8 padding[2]; - u8 fw_version[WL1271_FW_VERSION_MAX_LEN]; - u32 hw_version; - u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS]; -}; - -/* number of times we try to read the INIT interrupt */ -#define INIT_LOOP 20000 - -/* delay between retries */ -#define INIT_LOOP_DELAY 50 - -#define REF_CLOCK 2 -#define WU_COUNTER_PAUSE_VAL 0x3FF -#define WELP_ARM_COMMAND_VAL 0x4 - -#define OCP_REG_POLARITY 0x0064 -#define OCP_REG_CLK_TYPE 0x0448 -#define OCP_REG_CLK_POLARITY 0x0cb2 -#define OCP_REG_CLK_PULL 0x0cb4 - -#define REG_FUSE_DATA_2_1 0x050a -#define PG_VER_MASK 0x3c -#define PG_VER_OFFSET 2 - -#define CMD_MBOX_ADDRESS 0x407B4 - -#define POLARITY_LOW BIT(1) -#define NO_PULL (BIT(14) | BIT(15)) - -#define FREF_CLK_TYPE_BITS 0xfffffe7f -#define CLK_REQ_PRCM 0x100 -#define FREF_CLK_POLARITY_BITS 0xfffff8ff -#define CLK_REQ_OUTN_SEL 0x700 - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c deleted file mode 100644 index 19393e236e2..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ /dev/null @@ -1,985 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009-2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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/platform_device.h> -#include <linux/crc7.h> -#include <linux/spi/spi.h> -#include <linux/etherdevice.h> -#include <linux/ieee80211.h> -#include <linux/slab.h> - -#include "wl1271.h" -#include "wl1271_reg.h" -#include "wl1271_io.h" -#include "wl1271_acx.h" -#include "wl12xx_80211.h" -#include "wl1271_cmd.h" -#include "wl1271_event.h" - -#define WL1271_CMD_FAST_POLL_COUNT 50 - -/* - * 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 wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, - size_t res_len) -{ - struct wl1271_cmd_header *cmd; - unsigned long timeout; - u32 intr; - int ret = 0; - u16 status; - u16 poll_count = 0; - - cmd = buf; - cmd->id = cpu_to_le16(id); - cmd->status = 0; - - WARN_ON(len % 4 != 0); - - wl1271_write(wl, wl->cmd_box_addr, buf, len, false); - - wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); - - timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); - - intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { - if (time_after(jiffies, timeout)) { - wl1271_error("command complete timeout"); - ret = -ETIMEDOUT; - goto out; - } - - poll_count++; - if (poll_count < WL1271_CMD_FAST_POLL_COUNT) - udelay(10); - else - msleep(1); - - intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); - } - - /* read back the status code of the command */ - if (res_len == 0) - res_len = sizeof(struct wl1271_cmd_header); - wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false); - - status = le16_to_cpu(cmd->status); - if (status != CMD_STATUS_SUCCESS) { - wl1271_error("command execute failure %d", status); - ret = -EIO; - } - - wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, - WL1271_ACX_INTR_CMD_COMPLETE); - -out: - return ret; -} - -static int wl1271_cmd_cal_channel_tune(struct wl1271 *wl) -{ - struct wl1271_cmd_cal_channel_tune *cmd; - int ret = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - cmd->test.id = TEST_CMD_CHANNEL_TUNE; - - cmd->band = WL1271_CHANNEL_TUNE_BAND_2_4; - /* set up any channel, 7 is in the middle of the range */ - cmd->channel = 7; - - ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0); - if (ret < 0) - wl1271_warning("TEST_CMD_CHANNEL_TUNE failed"); - - kfree(cmd); - return ret; -} - -static int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl) -{ - struct wl1271_cmd_cal_update_ref_point *cmd; - int ret = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - cmd->test.id = TEST_CMD_UPDATE_PD_REFERENCE_POINT; - - /* FIXME: still waiting for the correct values */ - cmd->ref_power = 0; - cmd->ref_detector = 0; - - cmd->sub_band = WL1271_PD_REFERENCE_POINT_BAND_B_G; - - ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0); - if (ret < 0) - wl1271_warning("TEST_CMD_UPDATE_PD_REFERENCE_POINT failed"); - - kfree(cmd); - return ret; -} - -static int wl1271_cmd_cal_p2g(struct wl1271 *wl) -{ - struct wl1271_cmd_cal_p2g *cmd; - int ret = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - cmd->test.id = TEST_CMD_P2G_CAL; - - cmd->sub_band_mask = WL1271_CAL_P2G_BAND_B_G; - - ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0); - if (ret < 0) - wl1271_warning("TEST_CMD_P2G_CAL failed"); - - kfree(cmd); - return ret; -} - -static int wl1271_cmd_cal(struct wl1271 *wl) -{ - /* - * FIXME: we must make sure that we're not sleeping when calibration - * is done - */ - int ret; - - wl1271_notice("performing tx calibration"); - - ret = wl1271_cmd_cal_channel_tune(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_cal_update_ref_point(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_cal_p2g(wl); - if (ret < 0) - return ret; - - return ret; -} - -int wl1271_cmd_general_parms(struct wl1271 *wl) -{ - struct wl1271_general_parms_cmd *gen_parms; - int ret; - - if (!wl->nvs) - return -ENODEV; - - gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); - if (!gen_parms) - return -ENOMEM; - - gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; - - memcpy(gen_parms->params, wl->nvs->general_params, - WL1271_NVS_GENERAL_PARAMS_SIZE); - - ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0); - if (ret < 0) - wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); - - kfree(gen_parms); - return ret; -} - -int wl1271_cmd_radio_parms(struct wl1271 *wl) -{ - struct wl1271_radio_parms_cmd *radio_parms; - struct conf_radio_parms *rparam = &wl->conf.init.radioparam; - int ret; - - if (!wl->nvs) - return -ENODEV; - - radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); - if (!radio_parms) - return -ENOMEM; - - radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; - - memcpy(radio_parms->stat_radio_params, wl->nvs->stat_radio_params, - WL1271_NVS_STAT_RADIO_PARAMS_SIZE); - memcpy(radio_parms->dyn_radio_params, - wl->nvs->dyn_radio_params[rparam->fem], - WL1271_NVS_DYN_RADIO_PARAMS_SIZE); - - /* FIXME: current NVS is missing 5GHz parameters */ - - wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", - radio_parms, sizeof(*radio_parms)); - - ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0); - if (ret < 0) - wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed"); - - kfree(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) - */ -static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) -{ - u32 events_vector, event; - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); - - do { - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - - msleep(1); - - /* read from both event fields */ - wl1271_read(wl, wl->mbox_ptr[0], &events_vector, - sizeof(events_vector), false); - event = events_vector & mask; - wl1271_read(wl, wl->mbox_ptr[1], &events_vector, - sizeof(events_vector), false); - event |= events_vector & mask; - } while (!event); - - return 0; -} - -int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) -{ - static bool do_cal = true; - struct wl1271_cmd_join *join; - int ret, i; - u8 *bssid; - - /* FIXME: remove when we get calibration from the factory */ - if (do_cal) { - ret = wl1271_cmd_cal(wl); - if (ret < 0) - wl1271_warning("couldn't calibrate"); - else - do_cal = false; - } - - join = kzalloc(sizeof(*join), GFP_KERNEL); - if (!join) { - ret = -ENOMEM; - goto out; - } - - wl1271_debug(DEBUG_CMD, "cmd join"); - - /* 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 = cpu_to_le32(wl->rx_config); - join->rx_filter_options = cpu_to_le32(wl->rx_filter); - join->bss_type = bss_type; - join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); - - if (wl->band == IEEE80211_BAND_5GHZ) - join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; - - join->beacon_interval = cpu_to_le16(wl->beacon_int); - join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; - - join->channel = wl->channel; - join->ssid_len = wl->ssid_len; - memcpy(join->ssid, wl->ssid, wl->ssid_len); - join->ctrl = WL1271_JOIN_CMD_CTRL_TX_FLUSH; - - /* increment the session counter */ - wl->session_counter++; - if (wl->session_counter >= SESSION_COUNTER_MAX) - wl->session_counter = 0; - - join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; - - /* reset TX security counters */ - wl->tx_security_last_seq = 0; - wl->tx_security_seq = 0; - - ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); - if (ret < 0) { - wl1271_error("failed to initiate cmd join"); - goto out_free; - } - - ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID); - if (ret < 0) - wl1271_error("cmd join event completion error"); - -out_free: - kfree(join); - -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 wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer) -{ - int ret; - size_t res_len = 0; - - wl1271_debug(DEBUG_CMD, "cmd test"); - - if (answer) - res_len = buf_len; - - ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len); - - if (ret < 0) { - wl1271_warning("TEST command failed"); - return ret; - } - - return ret; -} - -/** - * 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 wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len) -{ - struct acx_header *acx = buf; - int ret; - - wl1271_debug(DEBUG_CMD, "cmd interrogate"); - - acx->id = cpu_to_le16(id); - - /* payload length, does not include any headers */ - acx->len = cpu_to_le16(len - sizeof(*acx)); - - ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len); - if (ret < 0) - wl1271_error("INTERROGATE command failed"); - - 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 wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len) -{ - struct acx_header *acx = buf; - int ret; - - wl1271_debug(DEBUG_CMD, "cmd configure"); - - acx->id = cpu_to_le16(id); - - /* payload length, does not include any headers */ - acx->len = cpu_to_le16(len - sizeof(*acx)); - - ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0); - if (ret < 0) { - wl1271_warning("CONFIGURE command NOK"); - return ret; - } - - return 0; -} - -int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) -{ - struct cmd_enabledisable_path *cmd; - int ret; - u16 cmd_rx, cmd_tx; - - wl1271_debug(DEBUG_CMD, "cmd data path"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - /* the channel here is only used for calibration, so hardcoded to 1 */ - cmd->channel = 1; - - if (enable) { - cmd_rx = CMD_ENABLE_RX; - cmd_tx = CMD_ENABLE_TX; - } else { - cmd_rx = CMD_DISABLE_RX; - cmd_tx = CMD_DISABLE_TX; - } - - ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_error("rx %s cmd for channel %d failed", - enable ? "start" : "stop", cmd->channel); - goto out; - } - - wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d", - enable ? "start" : "stop", cmd->channel); - - ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_error("tx %s cmd for channel %d failed", - enable ? "start" : "stop", cmd->channel); - goto out; - } - - wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", - enable ? "start" : "stop", cmd->channel); - -out: - kfree(cmd); - return ret; -} - -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, 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); - if (!ps_params) { - ret = -ENOMEM; - goto out; - } - - 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(1); /* 1 Mbps */ - - ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, - sizeof(*ps_params), 0); - if (ret < 0) { - wl1271_error("cmd set_ps_mode failed"); - goto out; - } - -out: - kfree(ps_params); - 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_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 active_scan, - u8 high_prio, u8 band, u8 probe_requests) -{ - - struct wl1271_cmd_trigger_scan_to *trigger = NULL; - struct wl1271_cmd_scan *params = NULL; - struct ieee80211_channel *channels; - u32 rate; - int i, j, n_ch, ret; - u16 scan_options = 0; - u8 ieee_band; - - if (band == WL1271_SCAN_BAND_2_4_GHZ) { - ieee_band = IEEE80211_BAND_2GHZ; - rate = wl->conf.tx.basic_rate; - } else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) { - ieee_band = IEEE80211_BAND_2GHZ; - rate = wl->conf.tx.basic_rate; - } else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) { - ieee_band = IEEE80211_BAND_5GHZ; - rate = wl->conf.tx.basic_rate_5; - } else - return -EINVAL; - - if (wl->hw->wiphy->bands[ieee_band]->channels == NULL) - return -EINVAL; - - channels = wl->hw->wiphy->bands[ieee_band]->channels; - n_ch = wl->hw->wiphy->bands[ieee_band]->n_channels; - - if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) - return -EINVAL; - - params = kzalloc(sizeof(*params), GFP_KERNEL); - if (!params) - return -ENOMEM; - - params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); - params->params.rx_filter_options = - cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); - - if (!active_scan) - scan_options |= WL1271_SCAN_OPT_PASSIVE; - if (high_prio) - scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH; - params->params.scan_options = cpu_to_le16(scan_options); - - params->params.num_probe_requests = probe_requests; - params->params.tx_rate = cpu_to_le32(rate); - params->params.tid_trigger = 0; - params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; - - if (band == WL1271_SCAN_BAND_DUAL) - params->params.band = WL1271_SCAN_BAND_2_4_GHZ; - else - params->params.band = band; - - for (i = 0, j = 0; i < n_ch && i < WL1271_SCAN_MAX_CHANNELS; i++) { - if (!(channels[i].flags & IEEE80211_CHAN_DISABLED)) { - params->channels[j].min_duration = - cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); - params->channels[j].max_duration = - cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); - memset(¶ms->channels[j].bssid_lsb, 0xff, 4); - memset(¶ms->channels[j].bssid_msb, 0xff, 2); - params->channels[j].early_termination = 0; - params->channels[j].tx_power_att = - WL1271_SCAN_CURRENT_TX_PWR; - params->channels[j].channel = channels[i].hw_value; - j++; - } - } - - params->params.num_channels = j; - - if (ssid_len && ssid) { - params->params.ssid_len = ssid_len; - memcpy(params->params.ssid, ssid, ssid_len); - } - - ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len, - ie, ie_len, ieee_band); - if (ret < 0) { - wl1271_error("PROBE request template failed"); - goto out; - } - - trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); - if (!trigger) { - ret = -ENOMEM; - goto out; - } - - /* disable the timeout */ - trigger->timeout = 0; - - ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, - sizeof(*trigger), 0); - if (ret < 0) { - wl1271_error("trigger scan to failed for hw scan"); - goto out; - } - - wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); - - set_bit(WL1271_FLAG_SCANNING, &wl->flags); - if (wl1271_11a_enabled()) { - wl->scan.state = band; - if (band == WL1271_SCAN_BAND_DUAL) { - wl->scan.active = active_scan; - wl->scan.high_prio = high_prio; - wl->scan.probe_requests = probe_requests; - if (ssid_len && ssid) { - wl->scan.ssid_len = ssid_len; - memcpy(wl->scan.ssid, ssid, ssid_len); - } else - wl->scan.ssid_len = 0; - } - } - - ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0); - if (ret < 0) { - wl1271_error("SCAN failed"); - clear_bit(WL1271_FLAG_SCANNING, &wl->flags); - goto out; - } - -out: - kfree(params); - kfree(trigger); - return ret; -} - -int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, - void *buf, size_t buf_len, int index, u32 rates) -{ - struct wl1271_cmd_template_set *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id); - - WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE); - buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->len = cpu_to_le16(buf_len); - cmd->template_type = template_id; - cmd->enabled_rates = cpu_to_le32(rates); - cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; - cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; - cmd->index = index; - - if (buf) - memcpy(cmd->template_data, buf, buf_len); - - ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_warning("cmd set_template failed: %d", ret); - goto out_free; - } - -out_free: - kfree(cmd); - -out: - return ret; -} - -int wl1271_cmd_build_null_data(struct wl1271 *wl) -{ - struct sk_buff *skb = NULL; - int size; - void *ptr; - int ret = -ENOMEM; - - - if (wl->bss_type == BSS_TYPE_IBSS) { - size = sizeof(struct wl12xx_null_data_template); - ptr = NULL; - } else { - skb = ieee80211_nullfunc_get(wl->hw, wl->vif); - if (!skb) - goto out; - size = skb->len; - ptr = skb->data; - } - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, - WL1271_RATE_AUTOMATIC); - -out: - dev_kfree_skb(skb); - if (ret) - wl1271_warning("cmd buld null data failed %d", ret); - - return ret; - -} - -int wl1271_cmd_build_klv_null_data(struct wl1271 *wl) -{ - struct sk_buff *skb = NULL; - int ret = -ENOMEM; - - skb = ieee80211_nullfunc_get(wl->hw, wl->vif); - if (!skb) - goto out; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, - skb->data, skb->len, - CMD_TEMPL_KLV_IDX_NULL_DATA, - WL1271_RATE_AUTOMATIC); - -out: - dev_kfree_skb(skb); - if (ret) - wl1271_warning("cmd build klv null data failed %d", ret); - - return ret; - -} - -int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) -{ - struct sk_buff *skb; - int ret = 0; - - skb = ieee80211_pspoll_get(wl->hw, wl->vif); - if (!skb) - goto out; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, - skb->len, 0, wl->basic_rate); - -out: - dev_kfree_skb(skb); - return ret; -} - -int wl1271_cmd_build_probe_req(struct wl1271 *wl, - const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 band) -{ - struct sk_buff *skb; - int ret; - - skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, - ie, ie_len); - if (!skb) { - ret = -ENOMEM; - goto out; - } - - wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); - - if (band == IEEE80211_BAND_2GHZ) - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, - skb->data, skb->len, 0, - wl->conf.tx.basic_rate); - else - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, - skb->data, skb->len, 0, - wl->conf.tx.basic_rate_5); - -out: - dev_kfree_skb(skb); - return ret; -} - -int wl1271_build_qos_null_data(struct wl1271 *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 wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, - sizeof(template), 0, - WL1271_RATE_AUTOMATIC); -} - -int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) -{ - struct wl1271_cmd_set_keys *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->id = id; - cmd->key_action = cpu_to_le16(KEY_SET_ID); - cmd->key_type = KEY_WEP; - - ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_warning("cmd set_default_wep_key failed: %d", ret); - goto out; - } - -out: - kfree(cmd); - - return ret; -} - -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) -{ - struct wl1271_cmd_set_keys *cmd; - int ret = 0; - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - if (key_type != KEY_WEP) - memcpy(cmd->addr, addr, ETH_ALEN); - - cmd->key_action = cpu_to_le16(action); - cmd->key_size = key_size; - cmd->key_type = key_type; - - cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16); - cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32); - - /* we have only one SSID profile */ - cmd->ssid_profile = 0; - - cmd->id = id; - - if (key_type == KEY_TKIP) { - /* - * 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(cmd->key, key, 16); - memcpy(cmd->key + 16, key + 24, 8); - memcpy(cmd->key + 24, key + 16, 8); - - } else { - memcpy(cmd->key, key, key_size); - } - - wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd)); - - ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_warning("could not set keys"); - goto out; - } - -out: - kfree(cmd); - - return ret; -} - -int wl1271_cmd_disconnect(struct wl1271 *wl) -{ - struct wl1271_cmd_disconnect *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd disconnect"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - cmd->rx_config_options = cpu_to_le32(wl->rx_config); - cmd->rx_filter_options = cpu_to_le32(wl->rx_filter); - /* disconnect reason is not used in immediate disconnections */ - cmd->type = DISCONNECT_IMMEDIATE; - - ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd), 0); - if (ret < 0) { - wl1271_error("failed to send disconnect command"); - goto out_free; - } - - ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID); - if (ret < 0) - wl1271_error("cmd disconnect event completion error"); - -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 deleted file mode 100644 index f2820b42a94..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ /dev/null @@ -1,534 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_CMD_H__ -#define __WL1271_CMD_H__ - -#include "wl1271.h" - -struct acx_header; - -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_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_read_memory(struct wl1271 *wl, u32 addr, void *answer, - size_t len); -int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 active_scan, - u8 high_prio, u8 band, u8 probe_requests); -int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, - void *buf, size_t buf_len, int index, u32 rates); -int wl1271_cmd_build_null_data(struct wl1271 *wl); -int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); -int wl1271_cmd_build_probe_req(struct wl1271 *wl, - const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 band); -int wl1271_build_qos_null_data(struct wl1271 *wl); -int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); -int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); -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); - -enum wl1271_commands { - 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_START_JOIN = 11, - CMD_SET_KEYS = 12, - CMD_READ_MEMORY = 13, - CMD_WRITE_MEMORY = 14, - CMD_SET_TEMPLATE = 19, - CMD_TEST = 23, - CMD_NOISE_HIST = 28, - 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, - CMD_CONNECTION_SCAN_CFG = 48, - CMD_CONNECTION_SCAN_SSID_CFG = 49, - CMD_START_PERIODIC_SCAN = 50, - CMD_STOP_PERIODIC_SCAN = 51, - CMD_SET_STA_STATE = 52, - - NUM_COMMANDS, - MAX_COMMAND_ID = 0xFFFF, -}; - -#define MAX_CMD_PARAMS 572 - -enum { - CMD_TEMPL_KLV_IDX_NULL_DATA = 0, - CMD_TEMPL_KLV_IDX_MAX = 4 -}; - -enum cmd_templ { - CMD_TEMPL_NULL_DATA = 0, - CMD_TEMPL_BEACON, - CMD_TEMPL_CFG_PROBE_REQ_2_4, - CMD_TEMPL_CFG_PROBE_REQ_5, - CMD_TEMPL_PROBE_RESPONSE, - CMD_TEMPL_QOS_NULL_DATA, - CMD_TEMPL_PS_POLL, - CMD_TEMPL_KLV, - CMD_TEMPL_DISCONNECT, - CMD_TEMPL_PROBE_REQ_2_4, /* for firmware internal use only */ - CMD_TEMPL_PROBE_REQ_5, /* for firmware internal use only */ - CMD_TEMPL_BAR, /* for firmware internal use only */ - CMD_TEMPL_CTS, /* - * For CTS-to-self (FastCTS) mechanism - * for BT/WLAN coexistence (SoftGemini). */ - CMD_TEMPL_MAX = 0xff -}; - -/* unit ms */ -#define WL1271_COMMAND_TIMEOUT 2000 -#define WL1271_CMD_TEMPL_MAX_SIZE 252 -#define WL1271_EVENT_TIMEOUT 750 - -struct wl1271_cmd_header { - __le16 id; - __le16 status; - /* payload */ - u8 data[0]; -} __attribute__ ((packed)); - -#define WL1271_CMD_MAX_PARAMS 572 - -struct wl1271_command { - struct wl1271_cmd_header header; - u8 parameters[WL1271_CMD_MAX_PARAMS]; -} __attribute__ ((packed)); - -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 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]; -} __attribute__ ((packed)); - -#define CMDMBOX_HEADER_LEN 4 -#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 - -enum { - BSS_TYPE_IBSS = 0, - BSS_TYPE_STA_BSS = 2, - BSS_TYPE_AP_BSS = 3, - MAX_BSS_TYPE = 0xFF -}; - -#define WL1271_JOIN_CMD_CTRL_TX_FLUSH 0x80 /* Firmware flushes all Tx */ -#define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1 -#define WL1271_JOIN_CMD_BSS_TYPE_5GHZ 0x10 - -struct wl1271_cmd_join { - struct wl1271_cmd_header header; - - __le32 bssid_lsb; - __le16 bssid_msb; - __le16 beacon_interval; /* in TBTTs */ - __le32 rx_config_options; - __le32 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). - */ - __le32 basic_rate_set; - u8 dtim_interval; - /* - * 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 reserved[3]; -} __attribute__ ((packed)); - -struct cmd_enabledisable_path { - struct wl1271_cmd_header header; - - u8 channel; - u8 padding[3]; -} __attribute__ ((packed)); - -#define WL1271_RATE_AUTOMATIC 0 - -struct wl1271_cmd_template_set { - struct wl1271_cmd_header header; - - __le16 len; - u8 template_type; - u8 index; /* relevant only for KLV_TEMPLATE type */ - __le32 enabled_rates; - u8 short_retry_limit; - u8 long_retry_limit; - u8 aflags; - u8 reserved; - u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE]; -} __attribute__ ((packed)); - -#define TIM_ELE_ID 5 -#define PARTIAL_VBM_MAX 251 - -struct wl1271_tim { - u8 identity; - u8 length; - u8 dtim_count; - u8 dtim_period; - u8 bitmap_ctrl; - u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */ -} __attribute__ ((packed)); - -enum wl1271_cmd_ps_mode { - STATION_ACTIVE_MODE, - STATION_POWER_SAVE_MODE -}; - -struct wl1271_cmd_ps_params { - struct wl1271_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; - __le32 null_data_rate; -} __attribute__ ((packed)); - -/* HW encryption keys */ -#define NUM_ACCESS_CATEGORIES_COPY 4 -#define MAX_KEY_SIZE 32 - -enum wl1271_cmd_key_action { - KEY_ADD_OR_REPLACE = 1, - KEY_REMOVE = 2, - KEY_SET_ID = 3, - MAX_KEY_ACTION = 0xffff, -}; - -enum wl1271_cmd_key_type { - KEY_NONE = 0, - KEY_WEP = 1, - KEY_TKIP = 2, - KEY_AES = 3, - KEY_GEM = 4 -}; - -/* FIXME: Add description for key-types */ - -struct wl1271_cmd_set_keys { - struct wl1271_cmd_header header; - - /* Ignored for default WEP key */ - u8 addr[ETH_ALEN]; - - /* key_action_e */ - __le16 key_action; - - __le16 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]; - __le16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY]; - __le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; -} __attribute__ ((packed)); - - -#define WL1271_SCAN_MAX_CHANNELS 24 -#define WL1271_SCAN_DEFAULT_TAG 1 -#define WL1271_SCAN_CURRENT_TX_PWR 0 -#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_BAND_DUAL 2 - -struct basic_scan_params { - __le32 rx_config_options; - __le32 rx_filter_options; - /* Scan option flags (WL1271_SCAN_OPT_*) */ - __le16 scan_options; - /* Number of scan channels in the list (maximum 30) */ - u8 num_channels; - /* This field indicates the number of probe requests to send - per channel for an active scan */ - u8 num_probe_requests; - /* Rate bit field for sending the probes */ - __le32 tx_rate; - u8 tid_trigger; - u8 ssid_len; - /* in order to align */ - u8 padding1[2]; - u8 ssid[IW_ESSID_MAX_SIZE]; - /* Band to scan */ - u8 band; - u8 use_ssid_list; - u8 scan_tag; - u8 padding2; -} __attribute__ ((packed)); - -struct basic_scan_channel_params { - /* Duration in TU to wait for frames on a channel for active scan */ - __le32 min_duration; - __le32 max_duration; - __le32 bssid_lsb; - __le16 bssid_msb; - u8 early_termination; - u8 tx_power_att; - u8 channel; - /* FW internal use only! */ - u8 dfs_candidate; - u8 activity_detected; - u8 pad; -} __attribute__ ((packed)); - -struct wl1271_cmd_scan { - struct wl1271_cmd_header header; - - struct basic_scan_params params; - struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS]; -} __attribute__ ((packed)); - -struct wl1271_cmd_trigger_scan_to { - struct wl1271_cmd_header header; - - __le32 timeout; -} __attribute__ ((packed)); - -struct wl1271_cmd_test_header { - u8 id; - u8 padding[3]; -} __attribute__ ((packed)); - -enum wl1271_channel_tune_bands { - WL1271_CHANNEL_TUNE_BAND_2_4, - WL1271_CHANNEL_TUNE_BAND_5, - WL1271_CHANNEL_TUNE_BAND_4_9 -}; - -#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 - -struct wl1271_general_parms_cmd { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - u8 params[WL1271_NVS_GENERAL_PARAMS_SIZE]; - s8 reserved[23]; -} __attribute__ ((packed)); - -#define WL1271_STAT_RADIO_PARAMS_5_SIZE 29 -#define WL1271_DYN_RADIO_PARAMS_5_SIZE 104 - -struct wl1271_radio_parms_cmd { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - u8 stat_radio_params[WL1271_NVS_STAT_RADIO_PARAMS_SIZE]; - u8 stat_radio_params_5[WL1271_STAT_RADIO_PARAMS_5_SIZE]; - - u8 dyn_radio_params[WL1271_NVS_DYN_RADIO_PARAMS_SIZE]; - u8 reserved; - u8 dyn_radio_params_5[WL1271_DYN_RADIO_PARAMS_5_SIZE]; -} __attribute__ ((packed)); - -struct wl1271_cmd_cal_channel_tune { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - u8 band; - u8 channel; - - __le16 radio_status; -} __attribute__ ((packed)); - -struct wl1271_cmd_cal_update_ref_point { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - __le32 ref_power; - __le32 ref_detector; - u8 sub_band; - u8 padding[3]; -} __attribute__ ((packed)); - -#define MAX_TLV_LENGTH 400 -#define MAX_NVS_VERSION_LENGTH 12 - -#define WL1271_CAL_P2G_BAND_B_G BIT(0) - -struct wl1271_cmd_cal_p2g { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - __le16 len; - u8 buf[MAX_TLV_LENGTH]; - u8 type; - u8 padding; - - __le16 radio_status; - u8 nvs_version[MAX_NVS_VERSION_LENGTH]; - - u8 sub_band_mask; - u8 padding2; -} __attribute__ ((packed)); - - -/* - * There are three types of disconnections: - * - * DISCONNECT_IMMEDIATE: the fw doesn't send any frames - * DISCONNECT_DEAUTH: the fw generates a DEAUTH request with the reason - * we have passed - * DISCONNECT_DISASSOC: the fw generates a DESASSOC request with the reason - * we have passed - */ -enum wl1271_disconnect_type { - DISCONNECT_IMMEDIATE, - DISCONNECT_DEAUTH, - DISCONNECT_DISASSOC -}; - -struct wl1271_cmd_disconnect { - struct wl1271_cmd_header header; - - __le32 rx_config_options; - __le32 rx_filter_options; - - __le16 reason; - u8 type; - - u8 padding; -} __attribute__ ((packed)); - -#endif /* __WL1271_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h deleted file mode 100644 index d046d044b5b..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ /dev/null @@ -1,1031 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_CONF_H__ -#define __WL1271_CONF_H__ - -enum { - CONF_HW_BIT_RATE_1MBPS = BIT(0), - CONF_HW_BIT_RATE_2MBPS = BIT(1), - CONF_HW_BIT_RATE_5_5MBPS = BIT(2), - CONF_HW_BIT_RATE_6MBPS = BIT(3), - CONF_HW_BIT_RATE_9MBPS = BIT(4), - CONF_HW_BIT_RATE_11MBPS = BIT(5), - CONF_HW_BIT_RATE_12MBPS = BIT(6), - CONF_HW_BIT_RATE_18MBPS = BIT(7), - CONF_HW_BIT_RATE_22MBPS = BIT(8), - CONF_HW_BIT_RATE_24MBPS = BIT(9), - CONF_HW_BIT_RATE_36MBPS = BIT(10), - CONF_HW_BIT_RATE_48MBPS = BIT(11), - CONF_HW_BIT_RATE_54MBPS = BIT(12), - CONF_HW_BIT_RATE_MCS_0 = BIT(13), - CONF_HW_BIT_RATE_MCS_1 = BIT(14), - CONF_HW_BIT_RATE_MCS_2 = BIT(15), - CONF_HW_BIT_RATE_MCS_3 = BIT(16), - CONF_HW_BIT_RATE_MCS_4 = BIT(17), - CONF_HW_BIT_RATE_MCS_5 = BIT(18), - CONF_HW_BIT_RATE_MCS_6 = BIT(19), - CONF_HW_BIT_RATE_MCS_7 = BIT(20) -}; - -enum { - CONF_HW_RATE_INDEX_1MBPS = 0, - CONF_HW_RATE_INDEX_2MBPS = 1, - CONF_HW_RATE_INDEX_5_5MBPS = 2, - CONF_HW_RATE_INDEX_6MBPS = 3, - CONF_HW_RATE_INDEX_9MBPS = 4, - CONF_HW_RATE_INDEX_11MBPS = 5, - CONF_HW_RATE_INDEX_12MBPS = 6, - CONF_HW_RATE_INDEX_18MBPS = 7, - CONF_HW_RATE_INDEX_22MBPS = 8, - CONF_HW_RATE_INDEX_24MBPS = 9, - CONF_HW_RATE_INDEX_36MBPS = 10, - CONF_HW_RATE_INDEX_48MBPS = 11, - CONF_HW_RATE_INDEX_54MBPS = 12, - CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, -}; - -enum { - CONF_HW_RXTX_RATE_MCS7 = 0, - CONF_HW_RXTX_RATE_MCS6, - CONF_HW_RXTX_RATE_MCS5, - CONF_HW_RXTX_RATE_MCS4, - CONF_HW_RXTX_RATE_MCS3, - CONF_HW_RXTX_RATE_MCS2, - CONF_HW_RXTX_RATE_MCS1, - CONF_HW_RXTX_RATE_MCS0, - CONF_HW_RXTX_RATE_54, - CONF_HW_RXTX_RATE_48, - CONF_HW_RXTX_RATE_36, - CONF_HW_RXTX_RATE_24, - CONF_HW_RXTX_RATE_22, - CONF_HW_RXTX_RATE_18, - CONF_HW_RXTX_RATE_12, - CONF_HW_RXTX_RATE_11, - CONF_HW_RXTX_RATE_9, - CONF_HW_RXTX_RATE_6, - CONF_HW_RXTX_RATE_5_5, - CONF_HW_RXTX_RATE_2, - CONF_HW_RXTX_RATE_1, - CONF_HW_RXTX_RATE_MAX, - CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff -}; - -enum { - CONF_SG_DISABLE = 0, - CONF_SG_PROTECTIVE, - CONF_SG_OPPORTUNISTIC -}; - -enum { - /* - * PER threshold in PPM of the BT voice - * - * Range: 0 - 10000000 - */ - CONF_SG_BT_PER_THRESHOLD = 0, - - /* - * Number of consequent RX_ACTIVE activities to override BT voice - * frames to ensure WLAN connection - * - * Range: 0 - 100 - */ - CONF_SG_HV3_MAX_OVERRIDE, - - /* - * Defines the PER threshold of the BT voice - * - * Range: 0 - 65000 - */ - CONF_SG_BT_NFS_SAMPLE_INTERVAL, - - /* - * Defines the load ratio of BT - * - * Range: 0 - 100 (%) - */ - CONF_SG_BT_LOAD_RATIO, - - /* - * Defines whether the SG will force WLAN host to enter/exit PSM - * - * Range: 1 - SG can force, 0 - host handles PSM - */ - CONF_SG_AUTO_PS_MODE, - - /* - * Compensation percentage of probe requests when scan initiated - * during BT voice/ACL link. - * - * Range: 0 - 255 (%) - */ - CONF_SG_AUTO_SCAN_PROBE_REQ, - - /* - * Compensation percentage of probe requests when active scan initiated - * during BT voice - * - * Range: 0 - 255 (%) - */ - CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3, - - /* - * Defines antenna configuration (single/dual antenna) - * - * Range: 0 - single antenna, 1 - dual antenna - */ - CONF_SG_ANTENNA_CONFIGURATION, - - /* - * The threshold (percent) of max consequtive beacon misses before - * increasing priority of beacon reception. - * - * Range: 0 - 100 (%) - */ - CONF_SG_BEACON_MISS_PERCENT, - - /* - * The rate threshold below which receiving a data frame from the AP - * will increase the priority of the data frame above BT traffic. - * - * Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54 - */ - CONF_SG_RATE_ADAPT_THRESH, - - /* - * Not used currently. - * - * Range: 0 - */ - CONF_SG_RATE_ADAPT_SNR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN PSM / BT master basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR, - CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR, - - /* - * The time after it expires no new WLAN trigger frame is trasmitted - * in WLAN PSM / BT master basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN PSM / BT slave basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR, - CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR, - - /* - * The time after it expires no new WLAN trigger frame is trasmitted - * in WLAN PSM / BT slave basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN PSM / BT master EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR, - CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR, - - /* - * The time after it expires no new WLAN trigger frame is trasmitted - * in WLAN PSM / BT master EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN PSM / BT slave EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR, - CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR, - - /* - * The time after it expires no new WLAN trigger frame is trasmitted - * in WLAN PSM / BT slave EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR, - - /* - * RX guard time before the beginning of a new BT voice frame during - * which no new WLAN trigger frame is transmitted. - * - * Range: 0 - 100000 (us) - */ - CONF_SG_RXT, - - /* - * TX guard time before the beginning of a new BT voice frame during - * which no new WLAN frame is transmitted. - * - * Range: 0 - 100000 (us) - */ - - CONF_SG_TXT, - - /* - * Enable adaptive RXT/TXT algorithm. If disabled, the host values - * will be utilized. - * - * Range: 0 - disable, 1 - enable - */ - CONF_SG_ADAPTIVE_RXT_TXT, - - /* - * The used WLAN legacy service period during active BT ACL link - * - * Range: 0 - 255 (ms) - */ - CONF_SG_PS_POLL_TIMEOUT, - - /* - * The used WLAN UPSD service period during active BT ACL link - * - * Range: 0 - 255 (ms) - */ - CONF_SG_UPSD_TIMEOUT, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN Active / BT master EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR, - CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR, - - /* - * The maximum time WLAN can gain the antenna for - * in WLAN Active / BT master EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN Active / BT slave EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR, - CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR, - - /* - * The maximum time WLAN can gain the antenna for - * in WLAN Active / BT slave EDR - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR, - - /* - * Configure the min and max time BT gains the antenna - * in WLAN Active / BT basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR, - CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR, - - /* - * The maximum time WLAN can gain the antenna for - * in WLAN Active / BT basic rate - * - * Range: 0 - 255 (ms) - */ - CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR, - - /* - * Compensation percentage of WLAN passive scan window if initiated - * during BT voice - * - * Range: 0 - 1000 (%) - */ - CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3, - - /* - * Compensation percentage of WLAN passive scan window if initiated - * during BT A2DP - * - * Range: 0 - 1000 (%) - */ - CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP, - - /* - * Fixed time ensured for BT traffic to gain the antenna during WLAN - * passive scan. - * - * Range: 0 - 1000 ms - */ - CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME, - - /* - * Fixed time ensured for WLAN traffic to gain the antenna during WLAN - * passive scan. - * - * Range: 0 - 1000 ms - */ - CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME, - - /* - * Number of consequent BT voice frames not interrupted by WLAN - * - * Range: 0 - 100 - */ - CONF_SG_HV3_MAX_SERVED, - - /* - * Protection time of the DHCP procedure. - * - * Range: 0 - 100000 (ms) - */ - CONF_SG_DHCP_TIME, - - /* - * Compensation percentage of WLAN active scan window if initiated - * during BT A2DP - * - * Range: 0 - 1000 (%) - */ - CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP, - CONF_SG_TEMP_PARAM_1, - CONF_SG_TEMP_PARAM_2, - CONF_SG_TEMP_PARAM_3, - CONF_SG_TEMP_PARAM_4, - CONF_SG_TEMP_PARAM_5, - CONF_SG_PARAMS_MAX, - CONF_SG_PARAMS_ALL = 0xff -}; - -struct conf_sg_settings { - u32 params[CONF_SG_PARAMS_MAX]; - u8 state; -}; - -enum conf_rx_queue_type { - CONF_RX_QUEUE_TYPE_LOW_PRIORITY, /* All except the high priority */ - CONF_RX_QUEUE_TYPE_HIGH_PRIORITY, /* Management and voice packets */ -}; - -struct conf_rx_settings { - /* - * The maximum amount of time, in TU, before the - * firmware discards the MSDU. - * - * Range: 0 - 0xFFFFFFFF - */ - u32 rx_msdu_life_time; - - /* - * Packet detection threshold in the PHY. - * - * FIXME: details unknown. - */ - u32 packet_detection_threshold; - - /* - * The longest time the STA will wait to receive traffic from the AP - * after a PS-poll has been transmitted. - * - * Range: 0 - 200000 - */ - 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. - * - * Range: 0 - 200000 - */ - u16 upsd_timeout; - - /* - * The number of octets in an MPDU, below which an RTS/CTS - * handshake is not performed. - * - * Range: 0 - 4096 - */ - u16 rts_threshold; - - /* - * The RX Clear Channel Assessment threshold in the PHY - * (the energy threshold). - * - * Range: ENABLE_ENERGY_D == 0x140A - * DISABLE_ENERGY_D == 0xFFEF - */ - u16 rx_cca_threshold; - - /* - * Occupied Rx mem-blocks number which requires interrupting the host - * (0 = no buffering, 0xffff = disabled). - * - * Range: u16 - */ - u16 irq_blk_threshold; - - /* - * Rx packets number which requires interrupting the host - * (0 = no buffering). - * - * Range: u16 - */ - u16 irq_pkt_threshold; - - /* - * Max time in msec the FW may delay RX-Complete interrupt. - * - * Range: 1 - 100 - */ - u16 irq_timeout; - - /* - * The RX queue type. - * - * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY, - */ - u8 queue_type; -}; - -#define CONF_TX_MAX_RATE_CLASSES 8 - -#define CONF_TX_RATE_MASK_UNSPECIFIED 0 -#define CONF_TX_RATE_MASK_BASIC (CONF_HW_BIT_RATE_1MBPS | \ - CONF_HW_BIT_RATE_2MBPS) -#define CONF_TX_RATE_RETRY_LIMIT 10 - -struct conf_tx_rate_class { - - /* - * The rates enabled for this rate class. - * - * Range: CONF_HW_BIT_RATE_* bit mask - */ - u32 enabled_rates; - - /* - * The dot11 short retry limit used for TX retries. - * - * Range: u8 - */ - u8 short_retry_limit; - - /* - * The dot11 long retry limit used for TX retries. - * - * Range: u8 - */ - u8 long_retry_limit; - - /* - * Flags controlling the attributes of TX transmission. - * - * Range: bit 0: Truncate - when set, FW attempts to send a frame stop - * when the total valid per-rate attempts have - * been exhausted; otherwise transmissions - * will continue at the lowest available rate - * until the appropriate one of the - * short_retry_limit, long_retry_limit, - * dot11_max_transmit_msdu_life_time, or - * max_tx_life_time, is exhausted. - * 1: Preamble Override - indicates if the preamble type - * should be used in TX. - * 2: Preamble Type - the type of the preamble to be used by - * the policy (0 - long preamble, 1 - short preamble. - */ - u8 aflags; -}; - -#define CONF_TX_MAX_AC_COUNT 4 - -/* Slot number setting to start transmission at PIFS interval */ -#define CONF_TX_AIFS_PIFS 1 -/* Slot number setting to start transmission at DIFS interval normal - * DCF access */ -#define CONF_TX_AIFS_DIFS 2 - - -enum conf_tx_ac { - CONF_TX_AC_BE = 0, /* best effort / legacy */ - CONF_TX_AC_BK = 1, /* background */ - CONF_TX_AC_VI = 2, /* video */ - CONF_TX_AC_VO = 3, /* voice */ - CONF_TX_AC_CTS2SELF = 4, /* fictious AC, follows AC_VO */ - CONF_TX_AC_ANY_TID = 0x1f -}; - -struct conf_tx_ac_category { - /* - * The AC class identifier. - * - * Range: enum conf_tx_ac - */ - u8 ac; - - /* - * The contention window minimum size (in slots) for the access - * class. - * - * Range: u8 - */ - u8 cw_min; - - /* - * The contention window maximum size (in slots) for the access - * class. - * - * Range: u8 - */ - u16 cw_max; - - /* - * The AIF value (in slots) for the access class. - * - * Range: u8 - */ - u8 aifsn; - - /* - * The TX Op Limit (in microseconds) for the access class. - * - * Range: u16 - */ - u16 tx_op_limit; -}; - -#define CONF_TX_MAX_TID_COUNT 7 - -enum { - CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/ - CONF_CHANNEL_TYPE_EDCF = 1, /* EDCA*/ - CONF_CHANNEL_TYPE_HCCA = 2, /* HCCA*/ -}; - -enum { - CONF_PS_SCHEME_LEGACY = 0, - CONF_PS_SCHEME_UPSD_TRIGGER = 1, - CONF_PS_SCHEME_LEGACY_PSPOLL = 2, - CONF_PS_SCHEME_SAPSD = 3, -}; - -enum { - CONF_ACK_POLICY_LEGACY = 0, - CONF_ACK_POLICY_NO_ACK = 1, - CONF_ACK_POLICY_BLOCK = 2, -}; - - -struct conf_tx_tid { - u8 queue_id; - u8 channel_type; - u8 tsid; - u8 ps_scheme; - u8 ack_policy; - u32 apsd_conf[2]; -}; - -struct conf_tx_settings { - /* - * The TX ED value for TELEC Enable/Disable. - * - * Range: 0, 1 - */ - u8 tx_energy_detection; - - /* - * Configuration for rate classes for TX (currently only one - * rate class supported.) - */ - struct conf_tx_rate_class rc_conf; - - /* - * Configuration for access categories for TX rate control. - */ - u8 ac_conf_count; - struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT]; - - /* - * Configuration for TID parameters. - */ - u8 tid_conf_count; - struct conf_tx_tid tid_conf[CONF_TX_MAX_TID_COUNT]; - - /* - * The TX fragmentation threshold. - * - * Range: u16 - */ - u16 frag_threshold; - - /* - * Max time in msec the FW may delay frame TX-Complete interrupt. - * - * Range: u16 - */ - u16 tx_compl_timeout; - - /* - * Completed TX packet count which requires to issue the TX-Complete - * interrupt. - * - * Range: u16 - */ - u16 tx_compl_threshold; - - /* - * The rate used for control messages and scanning on the 2.4GHz band - * - * Range: CONF_HW_BIT_RATE_* bit mask - */ - u32 basic_rate; - - /* - * The rate used for control messages and scanning on the 5GHz band - * - * Range: CONF_HW_BIT_RATE_* bit mask - */ - u32 basic_rate_5; -}; - -enum { - CONF_WAKE_UP_EVENT_BEACON = 0x01, /* Wake on every Beacon*/ - CONF_WAKE_UP_EVENT_DTIM = 0x02, /* Wake on every DTIM*/ - CONF_WAKE_UP_EVENT_N_DTIM = 0x04, /* Wake every Nth DTIM */ - CONF_WAKE_UP_EVENT_N_BEACONS = 0x08, /* Wake every Nth beacon */ - CONF_WAKE_UP_EVENT_BITS_MASK = 0x0F -}; - -#define CONF_MAX_BCN_FILT_IE_COUNT 32 - -#define CONF_BCN_RULE_PASS_ON_CHANGE BIT(0) -#define CONF_BCN_RULE_PASS_ON_APPEARANCE BIT(1) - -#define CONF_BCN_IE_OUI_LEN 3 -#define CONF_BCN_IE_VER_LEN 2 - -struct conf_bcn_filt_rule { - /* - * IE number to which to associate a rule. - * - * Range: u8 - */ - u8 ie; - - /* - * Rule to associate with the specific ie. - * - * Range: CONF_BCN_RULE_PASS_ON_* - */ - u8 rule; - - /* - * OUI for the vendor specifie IE (221) - */ - u8 oui[CONF_BCN_IE_OUI_LEN]; - - /* - * Type for the vendor specifie IE (221) - */ - u8 type; - - /* - * Version for the vendor specifie IE (221) - */ - u8 version[CONF_BCN_IE_VER_LEN]; -}; - -#define CONF_MAX_RSSI_SNR_TRIGGERS 8 - -enum { - CONF_TRIG_METRIC_RSSI_BEACON = 0, - CONF_TRIG_METRIC_RSSI_DATA, - CONF_TRIG_METRIC_SNR_BEACON, - CONF_TRIG_METRIC_SNR_DATA -}; - -enum { - CONF_TRIG_EVENT_TYPE_LEVEL = 0, - CONF_TRIG_EVENT_TYPE_EDGE -}; - -enum { - CONF_TRIG_EVENT_DIR_LOW = 0, - CONF_TRIG_EVENT_DIR_HIGH, - CONF_TRIG_EVENT_DIR_BIDIR -}; - -struct conf_sig_weights { - - /* - * RSSI from beacons average weight. - * - * Range: u8 - */ - u8 rssi_bcn_avg_weight; - - /* - * RSSI from data average weight. - * - * Range: u8 - */ - u8 rssi_pkt_avg_weight; - - /* - * SNR from beacons average weight. - * - * Range: u8 - */ - u8 snr_bcn_avg_weight; - - /* - * SNR from data average weight. - * - * Range: u8 - */ - u8 snr_pkt_avg_weight; -}; - -enum conf_bcn_filt_mode { - CONF_BCN_FILT_MODE_DISABLED = 0, - CONF_BCN_FILT_MODE_ENABLED = 1 -}; - -enum conf_bet_mode { - CONF_BET_MODE_DISABLE = 0, - CONF_BET_MODE_ENABLE = 1, -}; - -struct conf_conn_settings { - /* - * Firmware wakeup conditions configuration. The host may set only - * one bit. - * - * Range: CONF_WAKE_UP_EVENT_* - */ - u8 wake_up_event; - - /* - * Listen interval for beacons or Dtims. - * - * Range: 0 for beacon and Dtim wakeup - * 1-10 for x Dtims - * 1-255 for x beacons - */ - u8 listen_interval; - - /* - * Enable or disable the beacon filtering. - * - * Range: CONF_BCN_FILT_MODE_* - */ - enum conf_bcn_filt_mode bcn_filt_mode; - - /* - * Configure Beacon filter pass-thru rules. - */ - u8 bcn_filt_ie_count; - struct conf_bcn_filt_rule bcn_filt_ie[CONF_MAX_BCN_FILT_IE_COUNT]; - - /* - * The number of consequtive beacons to lose, before the firmware - * becomes out of synch. - * - * Range: u32 - */ - u32 synch_fail_thold; - - /* - * After out-of-synch, the number of TU's to wait without a further - * received beacon (or probe response) before issuing the BSS_EVENT_LOSE - * event. - * - * Range: u32 - */ - u32 bss_lose_timeout; - - /* - * Beacon receive timeout. - * - * Range: u32 - */ - u32 beacon_rx_timeout; - - /* - * Broadcast receive timeout. - * - * Range: u32 - */ - u32 broadcast_timeout; - - /* - * Enable/disable reception of broadcast packets in power save mode - * - * Range: 1 - enable, 0 - disable - */ - u8 rx_broadcast_in_ps; - - /* - * Consequtive PS Poll failures before sending event to driver - * - * Range: u8 - */ - u8 ps_poll_threshold; - - /* - * Configuration of signal average weights. - */ - struct conf_sig_weights sig_weights; - - /* - * Specifies if beacon early termination procedure is enabled or - * disabled. - * - * Range: CONF_BET_MODE_* - */ - u8 bet_enable; - - /* - * Specifies the maximum number of consecutive beacons that may be - * early terminated. After this number is reached at least one full - * beacon must be correctly received in FW before beacon ET - * resumes. - * - * Range 0 - 255 - */ - u8 bet_max_consecutive; - - /* - * Specifies the maximum number of times to try PSM entry if it fails - * (if sending the appropriate null-func message fails.) - * - * Range 0 - 255 - */ - u8 psm_entry_retries; - - /* - * - * Specifies the interval of the connection keep-alive null-func - * frame in ms. - * - * Range: 1000 - 3600000 - */ - u32 keep_alive_interval; - - /* - * Maximum listen interval supported by the driver in units of beacons. - * - * Range: u16 - */ - u8 max_listen_interval; -}; - -enum { - CONF_REF_CLK_19_2_E, - CONF_REF_CLK_26_E, - CONF_REF_CLK_38_4_E, - CONF_REF_CLK_52_E -}; - -enum single_dual_band_enum { - CONF_SINGLE_BAND, - CONF_DUAL_BAND -}; - -#define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15 -#define CONF_NUMBER_OF_SUB_BANDS_5 7 -#define CONF_NUMBER_OF_RATE_GROUPS 6 -#define CONF_NUMBER_OF_CHANNELS_2_4 14 -#define CONF_NUMBER_OF_CHANNELS_5 35 - -struct conf_radio_parms { - /* - * FEM parameter set to use - * - * Range: 0 or 1 - */ - u8 fem; -}; - -struct conf_init_settings { - /* - * Configure radio parameters. - */ - struct conf_radio_parms radioparam; - -}; - -struct conf_itrim_settings { - /* enable dco itrim */ - u8 enable; - - /* moderation timeout in microsecs from the last TX */ - u32 timeout; -}; - -struct conf_pm_config_settings { - /* - * Host clock settling time - * - * Range: 0 - 30000 us - */ - u32 host_clk_settling_time; - - /* - * Host fast wakeup support - * - * Range: true, false - */ - bool host_fast_wakeup_support; -}; - -struct conf_roam_trigger_settings { - /* - * The minimum interval between two trigger events. - * - * Range: 0 - 60000 ms - */ - u16 trigger_pacing; - - /* - * The weight for rssi/beacon average calculation - * - * Range: 0 - 255 - */ - u8 avg_weight_rssi_beacon; - - /* - * The weight for rssi/data frame average calculation - * - * Range: 0 - 255 - */ - u8 avg_weight_rssi_data; - - /* - * The weight for snr/beacon average calculation - * - * Range: 0 - 255 - */ - u8 avg_weight_snr_beacon; - - /* - * The weight for snr/data frame average calculation - * - * Range: 0 - 255 - */ - u8 avg_weight_snr_data; -}; - -struct conf_drv_settings { - struct conf_sg_settings sg; - struct conf_rx_settings rx; - struct conf_tx_settings tx; - struct conf_conn_settings conn; - struct conf_init_settings init; - struct conf_itrim_settings itrim; - struct conf_pm_config_settings pm_config; - struct conf_roam_trigger_settings roam_trigger; -}; - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c deleted file mode 100644 index c239ef4d0b8..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_debugfs.h" - -#include <linux/skbuff.h> -#include <linux/slab.h> - -#include "wl1271.h" -#include "wl1271_acx.h" -#include "wl1271_ps.h" -#include "wl1271_io.h" - -/* ms */ -#define WL1271_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 wl1271 *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 = wl1271_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 wl1271 *wl = file->private_data; \ - char buf[buflen]; \ - int res; \ - \ - wl1271_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 = wl1271_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 wl1271_debugfs_update_stats(struct wl1271 *wl) -{ - int ret; - - mutex_lock(&wl->mutex); - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - if (wl->state == WL1271_STATE_ON && - time_after(jiffies, wl->stats.fw_stats_update + - msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) { - wl1271_acx_statistics(wl, wl->stats.fw_stats); - wl->stats.fw_stats_update = jiffies; - } - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1271_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 wl1271 *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 = wl1271_open_file_generic, -}; - -static ssize_t gpio_power_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); - - int res; - char buf[10]; - - res = scnprintf(buf, sizeof(buf), "%d\n", state); - - return simple_read_from_buffer(user_buf, count, ppos, buf, res); -} - -static ssize_t gpio_power_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - char buf[10]; - size_t len; - unsigned long value; - int ret; - - mutex_lock(&wl->mutex); - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) { - ret = -EFAULT; - goto out; - } - buf[len] = '\0'; - - ret = strict_strtoul(buf, 0, &value); - if (ret < 0) { - wl1271_warning("illegal value in gpio_power"); - goto out; - } - - if (value) - wl1271_power_on(wl); - else - wl1271_power_off(wl); - -out: - mutex_unlock(&wl->mutex); - return count; -} - -static const struct file_operations gpio_power_ops = { - .read = gpio_power_read, - .write = gpio_power_write, - .open = wl1271_open_file_generic -}; - -static void wl1271_debugfs_delete_files(struct wl1271 *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(retry_count); - DEBUGFS_DEL(excessive_retries); - - DEBUGFS_DEL(gpio_power); -} - -static int wl1271_debugfs_add_files(struct wl1271 *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(retry_count, wl->debugfs.rootdir); - DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir); - - DEBUGFS_ADD(gpio_power, wl->debugfs.rootdir); - -out: - if (ret < 0) - wl1271_debugfs_delete_files(wl); - - return ret; -} - -void wl1271_debugfs_reset(struct wl1271 *wl) -{ - memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); - wl->stats.retry_count = 0; - wl->stats.excessive_retries = 0; -} - -int wl1271_debugfs_init(struct wl1271 *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 = wl1271_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 wl1271_debugfs_exit(struct wl1271 *wl) -{ - wl1271_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/wl1271_debugfs.h b/drivers/net/wireless/wl12xx/wl1271_debugfs.h deleted file mode 100644 index 00a45b2669a..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_debugfs.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 WL1271_DEBUGFS_H -#define WL1271_DEBUGFS_H - -#include "wl1271.h" - -int wl1271_debugfs_init(struct wl1271 *wl); -void wl1271_debugfs_exit(struct wl1271 *wl); -void wl1271_debugfs_reset(struct wl1271 *wl); - -#endif /* WL1271_DEBUGFS_H */ diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c deleted file mode 100644 index cf37aa6eb13..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h" -#include "wl1271_reg.h" -#include "wl1271_io.h" -#include "wl1271_event.h" -#include "wl1271_ps.h" -#include "wl12xx_80211.h" - -static int wl1271_event_scan_complete(struct wl1271 *wl, - struct event_mailbox *mbox) -{ - wl1271_debug(DEBUG_EVENT, "status: 0x%x", - mbox->scheduled_scan_status); - - if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) { - if (wl->scan.state == WL1271_SCAN_BAND_DUAL) { - /* 2.4 GHz band scanned, scan 5 GHz band, pretend - * to the wl1271_cmd_scan function that we are not - * scanning as it checks that. - */ - clear_bit(WL1271_FLAG_SCANNING, &wl->flags); - /* FIXME: ie missing! */ - wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, - NULL, 0, - wl->scan.active, - wl->scan.high_prio, - WL1271_SCAN_BAND_5_GHZ, - wl->scan.probe_requests); - } else { - mutex_unlock(&wl->mutex); - ieee80211_scan_completed(wl->hw, false); - mutex_lock(&wl->mutex); - clear_bit(WL1271_FLAG_SCANNING, &wl->flags); - } - } - return 0; -} - -static int wl1271_event_ps_report(struct wl1271 *wl, - struct event_mailbox *mbox, - bool *beacon_loss) -{ - int ret = 0; - - wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status); - - switch (mbox->ps_status) { - case EVENT_ENTER_POWER_SAVE_FAIL: - wl1271_debug(DEBUG_PSM, "PSM entry failed"); - - if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) { - /* remain in active mode */ - wl->psm_entry_retry = 0; - break; - } - - if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) { - wl->psm_entry_retry++; - ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - true); - } else { - wl1271_info("No ack to nullfunc from AP."); - wl->psm_entry_retry = 0; - *beacon_loss = true; - } - break; - case EVENT_ENTER_POWER_SAVE_SUCCESS: - wl->psm_entry_retry = 0; - - /* enable beacon filtering */ - ret = wl1271_acx_beacon_filter_opt(wl, true); - if (ret < 0) - break; - - /* enable beacon early termination */ - ret = wl1271_acx_bet_enable(wl, true); - if (ret < 0) - break; - - /* go to extremely low power mode */ - wl1271_ps_elp_sleep(wl); - if (ret < 0) - break; - break; - case EVENT_EXIT_POWER_SAVE_FAIL: - wl1271_debug(DEBUG_PSM, "PSM exit failed"); - - if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { - wl->psm_entry_retry = 0; - break; - } - - /* 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); - break; - case EVENT_EXIT_POWER_SAVE_SUCCESS: - default: - break; - } - - return ret; -} - -static void wl1271_event_rssi_trigger(struct wl1271 *wl, - struct event_mailbox *mbox) -{ - enum nl80211_cqm_rssi_threshold_event event; - s8 metric = mbox->rssi_snr_trigger_metric[0]; - - wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric); - - if (metric <= wl->rssi_thold) - event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; - else - event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; - - if (event != wl->last_rssi_event) - ieee80211_cqm_rssi_notify(wl->vif, event, GFP_KERNEL); - wl->last_rssi_event = event; -} - -static void wl1271_event_mbox_dump(struct event_mailbox *mbox) -{ - wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); - wl1271_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector); - wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask); -} - -static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) -{ - int ret; - u32 vector; - bool beacon_loss = false; - - wl1271_event_mbox_dump(mbox); - - vector = le32_to_cpu(mbox->events_vector); - vector &= ~(le32_to_cpu(mbox->events_mask)); - wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector); - - if (vector & SCAN_COMPLETE_EVENT_ID) { - ret = wl1271_event_scan_complete(wl, mbox); - if (ret < 0) - return ret; - } - - /* - * The BSS_LOSE_EVENT_ID is only needed while psm (and hence beacon - * filtering) is enabled. Without PSM, the stack will receive all - * beacons and can detect beacon loss by itself. - * - * As there's possibility that the driver disables PSM before receiving - * BSS_LOSE_EVENT, beacon loss has to be reported to the stack. - * - */ - if (vector & BSS_LOSE_EVENT_ID) { - wl1271_info("Beacon loss detected."); - - /* indicate to the stack, that beacons have been lost */ - beacon_loss = true; - } - - if (vector & PS_REPORT_EVENT_ID) { - wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT"); - ret = wl1271_event_ps_report(wl, mbox, &beacon_loss); - if (ret < 0) - return ret; - } - - if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { - wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT"); - if (wl->vif) - wl1271_event_rssi_trigger(wl, mbox); - } - - if (wl->vif && beacon_loss) - ieee80211_connection_loss(wl->vif); - - return 0; -} - -int wl1271_event_unmask(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask)); - if (ret < 0) - return ret; - - return 0; -} - -void wl1271_event_mbox_config(struct wl1271 *wl) -{ - wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR); - wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); - - wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x", - wl->mbox_ptr[0], wl->mbox_ptr[1]); -} - -int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) -{ - struct event_mailbox mbox; - int ret; - - wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num); - - if (mbox_num > 1) - return -EINVAL; - - /* first we read the mbox descriptor */ - wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox, - sizeof(struct event_mailbox), false); - - /* process the descriptor */ - ret = wl1271_event_process(wl, &mbox); - if (ret < 0) - return ret; - - /* then we let the firmware know it can go on...*/ - wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK); - - return 0; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h deleted file mode 100644 index 58371008f27..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_event.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_EVENT_H__ -#define __WL1271_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 { - RSSI_SNR_TRIGGER_0_EVENT_ID = BIT(0), - RSSI_SNR_TRIGGER_1_EVENT_ID = BIT(1), - RSSI_SNR_TRIGGER_2_EVENT_ID = BIT(2), - RSSI_SNR_TRIGGER_3_EVENT_ID = BIT(3), - RSSI_SNR_TRIGGER_4_EVENT_ID = BIT(4), - RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5), - RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6), - RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7), - MEASUREMENT_START_EVENT_ID = BIT(8), - MEASUREMENT_COMPLETE_EVENT_ID = BIT(9), - SCAN_COMPLETE_EVENT_ID = BIT(10), - SCHEDULED_SCAN_COMPLETE_EVENT_ID = BIT(11), - AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12), - PS_REPORT_EVENT_ID = BIT(13), - PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14), - DISCONNECT_EVENT_COMPLETE_ID = BIT(15), - JOIN_EVENT_COMPLETE_ID = BIT(16), - CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17), - BSS_LOSE_EVENT_ID = BIT(18), - REGAINED_BSS_EVENT_ID = BIT(19), - ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20), - SOFT_GEMINI_SENSE_EVENT_ID = BIT(22), - SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23), - SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24), - PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25), - DBG_EVENT_ID = BIT(26), - HEALTH_CHECK_REPLY_EVENT_ID = BIT(27), - PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28), - PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29), - BA_SESSION_TEAR_DOWN_EVENT_ID = BIT(30), - EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, -}; - -enum { - EVENT_ENTER_POWER_SAVE_FAIL = 0, - EVENT_ENTER_POWER_SAVE_SUCCESS, - EVENT_EXIT_POWER_SAVE_FAIL, - EVENT_EXIT_POWER_SAVE_SUCCESS, -}; - -struct event_debug_report { - u8 debug_event_id; - u8 num_params; - __le16 pad; - __le32 report_1; - __le32 report_2; - __le32 report_3; -} __attribute__ ((packed)); - -#define NUM_OF_RSSI_SNR_TRIGGERS 8 - -struct event_mailbox { - __le32 events_vector; - __le32 events_mask; - __le32 reserved_1; - __le32 reserved_2; - - u8 dbg_event_id; - u8 num_relevant_params; - __le16 reserved_3; - __le32 event_report_p1; - __le32 event_report_p2; - __le32 event_report_p3; - - u8 number_of_scan_results; - u8 scan_tag; - u8 reserved_4[2]; - __le32 compl_scheduled_scan_status; - - __le16 scheduled_scan_attended_channels; - u8 soft_gemini_sense_info; - u8 soft_gemini_protective_info; - s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS]; - u8 channel_switch_status; - u8 scheduled_scan_status; - u8 ps_status; - - u8 reserved_5[29]; -} __attribute__ ((packed)); - -int wl1271_event_unmask(struct wl1271 *wl); -void wl1271_event_mbox_config(struct wl1271 *wl); -int wl1271_event_handle(struct wl1271 *wl, u8 mbox); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c deleted file mode 100644 index 4447af1557f..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_init.h" -#include "wl12xx_80211.h" -#include "wl1271_acx.h" -#include "wl1271_cmd.h" -#include "wl1271_reg.h" - -static int wl1271_init_hwenc_config(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_feature_cfg(wl); - if (ret < 0) { - wl1271_warning("couldn't set feature config"); - return ret; - } - - ret = wl1271_cmd_set_default_wep_key(wl, wl->default_key); - if (ret < 0) { - wl1271_warning("couldn't set default key"); - return ret; - } - - return 0; -} - -int wl1271_init_templates_config(struct wl1271 *wl) -{ - int ret, i; - - /* send empty templates for fw memory reservation */ - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, - sizeof(struct wl12xx_probe_req_template), - 0, WL1271_RATE_AUTOMATIC); - 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; - } - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, - sizeof(struct wl12xx_null_data_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, - sizeof(struct wl12xx_ps_poll_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, - sizeof - (struct wl12xx_qos_null_data_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, - sizeof - (struct wl12xx_probe_resp_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, - sizeof - (struct wl12xx_beacon_template), - 0, WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - - for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL, - WL1271_CMD_TEMPL_MAX_SIZE, i, - WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - } - - return 0; -} - -static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter) -{ - int ret; - - ret = wl1271_acx_rx_msdu_life_time(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_rx_config(wl, config, filter); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_init_phy_config(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_pd_threshold(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME); - if (ret < 0) - return ret; - - ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0); - if (ret < 0) - return ret; - - ret = wl1271_acx_service_period_timeout(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold); - if (ret < 0) - return ret; - - return 0; -} - -static int wl1271_init_beacon_filter(struct wl1271 *wl) -{ - int ret; - - /* disable beacon filtering at this stage */ - ret = wl1271_acx_beacon_filter_opt(wl, false); - if (ret < 0) - return ret; - - ret = wl1271_acx_beacon_filter_table(wl); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_init_pta(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_sg_cfg(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_sg_enable(wl, wl->sg_enabled); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_init_energy_detection(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_cca_threshold(wl); - if (ret < 0) - return ret; - - return 0; -} - -static int wl1271_init_beacon_broadcast(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_bcn_dtim_options(wl); - if (ret < 0) - return ret; - - return 0; -} - -int wl1271_hw_init(struct wl1271 *wl) -{ - struct conf_tx_ac_category *conf_ac; - struct conf_tx_tid *conf_tid; - int ret, i; - - ret = wl1271_cmd_general_parms(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_radio_parms(wl); - if (ret < 0) - return ret; - - /* Template settings */ - ret = wl1271_init_templates_config(wl); - if (ret < 0) - return ret; - - /* Default memory configuration */ - ret = wl1271_acx_init_mem_config(wl); - if (ret < 0) - return ret; - - /* RX config */ - ret = wl1271_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_memmap; - - /* PHY layer config */ - ret = wl1271_init_phy_config(wl); - if (ret < 0) - goto out_free_memmap; - - ret = wl1271_acx_dco_itrim_params(wl); - if (ret < 0) - goto out_free_memmap; - - /* Initialize connection monitoring thresholds */ - ret = wl1271_acx_conn_monit_params(wl, false); - if (ret < 0) - goto out_free_memmap; - - /* Beacon filtering */ - ret = wl1271_init_beacon_filter(wl); - if (ret < 0) - goto out_free_memmap; - - /* Configure TX patch complete interrupt behavior */ - ret = wl1271_acx_tx_config_options(wl); - if (ret < 0) - goto out_free_memmap; - - /* RX complete interrupt pacing */ - ret = wl1271_acx_init_rx_interrupt(wl); - if (ret < 0) - goto out_free_memmap; - - /* Bluetooth WLAN coexistence */ - ret = wl1271_init_pta(wl); - if (ret < 0) - goto out_free_memmap; - - /* Energy detection */ - ret = wl1271_init_energy_detection(wl); - if (ret < 0) - goto out_free_memmap; - - /* Beacons and boradcast settings */ - ret = wl1271_init_beacon_broadcast(wl); - if (ret < 0) - goto out_free_memmap; - - /* Default fragmentation threshold */ - ret = wl1271_acx_frag_threshold(wl); - if (ret < 0) - goto out_free_memmap; - - /* Default TID configuration */ - for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { - conf_tid = &wl->conf.tx.tid_conf[i]; - ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, - conf_tid->channel_type, - conf_tid->tsid, - conf_tid->ps_scheme, - conf_tid->ack_policy, - conf_tid->apsd_conf[0], - conf_tid->apsd_conf[1]); - if (ret < 0) - 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) - goto out_free_memmap; - - /* Enable data path */ - ret = wl1271_cmd_data_path(wl, 1); - if (ret < 0) - goto out_free_memmap; - - /* Configure for ELP power saving */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); - if (ret < 0) - goto out_free_memmap; - - /* Configure HW encryption */ - ret = wl1271_init_hwenc_config(wl); - if (ret < 0) - goto out_free_memmap; - - /* configure PM */ - ret = wl1271_acx_pm_config(wl); - if (ret < 0) - goto out_free_memmap; - - /* disable all keep-alive templates */ - for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { - ret = wl1271_acx_keep_alive_config(wl, i, - ACX_KEEP_ALIVE_TPL_INVALID); - if (ret < 0) - goto out_free_memmap; - } - - /* disable the keep-alive feature */ - ret = wl1271_acx_keep_alive_mode(wl, false); - if (ret < 0) - goto out_free_memmap; - - /* Configure rssi/snr averaging weights */ - ret = wl1271_acx_rssi_snr_avg_weights(wl); - if (ret < 0) - goto out_free_memmap; - - return 0; - - out_free_memmap: - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - - return ret; -} diff --git a/drivers/net/wireless/wl12xx/wl1271_init.h b/drivers/net/wireless/wl12xx/wl1271_init.h deleted file mode 100644 index bc26f8c53b9..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_init.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_INIT_H__ -#define __WL1271_INIT_H__ - -#include "wl1271.h" - -int wl1271_hw_init_power_auth(struct wl1271 *wl); -int wl1271_init_templates_config(struct wl1271 *wl); -int wl1271_init_phy_config(struct wl1271 *wl); -int wl1271_init_pta(struct wl1271 *wl); -int wl1271_init_energy_detection(struct wl1271 *wl); -int wl1271_hw_init(struct wl1271 *wl); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_io.c b/drivers/net/wireless/wl12xx/wl1271_io.c deleted file mode 100644 index c8759acef13..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_io.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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/platform_device.h> -#include <linux/crc7.h> -#include <linux/spi/spi.h> - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_io.h" - -#define OCP_CMD_LOOP 32 - -#define OCP_CMD_WRITE 0x1 -#define OCP_CMD_READ 0x2 - -#define OCP_READY_MASK BIT(18) -#define OCP_STATUS_MASK (BIT(16) | BIT(17)) - -#define OCP_STATUS_NO_RESP 0x00000 -#define OCP_STATUS_OK 0x10000 -#define OCP_STATUS_REQ_FAILED 0x20000 -#define OCP_STATUS_RESP_ERROR 0x30000 - -void wl1271_disable_interrupts(struct wl1271 *wl) -{ - wl->if_ops->disable_irq(wl); -} - -void wl1271_enable_interrupts(struct wl1271 *wl) -{ - wl->if_ops->enable_irq(wl); -} - -/* Set the SPI partitions to access the chip addresses - * - * To simplify driver code, a fixed (virtual) memory map is defined for - * register and memory addresses. Because in the chipset, in different stages - * of operation, those addresses will move around, an address translation - * mechanism is required. - * - * There are four partitions (three memory and one register partition), - * which are mapped to two different areas of the hardware memory. - * - * Virtual address - * space - * - * | | - * ...+----+--> mem.start - * Physical address ... | | - * space ... | | [PART_0] - * ... | | - * 00000000 <--+----+... ...+----+--> mem.start + mem.size - * | | ... | | - * |MEM | ... | | - * | | ... | | - * mem.size <--+----+... | | {unused area) - * | | ... | | - * |REG | ... | | - * mem.size | | ... | | - * + <--+----+... ...+----+--> reg.start - * reg.size | | ... | | - * |MEM2| ... | | [PART_1] - * | | ... | | - * ...+----+--> reg.start + reg.size - * | | - * - */ -int wl1271_set_partition(struct wl1271 *wl, - struct wl1271_partition_set *p) -{ - /* copy partition info */ - memcpy(&wl->part, p, sizeof(*p)); - - wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", - p->mem.start, p->mem.size); - wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", - p->reg.start, p->reg.size); - wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X", - p->mem2.start, p->mem2.size); - wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X", - p->mem3.start, p->mem3.size); - - /* write partition info to the chipset */ - wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); - wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); - wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); - wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); - wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); - wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); - wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); - - return 0; -} - -void wl1271_io_reset(struct wl1271 *wl) -{ - wl->if_ops->reset(wl); -} - -void wl1271_io_init(struct wl1271 *wl) -{ - wl->if_ops->init(wl); -} - -void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) -{ - /* write address >> 1 + 0x30000 to OCP_POR_CTR */ - addr = (addr >> 1) + 0x30000; - wl1271_write32(wl, OCP_POR_CTR, addr); - - /* write value to OCP_POR_WDATA */ - wl1271_write32(wl, OCP_DATA_WRITE, val); - - /* write 1 to OCP_CMD */ - wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE); -} - -u16 wl1271_top_reg_read(struct wl1271 *wl, int addr) -{ - u32 val; - int timeout = OCP_CMD_LOOP; - - /* write address >> 1 + 0x30000 to OCP_POR_CTR */ - addr = (addr >> 1) + 0x30000; - wl1271_write32(wl, OCP_POR_CTR, addr); - - /* write 2 to OCP_CMD */ - wl1271_write32(wl, OCP_CMD, OCP_CMD_READ); - - /* poll for data ready */ - do { - val = wl1271_read32(wl, OCP_DATA_READ); - } while (!(val & OCP_READY_MASK) && --timeout); - - if (!timeout) { - wl1271_warning("Top register access timed out."); - return 0xffff; - } - - /* check data status and return if OK */ - if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK) - return val & 0xffff; - else { - wl1271_warning("Top register access returned error."); - return 0xffff; - } -} - diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h deleted file mode 100644 index bc806c74c63..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_io.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_IO_H__ -#define __WL1271_IO_H__ - -#include "wl1271_reg.h" - -#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 - -#define HW_PARTITION_REGISTERS_ADDR 0x1FFC0 -#define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR) -#define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4) -#define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8) -#define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12) -#define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16) -#define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20) -#define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24) - -#define HW_ACCESS_REGISTER_SIZE 4 - -#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 - -struct wl1271; - -void wl1271_disable_interrupts(struct wl1271 *wl); -void wl1271_enable_interrupts(struct wl1271 *wl); - -void wl1271_io_reset(struct wl1271 *wl); -void wl1271_io_init(struct wl1271 *wl); - -static inline struct device *wl1271_wl_to_dev(struct wl1271 *wl) -{ - return wl->if_ops->dev(wl); -} - - -/* Raw target IO, address is not translated */ -static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - wl->if_ops->write(wl, addr, buf, len, fixed); -} - -static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - wl->if_ops->read(wl, addr, buf, len, fixed); -} - -static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) -{ - wl1271_raw_read(wl, addr, &wl->buffer_32, - sizeof(wl->buffer_32), false); - - return le32_to_cpu(wl->buffer_32); -} - -static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) -{ - wl->buffer_32 = cpu_to_le32(val); - wl1271_raw_write(wl, addr, &wl->buffer_32, - sizeof(wl->buffer_32), false); -} - -/* Translated target IO */ -static inline int wl1271_translate_addr(struct wl1271 *wl, int addr) -{ - /* - * To translate, first check to which window of addresses the - * particular address belongs. Then subtract the starting address - * of that window from the address. Then, add offset of the - * translated region. - * - * The translated regions occur next to each other in physical device - * memory, so just add the sizes of the preceeding address regions to - * get the offset to the new region. - * - * Currently, only the two first regions are addressed, and the - * assumption is that all addresses will fall into either of those - * two. - */ - if ((addr >= wl->part.reg.start) && - (addr < wl->part.reg.start + wl->part.reg.size)) - return addr - wl->part.reg.start + wl->part.mem.size; - else - return addr - wl->part.mem.start; -} - -static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int physical; - - physical = wl1271_translate_addr(wl, addr); - - wl1271_raw_read(wl, physical, buf, len, fixed); -} - -static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int physical; - - physical = wl1271_translate_addr(wl, addr); - - wl1271_raw_write(wl, physical, buf, len, fixed); -} - -static inline u32 wl1271_read32(struct wl1271 *wl, int addr) -{ - return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); -} - -static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) -{ - wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); -} - -static inline void wl1271_power_off(struct wl1271 *wl) -{ - wl->if_ops->power(wl, false); - clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); -} - -static inline void wl1271_power_on(struct wl1271 *wl) -{ - wl->if_ops->power(wl, true); - set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); -} - - -/* Top Register IO */ -void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); -u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); - -int wl1271_set_partition(struct wl1271 *wl, - struct wl1271_partition_set *p); - -/* Functions from wl1271_main.c */ - -int wl1271_register_hw(struct wl1271 *wl); -void wl1271_unregister_hw(struct wl1271 *wl); -int wl1271_init_ieee80211(struct wl1271 *wl); -struct ieee80211_hw *wl1271_alloc_hw(void); -int wl1271_free_hw(struct wl1271 *wl); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c deleted file mode 100644 index b7d9137851a..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ /dev/null @@ -1,2470 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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/firmware.h> -#include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/crc32.h> -#include <linux/etherdevice.h> -#include <linux/vmalloc.h> -#include <linux/inetdevice.h> -#include <linux/platform_device.h> -#include <linux/slab.h> - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_reg.h" -#include "wl1271_io.h" -#include "wl1271_event.h" -#include "wl1271_tx.h" -#include "wl1271_rx.h" -#include "wl1271_ps.h" -#include "wl1271_init.h" -#include "wl1271_debugfs.h" -#include "wl1271_cmd.h" -#include "wl1271_boot.h" -#include "wl1271_testmode.h" - -#define WL1271_BOOT_RETRIES 3 - -static struct conf_drv_settings default_conf = { - .sg = { - .params = { - [CONF_SG_BT_PER_THRESHOLD] = 7500, - [CONF_SG_HV3_MAX_OVERRIDE] = 0, - [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400, - [CONF_SG_BT_LOAD_RATIO] = 50, - [CONF_SG_AUTO_PS_MODE] = 0, - [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, - [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, - [CONF_SG_ANTENNA_CONFIGURATION] = 0, - [CONF_SG_BEACON_MISS_PERCENT] = 60, - [CONF_SG_RATE_ADAPT_THRESH] = 12, - [CONF_SG_RATE_ADAPT_SNR] = 0, - [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10, - [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 30, - [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 8, - [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20, - [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 50, - /* Note: with UPSD, this should be 4 */ - [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 8, - [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7, - [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25, - [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 20, - /* Note: with UPDS, this should be 15 */ - [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8, - /* Note: with UPDS, this should be 50 */ - [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 40, - /* Note: with UPDS, this should be 10 */ - [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 20, - [CONF_SG_RXT] = 1200, - [CONF_SG_TXT] = 1000, - [CONF_SG_ADAPTIVE_RXT_TXT] = 1, - [CONF_SG_PS_POLL_TIMEOUT] = 10, - [CONF_SG_UPSD_TIMEOUT] = 10, - [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7, - [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15, - [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15, - [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8, - [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20, - [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15, - [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20, - [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50, - [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10, - [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200, - [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800, - [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75, - [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15, - [CONF_SG_HV3_MAX_SERVED] = 6, - [CONF_SG_DHCP_TIME] = 5000, - [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100, - }, - .state = CONF_SG_PROTECTIVE, - }, - .rx = { - .rx_msdu_life_time = 512000, - .packet_detection_threshold = 0, - .ps_poll_timeout = 15, - .upsd_timeout = 15, - .rts_threshold = 2347, - .rx_cca_threshold = 0, - .irq_blk_threshold = 0xFFFF, - .irq_pkt_threshold = 0, - .irq_timeout = 600, - .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY, - }, - .tx = { - .tx_energy_detection = 0, - .rc_conf = { - .enabled_rates = 0, - .short_retry_limit = 10, - .long_retry_limit = 10, - .aflags = 0 - }, - .ac_conf_count = 4, - .ac_conf = { - [0] = { - .ac = CONF_TX_AC_BE, - .cw_min = 15, - .cw_max = 63, - .aifsn = 3, - .tx_op_limit = 0, - }, - [1] = { - .ac = CONF_TX_AC_BK, - .cw_min = 15, - .cw_max = 63, - .aifsn = 7, - .tx_op_limit = 0, - }, - [2] = { - .ac = CONF_TX_AC_VI, - .cw_min = 15, - .cw_max = 63, - .aifsn = CONF_TX_AIFS_PIFS, - .tx_op_limit = 3008, - }, - [3] = { - .ac = CONF_TX_AC_VO, - .cw_min = 15, - .cw_max = 63, - .aifsn = CONF_TX_AIFS_PIFS, - .tx_op_limit = 1504, - }, - }, - .tid_conf_count = 7, - .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, - .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, - .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, - .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, - .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, - .tx_compl_threshold = 4, - .basic_rate = CONF_HW_BIT_RATE_1MBPS, - .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, - }, - .conn = { - .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, - .listen_interval = 1, - .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, - .bcn_filt_ie_count = 1, - .bcn_filt_ie = { - [0] = { - .ie = WLAN_EID_CHANNEL_SWITCH, - .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE, - } - }, - .synch_fail_thold = 10, - .bss_lose_timeout = 100, - .beacon_rx_timeout = 10000, - .broadcast_timeout = 20000, - .rx_broadcast_in_ps = 1, - .ps_poll_threshold = 20, - .bet_enable = CONF_BET_MODE_ENABLE, - .bet_max_consecutive = 10, - .psm_entry_retries = 3, - .keep_alive_interval = 55000, - .max_listen_interval = 20, - }, - .init = { - .radioparam = { - .fem = 1, - } - }, - .itrim = { - .enable = false, - .timeout = 50000, - }, - .pm_config = { - .host_clk_settling_time = 5000, - .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 - } -}; - -static void wl1271_device_release(struct device *dev) -{ - -} - -static struct platform_device wl1271_device = { - .name = "wl1271", - .id = -1, - - /* device model insists to have a release function */ - .dev = { - .release = wl1271_device_release, - }, -}; - -static LIST_HEAD(wl_list); - -static void wl1271_conf_init(struct wl1271 *wl) -{ - - /* - * This function applies the default configuration to the driver. This - * function is invoked upon driver load (spi probe.) - * - * The configuration is stored in a run-time structure in order to - * facilitate for run-time adjustment of any of the parameters. Making - * changes to the configuration structure will apply the new values on - * the next interface up (wl1271_op_start.) - */ - - /* apply driver default configuration */ - memcpy(&wl->conf, &default_conf, sizeof(default_conf)); -} - - -static int wl1271_plt_init(struct wl1271 *wl) -{ - struct conf_tx_ac_category *conf_ac; - struct conf_tx_tid *conf_tid; - int ret, i; - - ret = wl1271_cmd_general_parms(wl); - if (ret < 0) - return ret; - - ret = wl1271_cmd_radio_parms(wl); - if (ret < 0) - return ret; - - ret = wl1271_init_templates_config(wl); - if (ret < 0) - return ret; - - ret = wl1271_acx_init_mem_config(wl); - if (ret < 0) - return ret; - - /* PHY layer config */ - ret = wl1271_init_phy_config(wl); - if (ret < 0) - goto out_free_memmap; - - ret = wl1271_acx_dco_itrim_params(wl); - if (ret < 0) - goto out_free_memmap; - - /* Initialize connection monitoring thresholds */ - ret = wl1271_acx_conn_monit_params(wl, false); - if (ret < 0) - goto out_free_memmap; - - /* Bluetooth WLAN coexistence */ - ret = wl1271_init_pta(wl); - if (ret < 0) - goto out_free_memmap; - - /* Energy detection */ - ret = wl1271_init_energy_detection(wl); - if (ret < 0) - goto out_free_memmap; - - /* Default fragmentation threshold */ - ret = wl1271_acx_frag_threshold(wl); - if (ret < 0) - goto out_free_memmap; - - /* Default TID configuration */ - for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { - conf_tid = &wl->conf.tx.tid_conf[i]; - ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, - conf_tid->channel_type, - conf_tid->tsid, - conf_tid->ps_scheme, - conf_tid->ack_policy, - conf_tid->apsd_conf[0], - conf_tid->apsd_conf[1]); - if (ret < 0) - 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) - goto out_free_memmap; - - /* Configure for CAM power saving (ie. always active) */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - if (ret < 0) - goto out_free_memmap; - - /* configure PM */ - ret = wl1271_acx_pm_config(wl); - if (ret < 0) - goto out_free_memmap; - - return 0; - - out_free_memmap: - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - - return ret; -} - -static void wl1271_fw_status(struct wl1271 *wl, - struct wl1271_fw_status *status) -{ - struct timespec ts; - u32 total = 0; - int i; - - wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); - - wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " - "drv_rx_counter = %d, tx_results_counter = %d)", - status->intr, - status->fw_rx_counter, - status->drv_rx_counter, - status->tx_results_counter); - - /* update number of available TX blocks */ - for (i = 0; i < NUM_TX_QUEUES; i++) { - u32 cnt = le32_to_cpu(status->tx_released_blks[i]) - - wl->tx_blocks_freed[i]; - - wl->tx_blocks_freed[i] = - le32_to_cpu(status->tx_released_blks[i]); - wl->tx_blocks_available += cnt; - total += cnt; - } - - /* if more blocks are available now, schedule some tx work */ - if (total && !skb_queue_empty(&wl->tx_queue)) - ieee80211_queue_work(wl->hw, &wl->tx_work); - - /* update the host-chipset time offset */ - getnstimeofday(&ts); - wl->time_offset = (timespec_to_ns(&ts) >> 10) - - (s64)le32_to_cpu(status->fw_localtime); -} - -#define WL1271_IRQ_MAX_LOOPS 10 - -static void wl1271_irq_work(struct work_struct *work) -{ - int ret; - u32 intr; - int loopcount = WL1271_IRQ_MAX_LOOPS; - unsigned long flags; - struct wl1271 *wl = - container_of(work, struct wl1271, irq_work); - - mutex_lock(&wl->mutex); - - wl1271_debug(DEBUG_IRQ, "IRQ work"); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, true); - if (ret < 0) - goto out; - - spin_lock_irqsave(&wl->wl_lock, flags); - while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) { - clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - loopcount--; - - wl1271_fw_status(wl, wl->fw_status); - intr = le32_to_cpu(wl->fw_status->intr); - if (!intr) { - wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); - spin_lock_irqsave(&wl->wl_lock, flags); - continue; - } - - intr &= WL1271_INTR_MASK; - - if (intr & WL1271_ACX_INTR_DATA) { - wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); - - /* check for tx results */ - if (wl->fw_status->tx_results_counter != - (wl->tx_results_count & 0xff)) - wl1271_tx_complete(wl); - - wl1271_rx(wl, wl->fw_status); - } - - if (intr & WL1271_ACX_INTR_EVENT_A) { - wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); - wl1271_event_handle(wl, 0); - } - - if (intr & WL1271_ACX_INTR_EVENT_B) { - wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); - wl1271_event_handle(wl, 1); - } - - if (intr & WL1271_ACX_INTR_INIT_COMPLETE) - wl1271_debug(DEBUG_IRQ, - "WL1271_ACX_INTR_INIT_COMPLETE"); - - if (intr & WL1271_ACX_INTR_HW_AVAILABLE) - wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); - - spin_lock_irqsave(&wl->wl_lock, flags); - } - - if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - else - clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1271_fetch_firmware(struct wl1271 *wl) -{ - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); - - if (ret < 0) { - wl1271_error("could not get firmware: %d", ret); - return ret; - } - - if (fw->size % 4) { - wl1271_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) { - wl1271_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 wl1271_fetch_nvs(struct wl1271 *wl) -{ - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); - - if (ret < 0) { - wl1271_error("could not get nvs file: %d", ret); - return ret; - } - - if (fw->size != sizeof(struct wl1271_nvs_file)) { - wl1271_error("nvs size is not as expected: %zu != %zu", - fw->size, sizeof(struct wl1271_nvs_file)); - ret = -EILSEQ; - goto out; - } - - wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); - - if (!wl->nvs) { - wl1271_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file)); - -out: - release_firmware(fw); - - return ret; -} - -static void wl1271_fw_wakeup(struct wl1271 *wl) -{ - u32 elp_reg; - - elp_reg = ELPCTRL_WAKE_UP; - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); -} - -static int wl1271_setup(struct wl1271 *wl) -{ - wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL); - if (!wl->fw_status) - return -ENOMEM; - - wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); - if (!wl->tx_res_if) { - kfree(wl->fw_status); - return -ENOMEM; - } - - INIT_WORK(&wl->irq_work, wl1271_irq_work); - INIT_WORK(&wl->tx_work, wl1271_tx_work); - return 0; -} - -static int wl1271_chip_wakeup(struct wl1271 *wl) -{ - struct wl1271_partition_set partition; - int ret = 0; - - msleep(WL1271_PRE_POWER_ON_SLEEP); - wl1271_power_on(wl); - msleep(WL1271_POWER_ON_SLEEP); - wl1271_io_reset(wl); - wl1271_io_init(wl); - - /* We don't need a real memory partition here, because we only want - * to use the registers at this point. */ - memset(&partition, 0, sizeof(partition)); - partition.reg.start = REGISTERS_BASE; - partition.reg.size = REGISTERS_DOWN_SIZE; - wl1271_set_partition(wl, &partition); - - /* ELP module wake up */ - wl1271_fw_wakeup(wl); - - /* whal_FwCtrl_BootSm() */ - - /* 0. read chip id from CHIP_ID */ - wl->chip.id = wl1271_read32(wl, CHIP_ID_B); - - /* 1. check if chip id is valid */ - - switch (wl->chip.id) { - case CHIP_ID_1271_PG10: - wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", - wl->chip.id); - - ret = wl1271_setup(wl); - if (ret < 0) - goto out; - break; - case CHIP_ID_1271_PG20: - wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", - wl->chip.id); - - ret = wl1271_setup(wl); - if (ret < 0) - goto out; - break; - default: - wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); - ret = -ENODEV; - goto out; - } - - if (wl->fw == NULL) { - ret = wl1271_fetch_firmware(wl); - if (ret < 0) - goto out; - } - - /* No NVS from netlink, try to get it from the filesystem */ - if (wl->nvs == NULL) { - ret = wl1271_fetch_nvs(wl); - if (ret < 0) - goto out; - } - -out: - return ret; -} - -int wl1271_plt_start(struct wl1271 *wl) -{ - int retries = WL1271_BOOT_RETRIES; - int ret; - - mutex_lock(&wl->mutex); - - wl1271_notice("power up"); - - if (wl->state != WL1271_STATE_OFF) { - wl1271_error("cannot go into PLT state because not " - "in off state: %d", wl->state); - ret = -EBUSY; - goto out; - } - - while (retries) { - retries--; - ret = wl1271_chip_wakeup(wl); - if (ret < 0) - goto power_off; - - ret = wl1271_boot(wl); - if (ret < 0) - goto power_off; - - ret = wl1271_plt_init(wl); - if (ret < 0) - goto irq_disable; - - wl->state = WL1271_STATE_PLT; - wl1271_notice("firmware booted in PLT mode (%s)", - wl->chip.fw_ver); - goto out; - -irq_disable: - wl1271_disable_interrupts(wl); - mutex_unlock(&wl->mutex); - /* Unlocking the mutex in the middle of handling is - inherently unsafe. In this case we deem it safe to do, - because we need to let any possibly pending IRQ out of - the system (and while we are WL1271_STATE_OFF the IRQ - work function will not do anything.) Also, any other - possible concurrent operations will fail due to the - current state, hence the wl1271 struct should be safe. */ - cancel_work_sync(&wl->irq_work); - mutex_lock(&wl->mutex); -power_off: - wl1271_power_off(wl); - } - - wl1271_error("firmware boot in PLT mode failed despite %d retries", - WL1271_BOOT_RETRIES); -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -int wl1271_plt_stop(struct wl1271 *wl) -{ - int ret = 0; - - mutex_lock(&wl->mutex); - - wl1271_notice("power down"); - - if (wl->state != WL1271_STATE_PLT) { - wl1271_error("cannot power down because not in PLT " - "state: %d", wl->state); - ret = -EBUSY; - goto out; - } - - wl1271_disable_interrupts(wl); - wl1271_power_off(wl); - - wl->state = WL1271_STATE_OFF; - wl->rx_counter = 0; - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - - -static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct wl1271 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); - struct ieee80211_sta *sta = txinfo->control.sta; - unsigned long flags; - - /* peek into the rates configured in the STA entry */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) { - wl->sta_rate_set = sta->supp_rates[conf->channel->band]; - set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); - } - spin_unlock_irqrestore(&wl->wl_lock, flags); - - /* queue the packet */ - 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) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { - wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); - - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_stop_queues(wl->hw); - set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - } - - return NETDEV_TX_OK; -} - -static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, - void *arg) -{ - struct net_device *dev; - struct wireless_dev *wdev; - struct wiphy *wiphy; - struct ieee80211_hw *hw; - struct wl1271 *wl; - struct wl1271 *wl_temp; - struct in_device *idev; - struct in_ifaddr *ifa = arg; - int ret = 0; - - /* FIXME: this ugly function should probably be implemented in the - * mac80211, and here should only be a simple callback handling actual - * setting of the filters. Now we need to dig up references to - * various structures to gain access to what we need. - * Also, because of this, there is no "initial" setting of the filter - * in "op_start", because we don't want to dig up struct net_device - * there - the filter will be set upon first change of the interface - * IP address. */ - - dev = ifa->ifa_dev->dev; - - 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; - - /* Check that the interface is one supported by this driver. */ - wl_temp = hw->priv; - list_for_each_entry(wl, &wl_list, list) { - if (wl == wl_temp) - break; - } - if (wl != wl_temp) - return NOTIFY_DONE; - - /* Get the interface IP address for the device. "ifa" will become - NULL if: - - there is no IPV4 protocol address configured - - there are multiple (virtual) IPV4 addresses configured - When "ifa" is NULL, filtering will be disabled. - */ - ifa = NULL; - idev = dev->ip_ptr; - if (idev) - ifa = idev->ifa_list; - - if (ifa && ifa->ifa_next) - ifa = NULL; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1271_STATE_OFF) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - if (ifa) - ret = wl1271_acx_arp_ip_filter(wl, true, - (u8 *)&ifa->ifa_address, - ACX_IPV4_VERSION); - else - ret = wl1271_acx_arp_ip_filter(wl, false, NULL, - ACX_IPV4_VERSION); - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return NOTIFY_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"); - - /* - * We have to delay the booting of the hardware because - * we need to know the local MAC address before downloading and - * initializing the firmware. The MAC address cannot be changed - * after boot, and without the proper MAC address, the firmware - * will not function properly. - * - * The MAC address is first known when the corresponding interface - * is added. That is where we will initialize the hardware. - */ - - return 0; -} - -static void wl1271_op_stop(struct ieee80211_hw *hw) -{ - wl1271_debug(DEBUG_MAC80211, "mac80211 stop"); -} - -static int wl1271_op_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct wl1271 *wl = hw->priv; - int retries = WL1271_BOOT_RETRIES; - int ret = 0; - - wl1271_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; - wl->set_bss_type = BSS_TYPE_STA_BSS; - break; - case NL80211_IFTYPE_ADHOC: - wl->bss_type = BSS_TYPE_IBSS; - wl->set_bss_type = BSS_TYPE_STA_BSS; - break; - default: - ret = -EOPNOTSUPP; - goto out; - } - - memcpy(wl->mac_addr, vif->addr, ETH_ALEN); - - if (wl->state != WL1271_STATE_OFF) { - wl1271_error("cannot start because not in off state: %d", - wl->state); - ret = -EBUSY; - goto out; - } - - while (retries) { - retries--; - ret = wl1271_chip_wakeup(wl); - if (ret < 0) - goto power_off; - - ret = wl1271_boot(wl); - if (ret < 0) - goto power_off; - - ret = wl1271_hw_init(wl); - if (ret < 0) - goto irq_disable; - - wl->state = WL1271_STATE_ON; - wl1271_info("firmware booted (%s)", wl->chip.fw_ver); - goto out; - -irq_disable: - wl1271_disable_interrupts(wl); - mutex_unlock(&wl->mutex); - /* Unlocking the mutex in the middle of handling is - inherently unsafe. In this case we deem it safe to do, - because we need to let any possibly pending IRQ out of - the system (and while we are WL1271_STATE_OFF the IRQ - work function will not do anything.) Also, any other - possible concurrent operations will fail due to the - current state, hence the wl1271 struct should be safe. */ - cancel_work_sync(&wl->irq_work); - mutex_lock(&wl->mutex); -power_off: - wl1271_power_off(wl); - } - - wl1271_error("firmware boot failed despite %d retries", - WL1271_BOOT_RETRIES); -out: - mutex_unlock(&wl->mutex); - - if (!ret) { - list_add(&wl->list, &wl_list); - register_inetaddr_notifier(&wl1271_dev_notifier); - } - - return ret; -} - -static void wl1271_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct wl1271 *wl = hw->priv; - int i; - - unregister_inetaddr_notifier(&wl1271_dev_notifier); - - mutex_lock(&wl->mutex); - wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); - - wl1271_info("down"); - - list_del(&wl->list); - - WARN_ON(wl->state != WL1271_STATE_ON); - - if (test_and_clear_bit(WL1271_FLAG_SCANNING, &wl->flags)) { - mutex_unlock(&wl->mutex); - ieee80211_scan_completed(wl->hw, true); - mutex_lock(&wl->mutex); - } - - wl->state = WL1271_STATE_OFF; - - wl1271_disable_interrupts(wl); - - mutex_unlock(&wl->mutex); - - cancel_work_sync(&wl->irq_work); - cancel_work_sync(&wl->tx_work); - - mutex_lock(&wl->mutex); - - /* let's notify MAC80211 about the remaining pending TX frames */ - wl1271_tx_flush(wl); - wl1271_power_off(wl); - - memset(wl->bssid, 0, ETH_ALEN); - memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1); - wl->ssid_len = 0; - wl->bss_type = MAX_BSS_TYPE; - wl->set_bss_type = MAX_BSS_TYPE; - wl->band = IEEE80211_BAND_2GHZ; - - wl->rx_counter = 0; - wl->psm_entry_retry = 0; - wl->power_level = WL1271_DEFAULT_POWER_LEVEL; - wl->tx_blocks_available = 0; - wl->tx_results_count = 0; - wl->tx_packets_count = 0; - wl->tx_security_last_seq = 0; - wl->tx_security_seq = 0; - wl->time_offset = 0; - wl->session_counter = 0; - wl->rate_set = CONF_TX_RATE_MASK_BASIC; - wl->sta_rate_set = 0; - wl->flags = 0; - wl->vif = NULL; - wl->filters = 0; - - for (i = 0; i < NUM_TX_QUEUES; i++) - wl->tx_blocks_freed[i] = 0; - - wl1271_debugfs_reset(wl); - - kfree(wl->fw_status); - wl->fw_status = NULL; - kfree(wl->tx_res_if); - wl->tx_res_if = NULL; - kfree(wl->target_mem_map); - wl->target_mem_map = NULL; - - mutex_unlock(&wl->mutex); -} - -static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) -{ - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; - - /* combine requested filters with current filter config */ - filters = wl->filters | filters; - - wl1271_debug(DEBUG_FILTERS, "RX filters set: "); - - if (filters & FIF_PROMISC_IN_BSS) { - wl1271_debug(DEBUG_FILTERS, " - FIF_PROMISC_IN_BSS"); - wl->rx_config &= ~CFG_UNI_FILTER_EN; - wl->rx_config |= CFG_BSSID_FILTER_EN; - } - if (filters & FIF_BCN_PRBRESP_PROMISC) { - wl1271_debug(DEBUG_FILTERS, " - FIF_BCN_PRBRESP_PROMISC"); - wl->rx_config &= ~CFG_BSSID_FILTER_EN; - wl->rx_config &= ~CFG_SSID_FILTER_EN; - } - if (filters & FIF_OTHER_BSS) { - wl1271_debug(DEBUG_FILTERS, " - FIF_OTHER_BSS"); - wl->rx_config &= ~CFG_BSSID_FILTER_EN; - } - if (filters & FIF_CONTROL) { - wl1271_debug(DEBUG_FILTERS, " - FIF_CONTROL"); - wl->rx_filter |= CFG_RX_CTL_EN; - } - if (filters & FIF_FCSFAIL) { - wl1271_debug(DEBUG_FILTERS, " - FIF_FCSFAIL"); - wl->rx_filter |= CFG_RX_FCS_ERROR; - } -} - -static int wl1271_dummy_join(struct wl1271 *wl) -{ - int ret = 0; - /* we need to use a dummy BSSID for now */ - static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, - 0xad, 0xbe, 0xef }; - - memcpy(wl->bssid, dummy_bssid, ETH_ALEN); - - /* pass through frames from all BSS */ - wl1271_configure_filters(wl, FIF_OTHER_BSS); - - ret = wl1271_cmd_join(wl, wl->set_bss_type); - if (ret < 0) - goto out; - - set_bit(WL1271_FLAG_JOINED, &wl->flags); - -out: - return ret; -} - -static int wl1271_join(struct wl1271 *wl, bool set_assoc) -{ - int ret; - - /* - * One of the side effects of the JOIN command is that is clears - * WPA/WPA2 keys from the chipset. Performing a JOIN while associated - * to a WPA/WPA2 access point will therefore kill the data-path. - * Currently there is no supported scenario for JOIN during - * association - if it becomes a supported scenario, the WPA/WPA2 keys - * must be handled somehow. - * - */ - if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - wl1271_info("JOIN while associated."); - - if (set_assoc) - set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); - - ret = wl1271_cmd_join(wl, wl->set_bss_type); - if (ret < 0) - goto out; - - set_bit(WL1271_FLAG_JOINED, &wl->flags); - - if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - goto out; - - /* - * The join command disable the keep-alive mode, shut down its process, - * and also clear the template config, so we need to reset it all after - * the join. The acx_aid starts the keep-alive process, and the order - * of the commands below is relevant. - */ - ret = wl1271_acx_keep_alive_mode(wl, true); - if (ret < 0) - goto out; - - ret = wl1271_acx_aid(wl, wl->aid); - if (ret < 0) - goto out; - - ret = wl1271_cmd_build_klv_null_data(wl); - if (ret < 0) - goto out; - - ret = wl1271_acx_keep_alive_config(wl, CMD_TEMPL_KLV_IDX_NULL_DATA, - ACX_KEEP_ALIVE_TPL_VALID); - if (ret < 0) - goto out; - -out: - return ret; -} - -static int wl1271_unjoin(struct wl1271 *wl) -{ - int ret; - - /* to stop listening to a channel, we disconnect */ - ret = wl1271_cmd_disconnect(wl); - if (ret < 0) - goto out; - - clear_bit(WL1271_FLAG_JOINED, &wl->flags); - memset(wl->bssid, 0, ETH_ALEN); - - /* stop filterting packets based on bssid */ - wl1271_configure_filters(wl, FIF_OTHER_BSS); - -out: - return ret; -} - -static void wl1271_set_band_rate(struct wl1271 *wl) -{ - if (wl->band == IEEE80211_BAND_2GHZ) - wl->basic_rate_set = wl->conf.tx.basic_rate; - else - wl->basic_rate_set = wl->conf.tx.basic_rate_5; -} - -static u32 wl1271_min_rate_get(struct wl1271 *wl) -{ - int i; - u32 rate = 0; - - if (!wl->basic_rate_set) { - WARN_ON(1); - wl->basic_rate_set = wl->conf.tx.basic_rate; - } - - for (i = 0; !rate; i++) { - if ((wl->basic_rate_set >> i) & 0x1) - rate = 1 << i; - } - - return rate; -} - -static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) -{ - struct wl1271 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - int channel, ret = 0; - - channel = ieee80211_frequency_to_channel(conf->channel->center_freq); - - wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s", - channel, - conf->flags & IEEE80211_CONF_PS ? "on" : "off", - conf->power_level, - conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use"); - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - /* if the channel changes while joined, join again */ - if (changed & IEEE80211_CONF_CHANGE_CHANNEL && - ((wl->band != conf->channel->band) || - (wl->channel != channel))) { - wl->band = conf->channel->band; - wl->channel = channel; - - /* - * FIXME: the mac80211 should really provide a fixed rate - * to use here. for now, just use the smallest possible rate - * for the band as a fixed rate for association frames and - * other control messages. - */ - if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - wl1271_set_band_rate(wl); - - wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); - if (ret < 0) - wl1271_warning("rate policy for update channel " - "failed %d", ret); - - if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { - ret = wl1271_join(wl, false); - if (ret < 0) - wl1271_warning("cmd join to update channel " - "failed %d", ret); - } - } - - if (changed & IEEE80211_CONF_CHANGE_IDLE) { - if (conf->flags & IEEE80211_CONF_IDLE && - test_bit(WL1271_FLAG_JOINED, &wl->flags)) - wl1271_unjoin(wl); - else if (!(conf->flags & IEEE80211_CONF_IDLE)) - wl1271_dummy_join(wl); - - if (conf->flags & IEEE80211_CONF_IDLE) { - wl->rate_set = wl1271_min_rate_get(wl); - wl->sta_rate_set = 0; - wl1271_acx_rate_policies(wl); - wl1271_acx_keep_alive_config( - wl, CMD_TEMPL_KLV_IDX_NULL_DATA, - ACX_KEEP_ALIVE_TPL_INVALID); - set_bit(WL1271_FLAG_IDLE, &wl->flags); - } else - clear_bit(WL1271_FLAG_IDLE, &wl->flags); - } - - if (conf->flags & IEEE80211_CONF_PS && - !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { - set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); - - /* - * We enter PSM only if we're already associated. - * If we're not, we'll enter it when joining an SSID, - * through the bss_info_changed() hook. - */ - 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); - } - } else if (!(conf->flags & IEEE80211_CONF_PS) && - test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { - wl1271_debug(DEBUG_PSM, "psm disabled"); - - clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); - - if (test_bit(WL1271_FLAG_PSM, &wl->flags)) - ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - true); - } - - if (conf->power_level != wl->power_level) { - ret = wl1271_acx_tx_power(wl, conf->power_level); - if (ret < 0) - goto out_sleep; - - wl->power_level = conf->power_level; - } - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -struct wl1271_filter_params { - bool enabled; - int mc_list_length; - u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN]; -}; - -static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - struct wl1271_filter_params *fp; - struct netdev_hw_addr *ha; - struct wl1271 *wl = hw->priv; - - if (unlikely(wl->state == WL1271_STATE_OFF)) - return 0; - - fp = kzalloc(sizeof(*fp), GFP_ATOMIC); - if (!fp) { - wl1271_error("Out of memory setting filters."); - return 0; - } - - /* update multicast filtering parameters */ - fp->mc_list_length = 0; - if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) { - fp->enabled = false; - } else { - fp->enabled = true; - netdev_hw_addr_list_for_each(ha, mc_list) { - memcpy(fp->mc_list[fp->mc_list_length], - ha->addr, ETH_ALEN); - fp->mc_list_length++; - } - } - - return (u64)(unsigned long)fp; -} - -#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \ - FIF_ALLMULTI | \ - FIF_FCSFAIL | \ - FIF_BCN_PRBRESP_PROMISC | \ - FIF_CONTROL | \ - FIF_OTHER_BSS) - -static void wl1271_op_configure_filter(struct ieee80211_hw *hw, - unsigned int changed, - unsigned int *total, u64 multicast) -{ - struct wl1271_filter_params *fp = (void *)(unsigned long)multicast; - struct wl1271 *wl = hw->priv; - int ret; - - wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter"); - - mutex_lock(&wl->mutex); - - *total &= WL1271_SUPPORTED_FILTERS; - changed &= WL1271_SUPPORTED_FILTERS; - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - - if (*total & FIF_ALLMULTI) - ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0); - else if (fp) - ret = wl1271_acx_group_address_tbl(wl, fp->enabled, - fp->mc_list, - fp->mc_list_length); - if (ret < 0) - goto out_sleep; - - /* determine, whether supported filter values have changed */ - if (changed == 0) - goto out_sleep; - - /* configure filters */ - wl->filters = *total; - wl1271_configure_filters(wl, 0); - - /* apply configured filters */ - ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - kfree(fp); -} - -static int wl1271_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_conf) -{ - struct wl1271 *wl = hw->priv; - const u8 *addr; - int ret; - u32 tx_seq_32 = 0; - u16 tx_seq_16 = 0; - u8 key_type; - - static const u8 bcast_addr[ETH_ALEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - - wl1271_debug(DEBUG_MAC80211, "mac80211 set key"); - - addr = sta ? sta->addr : bcast_addr; - - 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->keylen, key_conf->flags); - wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); - - if (is_zero_ether_addr(addr)) { - /* We dont support TX only encryption */ - ret = -EOPNOTSUPP; - goto out; - } - - mutex_lock(&wl->mutex); - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out_unlock; - - switch (key_conf->alg) { - case ALG_WEP: - key_type = KEY_WEP; - - key_conf->hw_key_idx = key_conf->keyidx; - break; - case ALG_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: - 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; - default: - wl1271_error("Unknown key algo 0x%x", key_conf->alg); - - ret = -EOPNOTSUPP; - goto out_sleep; - } - - switch (cmd) { - case SET_KEY: - ret = wl1271_cmd_set_key(wl, KEY_ADD_OR_REPLACE, - key_conf->keyidx, key_type, - key_conf->keylen, key_conf->key, - addr, tx_seq_32, tx_seq_16); - if (ret < 0) { - wl1271_error("Could not add or replace key"); - goto out_sleep; - } - - /* the default WEP key needs to be configured at least once */ - if (key_type == KEY_WEP) { - ret = wl1271_cmd_set_default_wep_key(wl, - wl->default_key); - if (ret < 0) - goto out_sleep; - } - break; - - case DISABLE_KEY: - /* The wl1271 does not allow to remove unicast keys - they - will be cleared automatically on next CMD_JOIN. Ignore the - request silently, as we dont want the mac80211 to emit - an error message. */ - if (!is_broadcast_ether_addr(addr)) - break; - - ret = wl1271_cmd_set_key(wl, KEY_REMOVE, - key_conf->keyidx, key_type, - key_conf->keylen, key_conf->key, - addr, 0, 0); - if (ret < 0) { - wl1271_error("Could not remove key"); - goto out_sleep; - } - break; - - default: - wl1271_error("Unsupported key cmd 0x%x", cmd); - ret = -EOPNOTSUPP; - break; - } - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out_unlock: - mutex_unlock(&wl->mutex); - -out: - return ret; -} - -static int wl1271_op_hw_scan(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_scan_request *req) -{ - struct wl1271 *wl = hw->priv; - int ret; - u8 *ssid = NULL; - size_t len = 0; - - wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan"); - - if (req->n_ssids) { - ssid = req->ssids[0].ssid; - len = req->ssids[0].ssid_len; - } - - mutex_lock(&wl->mutex); - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - if (wl1271_11a_enabled()) - ret = wl1271_cmd_scan(hw->priv, ssid, len, - req->ie, req->ie_len, 1, 0, - WL1271_SCAN_BAND_DUAL, 3); - else - ret = wl1271_cmd_scan(hw->priv, ssid, len, - req->ie, req->ie_len, 1, 0, - WL1271_SCAN_BAND_2_4_GHZ, 3); - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -{ - struct wl1271 *wl = hw->priv; - int ret = 0; - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - ret = wl1271_acx_rts_threshold(wl, (u16) value); - if (ret < 0) - wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret); - - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon) -{ - u8 *ptr = beacon->data + - offsetof(struct ieee80211_mgmt, u.beacon.variable); - - /* find the location of the ssid in the beacon */ - while (ptr < beacon->data + beacon->len) { - if (ptr[0] == WLAN_EID_SSID) { - wl->ssid_len = ptr[1]; - memcpy(wl->ssid, ptr+2, wl->ssid_len); - return; - } - ptr += ptr[1]; - } - wl1271_error("ad-hoc beacon template has no SSID!\n"); -} - -static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changed) -{ - enum wl1271_cmd_ps_mode mode; - struct wl1271 *wl = hw->priv; - bool do_join = false; - bool set_assoc = false; - int ret; - - wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); - - mutex_lock(&wl->mutex); - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - 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); - - wl->beacon_int = bss_conf->beacon_int; - do_join = true; - } - - if ((changed && BSS_CHANGED_BEACON) && - (wl->bss_type == BSS_TYPE_IBSS)) { - struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); - - wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon updated"); - - if (beacon) { - struct ieee80211_hdr *hdr; - - wl1271_ssid_set(wl, beacon); - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, - beacon->data, - beacon->len, 0, - wl1271_min_rate_get(wl)); - - if (ret < 0) { - dev_kfree_skb(beacon); - goto out_sleep; - } - - hdr = (struct ieee80211_hdr *) beacon->data; - hdr->frame_control = cpu_to_le16( - IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_PROBE_RESP); - - ret = wl1271_cmd_template_set(wl, - CMD_TEMPL_PROBE_RESPONSE, - beacon->data, - beacon->len, 0, - wl1271_min_rate_get(wl)); - dev_kfree_skb(beacon); - if (ret < 0) - goto out_sleep; - - /* Need to update the SSID (for filtering etc) */ - do_join = true; - } - } - - if ((changed & BSS_CHANGED_BEACON_ENABLED) && - (wl->bss_type == BSS_TYPE_IBSS)) { - wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s", - bss_conf->enable_beacon ? "enabled" : "disabled"); - - if (bss_conf->enable_beacon) - wl->set_bss_type = BSS_TYPE_IBSS; - else - wl->set_bss_type = BSS_TYPE_STA_BSS; - do_join = true; - } - - if (changed & BSS_CHANGED_CQM) { - bool enable = false; - if (bss_conf->cqm_rssi_thold) - enable = true; - ret = wl1271_acx_rssi_snr_trigger(wl, enable, - bss_conf->cqm_rssi_thold, - bss_conf->cqm_rssi_hyst); - if (ret < 0) - goto out; - wl->rssi_thold = bss_conf->cqm_rssi_thold; - } - - if ((changed & BSS_CHANGED_BSSID) && - /* - * Now we know the correct bssid, so we send a new join command - * and enable the BSSID filter - */ - memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { - memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); - - ret = wl1271_cmd_build_null_data(wl); - if (ret < 0) - goto out_sleep; - - ret = wl1271_build_qos_null_data(wl); - if (ret < 0) - goto out_sleep; - - /* filter out all packets not from this BSSID */ - wl1271_configure_filters(wl, 0); - - /* Need to update the BSSID (for filtering etc) */ - do_join = true; - } - - if (changed & BSS_CHANGED_ASSOC) { - if (bss_conf->assoc) { - u32 rates; - wl->aid = bss_conf->aid; - set_assoc = true; - - /* - * use basic rates from AP, and determine lowest rate - * to use with control frames. - */ - rates = bss_conf->basic_rates; - wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, - rates); - wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); - if (ret < 0) - goto out_sleep; - - /* - * with wl1271, we don't need to update the - * beacon_int and dtim_period, because the firmware - * updates it by itself when the first beacon is - * received after a join. - */ - ret = wl1271_cmd_build_ps_poll(wl, wl->aid); - if (ret < 0) - goto out_sleep; - - /* - * The SSID is intentionally set to NULL here - the - * firmware will set the probe request with a - * broadcast SSID regardless of what we set in the - * template. - */ - ret = wl1271_cmd_build_probe_req(wl, NULL, 0, - NULL, 0, wl->band); - - /* enable the connection monitoring feature */ - ret = wl1271_acx_conn_monit_params(wl, true); - if (ret < 0) - goto out_sleep; - - /* If we want to go in PSM but we're not there yet */ - 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); - if (ret < 0) - goto out_sleep; - } - } else { - /* use defaults when not associated */ - clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); - wl->aid = 0; - - /* revert back to minimum rates for the current band */ - wl1271_set_band_rate(wl); - wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); - if (ret < 0) - goto out_sleep; - - /* disable connection monitor features */ - ret = wl1271_acx_conn_monit_params(wl, false); - - /* Disable the keep-alive feature */ - ret = wl1271_acx_keep_alive_mode(wl, false); - - if (ret < 0) - goto out_sleep; - } - - } - - if (changed & BSS_CHANGED_ERP_SLOT) { - if (bss_conf->use_short_slot) - ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT); - else - ret = wl1271_acx_slot(wl, SLOT_TIME_LONG); - if (ret < 0) { - wl1271_warning("Set slot time failed %d", ret); - goto out_sleep; - } - } - - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - if (bss_conf->use_short_preamble) - wl1271_acx_set_preamble(wl, ACX_PREAMBLE_SHORT); - else - wl1271_acx_set_preamble(wl, ACX_PREAMBLE_LONG); - } - - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - if (bss_conf->use_cts_prot) - ret = wl1271_acx_cts_protect(wl, CTSPROTECT_ENABLE); - else - ret = wl1271_acx_cts_protect(wl, CTSPROTECT_DISABLE); - if (ret < 0) { - wl1271_warning("Set ctsprotect failed %d", ret); - goto out_sleep; - } - } - - if (do_join) { - ret = wl1271_join(wl, set_assoc); - if (ret < 0) { - wl1271_warning("cmd join failed %d", ret); - goto out_sleep; - } - } - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); -} - -static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct wl1271 *wl = hw->priv; - u8 ps_scheme; - int ret; - - mutex_lock(&wl->mutex); - - wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - /* the txop is confed in units of 32us by the mac80211, we need us */ - ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), - params->cw_min, params->cw_max, - params->aifs, params->txop << 5); - if (ret < 0) - goto out_sleep; - - if (params->uapsd) - ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER; - else - ps_scheme = CONF_PS_SCHEME_LEGACY; - - ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), - CONF_CHANNEL_TYPE_EDCF, - wl1271_tx_get_queue(queue), - ps_scheme, CONF_ACK_POLICY_LEGACY, 0, 0); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1271_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - - -/* can't be const, mac80211 writes to this */ -static struct ieee80211_rate wl1271_rates[] = { - { .bitrate = 10, - .hw_value = CONF_HW_BIT_RATE_1MBPS, - .hw_value_short = CONF_HW_BIT_RATE_1MBPS, }, - { .bitrate = 20, - .hw_value = CONF_HW_BIT_RATE_2MBPS, - .hw_value_short = CONF_HW_BIT_RATE_2MBPS, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 55, - .hw_value = CONF_HW_BIT_RATE_5_5MBPS, - .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 110, - .hw_value = CONF_HW_BIT_RATE_11MBPS, - .hw_value_short = CONF_HW_BIT_RATE_11MBPS, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 60, - .hw_value = CONF_HW_BIT_RATE_6MBPS, - .hw_value_short = CONF_HW_BIT_RATE_6MBPS, }, - { .bitrate = 90, - .hw_value = CONF_HW_BIT_RATE_9MBPS, - .hw_value_short = CONF_HW_BIT_RATE_9MBPS, }, - { .bitrate = 120, - .hw_value = CONF_HW_BIT_RATE_12MBPS, - .hw_value_short = CONF_HW_BIT_RATE_12MBPS, }, - { .bitrate = 180, - .hw_value = CONF_HW_BIT_RATE_18MBPS, - .hw_value_short = CONF_HW_BIT_RATE_18MBPS, }, - { .bitrate = 240, - .hw_value = CONF_HW_BIT_RATE_24MBPS, - .hw_value_short = CONF_HW_BIT_RATE_24MBPS, }, - { .bitrate = 360, - .hw_value = CONF_HW_BIT_RATE_36MBPS, - .hw_value_short = CONF_HW_BIT_RATE_36MBPS, }, - { .bitrate = 480, - .hw_value = CONF_HW_BIT_RATE_48MBPS, - .hw_value_short = CONF_HW_BIT_RATE_48MBPS, }, - { .bitrate = 540, - .hw_value = CONF_HW_BIT_RATE_54MBPS, - .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, -}; - -/* can't be const, mac80211 writes to this */ -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 }, -}; - -/* mapping to indexes for wl1271_rates */ -const static u8 wl1271_rate_to_idx_2ghz[] = { - /* MCS rates are used only with 11n */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */ - - 11, /* CONF_HW_RXTX_RATE_54 */ - 10, /* CONF_HW_RXTX_RATE_48 */ - 9, /* CONF_HW_RXTX_RATE_36 */ - 8, /* CONF_HW_RXTX_RATE_24 */ - - /* TI-specific rate */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */ - - 7, /* CONF_HW_RXTX_RATE_18 */ - 6, /* CONF_HW_RXTX_RATE_12 */ - 3, /* CONF_HW_RXTX_RATE_11 */ - 5, /* CONF_HW_RXTX_RATE_9 */ - 4, /* CONF_HW_RXTX_RATE_6 */ - 2, /* CONF_HW_RXTX_RATE_5_5 */ - 1, /* CONF_HW_RXTX_RATE_2 */ - 0 /* CONF_HW_RXTX_RATE_1 */ -}; - -/* can't be const, mac80211 writes to this */ -static struct ieee80211_supported_band wl1271_band_2ghz = { - .channels = wl1271_channels, - .n_channels = ARRAY_SIZE(wl1271_channels), - .bitrates = wl1271_rates, - .n_bitrates = ARRAY_SIZE(wl1271_rates), -}; - -/* 5 GHz data rates for WL1273 */ -static struct ieee80211_rate wl1271_rates_5ghz[] = { - { .bitrate = 60, - .hw_value = CONF_HW_BIT_RATE_6MBPS, - .hw_value_short = CONF_HW_BIT_RATE_6MBPS, }, - { .bitrate = 90, - .hw_value = CONF_HW_BIT_RATE_9MBPS, - .hw_value_short = CONF_HW_BIT_RATE_9MBPS, }, - { .bitrate = 120, - .hw_value = CONF_HW_BIT_RATE_12MBPS, - .hw_value_short = CONF_HW_BIT_RATE_12MBPS, }, - { .bitrate = 180, - .hw_value = CONF_HW_BIT_RATE_18MBPS, - .hw_value_short = CONF_HW_BIT_RATE_18MBPS, }, - { .bitrate = 240, - .hw_value = CONF_HW_BIT_RATE_24MBPS, - .hw_value_short = CONF_HW_BIT_RATE_24MBPS, }, - { .bitrate = 360, - .hw_value = CONF_HW_BIT_RATE_36MBPS, - .hw_value_short = CONF_HW_BIT_RATE_36MBPS, }, - { .bitrate = 480, - .hw_value = CONF_HW_BIT_RATE_48MBPS, - .hw_value_short = CONF_HW_BIT_RATE_48MBPS, }, - { .bitrate = 540, - .hw_value = CONF_HW_BIT_RATE_54MBPS, - .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, -}; - -/* 5 GHz band channels for WL1273 */ -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 = 136, .center_freq = 5680}, - { .hw_value = 140, .center_freq = 5700}, - { .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 = 165, .center_freq = 5825}, -}; - -/* mapping to indexes for wl1271_rates_5ghz */ -const static u8 wl1271_rate_to_idx_5ghz[] = { - /* MCS rates are used only with 11n */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */ - - 7, /* CONF_HW_RXTX_RATE_54 */ - 6, /* CONF_HW_RXTX_RATE_48 */ - 5, /* CONF_HW_RXTX_RATE_36 */ - 4, /* CONF_HW_RXTX_RATE_24 */ - - /* TI-specific rate */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */ - - 3, /* CONF_HW_RXTX_RATE_18 */ - 2, /* CONF_HW_RXTX_RATE_12 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */ - 1, /* CONF_HW_RXTX_RATE_9 */ - 0, /* CONF_HW_RXTX_RATE_6 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */ - CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */ - CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */ -}; - -static struct ieee80211_supported_band wl1271_band_5ghz = { - .channels = wl1271_channels_5ghz, - .n_channels = ARRAY_SIZE(wl1271_channels_5ghz), - .bitrates = wl1271_rates_5ghz, - .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), -}; - -const static u8 *wl1271_band_rate_to_idx[] = { - [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz, - [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz -}; - -static const struct ieee80211_ops wl1271_ops = { - .start = wl1271_op_start, - .stop = wl1271_op_stop, - .add_interface = wl1271_op_add_interface, - .remove_interface = wl1271_op_remove_interface, - .config = wl1271_op_config, - .prepare_multicast = wl1271_op_prepare_multicast, - .configure_filter = wl1271_op_configure_filter, - .tx = wl1271_op_tx, - .set_key = wl1271_op_set_key, - .hw_scan = wl1271_op_hw_scan, - .bss_info_changed = wl1271_op_bss_info_changed, - .set_rts_threshold = wl1271_op_set_rts_threshold, - .conf_tx = wl1271_op_conf_tx, - CFG80211_TESTMODE_CMD(wl1271_tm_cmd) -}; - - -u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate) -{ - u8 idx; - - BUG_ON(wl->band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *)); - - if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) { - wl1271_error("Illegal RX rate from HW: %d", rate); - return 0; - } - - idx = wl1271_band_rate_to_idx[wl->band][rate]; - if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) { - wl1271_error("Unsupported RX rate from HW: %d", rate); - return 0; - } - - return idx; -} - -static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct wl1271 *wl = dev_get_drvdata(dev); - ssize_t len; - - /* FIXME: what's the maximum length of buf? page size?*/ - len = 500; - - mutex_lock(&wl->mutex); - len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n", - wl->sg_enabled); - mutex_unlock(&wl->mutex); - - return len; - -} - -static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct wl1271 *wl = dev_get_drvdata(dev); - unsigned long res; - int ret; - - ret = strict_strtoul(buf, 10, &res); - - if (ret < 0) { - wl1271_warning("incorrect value written to bt_coex_mode"); - return count; - } - - mutex_lock(&wl->mutex); - - res = !!res; - - if (res == wl->sg_enabled) - goto out; - - wl->sg_enabled = res; - - if (wl->state == WL1271_STATE_OFF) - goto out; - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - wl1271_acx_sg_enable(wl, wl->sg_enabled); - wl1271_ps_elp_sleep(wl); - - out: - mutex_unlock(&wl->mutex); - return count; -} - -static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR, - wl1271_sysfs_show_bt_coex_state, - wl1271_sysfs_store_bt_coex_state); - -static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct wl1271 *wl = dev_get_drvdata(dev); - ssize_t len; - - /* FIXME: what's the maximum length of buf? page size?*/ - len = 500; - - mutex_lock(&wl->mutex); - if (wl->hw_pg_ver >= 0) - len = snprintf(buf, len, "%d\n", wl->hw_pg_ver); - else - len = snprintf(buf, len, "n/a\n"); - mutex_unlock(&wl->mutex); - - return len; -} - -static DEVICE_ATTR(hw_pg_ver, S_IRUGO | S_IWUSR, - wl1271_sysfs_show_hw_pg_ver, NULL); - -int wl1271_register_hw(struct wl1271 *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) { - wl1271_error("unable to register mac80211 hw: %d", ret); - return ret; - } - - wl->mac80211_registered = true; - - wl1271_notice("loaded"); - - return 0; -} -EXPORT_SYMBOL_GPL(wl1271_register_hw); - -void wl1271_unregister_hw(struct wl1271 *wl) -{ - ieee80211_unregister_hw(wl->hw); - wl->mac80211_registered = false; - -} -EXPORT_SYMBOL_GPL(wl1271_unregister_hw); - -int wl1271_init_ieee80211(struct wl1271 *wl) -{ - /* The tx descriptor buffer and the TKIP space. */ - wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + - sizeof(struct wl1271_tx_hw_descr); - - /* unit us */ - /* FIXME: find a proper value */ - wl->hw->channel_change_time = 10000; - wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; - - wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_BEACON_FILTER | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_UAPSD | - IEEE80211_HW_HAS_RATE_CONTROL | - IEEE80211_HW_CONNECTION_MONITOR | - IEEE80211_HW_SUPPORTS_CQM_RSSI; - - 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->queues = 4; - wl->hw->max_rates = 1; - - SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); - - return 0; -} -EXPORT_SYMBOL_GPL(wl1271_init_ieee80211); - -#define WL1271_DEFAULT_CHANNEL 0 - -struct ieee80211_hw *wl1271_alloc_hw(void) -{ - struct ieee80211_hw *hw; - struct platform_device *plat_dev = NULL; - struct wl1271 *wl; - int i, ret; - - hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); - if (!hw) { - wl1271_error("could not alloc ieee80211_hw"); - ret = -ENOMEM; - goto err_hw_alloc; - } - - plat_dev = kmalloc(sizeof(wl1271_device), GFP_KERNEL); - if (!plat_dev) { - wl1271_error("could not allocate platform_device"); - ret = -ENOMEM; - goto err_plat_alloc; - } - - memcpy(plat_dev, &wl1271_device, sizeof(wl1271_device)); - - wl = hw->priv; - memset(wl, 0, sizeof(*wl)); - - INIT_LIST_HEAD(&wl->list); - - wl->hw = hw; - wl->plat_dev = plat_dev; - - skb_queue_head_init(&wl->tx_queue); - - INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); - wl->channel = WL1271_DEFAULT_CHANNEL; - wl->beacon_int = WL1271_DEFAULT_BEACON_INT; - wl->default_key = 0; - wl->rx_counter = 0; - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; - wl->psm_entry_retry = 0; - wl->power_level = WL1271_DEFAULT_POWER_LEVEL; - wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; - wl->basic_rate = CONF_TX_RATE_MASK_BASIC; - wl->rate_set = CONF_TX_RATE_MASK_BASIC; - wl->sta_rate_set = 0; - wl->band = IEEE80211_BAND_2GHZ; - wl->vif = NULL; - wl->flags = 0; - wl->sg_enabled = true; - wl->hw_pg_ver = -1; - - for (i = 0; i < ACX_TX_DESCRIPTORS; i++) - wl->tx_frames[i] = NULL; - - spin_lock_init(&wl->wl_lock); - - wl->state = WL1271_STATE_OFF; - mutex_init(&wl->mutex); - - /* Apply default driver configuration. */ - wl1271_conf_init(wl); - - wl1271_debugfs_init(wl); - - /* Register platform device */ - ret = platform_device_register(wl->plat_dev); - if (ret) { - wl1271_error("couldn't register platform device"); - goto err_hw; - } - dev_set_drvdata(&wl->plat_dev->dev, wl); - - /* Create sysfs file to control bt coex state */ - ret = device_create_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state); - if (ret < 0) { - wl1271_error("failed to create sysfs file bt_coex_state"); - goto err_platform; - } - - /* Create sysfs file to get HW PG version */ - ret = device_create_file(&wl->plat_dev->dev, &dev_attr_hw_pg_ver); - if (ret < 0) { - wl1271_error("failed to create sysfs file hw_pg_ver"); - goto err_bt_coex_state; - } - - return hw; - -err_bt_coex_state: - device_remove_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state); - -err_platform: - platform_device_unregister(wl->plat_dev); - -err_hw: - wl1271_debugfs_exit(wl); - kfree(plat_dev); - -err_plat_alloc: - ieee80211_free_hw(hw); - -err_hw_alloc: - - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(wl1271_alloc_hw); - -int wl1271_free_hw(struct wl1271 *wl) -{ - platform_device_unregister(wl->plat_dev); - kfree(wl->plat_dev); - - wl1271_debugfs_exit(wl); - - vfree(wl->fw); - wl->fw = NULL; - kfree(wl->nvs); - wl->nvs = NULL; - - kfree(wl->fw_status); - kfree(wl->tx_res_if); - - ieee80211_free_hw(wl->hw); - - return 0; -} -EXPORT_SYMBOL_GPL(wl1271_free_hw); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); -MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c deleted file mode 100644 index a5e60e0403e..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_reg.h" -#include "wl1271_ps.h" -#include "wl1271_io.h" - -#define WL1271_WAKEUP_TIMEOUT 500 - -void wl1271_elp_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, elp_work); - - wl1271_debug(DEBUG_PSM, "elp work"); - - mutex_lock(&wl->mutex); - - if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || - (!test_bit(WL1271_FLAG_PSM, &wl->flags) && - !test_bit(WL1271_FLAG_IDLE, &wl->flags))) - goto out; - - wl1271_debug(DEBUG_PSM, "chip to elp"); - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); - set_bit(WL1271_FLAG_IN_ELP, &wl->flags); - -out: - mutex_unlock(&wl->mutex); -} - -#define ELP_ENTRY_DELAY 5 - -/* Routines to toggle sleep mode while in ELP */ -void wl1271_ps_elp_sleep(struct wl1271 *wl) -{ - if (test_bit(WL1271_FLAG_PSM, &wl->flags) || - 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)); - } -} - -int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) -{ - DECLARE_COMPLETION_ONSTACK(compl); - unsigned long flags; - int ret; - u32 start_time = jiffies; - bool pending = false; - - if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags)) - return 0; - - wl1271_debug(DEBUG_PSM, "waking up chip from elp"); - - /* - * The spinlock is required here to synchronize both the work and - * the completion variable in one entity. - */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (work_pending(&wl->irq_work) || chip_awake) - pending = true; - else - wl->elp_compl = &compl; - spin_unlock_irqrestore(&wl->wl_lock, flags); - - wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); - - if (!pending) { - ret = wait_for_completion_timeout( - &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT)); - if (ret == 0) { - wl1271_error("ELP wakeup timeout!"); - ret = -ETIMEDOUT; - goto err; - } else if (ret < 0) { - wl1271_error("ELP wakeup completion error."); - goto err; - } - } - - clear_bit(WL1271_FLAG_IN_ELP, &wl->flags); - - wl1271_debug(DEBUG_PSM, "wakeup time: %u ms", - jiffies_to_msecs(jiffies - start_time)); - goto out; - -err: - spin_lock_irqsave(&wl->wl_lock, flags); - wl->elp_compl = NULL; - spin_unlock_irqrestore(&wl->wl_lock, flags); - return ret; - -out: - return 0; -} - -int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, - bool send) -{ - int ret; - - switch (mode) { - case STATION_POWER_SAVE_MODE: - wl1271_debug(DEBUG_PSM, "entering psm"); - - ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send); - if (ret < 0) - return ret; - - set_bit(WL1271_FLAG_PSM, &wl->flags); - break; - case STATION_ACTIVE_MODE: - default: - wl1271_debug(DEBUG_PSM, "leaving psm"); - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - return ret; - - /* disable beacon early termination */ - ret = wl1271_acx_bet_enable(wl, false); - if (ret < 0) - return ret; - - /* disable beacon filtering */ - ret = wl1271_acx_beacon_filter_opt(wl, false); - if (ret < 0) - return ret; - - ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send); - if (ret < 0) - return ret; - - clear_bit(WL1271_FLAG_PSM, &wl->flags); - break; - } - - return ret; -} - - diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h deleted file mode 100644 index 940276f517a..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_ps.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_PS_H__ -#define __WL1271_PS_H__ - -#include "wl1271.h" -#include "wl1271_acx.h" - -int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, - 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); - -#endif /* __WL1271_PS_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/wl1271_reg.h deleted file mode 100644 index 99096077152..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_reg.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * This file is part of wl12xx - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 -#define FW_STATUS_ADDR (0x14FC0 + 0xA000) - -/* 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 - -/*=============================================== - 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. -===============================================*/ -#define ACX_REG_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000) - -#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008) -#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c) -#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018) - -#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474) -#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478) - -/*============================================= - 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 -*==============================================*/ -#define ACX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC) - -/*============================================= - 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). -==============================================*/ -#define ACX_REG_HINT_MASK_SET (REGISTERS_BASE + 0x04E0) - -/*============================================= - 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). -=============================================*/ -#define ACX_REG_HINT_MASK_CLR (REGISTERS_BASE + 0x04E4) - -/*============================================= - 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. -=============================================*/ -#define ACX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8) - -/*============================================= - 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. -==============================================*/ -#define ACX_REG_INTERRUPT_CLEAR (REGISTERS_BASE + 0x04F8) - -/*============================================= - 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) -==============================================*/ -#define ACX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0) - -#define RX_DRIVER_COUNTER_ADDRESS (REGISTERS_BASE + 0x0538) - -/* Device Configuration registers*/ -#define SOR_CFG (REGISTERS_BASE + 0x0800) - -/* 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 - ===============================================*/ -#define ACX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804) - -#define HI_CFG (REGISTERS_BASE + 0x0808) - -/*=============================================== - 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 -*================================================*/ -#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C) - -#define OCP_POR_CTR (REGISTERS_BASE + 0x09B4) -#define OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8) -#define OCP_DATA_READ (REGISTERS_BASE + 0x09BC) -#define OCP_CMD (REGISTERS_BASE + 0x09C0) - -#define WL1271_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8) - -#define CHIP_ID_B (REGISTERS_BASE + 0x5674) - -#define CHIP_ID_1271_PG10 (0x4030101) -#define CHIP_ID_1271_PG20 (0x4030111) - -#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) - -#define PLL_PARAMETERS (REGISTERS_BASE + 0x6040) -#define WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008) -#define WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100) -#define DRPW_SCRATCH_START (DRPW_BASE + 0x002C) - - -#define ACX_SLV_SOFT_RESET_BIT BIT(1) -#define ACX_REG_EEPROM_START_BIT BIT(1) - -/* 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 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 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 ACX_EE_DATA_REG EE_DATA - -/*=============================================== - 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 -}; - -#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/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c deleted file mode 100644 index b98fb643fab..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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/gfp.h> - -#include "wl1271.h" -#include "wl1271_acx.h" -#include "wl1271_reg.h" -#include "wl1271_rx.h" -#include "wl1271_io.h" - -static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, - u32 drv_rx_counter) -{ - return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & - RX_MEM_BLOCK_MASK; -} - -static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status, - u32 drv_rx_counter) -{ - return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & - RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; -} - -static void wl1271_rx_status(struct wl1271 *wl, - struct wl1271_rx_descriptor *desc, - struct ieee80211_rx_status *status, - u8 beacon) -{ - memset(status, 0, sizeof(struct ieee80211_rx_status)); - - status->band = wl->band; - status->rate_idx = wl1271_rate_to_idx(wl, desc->rate); - - /* - * FIXME: Add mactime handling. For IBSS (ad-hoc) we need to get the - * timestamp from the beacon (acx_tsf_info). In BSS mode (infra) we - * only need the mactime for monitor mode. For now the mactime is - * not valid, so RX_FLAG_TSFT should not be set - */ - status->signal = desc->rssi; - - status->freq = ieee80211_channel_to_frequency(desc->channel); - - if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { - status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; - - if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL))) - status->flag |= RX_FLAG_DECRYPTED; - if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL)) - status->flag |= RX_FLAG_MMIC_ERROR; - } -} - -static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) -{ - struct ieee80211_rx_status rx_status; - struct wl1271_rx_descriptor *desc; - struct sk_buff *skb; - u16 *fc; - u8 *buf; - u8 beacon = 0; - - /* - * In PLT mode we seem to get frames and mac80211 warns about them, - * workaround this by not retrieving them at all. - */ - if (unlikely(wl->state == WL1271_STATE_PLT)) - return; - - skb = __dev_alloc_skb(length, GFP_KERNEL); - if (!skb) { - wl1271_error("Couldn't allocate RX frame"); - return; - } - - buf = skb_put(skb, length); - wl1271_read(wl, WL1271_SLV_MEM_DATA, buf, length, true); - - /* the data read starts with the descriptor */ - desc = (struct wl1271_rx_descriptor *) buf; - - /* now we pull the descriptor out of the buffer */ - skb_pull(skb, sizeof(*desc)); - - fc = (u16 *)skb->data; - if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) - beacon = 1; - - wl1271_rx_status(wl, desc, &rx_status, 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); -} - -void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) -{ - struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; - 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 mem_block; - - 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); - - if (buf_size == 0) { - wl1271_warning("received empty data"); - break; - } - - 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; - } - - wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); -} diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h deleted file mode 100644 index b89be4758e7..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_rx.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_RX_H__ -#define __WL1271_RX_H__ - -#include <linux/bitops.h> - -#define WL1271_RX_MAX_RSSI -30 -#define WL1271_RX_MIN_RSSI -95 - -#define WL1271_RX_ALIGN_TO 4 -#define WL1271_RX_ALIGN(len) (((len) + WL1271_RX_ALIGN_TO - 1) & \ - ~(WL1271_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 NUM_RX_PKT_DESC_MOD_MASK 7 - -#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 - -/* - * RX Descriptor flags: - * - * Bits 0-1 - band - * Bit 2 - STBC - * Bit 3 - A-MPDU - * Bit 4 - HT - * Bits 5-7 - encryption - */ -#define WL1271_RX_DESC_BAND_MASK 0x03 -#define WL1271_RX_DESC_ENCRYPT_MASK 0xE0 - -#define WL1271_RX_DESC_BAND_BG 0x00 -#define WL1271_RX_DESC_BAND_J 0x01 -#define WL1271_RX_DESC_BAND_A 0x02 - -#define WL1271_RX_DESC_STBC BIT(2) -#define WL1271_RX_DESC_A_MPDU BIT(3) -#define WL1271_RX_DESC_HT BIT(4) - -#define WL1271_RX_DESC_ENCRYPT_WEP 0x20 -#define WL1271_RX_DESC_ENCRYPT_TKIP 0x40 -#define WL1271_RX_DESC_ENCRYPT_AES 0x60 -#define WL1271_RX_DESC_ENCRYPT_GEM 0x80 - -/* - * RX Descriptor status - * - * Bits 0-2 - status - * Bits 3-7 - reserved - */ -#define WL1271_RX_DESC_STATUS_MASK 0x07 - -#define WL1271_RX_DESC_SUCCESS 0x00 -#define WL1271_RX_DESC_DECRYPT_FAIL 0x01 -#define WL1271_RX_DESC_MIC_FAIL 0x02 -#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03 - -#define RX_MEM_BLOCK_MASK 0xFF -#define RX_BUF_SIZE_MASK 0xFFF00 -#define RX_BUF_SIZE_SHIFT_DIV 6 - -struct wl1271_rx_descriptor { - __le16 length; - u8 status; - u8 flags; - u8 rate; - u8 channel; - s8 rssi; - u8 snr; - __le32 timestamp; - u8 packet_class; - u8 process_id; - u8 pad_len; - u8 reserved; -} __attribute__ ((packed)); - -void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); -u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c deleted file mode 100644 index d3d6f302f70..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009-2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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/crc7.h> -#include <linux/vmalloc.h> -#include <linux/mmc/sdio_func.h> -#include <linux/mmc/sdio_ids.h> -#include <linux/mmc/card.h> -#include <plat/gpio.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 - -#ifndef SDIO_DEVICE_ID_TI_WL1271 -#define SDIO_DEVICE_ID_TI_WL1271 0x4076 -#endif - -static const struct sdio_device_id wl1271_devices[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, - {} -}; -MODULE_DEVICE_TABLE(sdio, wl1271_devices); - -static inline struct sdio_func *wl_to_func(struct wl1271 *wl) -{ - return wl->if_priv; -} - -static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) -{ - return &(wl_to_func(wl)->dev); -} - -static irqreturn_t wl1271_irq(int irq, void *cookie) -{ - struct wl1271 *wl = cookie; - unsigned long flags; - - wl1271_debug(DEBUG_IRQ, "IRQ"); - - /* complete the ELP completion */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (wl->elp_compl) { - complete(wl->elp_compl); - wl->elp_compl = NULL; - } - - if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - - return IRQ_HANDLED; -} - -static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) -{ - disable_irq(wl->irq); -} - -static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) -{ - enable_irq(wl->irq); -} - -static void wl1271_sdio_reset(struct wl1271 *wl) -{ -} - -static void wl1271_sdio_init(struct wl1271 *wl) -{ -} - -static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int ret; - struct sdio_func *func = wl_to_func(wl); - - 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", - addr, ((u8 *)buf)[0]); - } else { - if (fixed) - ret = sdio_readsb(func, buf, addr, len); - else - ret = sdio_memcpy_fromio(func, buf, addr, len); - - wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes", - addr, len); - wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); - } - - if (ret) - wl1271_error("sdio read failed (%d)", ret); - -} - -static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, - size_t len, bool fixed) -{ - int ret; - struct sdio_func *func = wl_to_func(wl); - - 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", - addr, ((u8 *)buf)[0]); - } else { - wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes", - addr, len); - wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); - - if (fixed) - ret = sdio_writesb(func, addr, buf, len); - else - ret = sdio_memcpy_toio(func, addr, buf, len); - } - if (ret) - wl1271_error("sdio write failed (%d)", ret); - -} - -static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) -{ - 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); - } -} - -static struct wl1271_if_operations sdio_ops = { - .read = wl1271_sdio_raw_read, - .write = wl1271_sdio_raw_write, - .reset = wl1271_sdio_reset, - .init = wl1271_sdio_init, - .power = wl1271_sdio_set_power, - .dev = wl1271_sdio_wl_to_dev, - .enable_irq = wl1271_sdio_enable_interrupts, - .disable_irq = wl1271_sdio_disable_interrupts -}; - -static int __devinit wl1271_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - struct ieee80211_hw *hw; - struct wl1271 *wl; - int ret; - - /* We are only able to handle the wlan function */ - if (func->num != 0x02) - return -ENODEV; - - hw = wl1271_alloc_hw(); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - wl = hw->priv; - - wl->if_priv = func; - wl->if_ops = &sdio_ops; - - /* 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!"); - goto out_free; - } - - ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); - if (ret < 0) { - wl1271_error("request_irq() failed: %d", ret); - goto out_free; - } - - set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - - disable_irq(wl->irq); - - ret = wl1271_init_ieee80211(wl); - if (ret) - goto out_irq; - - ret = wl1271_register_hw(wl); - if (ret) - goto out_irq; - - sdio_set_drvdata(func, wl); - - wl1271_notice("initialized"); - - return 0; - - out_irq: - free_irq(wl->irq, wl); - - - out_free: - wl1271_free_hw(wl); - - return ret; -} - -static void __devexit wl1271_remove(struct sdio_func *func) -{ - struct wl1271 *wl = sdio_get_drvdata(func); - - free_irq(wl->irq, wl); - - wl1271_unregister_hw(wl); - wl1271_free_hw(wl); -} - -static struct sdio_driver wl1271_sdio_driver = { - .name = "wl1271_sdio", - .id_table = wl1271_devices, - .probe = wl1271_probe, - .remove = __devexit_p(wl1271_remove), -}; - -static int __init wl1271_init(void) -{ - int ret; - - ret = sdio_register_driver(&wl1271_sdio_driver); - if (ret < 0) { - wl1271_error("failed to register sdio driver: %d", ret); - goto out; - } - -out: - return ret; -} - -static void __exit wl1271_exit(void) -{ - sdio_unregister_driver(&wl1271_sdio_driver); - - wl1271_notice("unloaded"); -} - -module_init(wl1271_init); -module_exit(wl1271_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); -MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); -MODULE_FIRMWARE(WL1271_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c deleted file mode 100644 index 5189b812f93..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2008-2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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/crc7.h> -#include <linux/spi/spi.h> -#include <linux/spi/wl12xx.h> -#include <linux/slab.h> - -#include "wl1271.h" -#include "wl12xx_80211.h" -#include "wl1271_io.h" - -#include "wl1271_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 \ - ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) -#define HW_ACCESS_WSPI_INIT_CMD_MASK 0 - -static inline struct spi_device *wl_to_spi(struct wl1271 *wl) -{ - return wl->if_priv; -} - -static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl) -{ - return &(wl_to_spi(wl)->dev); -} - -static void wl1271_spi_disable_interrupts(struct wl1271 *wl) -{ - disable_irq(wl->irq); -} - -static void wl1271_spi_enable_interrupts(struct wl1271 *wl) -{ - enable_irq(wl->irq); -} - -static void wl1271_spi_reset(struct wl1271 *wl) -{ - u8 *cmd; - struct spi_transfer t; - struct spi_message m; - - cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); - if (!cmd) { - wl1271_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); - kfree(cmd); - - wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); -} - -static void wl1271_spi_init(struct wl1271 *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) { - wl1271_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); - kfree(cmd); - - wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); -} - -#define WL1271_BUSY_WORD_TIMEOUT 1000 - -static int wl1271_spi_read_busy(struct wl1271 *wl) -{ - struct spi_transfer t[1]; - struct spi_message m; - u32 *busy_buf; - int num_busy_bytes = 0; - - /* - * Read further busy words from SPI until a non-busy word is - * encountered, then read the data itself into the buffer. - */ - - num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT; - busy_buf = wl->buffer_busyword; - while (num_busy_bytes) { - num_busy_bytes--; - spi_message_init(&m); - memset(t, 0, sizeof(t)); - t[0].rx_buf = busy_buf; - t[0].len = sizeof(u32); - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); - spi_sync(wl_to_spi(wl), &m); - - if (*busy_buf & 0x1) - return 0; - } - - /* The SPI bus is unresponsive, the read failed. */ - wl1271_error("SPI read busy-word timeout!\n"); - return -ETIMEDOUT; -} - -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_message m; - u32 *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; - - if (fixed) - *cmd |= WSPI_CMD_FIXED; - - spi_message_init(&m); - memset(t, 0, sizeof(t)); - - t[0].tx_buf = cmd; - t[0].len = 4; - t[0].cs_change = true; - spi_message_add_tail(&t[0], &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); - - spi_sync(wl_to_spi(wl), &m); - - if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && - wl1271_spi_read_busy(wl)) { - memset(buf, 0, len); - return; - } - - spi_message_init(&m); - memset(t, 0, sizeof(t)); - - t[0].rx_buf = buf; - t[0].len = len; - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); - - 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, 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_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; - - if (fixed) - *cmd |= WSPI_CMD_FIXED; - - 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); - - wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); - wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); -} - -static irqreturn_t wl1271_irq(int irq, void *cookie) -{ - struct wl1271 *wl; - unsigned long flags; - - wl1271_debug(DEBUG_IRQ, "IRQ"); - - wl = cookie; - - /* complete the ELP completion */ - spin_lock_irqsave(&wl->wl_lock, flags); - if (wl->elp_compl) { - complete(wl->elp_compl); - wl->elp_compl = NULL; - } - - if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - - return IRQ_HANDLED; -} - -static void wl1271_spi_set_power(struct wl1271 *wl, bool enable) -{ - if (wl->set_power) - wl->set_power(enable); -} - -static struct wl1271_if_operations spi_ops = { - .read = wl1271_spi_raw_read, - .write = wl1271_spi_raw_write, - .reset = wl1271_spi_reset, - .init = wl1271_spi_init, - .power = wl1271_spi_set_power, - .dev = wl1271_spi_wl_to_dev, - .enable_irq = wl1271_spi_enable_interrupts, - .disable_irq = wl1271_spi_disable_interrupts -}; - -static int __devinit wl1271_probe(struct spi_device *spi) -{ - struct wl12xx_platform_data *pdata; - struct ieee80211_hw *hw; - struct wl1271 *wl; - int ret; - - pdata = spi->dev.platform_data; - if (!pdata) { - wl1271_error("no platform data"); - return -ENODEV; - } - - hw = wl1271_alloc_hw(); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - wl = hw->priv; - - dev_set_drvdata(&spi->dev, wl); - wl->if_priv = spi; - - wl->if_ops = &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) { - wl1271_error("spi_setup failed"); - goto out_free; - } - - wl->set_power = pdata->set_power; - if (!wl->set_power) { - wl1271_error("set power function missing in platform data"); - ret = -ENODEV; - goto out_free; - } - - wl->irq = spi->irq; - if (wl->irq < 0) { - wl1271_error("irq missing in platform data"); - ret = -ENODEV; - goto out_free; - } - - ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); - if (ret < 0) { - wl1271_error("request_irq() failed: %d", ret); - goto out_free; - } - - set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - - disable_irq(wl->irq); - - ret = wl1271_init_ieee80211(wl); - if (ret) - goto out_irq; - - ret = wl1271_register_hw(wl); - if (ret) - goto out_irq; - - wl1271_notice("initialized"); - - return 0; - - out_irq: - free_irq(wl->irq, wl); - - out_free: - wl1271_free_hw(wl); - - return ret; -} - -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); - wl1271_free_hw(wl); - - return 0; -} - - -static struct spi_driver wl1271_spi_driver = { - .driver = { - .name = "wl1271_spi", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - - .probe = wl1271_probe, - .remove = __devexit_p(wl1271_remove), -}; - -static int __init wl1271_init(void) -{ - int ret; - - ret = spi_register_driver(&wl1271_spi_driver); - if (ret < 0) { - wl1271_error("failed to register spi driver: %d", ret); - goto out; - } - -out: - return ret; -} - -static void __exit wl1271_exit(void) -{ - spi_unregister_driver(&wl1271_spi_driver); - - wl1271_notice("unloaded"); -} - -module_init(wl1271_init); -module_exit(wl1271_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); -MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); -MODULE_FIRMWARE(WL1271_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c deleted file mode 100644 index 554deb4d024..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_testmode.h" - -#include <linux/slab.h> -#include <net/genetlink.h> - -#include "wl1271.h" -#include "wl1271_acx.h" - -#define WL1271_TM_MAX_DATA_LENGTH 1024 - -enum wl1271_tm_commands { - WL1271_TM_CMD_UNSPEC, - WL1271_TM_CMD_TEST, - WL1271_TM_CMD_INTERROGATE, - WL1271_TM_CMD_CONFIGURE, - WL1271_TM_CMD_NVS_PUSH, - WL1271_TM_CMD_SET_PLT_MODE, - - __WL1271_TM_CMD_AFTER_LAST -}; -#define WL1271_TM_CMD_MAX (__WL1271_TM_CMD_AFTER_LAST - 1) - -enum wl1271_tm_attrs { - WL1271_TM_ATTR_UNSPEC, - WL1271_TM_ATTR_CMD_ID, - WL1271_TM_ATTR_ANSWER, - WL1271_TM_ATTR_DATA, - WL1271_TM_ATTR_IE_ID, - WL1271_TM_ATTR_PLT_MODE, - - __WL1271_TM_ATTR_AFTER_LAST -}; -#define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1) - -static struct nla_policy wl1271_tm_policy[WL1271_TM_ATTR_MAX + 1] = { - [WL1271_TM_ATTR_CMD_ID] = { .type = NLA_U32 }, - [WL1271_TM_ATTR_ANSWER] = { .type = NLA_U8 }, - [WL1271_TM_ATTR_DATA] = { .type = NLA_BINARY, - .len = WL1271_TM_MAX_DATA_LENGTH }, - [WL1271_TM_ATTR_IE_ID] = { .type = NLA_U32 }, - [WL1271_TM_ATTR_PLT_MODE] = { .type = NLA_U32 }, -}; - - -static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[]) -{ - int buf_len, ret, len; - struct sk_buff *skb; - void *buf; - u8 answer = 0; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd test"); - - if (!tb[WL1271_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[WL1271_TM_ATTR_DATA]); - buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]); - - if (tb[WL1271_TM_ATTR_ANSWER]) - answer = nla_get_u8(tb[WL1271_TM_ATTR_ANSWER]); - - if (buf_len > sizeof(struct wl1271_command)) - return -EMSGSIZE; - - mutex_lock(&wl->mutex); - ret = wl1271_cmd_test(wl, buf, buf_len, answer); - mutex_unlock(&wl->mutex); - - if (ret < 0) { - wl1271_warning("testmode cmd test failed: %d", ret); - return ret; - } - - if (answer) { - len = nla_total_size(buf_len); - skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len); - if (!skb) - return -ENOMEM; - - NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf); - ret = cfg80211_testmode_reply(skb); - if (ret < 0) - return ret; - } - - return 0; - -nla_put_failure: - kfree_skb(skb); - return -EMSGSIZE; -} - -static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) -{ - int ret; - struct wl1271_command *cmd; - struct sk_buff *skb; - u8 ie_id; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd interrogate"); - - if (!tb[WL1271_TM_ATTR_IE_ID]) - return -EINVAL; - - ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; - - mutex_lock(&wl->mutex); - ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd)); - mutex_unlock(&wl->mutex); - - if (ret < 0) { - wl1271_warning("testmode cmd interrogate failed: %d", ret); - return ret; - } - - skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd); - - return 0; - -nla_put_failure: - kfree_skb(skb); - return -EMSGSIZE; -} - -static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) -{ - int buf_len, ret; - void *buf; - u8 ie_id; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd configure"); - - if (!tb[WL1271_TM_ATTR_DATA]) - return -EINVAL; - if (!tb[WL1271_TM_ATTR_IE_ID]) - return -EINVAL; - - ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]); - buf = nla_data(tb[WL1271_TM_ATTR_DATA]); - buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]); - - if (buf_len > sizeof(struct wl1271_command)) - return -EMSGSIZE; - - mutex_lock(&wl->mutex); - ret = wl1271_cmd_configure(wl, ie_id, buf, buf_len); - mutex_unlock(&wl->mutex); - - if (ret < 0) { - wl1271_warning("testmode cmd configure failed: %d", ret); - return ret; - } - - return 0; -} - -static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) -{ - int ret = 0; - size_t len; - void *buf; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push"); - - if (!tb[WL1271_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[WL1271_TM_ATTR_DATA]); - len = nla_len(tb[WL1271_TM_ATTR_DATA]); - - if (len != sizeof(struct wl1271_nvs_file)) { - 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); - - wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); - if (!wl->nvs) { - wl1271_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->nvs, buf, len); - - wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - -static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) -{ - u32 val; - int ret; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd set plt mode"); - - if (!tb[WL1271_TM_ATTR_PLT_MODE]) - return -EINVAL; - - val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]); - - switch (val) { - case 0: - ret = wl1271_plt_stop(wl); - break; - case 1: - ret = wl1271_plt_start(wl); - break; - default: - ret = -EINVAL; - break; - } - - return ret; -} - -int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) -{ - struct wl1271 *wl = hw->priv; - struct nlattr *tb[WL1271_TM_ATTR_MAX + 1]; - int err; - - err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy); - if (err) - return err; - - if (!tb[WL1271_TM_ATTR_CMD_ID]) - return -EINVAL; - - switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) { - case WL1271_TM_CMD_TEST: - return wl1271_tm_cmd_test(wl, tb); - case WL1271_TM_CMD_INTERROGATE: - return wl1271_tm_cmd_interrogate(wl, tb); - case WL1271_TM_CMD_CONFIGURE: - return wl1271_tm_cmd_configure(wl, tb); - case WL1271_TM_CMD_NVS_PUSH: - return wl1271_tm_cmd_nvs_push(wl, tb); - case WL1271_TM_CMD_SET_PLT_MODE: - return wl1271_tm_cmd_set_plt_mode(wl, tb); - default: - return -EOPNOTSUPP; - } -} diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.h b/drivers/net/wireless/wl12xx/wl1271_testmode.h deleted file mode 100644 index c196d28f9d9..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_TESTMODE_H__ -#define __WL1271_TESTMODE_H__ - -#include <net/mac80211.h> - -int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len); - -#endif /* __WL1271_TESTMODE_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c deleted file mode 100644 index 62db79508dd..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h" -#include "wl1271_io.h" -#include "wl1271_reg.h" -#include "wl1271_ps.h" -#include "wl1271_tx.h" - -static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb) -{ - int i; - for (i = 0; i < ACX_TX_DESCRIPTORS; i++) - if (wl->tx_frames[i] == NULL) { - wl->tx_frames[i] = skb; - return i; - } - - return -EBUSY; -} - -static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) -{ - 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; - - /* allocate free identifier for the packet */ - id = wl1271_tx_id(wl, skb); - if (id < 0) - return id; - - /* approximate the number of blocks required for this packet - in the firmware */ - total_blocks = total_len + TX_HW_BLOCK_SIZE - 1; - total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE; - if (total_blocks <= wl->tx_blocks_available) { - desc = (struct wl1271_tx_hw_descr *)skb_push( - skb, total_len - skb->len); - - desc->extra_mem_blocks = TX_HW_BLOCK_SPARE; - desc->total_mem_blocks = total_blocks; - desc->id = id; - - wl->tx_blocks_available -= total_blocks; - - ret = 0; - - wl1271_debug(DEBUG_TX, - "tx_allocate: size: %d, blocks: %d, id: %d", - total_len, total_blocks, id); - } else - wl->tx_frames[id] = NULL; - - return ret; -} - -static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, - u32 extra, struct ieee80211_tx_info *control) -{ - struct timespec ts; - struct wl1271_tx_hw_descr *desc; - int pad, ac; - s64 hosttime; - u16 tx_attr; - - desc = (struct wl1271_tx_hw_descr *) skb->data; - - /* relocate space for security header */ - if (extra) { - void *framestart = skb->data + sizeof(*desc); - u16 fc = *(u16 *)(framestart + extra); - int hdrlen = ieee80211_hdrlen(cpu_to_le16(fc)); - memmove(framestart, framestart + extra, hdrlen); - } - - /* configure packet life time */ - getnstimeofday(&ts); - hosttime = (timespec_to_ns(&ts) >> 10); - desc->start_time = cpu_to_le32(hosttime - wl->time_offset); - desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); - - /* configure the tx attributes */ - tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; - - /* queue */ - ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); - desc->tid = wl1271_tx_ac_to_tid(ac); - - desc->aid = TX_HW_DEFAULT_AID; - desc->reserved = 0; - - /* align the length (and store in terms of words) */ - pad = WL1271_TX_ALIGN(skb->len); - desc->length = cpu_to_le16(pad >> 2); - - /* calculate number of padding bytes */ - pad = pad - skb->len; - tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; - - /* if the packets are destined for AP (have a STA entry) send them - with AP rate policies, otherwise use default basic rates */ - if (control->control.sta) - tx_attr |= ACX_TX_AP_FULL_RATE << TX_HW_ATTR_OFST_RATE_POLICY; - - 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) -{ - struct ieee80211_tx_info *info; - u32 extra = 0; - int ret = 0; - u8 idx; - - if (!skb) - return -EINVAL; - - info = IEEE80211_SKB_CB(skb); - - if (info->control.hw_key && - info->control.hw_key->alg == ALG_TKIP) - extra = WL1271_TKIP_IV_SPACE; - - if (info->control.hw_key) { - idx = info->control.hw_key->hw_key_idx; - - /* FIXME: do we have to do this if we're not using WEP? */ - if (unlikely(wl->default_key != idx)) { - ret = wl1271_cmd_set_default_wep_key(wl, idx); - if (ret < 0) - return ret; - wl->default_key = idx; - } - } - - ret = wl1271_tx_allocate(wl, skb, extra); - if (ret < 0) - return ret; - - ret = wl1271_tx_fill_hdr(wl, skb, extra, info); - if (ret < 0) - return ret; - - ret = wl1271_tx_send_packet(wl, skb, info); - if (ret < 0) - return ret; - - return ret; -} - -u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) -{ - struct ieee80211_supported_band *band; - u32 enabled_rates = 0; - int bit; - - band = wl->hw->wiphy->bands[wl->band]; - for (bit = 0; bit < band->n_bitrates; bit++) { - if (rate_set & 0x1) - enabled_rates |= band->bitrates[bit].hw_value; - rate_set >>= 1; - } - - return enabled_rates; -} - -void wl1271_tx_work(struct work_struct *work) -{ - struct wl1271 *wl = container_of(work, struct wl1271, tx_work); - struct sk_buff *skb; - bool woken_up = false; - u32 sta_rates = 0; - u32 prev_tx_packets_count; - int ret; - - /* check if the rates supported by the AP have changed */ - if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED, - &wl->flags))) { - unsigned long flags; - spin_lock_irqsave(&wl->wl_lock, flags); - sta_rates = wl->sta_rate_set; - spin_unlock_irqrestore(&wl->wl_lock, flags); - } - - mutex_lock(&wl->mutex); - - 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); - } - - while ((skb = skb_dequeue(&wl->tx_queue))) { - if (!woken_up) { - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out_ack; - woken_up = true; - } - - ret = wl1271_tx_frame(wl, skb); - if (ret == -EBUSY) { - /* firmware buffer is full, lets stop transmitting. */ - skb_queue_head(&wl->tx_queue, skb); - goto out_ack; - } else if (ret < 0) { - dev_kfree_skb(skb); - goto out_ack; - } - } - -out_ack: - /* interrupt the firmware with the new packets */ - if (prev_tx_packets_count != wl->tx_packets_count) - wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); - -out: - if (woken_up) - wl1271_ps_elp_sleep(wl); - - mutex_unlock(&wl->mutex); -} - -static void wl1271_tx_complete_packet(struct wl1271 *wl, - struct wl1271_tx_hw_res_descr *result) -{ - struct ieee80211_tx_info *info; - struct sk_buff *skb; - int id = result->id; - int rate = -1; - u8 retries = 0; - - /* check for id legality */ - if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) { - wl1271_warning("TX result illegal id: %d", id); - return; - } - - skb = wl->tx_frames[id]; - info = IEEE80211_SKB_CB(skb); - - /* update the TX status info */ - if (result->status == TX_SUCCESS) { - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) - info->flags |= IEEE80211_TX_STAT_ACK; - rate = wl1271_rate_to_idx(wl, result->rate_class_index); - retries = result->ack_failures; - } else if (result->status == TX_RETRY_EXCEEDED) { - wl->stats.excessive_retries++; - retries = result->ack_failures; - } - - info->status.rates[0].idx = rate; - info->status.rates[0].count = retries; - info->status.rates[0].flags = 0; - info->status.ack_signal = -1; - - wl->stats.retry_count += result->ack_failures; - - /* update security sequence number */ - wl->tx_security_seq += (result->lsb_security_sequence_number - - wl->tx_security_last_seq); - wl->tx_security_last_seq = result->lsb_security_sequence_number; - - /* remove private header from packet */ - skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); - - /* remove TKIP header space if present */ - if (info->control.hw_key && - info->control.hw_key->alg == ALG_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); - } - - wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x" - " status 0x%x", - result->id, skb, result->ack_failures, - result->rate_class_index, result->status); - - /* return the packet to the stack */ - ieee80211_tx_status(wl->hw, skb); - wl->tx_frames[result->id] = NULL; -} - -/* Called upon reception of a TX complete interrupt */ -void wl1271_tx_complete(struct wl1271 *wl) -{ - struct wl1271_acx_mem_map *memmap = - (struct wl1271_acx_mem_map *)wl->target_mem_map; - u32 count, fw_counter; - u32 i; - - /* read the tx results from the chipset */ - wl1271_read(wl, le32_to_cpu(memmap->tx_result), - wl->tx_res_if, sizeof(*wl->tx_res_if), false); - fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter); - - /* write host counter to chipset (to ack) */ - wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + - offsetof(struct wl1271_tx_hw_res_if, - tx_result_host_counter), fw_counter); - - count = fw_counter - wl->tx_results_count; - wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); - - /* verify that the result buffer is not getting overrun */ - if (unlikely(count > TX_HW_RESULT_QUEUE_LEN)) - wl1271_warning("TX result overflow from chipset: %d", count); - - /* process the results */ - for (i = 0; i < count; i++) { - struct wl1271_tx_hw_res_descr *result; - u8 offset = wl->tx_results_count & TX_HW_RESULT_QUEUE_LEN_MASK; - - /* process the packet */ - result = &(wl->tx_res_if->tx_results_queue[offset]); - wl1271_tx_complete_packet(wl, result); - - wl->tx_results_count++; - } - - if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && - skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { - unsigned long flags; - - /* firmware buffer has space, restart queues */ - wl1271_debug(DEBUG_TX, "tx_complete: waking queues"); - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_wake_queues(wl->hw); - clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - ieee80211_queue_work(wl->hw, &wl->tx_work); - } -} - -/* caller must hold wl->mutex */ -void wl1271_tx_flush(struct wl1271 *wl) -{ - int i; - struct sk_buff *skb; - - /* TX failure */ -/* control->flags = 0; FIXME */ - - while ((skb = skb_dequeue(&wl->tx_queue))) { - wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb); - ieee80211_tx_status(wl->hw, skb); - } - - for (i = 0; i < ACX_TX_DESCRIPTORS; i++) - if (wl->tx_frames[i] != NULL) { - skb = wl->tx_frames[i]; - wl->tx_frames[i] = NULL; - ieee80211_tx_status(wl->hw, skb); - } -} diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h deleted file mode 100644 index 3b8b7ac253f..00000000000 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * This file is part of wl1271 - * - * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. - * Copyright (C) 2009 Nokia Corporation - * - * Contact: Luciano Coelho <luciano.coelho@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 __WL1271_TX_H__ -#define __WL1271_TX_H__ - -#define TX_HW_BLOCK_SPARE 2 -#define TX_HW_BLOCK_SIZE 252 - -#define TX_HW_MGMT_PKT_LIFETIME_TU 2000 -/* The chipset reference driver states, that the "aid" value 1 - * is for infra-BSS, but is still always used */ -#define TX_HW_DEFAULT_AID 1 - -#define TX_HW_ATTR_SAVE_RETRIES BIT(0) -#define TX_HW_ATTR_HEADER_PAD BIT(1) -#define TX_HW_ATTR_SESSION_COUNTER (BIT(2) | BIT(3) | BIT(4)) -#define TX_HW_ATTR_RATE_POLICY (BIT(5) | BIT(6) | BIT(7) | \ - BIT(8) | BIT(9)) -#define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11)) -#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12) - -#define TX_HW_ATTR_OFST_SAVE_RETRIES 0 -#define TX_HW_ATTR_OFST_HEADER_PAD 1 -#define TX_HW_ATTR_OFST_SESSION_COUNTER 2 -#define TX_HW_ATTR_OFST_RATE_POLICY 5 -#define TX_HW_ATTR_OFST_LAST_WORD_PAD 10 -#define TX_HW_ATTR_OFST_TX_CMPLT_REQ 12 - -#define TX_HW_RESULT_QUEUE_LEN 16 -#define TX_HW_RESULT_QUEUE_LEN_MASK 0xf - -#define WL1271_TX_ALIGN_TO 4 -#define WL1271_TX_ALIGN(len) (((len) + WL1271_TX_ALIGN_TO - 1) & \ - ~(WL1271_TX_ALIGN_TO - 1)) -#define WL1271_TKIP_IV_SPACE 4 - -struct wl1271_tx_hw_descr { - /* Length of packet in words, including descriptor+header+data */ - __le16 length; - /* Number of extra memory blocks to allocate for this packet in - addition to the number of blocks derived from the packet length */ - u8 extra_mem_blocks; - /* Total number of memory blocks allocated by the host for this packet. - Must be equal or greater than the actual blocks number allocated by - HW!! */ - u8 total_mem_blocks; - /* Device time (in us) when the packet arrived to the driver */ - __le32 start_time; - /* Max delay in TUs until transmission. The last device time the - packet can be transmitted is: startTime+(1024*LifeTime) */ - __le16 life_time; - /* Bitwise fields - see TX_ATTR... definitions above. */ - __le16 tx_attr; - /* Packet identifier used also in the Tx-Result. */ - u8 id; - /* The packet TID value (as User-Priority) */ - u8 tid; - /* Identifier of the remote STA in IBSS, 1 in infra-BSS */ - u8 aid; - u8 reserved; -} __attribute__ ((packed)); - -enum wl1271_tx_hw_res_status { - TX_SUCCESS = 0, - TX_HW_ERROR = 1, - TX_DISABLED = 2, - TX_RETRY_EXCEEDED = 3, - TX_TIMEOUT = 4, - TX_KEY_NOT_FOUND = 5, - TX_PEER_NOT_FOUND = 6, - TX_SESSION_MISMATCH = 7 -}; - -struct wl1271_tx_hw_res_descr { - /* Packet Identifier - same value used in the Tx descriptor.*/ - u8 id; - /* The status of the transmission, indicating success or one of - several possible reasons for failure. */ - u8 status; - /* Total air access duration including all retrys and overheads.*/ - __le16 medium_usage; - /* The time passed from host xfer to Tx-complete.*/ - __le32 fw_handling_time; - /* Total media delay - (from 1st EDCA AIFS counter until TX Complete). */ - __le32 medium_delay; - /* LS-byte of last TKIP seq-num (saved per AC for recovery). */ - u8 lsb_security_sequence_number; - /* Retry count - number of transmissions without successful ACK.*/ - u8 ack_failures; - /* The rate that succeeded getting ACK - (Valid only if status=SUCCESS). */ - u8 rate_class_index; - /* for 4-byte alignment. */ - u8 spare; -} __attribute__ ((packed)); - -struct wl1271_tx_hw_res_if { - __le32 tx_result_fw_counter; - __le32 tx_result_host_counter; - struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; -} __attribute__ ((packed)); - -static inline int wl1271_tx_get_queue(int queue) -{ - switch (queue) { - case 0: - return CONF_TX_AC_VO; - case 1: - return CONF_TX_AC_VI; - case 2: - return CONF_TX_AC_BE; - case 3: - return CONF_TX_AC_BK; - default: - return CONF_TX_AC_BE; - } -} - -/* 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_flush(struct wl1271 *wl); -u8 wl1271_rate_to_idx(struct wl1271 *wl, int rate); -u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); - -#endif diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h deleted file mode 100644 index 055d7bc6f59..00000000000 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef __WL12XX_80211_H__ -#define __WL12XX_80211_H__ - -#include <linux/if_ether.h> /* ETH_ALEN */ - -/* RATES */ -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 -#define IEEE80211_OFDM_RATE_12MB 0x18 -#define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_OFDM_RATE_36MB 0x48 -#define IEEE80211_OFDM_RATE_48MB 0x60 -#define IEEE80211_OFDM_RATE_54MB 0x6C -#define IEEE80211_BASIC_RATE_MASK 0x80 - -#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) -#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) -#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) -#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) -#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) -#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) -#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) -#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) -#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) -#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) -#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) -#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) - -#define IEEE80211_CCK_RATES_MASK 0x0000000F -#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ - IEEE80211_CCK_RATE_2MB_MASK) -#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ - IEEE80211_CCK_RATE_5MB_MASK | \ - IEEE80211_CCK_RATE_11MB_MASK) - -#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 -#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ - IEEE80211_OFDM_RATE_12MB_MASK | \ - IEEE80211_OFDM_RATE_24MB_MASK) -#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ - IEEE80211_OFDM_RATE_9MB_MASK | \ - IEEE80211_OFDM_RATE_18MB_MASK | \ - IEEE80211_OFDM_RATE_36MB_MASK | \ - IEEE80211_OFDM_RATE_48MB_MASK | \ - IEEE80211_OFDM_RATE_54MB_MASK) -#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ - IEEE80211_CCK_DEFAULT_RATES_MASK) - - -/* This really should be 8, but not for our firmware */ -#define MAX_SUPPORTED_RATES 32 -#define COUNTRY_STRING_LEN 3 -#define MAX_COUNTRY_TRIPLETS 32 - -/* Headers */ -struct ieee80211_header { - __le16 frame_ctl; - __le16 duration_id; - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[0]; -} __attribute__ ((packed)); - -struct wl12xx_ie_header { - u8 id; - u8 len; -} __attribute__ ((packed)); - -/* IEs */ - -struct wl12xx_ie_ssid { - struct wl12xx_ie_header header; - char ssid[IW_ESSID_MAX_SIZE]; -} __attribute__ ((packed)); - -struct wl12xx_ie_rates { - struct wl12xx_ie_header header; - u8 rates[MAX_SUPPORTED_RATES]; -} __attribute__ ((packed)); - -struct wl12xx_ie_ds_params { - struct wl12xx_ie_header header; - u8 channel; -} __attribute__ ((packed)); - -struct country_triplet { - u8 channel; - u8 num_channels; - u8 max_tx_power; -} __attribute__ ((packed)); - -struct wl12xx_ie_country { - struct wl12xx_ie_header header; - u8 country_string[COUNTRY_STRING_LEN]; - struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; -} __attribute__ ((packed)); - - -/* Templates */ - -struct wl12xx_beacon_template { - struct ieee80211_header header; - __le32 time_stamp[2]; - __le16 beacon_interval; - __le16 capability; - struct wl12xx_ie_ssid ssid; - struct wl12xx_ie_rates rates; - struct wl12xx_ie_rates ext_rates; - struct wl12xx_ie_ds_params ds_params; - struct wl12xx_ie_country country; -} __attribute__ ((packed)); - -struct wl12xx_null_data_template { - struct ieee80211_header header; -} __attribute__ ((packed)); - -struct wl12xx_ps_poll_template { - __le16 fc; - __le16 aid; - u8 bssid[ETH_ALEN]; - u8 ta[ETH_ALEN]; -} __attribute__ ((packed)); - -struct wl12xx_qos_null_data_template { - struct ieee80211_header header; - __le16 qos_ctl; -} __attribute__ ((packed)); - -struct wl12xx_probe_req_template { - struct ieee80211_header header; - struct wl12xx_ie_ssid ssid; - struct wl12xx_ie_rates rates; - struct wl12xx_ie_rates ext_rates; -} __attribute__ ((packed)); - - -struct wl12xx_probe_resp_template { - struct ieee80211_header header; - __le32 time_stamp[2]; - __le16 beacon_interval; - __le16 capability; - struct wl12xx_ie_ssid ssid; - struct wl12xx_ie_rates rates; - struct wl12xx_ie_rates ext_rates; - struct wl12xx_ie_ds_params ds_params; - struct wl12xx_ie_country country; -} __attribute__ ((packed)); - -#endif |
