2009-08-06 21:25:28 +08:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2010-11-08 19:20:10 +08:00
|
|
|
#ifndef __WL12XX_H__
|
|
|
|
#define __WL12XX_H__
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
#include <linux/mutex.h>
|
|
|
|
#include <linux/completion.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/bitops.h>
|
|
|
|
#include <net/mac80211.h>
|
|
|
|
|
2010-11-08 19:20:10 +08:00
|
|
|
#include "conf.h"
|
|
|
|
#include "ini.h"
|
2009-10-13 17:47:39 +08:00
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
#define DRIVER_NAME "wl1271"
|
|
|
|
#define DRIVER_PREFIX DRIVER_NAME ": "
|
|
|
|
|
2011-01-23 14:27:22 +08:00
|
|
|
/*
|
|
|
|
* FW versions support BA 11n
|
|
|
|
* versions marks x.x.x.50-60.x
|
|
|
|
*/
|
|
|
|
#define WL12XX_BA_SUPPORT_FW_COST_VER2_START 50
|
|
|
|
#define WL12XX_BA_SUPPORT_FW_COST_VER2_END 60
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
enum {
|
|
|
|
DEBUG_NONE = 0,
|
|
|
|
DEBUG_IRQ = BIT(0),
|
|
|
|
DEBUG_SPI = BIT(1),
|
|
|
|
DEBUG_BOOT = BIT(2),
|
|
|
|
DEBUG_MAILBOX = BIT(3),
|
2010-02-18 19:25:53 +08:00
|
|
|
DEBUG_TESTMODE = BIT(4),
|
2009-08-06 21:25:28 +08:00
|
|
|
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),
|
2010-03-18 18:26:41 +08:00
|
|
|
DEBUG_SDIO = BIT(14),
|
2010-03-18 18:26:43 +08:00
|
|
|
DEBUG_FILTERS = BIT(15),
|
2010-03-26 18:53:24 +08:00
|
|
|
DEBUG_ADHOC = BIT(16),
|
2010-10-17 01:07:21 +08:00
|
|
|
DEBUG_AP = BIT(17),
|
|
|
|
DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP),
|
2009-08-06 21:25:28 +08:00
|
|
|
DEBUG_ALL = ~0,
|
|
|
|
};
|
|
|
|
|
2010-12-12 18:15:35 +08:00
|
|
|
extern u32 wl12xx_debug_level;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
#define DEBUG_DUMP_LIMIT 1024
|
|
|
|
|
|
|
|
#define wl1271_error(fmt, arg...) \
|
2010-12-12 18:15:35 +08:00
|
|
|
pr_err(DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
#define wl1271_warning(fmt, arg...) \
|
2010-12-12 18:15:35 +08:00
|
|
|
pr_warning(DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
#define wl1271_notice(fmt, arg...) \
|
2010-12-12 18:15:35 +08:00
|
|
|
pr_info(DRIVER_PREFIX fmt "\n", ##arg)
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
#define wl1271_info(fmt, arg...) \
|
2010-12-12 18:15:35 +08:00
|
|
|
pr_info(DRIVER_PREFIX fmt "\n", ##arg)
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
#define wl1271_debug(level, fmt, arg...) \
|
|
|
|
do { \
|
2010-12-12 18:15:35 +08:00
|
|
|
if (level & wl12xx_debug_level) \
|
|
|
|
pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \
|
2009-08-06 21:25:28 +08:00
|
|
|
} while (0)
|
|
|
|
|
2010-12-12 18:15:35 +08:00
|
|
|
/* TODO: use pr_debug_hex_dump when it will be available */
|
2009-08-06 21:25:28 +08:00
|
|
|
#define wl1271_dump(level, prefix, buf, len) \
|
|
|
|
do { \
|
2010-12-12 18:15:35 +08:00
|
|
|
if (level & wl12xx_debug_level) \
|
2009-08-06 21:25:28 +08:00
|
|
|
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 { \
|
2010-12-12 18:15:35 +08:00
|
|
|
if (level & wl12xx_debug_level) \
|
2009-08-06 21:25:28 +08:00
|
|
|
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)
|
|
|
|
|
2011-08-17 15:45:48 +08:00
|
|
|
#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-3.bin"
|
|
|
|
#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-3.bin"
|
2010-10-17 03:44:57 +08:00
|
|
|
|
2011-03-06 22:32:07 +08:00
|
|
|
/*
|
|
|
|
* wl127x and wl128x are using the same NVS file name. However, the
|
|
|
|
* ini parameters between them are different. The driver validates
|
|
|
|
* the correct NVS size in wl1271_boot_upload_nvs().
|
|
|
|
*/
|
|
|
|
#define WL12XX_NVS_NAME "ti-connectivity/wl1271-nvs.bin"
|
2010-02-18 19:25:42 +08:00
|
|
|
|
2010-02-22 14:38:40 +08:00
|
|
|
#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
|
|
|
|
#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
|
2011-06-26 15:36:02 +08:00
|
|
|
#define WL1271_TX_SQN_POST_RECOVERY_PADDING 0xff
|
2010-02-22 14:38:40 +08:00
|
|
|
|
2010-09-27 18:42:07 +08:00
|
|
|
#define WL1271_CIPHER_SUITE_GEM 0x00147201
|
|
|
|
|
2010-03-26 18:53:18 +08:00
|
|
|
#define WL1271_BUSY_WORD_CNT 1
|
2009-10-09 02:56:23 +08:00
|
|
|
#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
#define WL1271_ELP_HW_STATE_ASLEEP 0
|
|
|
|
#define WL1271_ELP_HW_STATE_IRQ 1
|
|
|
|
|
2009-10-09 02:56:25 +08:00
|
|
|
#define WL1271_DEFAULT_BEACON_INT 100
|
|
|
|
#define WL1271_DEFAULT_DTIM_PERIOD 1
|
|
|
|
|
2011-08-14 18:17:07 +08:00
|
|
|
#define WL12XX_MAX_ROLES 4
|
2011-08-14 18:17:05 +08:00
|
|
|
#define WL12XX_MAX_LINKS 8
|
2011-08-14 18:17:06 +08:00
|
|
|
#define WL12XX_INVALID_ROLE_ID 0xff
|
|
|
|
#define WL12XX_INVALID_LINK_ID 0xff
|
2011-08-14 18:17:21 +08:00
|
|
|
|
|
|
|
/* Defined by FW as 0. Will not be freed or allocated. */
|
2011-08-14 18:17:15 +08:00
|
|
|
#define WL12XX_SYSTEM_HLID 0
|
2011-08-14 18:17:21 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO: we currently don't support multirole. remove
|
|
|
|
* this constant from the code when we do.
|
|
|
|
*/
|
|
|
|
#define WL1271_AP_STA_HLID_START 3
|
2010-10-17 00:08:58 +08:00
|
|
|
|
2011-02-23 06:22:31 +08:00
|
|
|
/*
|
2011-08-14 18:17:35 +08:00
|
|
|
* When in AP-mode, we allow (at least) this number of packets
|
2011-02-23 06:22:31 +08:00
|
|
|
* to be transmitted to FW for a STA in PS-mode. Only when packets are
|
|
|
|
* present in the FW buffers it will wake the sleeping STA. We want to put
|
|
|
|
* enough packets for the driver to transmit all of its buffered data before
|
2011-08-14 18:17:35 +08:00
|
|
|
* the STA goes to sleep again. But we don't want to take too much memory
|
2011-02-23 06:22:31 +08:00
|
|
|
* as it might hurt the throughput of active STAs.
|
|
|
|
*/
|
2011-08-14 18:17:35 +08:00
|
|
|
#define WL1271_PS_STA_MAX_PACKETS 2
|
2011-02-23 06:22:31 +08:00
|
|
|
|
2010-10-17 00:08:58 +08:00
|
|
|
#define WL1271_AP_BSS_INDEX 0
|
|
|
|
#define WL1271_AP_DEF_BEACON_EXP 20
|
|
|
|
|
2011-08-14 18:17:11 +08:00
|
|
|
#define ACX_TX_DESCRIPTORS 16
|
2009-10-09 02:56:26 +08:00
|
|
|
|
2010-09-30 19:28:27 +08:00
|
|
|
#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
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;
|
2009-10-12 20:08:46 +08:00
|
|
|
struct wl1271_partition mem2;
|
|
|
|
struct wl1271_partition mem3;
|
2009-08-06 21:25:28 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct wl1271;
|
|
|
|
|
2011-03-10 21:24:57 +08:00
|
|
|
enum {
|
|
|
|
FW_VER_CHIP,
|
|
|
|
FW_VER_IF_TYPE,
|
|
|
|
FW_VER_MAJOR,
|
|
|
|
FW_VER_SUBTYPE,
|
|
|
|
FW_VER_MINOR,
|
|
|
|
|
|
|
|
NUM_FW_VER
|
|
|
|
};
|
|
|
|
|
|
|
|
#define FW_VER_CHIP_WL127X 6
|
|
|
|
#define FW_VER_CHIP_WL128X 7
|
|
|
|
|
|
|
|
#define FW_VER_IF_TYPE_STA 1
|
|
|
|
#define FW_VER_IF_TYPE_AP 2
|
|
|
|
|
|
|
|
#define FW_VER_MINOR_1_SPARE_STA_MIN 58
|
|
|
|
#define FW_VER_MINOR_1_SPARE_AP_MIN 47
|
2011-01-23 14:27:22 +08:00
|
|
|
|
2011-06-06 19:57:06 +08:00
|
|
|
#define FW_VER_MINOR_FWLOG_STA_MIN 70
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
struct wl1271_chip {
|
|
|
|
u32 id;
|
2011-01-23 14:27:22 +08:00
|
|
|
char fw_ver_str[ETHTOOL_BUSINFO_LEN];
|
2011-03-10 21:24:57 +08:00
|
|
|
unsigned int fw_ver[NUM_FW_VER];
|
2009-08-06 21:25:28 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct wl1271_stats {
|
|
|
|
struct acx_statistics *fw_stats;
|
|
|
|
unsigned long fw_stats_update;
|
|
|
|
|
|
|
|
unsigned int retry_count;
|
|
|
|
unsigned int excessive_retries;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define NUM_TX_QUEUES 4
|
|
|
|
#define NUM_RX_PKT_DESC 8
|
|
|
|
|
2011-08-25 17:43:14 +08:00
|
|
|
#define AP_MAX_STATIONS 8
|
2010-10-17 00:53:48 +08:00
|
|
|
|
2011-08-14 18:17:35 +08:00
|
|
|
/* Broadcast and Global links + system link + links to stations */
|
|
|
|
/*
|
|
|
|
* TODO: when WL1271_AP_STA_HLID_START is no longer constant, change all
|
|
|
|
* the places that use this.
|
|
|
|
*/
|
2011-08-25 17:43:14 +08:00
|
|
|
#define AP_MAX_LINKS (AP_MAX_STATIONS + WL1271_AP_STA_HLID_START)
|
2010-10-17 00:53:48 +08:00
|
|
|
|
2011-08-14 18:17:05 +08:00
|
|
|
/* FW status registers */
|
|
|
|
struct wl12xx_fw_status {
|
2009-10-15 15:33:29 +08:00
|
|
|
__le32 intr;
|
2009-08-06 21:25:28 +08:00
|
|
|
u8 fw_rx_counter;
|
|
|
|
u8 drv_rx_counter;
|
|
|
|
u8 reserved;
|
|
|
|
u8 tx_results_counter;
|
2009-10-15 15:33:29 +08:00
|
|
|
__le32 rx_pkt_descs[NUM_RX_PKT_DESC];
|
|
|
|
__le32 fw_localtime;
|
2010-10-17 00:53:48 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* A bitmap (where each bit represents a single HLID)
|
|
|
|
* to indicate if the station is in PS mode.
|
|
|
|
*/
|
|
|
|
__le32 link_ps_bitmap;
|
|
|
|
|
2011-08-14 18:17:05 +08:00
|
|
|
/*
|
|
|
|
* A bitmap (where each bit represents a single HLID) to indicate
|
|
|
|
* if the station is in Fast mode
|
|
|
|
*/
|
|
|
|
__le32 link_fast_bitmap;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2011-08-14 18:17:05 +08:00
|
|
|
/* Cumulative counter of total released mem blocks since FW-reset */
|
|
|
|
__le32 total_released_blks;
|
2011-02-02 15:59:35 +08:00
|
|
|
|
2011-08-14 18:17:05 +08:00
|
|
|
/* Size (in Memory Blocks) of TX pool */
|
|
|
|
__le32 tx_total;
|
2011-02-02 15:59:35 +08:00
|
|
|
|
2011-08-14 18:17:32 +08:00
|
|
|
/* Cumulative counter of released packets per AC */
|
|
|
|
u8 tx_released_pkts[NUM_TX_QUEUES];
|
2011-02-02 15:59:35 +08:00
|
|
|
|
2011-08-14 18:17:35 +08:00
|
|
|
/* Cumulative counter of freed packets per HLID */
|
|
|
|
u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
|
2011-08-14 18:17:05 +08:00
|
|
|
|
|
|
|
/* Cumulative counter of released Voice memory blocks */
|
|
|
|
u8 tx_voice_released_blks;
|
|
|
|
u8 padding_1[7];
|
|
|
|
__le32 log_start_addr;
|
|
|
|
} __packed;
|
2011-02-02 15:59:35 +08:00
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
struct wl1271_rx_mem_pool_addr {
|
|
|
|
u32 addr;
|
|
|
|
u32 addr_extra;
|
|
|
|
};
|
|
|
|
|
2011-03-22 05:16:14 +08:00
|
|
|
#define WL1271_MAX_CHANNELS 64
|
2009-10-13 17:47:50 +08:00
|
|
|
struct wl1271_scan {
|
2010-05-24 16:18:20 +08:00
|
|
|
struct cfg80211_scan_request *req;
|
2011-03-22 05:16:14 +08:00
|
|
|
unsigned long scanned_ch[BITS_TO_LONGS(WL1271_MAX_CHANNELS)];
|
2010-09-21 12:23:32 +08:00
|
|
|
bool failed;
|
2009-10-13 17:47:50 +08:00
|
|
|
u8 state;
|
2011-07-13 16:39:16 +08:00
|
|
|
u8 ssid[IEEE80211_MAX_SSID_LEN+1];
|
2009-10-13 17:47:50 +08:00
|
|
|
size_t ssid_len;
|
|
|
|
};
|
|
|
|
|
2010-02-22 14:38:23 +08:00
|
|
|
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);
|
2010-09-16 07:22:04 +08:00
|
|
|
int (*power)(struct wl1271 *wl, bool enable);
|
2010-02-22 14:38:23 +08:00
|
|
|
struct device* (*dev)(struct wl1271 *wl);
|
|
|
|
void (*enable_irq)(struct wl1271 *wl);
|
|
|
|
void (*disable_irq)(struct wl1271 *wl);
|
2011-03-31 16:06:58 +08:00
|
|
|
void (*set_block_size) (struct wl1271 *wl, unsigned int blksz);
|
2010-02-22 14:38:23 +08:00
|
|
|
};
|
|
|
|
|
2010-10-17 03:39:06 +08:00
|
|
|
#define MAX_NUM_KEYS 14
|
|
|
|
#define MAX_KEY_SIZE 32
|
|
|
|
|
|
|
|
struct wl1271_ap_key {
|
|
|
|
u8 id;
|
|
|
|
u8 key_type;
|
|
|
|
u8 key_size;
|
|
|
|
u8 key[MAX_KEY_SIZE];
|
|
|
|
u8 hlid;
|
|
|
|
u32 tx_seq_32;
|
|
|
|
u16 tx_seq_16;
|
|
|
|
};
|
|
|
|
|
2011-02-02 15:59:37 +08:00
|
|
|
enum wl12xx_flags {
|
|
|
|
WL1271_FLAG_STA_ASSOCIATED,
|
2011-08-14 18:17:26 +08:00
|
|
|
WL1271_FLAG_IBSS_JOINED,
|
2011-02-02 15:59:37 +08:00
|
|
|
WL1271_FLAG_GPIO_POWER,
|
|
|
|
WL1271_FLAG_TX_QUEUE_STOPPED,
|
2011-03-01 21:14:43 +08:00
|
|
|
WL1271_FLAG_TX_PENDING,
|
2011-02-02 15:59:37 +08:00
|
|
|
WL1271_FLAG_IN_ELP,
|
2011-04-03 07:01:59 +08:00
|
|
|
WL1271_FLAG_ELP_REQUESTED,
|
2011-02-02 15:59:37 +08:00
|
|
|
WL1271_FLAG_PSM,
|
|
|
|
WL1271_FLAG_PSM_REQUESTED,
|
|
|
|
WL1271_FLAG_IRQ_RUNNING,
|
|
|
|
WL1271_FLAG_IDLE,
|
|
|
|
WL1271_FLAG_PSPOLL_FAILURE,
|
|
|
|
WL1271_FLAG_STA_STATE_SENT,
|
|
|
|
WL1271_FLAG_FW_TX_BUSY,
|
2011-03-29 21:43:50 +08:00
|
|
|
WL1271_FLAG_AP_STARTED,
|
|
|
|
WL1271_FLAG_IF_INITIALIZED,
|
2011-03-31 16:06:59 +08:00
|
|
|
WL1271_FLAG_DUMMY_PACKET_PENDING,
|
2011-05-13 16:57:11 +08:00
|
|
|
WL1271_FLAG_SUSPENDED,
|
|
|
|
WL1271_FLAG_PENDING_WORK,
|
2011-05-15 16:10:29 +08:00
|
|
|
WL1271_FLAG_SOFT_GEMINI,
|
|
|
|
WL1271_FLAG_RX_STREAMING_STARTED,
|
2011-06-06 19:57:05 +08:00
|
|
|
WL1271_FLAG_RECOVERY_IN_PROGRESS,
|
2011-02-02 15:59:37 +08:00
|
|
|
};
|
|
|
|
|
2011-02-23 06:22:26 +08:00
|
|
|
struct wl1271_link {
|
|
|
|
/* AP-mode - TX queue per AC in link */
|
|
|
|
struct sk_buff_head tx_queue[NUM_TX_QUEUES];
|
2011-02-23 06:22:30 +08:00
|
|
|
|
2011-08-14 18:17:35 +08:00
|
|
|
/* accounting for allocated / freed packets in FW */
|
|
|
|
u8 allocated_pkts;
|
|
|
|
u8 prev_freed_pkts;
|
2011-02-23 06:22:31 +08:00
|
|
|
|
|
|
|
u8 addr[ETH_ALEN];
|
2011-08-17 15:45:49 +08:00
|
|
|
|
|
|
|
/* bitmap of TIDs where RX BA sessions are active for this link */
|
|
|
|
u8 ba_bitmap;
|
2011-02-23 06:22:26 +08:00
|
|
|
};
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
struct wl1271 {
|
2010-03-18 18:26:46 +08:00
|
|
|
struct platform_device *plat_dev;
|
2009-08-06 21:25:28 +08:00
|
|
|
struct ieee80211_hw *hw;
|
|
|
|
bool mac80211_registered;
|
|
|
|
|
2010-02-22 14:38:23 +08:00
|
|
|
void *if_priv;
|
|
|
|
|
|
|
|
struct wl1271_if_operations *if_ops;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
void (*set_power)(bool enable);
|
|
|
|
int irq;
|
2010-09-16 07:31:51 +08:00
|
|
|
int ref_clock;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
spinlock_t wl_lock;
|
|
|
|
|
|
|
|
enum wl1271_state state;
|
|
|
|
struct mutex mutex;
|
|
|
|
|
2009-12-11 21:41:06 +08:00
|
|
|
unsigned long flags;
|
|
|
|
|
2009-10-12 20:08:46 +08:00
|
|
|
struct wl1271_partition_set part;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
struct wl1271_chip chip;
|
|
|
|
|
|
|
|
int cmd_box_addr;
|
|
|
|
int event_box_addr;
|
|
|
|
|
|
|
|
u8 *fw;
|
|
|
|
size_t fw_len;
|
2011-03-06 22:32:10 +08:00
|
|
|
void *nvs;
|
2010-08-19 10:41:15 +08:00
|
|
|
size_t nvs_len;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2010-05-07 16:38:58 +08:00
|
|
|
s8 hw_pg_ver;
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
u8 bssid[ETH_ALEN];
|
|
|
|
u8 mac_addr[ETH_ALEN];
|
|
|
|
u8 bss_type;
|
2010-03-26 18:53:24 +08:00
|
|
|
u8 set_bss_type;
|
2011-08-28 20:23:01 +08:00
|
|
|
u8 p2p; /* we are using p2p role */
|
2011-07-13 16:39:16 +08:00
|
|
|
u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
|
2009-08-06 21:25:28 +08:00
|
|
|
u8 ssid_len;
|
|
|
|
int channel;
|
2011-08-14 18:17:06 +08:00
|
|
|
u8 role_id;
|
2011-08-14 18:17:09 +08:00
|
|
|
u8 dev_role_id;
|
2011-08-14 18:17:15 +08:00
|
|
|
u8 system_hlid;
|
2011-08-14 18:17:06 +08:00
|
|
|
u8 sta_hlid;
|
2011-08-14 18:17:07 +08:00
|
|
|
u8 dev_hlid;
|
2011-08-14 18:17:21 +08:00
|
|
|
u8 ap_global_hlid;
|
|
|
|
u8 ap_bcast_hlid;
|
2011-08-14 18:17:07 +08:00
|
|
|
|
|
|
|
unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
|
|
|
|
unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
|
wl12xx: replace dummy_join with ROC/CROC commands
The ROC command asks the fw stay on the channel of the given
hlid. it currently has 2 primary functions:
1. Allow tx/rx from the device role.
In order to tx/rx packets while the stations is not associated
(e.g. auth req/resp), the device role has to be used, along
with ROC on its link.
Keep the logic similiar to the one used in dummy_join. However,
since we can't scan while we ROC, we add CROC before starting
a scan, and ROC again (if needed) on scan complete.
2. Keeping the antenna for a specific link.
We ROC until the connection was completed (after EAPOLs exchange)
in order to prevent BT coex operations from taking the antenna
and failing the connection (after this stage, psm can be used).
During association, we ROC on the station role, and then CROC
the device role, thus assuring being ROC during all the connection
process.
Delete the WL1271_FLAG_JOINED flag, and use a roc bitmap
to indicate what roles are currently ROCed.
Add wl12xx_roc/croc functions in order to wrap the roc/croc
commands while taking care of the roc bitmap.
The current ROC/CROC state-machine is a bit complicated. In
the future we'll probably want to use wpa_supplicant to control
the ROC during connection.
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
2011-08-14 18:17:17 +08:00
|
|
|
unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
struct wl1271_acx_mem_map *target_mem_map;
|
|
|
|
|
|
|
|
/* Accounting for allocated / available TX blocks on HW */
|
2011-08-14 18:17:05 +08:00
|
|
|
u32 tx_blocks_freed;
|
2009-08-06 21:25:28 +08:00
|
|
|
u32 tx_blocks_available;
|
2011-08-14 18:17:00 +08:00
|
|
|
u32 tx_allocated_blocks;
|
2010-02-22 14:38:31 +08:00
|
|
|
u32 tx_results_count;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2011-08-17 00:49:12 +08:00
|
|
|
/* amount of spare TX blocks to use */
|
|
|
|
u32 tx_spare_blocks;
|
|
|
|
|
2011-08-14 18:17:32 +08:00
|
|
|
/* Accounting for allocated / available Tx packets in HW */
|
|
|
|
u32 tx_pkts_freed[NUM_TX_QUEUES];
|
2011-08-14 18:17:33 +08:00
|
|
|
u32 tx_allocated_pkts[NUM_TX_QUEUES];
|
2011-08-14 18:17:32 +08:00
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
/* Transmitted TX packets counter for chipset interface */
|
2010-02-22 14:38:31 +08:00
|
|
|
u32 tx_packets_count;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
/* Time-offset between host and chipset clocks */
|
2010-02-22 14:38:38 +08:00
|
|
|
s64 time_offset;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
/* Session counter for the chipset */
|
|
|
|
int session_counter;
|
|
|
|
|
|
|
|
/* Frames scheduled for transmission, not handled yet */
|
2010-12-13 15:52:37 +08:00
|
|
|
struct sk_buff_head tx_queue[NUM_TX_QUEUES];
|
2011-07-07 19:25:23 +08:00
|
|
|
int tx_queue_count[NUM_TX_QUEUES];
|
2011-06-24 18:03:37 +08:00
|
|
|
long stopped_queues_map;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2011-03-01 21:14:41 +08:00
|
|
|
/* Frames received, not handled yet by mac80211 */
|
|
|
|
struct sk_buff_head deferred_rx_queue;
|
|
|
|
|
|
|
|
/* Frames sent, not returned yet to mac80211 */
|
|
|
|
struct sk_buff_head deferred_tx_queue;
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
struct work_struct tx_work;
|
2011-06-07 17:50:46 +08:00
|
|
|
struct workqueue_struct *freezable_wq;
|
2009-10-09 02:56:31 +08:00
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
/* Pending TX frames */
|
2010-10-12 22:20:06 +08:00
|
|
|
unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];
|
2009-10-09 02:56:26 +08:00
|
|
|
struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
|
2010-05-24 16:18:17 +08:00
|
|
|
int tx_frames_cnt;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2011-06-26 15:36:02 +08:00
|
|
|
/*
|
|
|
|
* Security sequence number
|
|
|
|
* bits 0-15: lower 16 bits part of sequence number
|
|
|
|
* bits 16-47: higher 32 bits part of sequence number
|
|
|
|
* bits 48-63: not in use
|
|
|
|
*/
|
|
|
|
u64 tx_security_seq;
|
|
|
|
|
|
|
|
/* 8 bits of the last sequence number in use */
|
|
|
|
u8 tx_security_last_seq_lsb;
|
2009-10-09 02:56:19 +08:00
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
/* FW Rx counter */
|
|
|
|
u32 rx_counter;
|
|
|
|
|
|
|
|
/* Rx memory pool address */
|
|
|
|
struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
|
|
|
|
|
2010-09-30 19:28:27 +08:00
|
|
|
/* Intermediate buffer, used for packet aggregation */
|
|
|
|
u8 *aggr_buf;
|
|
|
|
|
2011-03-31 16:06:59 +08:00
|
|
|
/* Reusable dummy packet template */
|
|
|
|
struct sk_buff *dummy_packet;
|
|
|
|
|
2011-03-01 21:14:41 +08:00
|
|
|
/* Network stack work */
|
|
|
|
struct work_struct netstack_work;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2011-06-06 19:57:06 +08:00
|
|
|
/* FW log buffer */
|
|
|
|
u8 *fwlog;
|
|
|
|
|
|
|
|
/* Number of valid bytes in the FW log buffer */
|
|
|
|
ssize_t fwlog_size;
|
|
|
|
|
|
|
|
/* Sysfs FW log entry readers wait queue */
|
|
|
|
wait_queue_head_t fwlog_waitq;
|
|
|
|
|
2010-09-21 12:23:31 +08:00
|
|
|
/* Hardware recovery work */
|
|
|
|
struct work_struct recovery_work;
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
/* The mbox event mask */
|
|
|
|
u32 event_mask;
|
|
|
|
|
|
|
|
/* Mailbox pointers */
|
|
|
|
u32 mbox_ptr[2];
|
|
|
|
|
|
|
|
/* Are we currently scanning */
|
2009-10-13 17:47:50 +08:00
|
|
|
struct wl1271_scan scan;
|
2010-09-21 12:23:32 +08:00
|
|
|
struct delayed_work scan_complete_work;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2011-05-10 19:46:02 +08:00
|
|
|
bool sched_scanning;
|
|
|
|
|
2010-11-24 14:16:57 +08:00
|
|
|
/* probe-req template for the current AP */
|
|
|
|
struct sk_buff *probereq;
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
/* Our association ID */
|
|
|
|
u16 aid;
|
|
|
|
|
2010-10-13 22:09:39 +08:00
|
|
|
/*
|
|
|
|
* currently configured rate set:
|
|
|
|
* bits 0-15 - 802.11abg rates
|
|
|
|
* bits 16-23 - 802.11n MCS index mask
|
|
|
|
* support only 1 stream, thus only 8 bits for the MCS rates (0-7).
|
|
|
|
*/
|
2009-10-09 02:56:25 +08:00
|
|
|
u32 basic_rate_set;
|
2010-04-01 16:38:20 +08:00
|
|
|
u32 basic_rate;
|
2009-12-11 21:41:06 +08:00
|
|
|
u32 rate_set;
|
2009-10-09 02:56:25 +08:00
|
|
|
|
2009-10-09 02:56:24 +08:00
|
|
|
/* The current band */
|
|
|
|
enum ieee80211_band band;
|
|
|
|
|
2010-03-26 18:53:25 +08:00
|
|
|
/* Beaconing interval (needed for ad-hoc) */
|
|
|
|
u32 beacon_int;
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
/* Default key (for WEP) */
|
|
|
|
u32 default_key;
|
|
|
|
|
2011-05-15 16:10:29 +08:00
|
|
|
/* Rx Streaming */
|
|
|
|
struct work_struct rx_streaming_enable_work;
|
|
|
|
struct work_struct rx_streaming_disable_work;
|
|
|
|
struct timer_list rx_streaming_timer;
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
struct completion *elp_compl;
|
2011-05-13 16:57:13 +08:00
|
|
|
struct completion *ps_compl;
|
2009-10-09 02:56:21 +08:00
|
|
|
struct delayed_work elp_work;
|
2010-07-08 22:50:00 +08:00
|
|
|
struct delayed_work pspoll_work;
|
|
|
|
|
|
|
|
/* counter for ps-poll delivery failures */
|
|
|
|
int ps_poll_failures;
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2009-11-03 02:22:11 +08:00
|
|
|
/* retry counter for PSM entries */
|
|
|
|
u8 psm_entry_retry;
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
/* in dBm */
|
|
|
|
int power_level;
|
|
|
|
|
2010-04-09 16:07:30 +08:00
|
|
|
int rssi_thold;
|
|
|
|
int last_rssi_event;
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
struct wl1271_stats stats;
|
|
|
|
|
2010-05-07 16:38:59 +08:00
|
|
|
__le32 buffer_32;
|
2009-08-06 21:25:28 +08:00
|
|
|
u32 buffer_cmd;
|
2009-10-09 02:56:23 +08:00
|
|
|
u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2011-08-14 18:17:05 +08:00
|
|
|
struct wl12xx_fw_status *fw_status;
|
2009-08-06 21:25:28 +08:00
|
|
|
struct wl1271_tx_hw_res_if *tx_res_if;
|
2009-10-09 02:56:34 +08:00
|
|
|
|
|
|
|
struct ieee80211_vif *vif;
|
2009-10-12 20:08:43 +08:00
|
|
|
|
2009-10-13 17:47:39 +08:00
|
|
|
/* Current chipset configuration */
|
|
|
|
struct conf_drv_settings conf;
|
2009-10-13 17:47:55 +08:00
|
|
|
|
2010-03-18 18:26:32 +08:00
|
|
|
bool sg_enabled;
|
|
|
|
|
2010-08-19 10:41:15 +08:00
|
|
|
bool enable_11a;
|
|
|
|
|
2009-10-13 17:47:55 +08:00
|
|
|
struct list_head list;
|
2010-07-29 04:41:06 +08:00
|
|
|
|
|
|
|
/* Most recently reported noise in dBm */
|
|
|
|
s8 noise;
|
2010-10-17 02:21:23 +08:00
|
|
|
|
|
|
|
/* map for HLIDs of associated stations - when operating in AP mode */
|
|
|
|
unsigned long ap_hlid_map[BITS_TO_LONGS(AP_MAX_STATIONS)];
|
2010-10-17 03:39:06 +08:00
|
|
|
|
|
|
|
/* recoreded keys for AP-mode - set here before AP startup */
|
|
|
|
struct wl1271_ap_key *recorded_ap_keys[MAX_NUM_KEYS];
|
2011-01-12 01:25:18 +08:00
|
|
|
|
|
|
|
/* bands supported by this instance of wl12xx */
|
|
|
|
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
|
2011-01-23 14:27:22 +08:00
|
|
|
|
|
|
|
/* RX BA constraint value */
|
|
|
|
bool ba_support;
|
|
|
|
u8 ba_rx_bitmap;
|
2011-05-22 21:10:22 +08:00
|
|
|
bool ba_allowed;
|
2011-02-23 06:22:26 +08:00
|
|
|
|
2011-03-06 22:32:11 +08:00
|
|
|
int tcxo_clock;
|
2011-03-06 22:32:08 +08:00
|
|
|
|
2011-05-13 16:57:09 +08:00
|
|
|
/*
|
|
|
|
* wowlan trigger was configured during suspend.
|
|
|
|
* (currently, only "ANY" trigger is supported)
|
|
|
|
*/
|
|
|
|
bool wow_enabled;
|
2011-06-06 17:21:55 +08:00
|
|
|
bool irq_wake_enabled;
|
2011-05-13 16:57:09 +08:00
|
|
|
|
2011-02-23 06:22:26 +08:00
|
|
|
/*
|
|
|
|
* AP-mode - links indexed by HLID. The global and broadcast links
|
|
|
|
* are always active.
|
|
|
|
*/
|
|
|
|
struct wl1271_link links[AP_MAX_LINKS];
|
|
|
|
|
|
|
|
/* the hlid of the link where the last transmitted skb came from */
|
|
|
|
int last_tx_hlid;
|
2011-02-23 06:22:31 +08:00
|
|
|
|
|
|
|
/* AP-mode - a bitmap of links currently in PS mode according to FW */
|
|
|
|
u32 ap_fw_ps_map;
|
|
|
|
|
|
|
|
/* AP-mode - a bitmap of links currently in PS mode in mac80211 */
|
|
|
|
unsigned long ap_ps_map;
|
2011-03-01 21:14:39 +08:00
|
|
|
|
|
|
|
/* Quirks of specific hardware revisions */
|
|
|
|
unsigned int quirks;
|
2011-03-31 16:07:01 +08:00
|
|
|
|
|
|
|
/* Platform limitations */
|
|
|
|
unsigned int platform_quirks;
|
2011-08-17 15:45:49 +08:00
|
|
|
|
|
|
|
/* number of currently active RX BA sessions */
|
|
|
|
int ba_rx_session_count;
|
2011-08-25 17:43:15 +08:00
|
|
|
|
|
|
|
/* AP-mode - number of currently connected stations */
|
|
|
|
int active_sta_count;
|
2010-10-17 02:21:23 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct wl1271_station {
|
|
|
|
u8 hlid;
|
2009-08-06 21:25:28 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
int wl1271_plt_start(struct wl1271 *wl);
|
|
|
|
int wl1271_plt_stop(struct wl1271 *wl);
|
2011-05-15 16:10:29 +08:00
|
|
|
int wl1271_recalc_rx_streaming(struct wl1271 *wl);
|
2011-06-06 19:57:05 +08:00
|
|
|
void wl12xx_queue_recovery_work(struct wl1271 *wl);
|
2011-06-06 19:57:06 +08:00
|
|
|
size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
|
2009-08-06 21:25:28 +08:00
|
|
|
|
|
|
|
#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
|
|
|
|
|
2011-06-24 18:03:36 +08:00
|
|
|
#define WL1271_TX_QUEUE_LOW_WATERMARK 32
|
|
|
|
#define WL1271_TX_QUEUE_HIGH_WATERMARK 256
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2011-03-01 21:14:41 +08:00
|
|
|
#define WL1271_DEFERRED_QUEUE_LIMIT 64
|
|
|
|
|
2009-12-11 21:41:02 +08:00
|
|
|
/* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power
|
|
|
|
on in case is has been shut down shortly before */
|
2011-01-02 22:12:42 +08:00
|
|
|
#define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */
|
|
|
|
#define WL1271_POWER_ON_SLEEP 200 /* in milliseconds */
|
2009-08-06 21:25:28 +08:00
|
|
|
|
2010-10-13 22:09:39 +08:00
|
|
|
/* Macros to handle wl1271.sta_rate_set */
|
|
|
|
#define HW_BG_RATES_MASK 0xffff
|
|
|
|
#define HW_HT_RATES_OFFSET 16
|
|
|
|
|
2011-03-01 21:14:39 +08:00
|
|
|
/* Quirks */
|
|
|
|
|
|
|
|
/* Each RX/TX transaction requires an end-of-transaction transfer */
|
2011-03-31 16:06:58 +08:00
|
|
|
#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
|
2011-03-01 21:14:39 +08:00
|
|
|
|
2011-03-31 16:06:58 +08:00
|
|
|
/* WL128X requires aggregated packets to be aligned to the SDIO block size */
|
|
|
|
#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)
|
2011-03-10 21:24:57 +08:00
|
|
|
|
2011-06-12 15:34:43 +08:00
|
|
|
/*
|
|
|
|
* WL127X AP mode requires Low Power DRPw (LPD) enable to reduce power
|
|
|
|
* consumption
|
|
|
|
*/
|
|
|
|
#define WL12XX_QUIRK_LPD_MODE BIT(3)
|
|
|
|
|
2011-06-06 19:57:06 +08:00
|
|
|
/* Older firmwares did not implement the FW logger over bus feature */
|
|
|
|
#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
|
|
|
|
|
|
|
|
#define WL12XX_HW_BLOCK_SIZE 256
|
|
|
|
|
2009-08-06 21:25:28 +08:00
|
|
|
#endif
|