cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mwl8k.c (157688B)


      1/*
      2 * drivers/net/wireless/mwl8k.c
      3 * Driver for Marvell TOPDOG 802.11 Wireless cards
      4 *
      5 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc.
      6 *
      7 * This file is licensed under the terms of the GNU General Public
      8 * License version 2.  This program is licensed "as is" without any
      9 * warranty of any kind, whether express or implied.
     10 */
     11
     12#include <linux/interrupt.h>
     13#include <linux/module.h>
     14#include <linux/kernel.h>
     15#include <linux/sched.h>
     16#include <linux/spinlock.h>
     17#include <linux/list.h>
     18#include <linux/pci.h>
     19#include <linux/delay.h>
     20#include <linux/completion.h>
     21#include <linux/etherdevice.h>
     22#include <linux/slab.h>
     23#include <net/mac80211.h>
     24#include <linux/moduleparam.h>
     25#include <linux/firmware.h>
     26#include <linux/workqueue.h>
     27
     28#define MWL8K_DESC	"Marvell TOPDOG(R) 802.11 Wireless Network Driver"
     29#define MWL8K_NAME	KBUILD_MODNAME
     30#define MWL8K_VERSION	"0.13"
     31
     32/* Module parameters */
     33static bool ap_mode_default;
     34module_param(ap_mode_default, bool, 0);
     35MODULE_PARM_DESC(ap_mode_default,
     36		 "Set to 1 to make ap mode the default instead of sta mode");
     37
     38/* Register definitions */
     39#define MWL8K_HIU_GEN_PTR			0x00000c10
     40#define  MWL8K_MODE_STA				 0x0000005a
     41#define  MWL8K_MODE_AP				 0x000000a5
     42#define MWL8K_HIU_INT_CODE			0x00000c14
     43#define  MWL8K_FWSTA_READY			 0xf0f1f2f4
     44#define  MWL8K_FWAP_READY			 0xf1f2f4a5
     45#define  MWL8K_INT_CODE_CMD_FINISHED		 0x00000005
     46#define MWL8K_HIU_SCRATCH			0x00000c40
     47
     48/* Host->device communications */
     49#define MWL8K_HIU_H2A_INTERRUPT_EVENTS		0x00000c18
     50#define MWL8K_HIU_H2A_INTERRUPT_STATUS		0x00000c1c
     51#define MWL8K_HIU_H2A_INTERRUPT_MASK		0x00000c20
     52#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL	0x00000c24
     53#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK	0x00000c28
     54#define  MWL8K_H2A_INT_DUMMY			 (1 << 20)
     55#define  MWL8K_H2A_INT_RESET			 (1 << 15)
     56#define  MWL8K_H2A_INT_DOORBELL			 (1 << 1)
     57#define  MWL8K_H2A_INT_PPA_READY		 (1 << 0)
     58
     59/* Device->host communications */
     60#define MWL8K_HIU_A2H_INTERRUPT_EVENTS		0x00000c2c
     61#define MWL8K_HIU_A2H_INTERRUPT_STATUS		0x00000c30
     62#define MWL8K_HIU_A2H_INTERRUPT_MASK		0x00000c34
     63#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL	0x00000c38
     64#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK	0x00000c3c
     65#define  MWL8K_A2H_INT_DUMMY			 (1 << 20)
     66#define  MWL8K_A2H_INT_BA_WATCHDOG		 (1 << 14)
     67#define  MWL8K_A2H_INT_CHNL_SWITCHED		 (1 << 11)
     68#define  MWL8K_A2H_INT_QUEUE_EMPTY		 (1 << 10)
     69#define  MWL8K_A2H_INT_RADAR_DETECT		 (1 << 7)
     70#define  MWL8K_A2H_INT_RADIO_ON			 (1 << 6)
     71#define  MWL8K_A2H_INT_RADIO_OFF		 (1 << 5)
     72#define  MWL8K_A2H_INT_MAC_EVENT		 (1 << 3)
     73#define  MWL8K_A2H_INT_OPC_DONE			 (1 << 2)
     74#define  MWL8K_A2H_INT_RX_READY			 (1 << 1)
     75#define  MWL8K_A2H_INT_TX_DONE			 (1 << 0)
     76
     77/* HW micro second timer register
     78 * located at offset 0xA600. This
     79 * will be used to timestamp tx
     80 * packets.
     81 */
     82
     83#define	MWL8K_HW_TIMER_REGISTER			0x0000a600
     84#define BBU_RXRDY_CNT_REG			0x0000a860
     85#define NOK_CCA_CNT_REG				0x0000a6a0
     86#define BBU_AVG_NOISE_VAL			0x67
     87
     88#define MWL8K_A2H_EVENTS	(MWL8K_A2H_INT_DUMMY | \
     89				 MWL8K_A2H_INT_CHNL_SWITCHED | \
     90				 MWL8K_A2H_INT_QUEUE_EMPTY | \
     91				 MWL8K_A2H_INT_RADAR_DETECT | \
     92				 MWL8K_A2H_INT_RADIO_ON | \
     93				 MWL8K_A2H_INT_RADIO_OFF | \
     94				 MWL8K_A2H_INT_MAC_EVENT | \
     95				 MWL8K_A2H_INT_OPC_DONE | \
     96				 MWL8K_A2H_INT_RX_READY | \
     97				 MWL8K_A2H_INT_TX_DONE | \
     98				 MWL8K_A2H_INT_BA_WATCHDOG)
     99
    100#define MWL8K_RX_QUEUES		1
    101#define MWL8K_TX_WMM_QUEUES	4
    102#define MWL8K_MAX_AMPDU_QUEUES	8
    103#define MWL8K_MAX_TX_QUEUES	(MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
    104#define mwl8k_tx_queues(priv)	(MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
    105
    106/* txpriorities are mapped with hw queues.
    107 * Each hw queue has a txpriority.
    108 */
    109#define TOTAL_HW_TX_QUEUES	8
    110
    111/* Each HW queue can have one AMPDU stream.
    112 * But, because one of the hw queue is reserved,
    113 * maximum AMPDU queues that can be created are
    114 * one short of total tx queues.
    115 */
    116#define MWL8K_NUM_AMPDU_STREAMS	(TOTAL_HW_TX_QUEUES - 1)
    117
    118#define MWL8K_NUM_CHANS 18
    119
    120struct rxd_ops {
    121	int rxd_size;
    122	void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
    123	void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
    124	int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
    125			   __le16 *qos, s8 *noise);
    126};
    127
    128struct mwl8k_device_info {
    129	char *part_name;
    130	char *helper_image;
    131	char *fw_image_sta;
    132	char *fw_image_ap;
    133	struct rxd_ops *ap_rxd_ops;
    134	u32 fw_api_ap;
    135};
    136
    137struct mwl8k_rx_queue {
    138	int rxd_count;
    139
    140	/* hw receives here */
    141	int head;
    142
    143	/* refill descs here */
    144	int tail;
    145
    146	void *rxd;
    147	dma_addr_t rxd_dma;
    148	struct {
    149		struct sk_buff *skb;
    150		DEFINE_DMA_UNMAP_ADDR(dma);
    151	} *buf;
    152};
    153
    154struct mwl8k_tx_queue {
    155	/* hw transmits here */
    156	int head;
    157
    158	/* sw appends here */
    159	int tail;
    160
    161	unsigned int len;
    162	struct mwl8k_tx_desc *txd;
    163	dma_addr_t txd_dma;
    164	struct sk_buff **skb;
    165};
    166
    167enum {
    168	AMPDU_NO_STREAM,
    169	AMPDU_STREAM_NEW,
    170	AMPDU_STREAM_IN_PROGRESS,
    171	AMPDU_STREAM_ACTIVE,
    172};
    173
    174struct mwl8k_ampdu_stream {
    175	struct ieee80211_sta *sta;
    176	u8 tid;
    177	u8 state;
    178	u8 idx;
    179};
    180
    181struct mwl8k_priv {
    182	struct ieee80211_hw *hw;
    183	struct pci_dev *pdev;
    184	int irq;
    185
    186	struct mwl8k_device_info *device_info;
    187
    188	void __iomem *sram;
    189	void __iomem *regs;
    190
    191	/* firmware */
    192	const struct firmware *fw_helper;
    193	const struct firmware *fw_ucode;
    194
    195	/* hardware/firmware parameters */
    196	bool ap_fw;
    197	struct rxd_ops *rxd_ops;
    198	struct ieee80211_supported_band band_24;
    199	struct ieee80211_channel channels_24[14];
    200	struct ieee80211_rate rates_24[13];
    201	struct ieee80211_supported_band band_50;
    202	struct ieee80211_channel channels_50[9];
    203	struct ieee80211_rate rates_50[8];
    204	u32 ap_macids_supported;
    205	u32 sta_macids_supported;
    206
    207	/* Ampdu stream information */
    208	u8 num_ampdu_queues;
    209	spinlock_t stream_lock;
    210	struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES];
    211	struct work_struct watchdog_ba_handle;
    212
    213	/* firmware access */
    214	struct mutex fw_mutex;
    215	struct task_struct *fw_mutex_owner;
    216	struct task_struct *hw_restart_owner;
    217	int fw_mutex_depth;
    218	struct completion *hostcmd_wait;
    219
    220	atomic_t watchdog_event_pending;
    221
    222	/* lock held over TX and TX reap */
    223	spinlock_t tx_lock;
    224
    225	/* TX quiesce completion, protected by fw_mutex and tx_lock */
    226	struct completion *tx_wait;
    227
    228	/* List of interfaces.  */
    229	u32 macids_used;
    230	struct list_head vif_list;
    231
    232	/* power management status cookie from firmware */
    233	u32 *cookie;
    234	dma_addr_t cookie_dma;
    235
    236	u16 num_mcaddrs;
    237	u8 hw_rev;
    238	u32 fw_rev;
    239	u32 caps;
    240
    241	/*
    242	 * Running count of TX packets in flight, to avoid
    243	 * iterating over the transmit rings each time.
    244	 */
    245	int pending_tx_pkts;
    246
    247	struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
    248	struct mwl8k_tx_queue txq[MWL8K_MAX_TX_QUEUES];
    249	u32 txq_offset[MWL8K_MAX_TX_QUEUES];
    250
    251	bool radio_on;
    252	bool radio_short_preamble;
    253	bool sniffer_enabled;
    254	bool wmm_enabled;
    255
    256	/* XXX need to convert this to handle multiple interfaces */
    257	bool capture_beacon;
    258	u8 capture_bssid[ETH_ALEN];
    259	struct sk_buff *beacon_skb;
    260
    261	/*
    262	 * This FJ worker has to be global as it is scheduled from the
    263	 * RX handler.  At this point we don't know which interface it
    264	 * belongs to until the list of bssids waiting to complete join
    265	 * is checked.
    266	 */
    267	struct work_struct finalize_join_worker;
    268
    269	/* Tasklet to perform TX reclaim.  */
    270	struct tasklet_struct poll_tx_task;
    271
    272	/* Tasklet to perform RX.  */
    273	struct tasklet_struct poll_rx_task;
    274
    275	/* Most recently reported noise in dBm */
    276	s8 noise;
    277
    278	/*
    279	 * preserve the queue configurations so they can be restored if/when
    280	 * the firmware image is swapped.
    281	 */
    282	struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];
    283
    284	/* To perform the task of reloading the firmware */
    285	struct work_struct fw_reload;
    286	bool hw_restart_in_progress;
    287
    288	/* async firmware loading state */
    289	unsigned fw_state;
    290	char *fw_pref;
    291	char *fw_alt;
    292	bool is_8764;
    293	struct completion firmware_loading_complete;
    294
    295	/* bitmap of running BSSes */
    296	u32 running_bsses;
    297
    298	/* ACS related */
    299	bool sw_scan_start;
    300	struct ieee80211_channel *acs_chan;
    301	unsigned long channel_time;
    302	struct survey_info survey[MWL8K_NUM_CHANS];
    303};
    304
    305#define MAX_WEP_KEY_LEN         13
    306#define NUM_WEP_KEYS            4
    307
    308/* Per interface specific private data */
    309struct mwl8k_vif {
    310	struct list_head list;
    311	struct ieee80211_vif *vif;
    312
    313	/* Firmware macid for this vif.  */
    314	int macid;
    315
    316	/* Non AMPDU sequence number assigned by driver.  */
    317	u16 seqno;
    318
    319	/* Saved WEP keys */
    320	struct {
    321		u8 enabled;
    322		u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN];
    323	} wep_key_conf[NUM_WEP_KEYS];
    324
    325	/* BSSID */
    326	u8 bssid[ETH_ALEN];
    327
    328	/* A flag to indicate is HW crypto is enabled for this bssid */
    329	bool is_hw_crypto_enabled;
    330};
    331#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
    332#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
    333
    334struct tx_traffic_info {
    335	u32 start_time;
    336	u32 pkts;
    337};
    338
    339#define MWL8K_MAX_TID 8
    340struct mwl8k_sta {
    341	/* Index into station database. Returned by UPDATE_STADB.  */
    342	u8 peer_id;
    343	u8 is_ampdu_allowed;
    344	struct tx_traffic_info tx_stats[MWL8K_MAX_TID];
    345};
    346#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
    347
    348static const struct ieee80211_channel mwl8k_channels_24[] = {
    349	{ .band = NL80211_BAND_2GHZ, .center_freq = 2412, .hw_value = 1, },
    350	{ .band = NL80211_BAND_2GHZ, .center_freq = 2417, .hw_value = 2, },
    351	{ .band = NL80211_BAND_2GHZ, .center_freq = 2422, .hw_value = 3, },
    352	{ .band = NL80211_BAND_2GHZ, .center_freq = 2427, .hw_value = 4, },
    353	{ .band = NL80211_BAND_2GHZ, .center_freq = 2432, .hw_value = 5, },
    354	{ .band = NL80211_BAND_2GHZ, .center_freq = 2437, .hw_value = 6, },
    355	{ .band = NL80211_BAND_2GHZ, .center_freq = 2442, .hw_value = 7, },
    356	{ .band = NL80211_BAND_2GHZ, .center_freq = 2447, .hw_value = 8, },
    357	{ .band = NL80211_BAND_2GHZ, .center_freq = 2452, .hw_value = 9, },
    358	{ .band = NL80211_BAND_2GHZ, .center_freq = 2457, .hw_value = 10, },
    359	{ .band = NL80211_BAND_2GHZ, .center_freq = 2462, .hw_value = 11, },
    360	{ .band = NL80211_BAND_2GHZ, .center_freq = 2467, .hw_value = 12, },
    361	{ .band = NL80211_BAND_2GHZ, .center_freq = 2472, .hw_value = 13, },
    362	{ .band = NL80211_BAND_2GHZ, .center_freq = 2484, .hw_value = 14, },
    363};
    364
    365static const struct ieee80211_rate mwl8k_rates_24[] = {
    366	{ .bitrate = 10, .hw_value = 2, },
    367	{ .bitrate = 20, .hw_value = 4, },
    368	{ .bitrate = 55, .hw_value = 11, },
    369	{ .bitrate = 110, .hw_value = 22, },
    370	{ .bitrate = 220, .hw_value = 44, },
    371	{ .bitrate = 60, .hw_value = 12, },
    372	{ .bitrate = 90, .hw_value = 18, },
    373	{ .bitrate = 120, .hw_value = 24, },
    374	{ .bitrate = 180, .hw_value = 36, },
    375	{ .bitrate = 240, .hw_value = 48, },
    376	{ .bitrate = 360, .hw_value = 72, },
    377	{ .bitrate = 480, .hw_value = 96, },
    378	{ .bitrate = 540, .hw_value = 108, },
    379};
    380
    381static const struct ieee80211_channel mwl8k_channels_50[] = {
    382	{ .band = NL80211_BAND_5GHZ, .center_freq = 5180, .hw_value = 36, },
    383	{ .band = NL80211_BAND_5GHZ, .center_freq = 5200, .hw_value = 40, },
    384	{ .band = NL80211_BAND_5GHZ, .center_freq = 5220, .hw_value = 44, },
    385	{ .band = NL80211_BAND_5GHZ, .center_freq = 5240, .hw_value = 48, },
    386	{ .band = NL80211_BAND_5GHZ, .center_freq = 5745, .hw_value = 149, },
    387	{ .band = NL80211_BAND_5GHZ, .center_freq = 5765, .hw_value = 153, },
    388	{ .band = NL80211_BAND_5GHZ, .center_freq = 5785, .hw_value = 157, },
    389	{ .band = NL80211_BAND_5GHZ, .center_freq = 5805, .hw_value = 161, },
    390	{ .band = NL80211_BAND_5GHZ, .center_freq = 5825, .hw_value = 165, },
    391};
    392
    393static const struct ieee80211_rate mwl8k_rates_50[] = {
    394	{ .bitrate = 60, .hw_value = 12, },
    395	{ .bitrate = 90, .hw_value = 18, },
    396	{ .bitrate = 120, .hw_value = 24, },
    397	{ .bitrate = 180, .hw_value = 36, },
    398	{ .bitrate = 240, .hw_value = 48, },
    399	{ .bitrate = 360, .hw_value = 72, },
    400	{ .bitrate = 480, .hw_value = 96, },
    401	{ .bitrate = 540, .hw_value = 108, },
    402};
    403
    404/* Set or get info from Firmware */
    405#define MWL8K_CMD_GET			0x0000
    406#define MWL8K_CMD_SET			0x0001
    407#define MWL8K_CMD_SET_LIST		0x0002
    408
    409/* Firmware command codes */
    410#define MWL8K_CMD_CODE_DNLD		0x0001
    411#define MWL8K_CMD_GET_HW_SPEC		0x0003
    412#define MWL8K_CMD_SET_HW_SPEC		0x0004
    413#define MWL8K_CMD_MAC_MULTICAST_ADR	0x0010
    414#define MWL8K_CMD_GET_STAT		0x0014
    415#define MWL8K_CMD_BBP_REG_ACCESS	0x001a
    416#define MWL8K_CMD_RADIO_CONTROL		0x001c
    417#define MWL8K_CMD_RF_TX_POWER		0x001e
    418#define MWL8K_CMD_TX_POWER		0x001f
    419#define MWL8K_CMD_RF_ANTENNA		0x0020
    420#define MWL8K_CMD_SET_BEACON		0x0100		/* per-vif */
    421#define MWL8K_CMD_SET_PRE_SCAN		0x0107
    422#define MWL8K_CMD_SET_POST_SCAN		0x0108
    423#define MWL8K_CMD_SET_RF_CHANNEL	0x010a
    424#define MWL8K_CMD_SET_AID		0x010d
    425#define MWL8K_CMD_SET_RATE		0x0110
    426#define MWL8K_CMD_SET_FINALIZE_JOIN	0x0111
    427#define MWL8K_CMD_RTS_THRESHOLD		0x0113
    428#define MWL8K_CMD_SET_SLOT		0x0114
    429#define MWL8K_CMD_SET_EDCA_PARAMS	0x0115
    430#define MWL8K_CMD_SET_WMM_MODE		0x0123
    431#define MWL8K_CMD_MIMO_CONFIG		0x0125
    432#define MWL8K_CMD_USE_FIXED_RATE	0x0126
    433#define MWL8K_CMD_ENABLE_SNIFFER	0x0150
    434#define MWL8K_CMD_SET_MAC_ADDR		0x0202		/* per-vif */
    435#define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
    436#define MWL8K_CMD_GET_WATCHDOG_BITMAP	0x0205
    437#define MWL8K_CMD_DEL_MAC_ADDR		0x0206		/* per-vif */
    438#define MWL8K_CMD_BSS_START		0x1100		/* per-vif */
    439#define MWL8K_CMD_SET_NEW_STN		0x1111		/* per-vif */
    440#define MWL8K_CMD_UPDATE_ENCRYPTION	0x1122		/* per-vif */
    441#define MWL8K_CMD_UPDATE_STADB		0x1123
    442#define MWL8K_CMD_BASTREAM		0x1125
    443
    444#define MWL8K_LEGACY_5G_RATE_OFFSET \
    445	(ARRAY_SIZE(mwl8k_rates_24) - ARRAY_SIZE(mwl8k_rates_50))
    446
    447static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
    448{
    449	u16 command = le16_to_cpu(cmd);
    450
    451#define MWL8K_CMDNAME(x)	case MWL8K_CMD_##x: do {\
    452					snprintf(buf, bufsize, "%s", #x);\
    453					return buf;\
    454					} while (0)
    455	switch (command & ~0x8000) {
    456		MWL8K_CMDNAME(CODE_DNLD);
    457		MWL8K_CMDNAME(GET_HW_SPEC);
    458		MWL8K_CMDNAME(SET_HW_SPEC);
    459		MWL8K_CMDNAME(MAC_MULTICAST_ADR);
    460		MWL8K_CMDNAME(GET_STAT);
    461		MWL8K_CMDNAME(RADIO_CONTROL);
    462		MWL8K_CMDNAME(RF_TX_POWER);
    463		MWL8K_CMDNAME(TX_POWER);
    464		MWL8K_CMDNAME(RF_ANTENNA);
    465		MWL8K_CMDNAME(SET_BEACON);
    466		MWL8K_CMDNAME(SET_PRE_SCAN);
    467		MWL8K_CMDNAME(SET_POST_SCAN);
    468		MWL8K_CMDNAME(SET_RF_CHANNEL);
    469		MWL8K_CMDNAME(SET_AID);
    470		MWL8K_CMDNAME(SET_RATE);
    471		MWL8K_CMDNAME(SET_FINALIZE_JOIN);
    472		MWL8K_CMDNAME(RTS_THRESHOLD);
    473		MWL8K_CMDNAME(SET_SLOT);
    474		MWL8K_CMDNAME(SET_EDCA_PARAMS);
    475		MWL8K_CMDNAME(SET_WMM_MODE);
    476		MWL8K_CMDNAME(MIMO_CONFIG);
    477		MWL8K_CMDNAME(USE_FIXED_RATE);
    478		MWL8K_CMDNAME(ENABLE_SNIFFER);
    479		MWL8K_CMDNAME(SET_MAC_ADDR);
    480		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
    481		MWL8K_CMDNAME(BSS_START);
    482		MWL8K_CMDNAME(SET_NEW_STN);
    483		MWL8K_CMDNAME(UPDATE_ENCRYPTION);
    484		MWL8K_CMDNAME(UPDATE_STADB);
    485		MWL8K_CMDNAME(BASTREAM);
    486		MWL8K_CMDNAME(GET_WATCHDOG_BITMAP);
    487	default:
    488		snprintf(buf, bufsize, "0x%x", cmd);
    489	}
    490#undef MWL8K_CMDNAME
    491
    492	return buf;
    493}
    494
    495/* Hardware and firmware reset */
    496static void mwl8k_hw_reset(struct mwl8k_priv *priv)
    497{
    498	iowrite32(MWL8K_H2A_INT_RESET,
    499		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
    500	iowrite32(MWL8K_H2A_INT_RESET,
    501		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
    502	msleep(20);
    503}
    504
    505/* Release fw image */
    506static void mwl8k_release_fw(const struct firmware **fw)
    507{
    508	if (*fw == NULL)
    509		return;
    510	release_firmware(*fw);
    511	*fw = NULL;
    512}
    513
    514static void mwl8k_release_firmware(struct mwl8k_priv *priv)
    515{
    516	mwl8k_release_fw(&priv->fw_ucode);
    517	mwl8k_release_fw(&priv->fw_helper);
    518}
    519
    520/* states for asynchronous f/w loading */
    521static void mwl8k_fw_state_machine(const struct firmware *fw, void *context);
    522enum {
    523	FW_STATE_INIT = 0,
    524	FW_STATE_LOADING_PREF,
    525	FW_STATE_LOADING_ALT,
    526	FW_STATE_ERROR,
    527};
    528
    529/* Request fw image */
    530static int mwl8k_request_fw(struct mwl8k_priv *priv,
    531			    const char *fname, const struct firmware **fw,
    532			    bool nowait)
    533{
    534	/* release current image */
    535	if (*fw != NULL)
    536		mwl8k_release_fw(fw);
    537
    538	if (nowait)
    539		return request_firmware_nowait(THIS_MODULE, 1, fname,
    540					       &priv->pdev->dev, GFP_KERNEL,
    541					       priv, mwl8k_fw_state_machine);
    542	else
    543		return request_firmware(fw, fname, &priv->pdev->dev);
    544}
    545
    546static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image,
    547				  bool nowait)
    548{
    549	struct mwl8k_device_info *di = priv->device_info;
    550	int rc;
    551
    552	if (di->helper_image != NULL) {
    553		if (nowait)
    554			rc = mwl8k_request_fw(priv, di->helper_image,
    555					      &priv->fw_helper, true);
    556		else
    557			rc = mwl8k_request_fw(priv, di->helper_image,
    558					      &priv->fw_helper, false);
    559		if (rc)
    560			printk(KERN_ERR "%s: Error requesting helper fw %s\n",
    561			       pci_name(priv->pdev), di->helper_image);
    562
    563		if (rc || nowait)
    564			return rc;
    565	}
    566
    567	if (nowait) {
    568		/*
    569		 * if we get here, no helper image is needed.  Skip the
    570		 * FW_STATE_INIT state.
    571		 */
    572		priv->fw_state = FW_STATE_LOADING_PREF;
    573		rc = mwl8k_request_fw(priv, fw_image,
    574				      &priv->fw_ucode,
    575				      true);
    576	} else
    577		rc = mwl8k_request_fw(priv, fw_image,
    578				      &priv->fw_ucode, false);
    579	if (rc) {
    580		printk(KERN_ERR "%s: Error requesting firmware file %s\n",
    581		       pci_name(priv->pdev), fw_image);
    582		mwl8k_release_fw(&priv->fw_helper);
    583		return rc;
    584	}
    585
    586	return 0;
    587}
    588
    589struct mwl8k_cmd_pkt {
    590	__le16	code;
    591	__le16	length;
    592	__u8	seq_num;
    593	__u8	macid;
    594	__le16	result;
    595	char	payload[];
    596} __packed;
    597
    598/*
    599 * Firmware loading.
    600 */
    601static int
    602mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
    603{
    604	void __iomem *regs = priv->regs;
    605	dma_addr_t dma_addr;
    606	int loops;
    607
    608	dma_addr = dma_map_single(&priv->pdev->dev, data, length,
    609				  DMA_TO_DEVICE);
    610	if (dma_mapping_error(&priv->pdev->dev, dma_addr))
    611		return -ENOMEM;
    612
    613	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
    614	iowrite32(0, regs + MWL8K_HIU_INT_CODE);
    615	iowrite32(MWL8K_H2A_INT_DOORBELL,
    616		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
    617	iowrite32(MWL8K_H2A_INT_DUMMY,
    618		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
    619
    620	loops = 1000;
    621	do {
    622		u32 int_code;
    623		if (priv->is_8764) {
    624			int_code = ioread32(regs +
    625					    MWL8K_HIU_H2A_INTERRUPT_STATUS);
    626			if (int_code == 0)
    627				break;
    628		} else {
    629			int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
    630			if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
    631				iowrite32(0, regs + MWL8K_HIU_INT_CODE);
    632				break;
    633			}
    634		}
    635		cond_resched();
    636		udelay(1);
    637	} while (--loops);
    638
    639	dma_unmap_single(&priv->pdev->dev, dma_addr, length, DMA_TO_DEVICE);
    640
    641	return loops ? 0 : -ETIMEDOUT;
    642}
    643
    644static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
    645				const u8 *data, size_t length)
    646{
    647	struct mwl8k_cmd_pkt *cmd;
    648	int done;
    649	int rc = 0;
    650
    651	cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL);
    652	if (cmd == NULL)
    653		return -ENOMEM;
    654
    655	cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
    656	cmd->seq_num = 0;
    657	cmd->macid = 0;
    658	cmd->result = 0;
    659
    660	done = 0;
    661	while (length) {
    662		int block_size = length > 256 ? 256 : length;
    663
    664		memcpy(cmd->payload, data + done, block_size);
    665		cmd->length = cpu_to_le16(block_size);
    666
    667		rc = mwl8k_send_fw_load_cmd(priv, cmd,
    668						sizeof(*cmd) + block_size);
    669		if (rc)
    670			break;
    671
    672		done += block_size;
    673		length -= block_size;
    674	}
    675
    676	if (!rc) {
    677		cmd->length = 0;
    678		rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd));
    679	}
    680
    681	kfree(cmd);
    682
    683	return rc;
    684}
    685
    686static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
    687				const u8 *data, size_t length)
    688{
    689	unsigned char *buffer;
    690	int may_continue, rc = 0;
    691	u32 done, prev_block_size;
    692
    693	buffer = kmalloc(1024, GFP_KERNEL);
    694	if (buffer == NULL)
    695		return -ENOMEM;
    696
    697	done = 0;
    698	prev_block_size = 0;
    699	may_continue = 1000;
    700	while (may_continue > 0) {
    701		u32 block_size;
    702
    703		block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH);
    704		if (block_size & 1) {
    705			block_size &= ~1;
    706			may_continue--;
    707		} else {
    708			done += prev_block_size;
    709			length -= prev_block_size;
    710		}
    711
    712		if (block_size > 1024 || block_size > length) {
    713			rc = -EOVERFLOW;
    714			break;
    715		}
    716
    717		if (length == 0) {
    718			rc = 0;
    719			break;
    720		}
    721
    722		if (block_size == 0) {
    723			rc = -EPROTO;
    724			may_continue--;
    725			udelay(1);
    726			continue;
    727		}
    728
    729		prev_block_size = block_size;
    730		memcpy(buffer, data + done, block_size);
    731
    732		rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
    733		if (rc)
    734			break;
    735	}
    736
    737	if (!rc && length != 0)
    738		rc = -EREMOTEIO;
    739
    740	kfree(buffer);
    741
    742	return rc;
    743}
    744
    745static int mwl8k_load_firmware(struct ieee80211_hw *hw)
    746{
    747	struct mwl8k_priv *priv = hw->priv;
    748	const struct firmware *fw = priv->fw_ucode;
    749	int rc;
    750	int loops;
    751
    752	if (!memcmp(fw->data, "\x01\x00\x00\x00", 4) && !priv->is_8764) {
    753		const struct firmware *helper = priv->fw_helper;
    754
    755		if (helper == NULL) {
    756			printk(KERN_ERR "%s: helper image needed but none "
    757			       "given\n", pci_name(priv->pdev));
    758			return -EINVAL;
    759		}
    760
    761		rc = mwl8k_load_fw_image(priv, helper->data, helper->size);
    762		if (rc) {
    763			printk(KERN_ERR "%s: unable to load firmware "
    764			       "helper image\n", pci_name(priv->pdev));
    765			return rc;
    766		}
    767		msleep(20);
    768
    769		rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
    770	} else {
    771		if (priv->is_8764)
    772			rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
    773		else
    774			rc = mwl8k_load_fw_image(priv, fw->data, fw->size);
    775	}
    776
    777	if (rc) {
    778		printk(KERN_ERR "%s: unable to load firmware image\n",
    779		       pci_name(priv->pdev));
    780		return rc;
    781	}
    782
    783	iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
    784
    785	loops = 500000;
    786	do {
    787		u32 ready_code;
    788
    789		ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE);
    790		if (ready_code == MWL8K_FWAP_READY) {
    791			priv->ap_fw = true;
    792			break;
    793		} else if (ready_code == MWL8K_FWSTA_READY) {
    794			priv->ap_fw = false;
    795			break;
    796		}
    797
    798		cond_resched();
    799		udelay(1);
    800	} while (--loops);
    801
    802	return loops ? 0 : -ETIMEDOUT;
    803}
    804
    805
    806/* DMA header used by firmware and hardware.  */
    807struct mwl8k_dma_data {
    808	__le16 fwlen;
    809	struct ieee80211_hdr wh;
    810	char data[];
    811} __packed __aligned(2);
    812
    813/* Routines to add/remove DMA header from skb.  */
    814static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
    815{
    816	struct mwl8k_dma_data *tr;
    817	int hdrlen;
    818
    819	tr = (struct mwl8k_dma_data *)skb->data;
    820	hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
    821
    822	if (hdrlen != sizeof(tr->wh)) {
    823		if (ieee80211_is_data_qos(tr->wh.frame_control)) {
    824			memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2);
    825			*((__le16 *)(tr->data - 2)) = qos;
    826		} else {
    827			memmove(tr->data - hdrlen, &tr->wh, hdrlen);
    828		}
    829	}
    830
    831	if (hdrlen != sizeof(*tr))
    832		skb_pull(skb, sizeof(*tr) - hdrlen);
    833}
    834
    835#define REDUCED_TX_HEADROOM	8
    836
    837static void
    838mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb,
    839						int head_pad, int tail_pad)
    840{
    841	struct ieee80211_hdr *wh;
    842	int hdrlen;
    843	int reqd_hdrlen;
    844	struct mwl8k_dma_data *tr;
    845
    846	/*
    847	 * Add a firmware DMA header; the firmware requires that we
    848	 * present a 2-byte payload length followed by a 4-address
    849	 * header (without QoS field), followed (optionally) by any
    850	 * WEP/ExtIV header (but only filled in for CCMP).
    851	 */
    852	wh = (struct ieee80211_hdr *)skb->data;
    853
    854	hdrlen = ieee80211_hdrlen(wh->frame_control);
    855
    856	/*
    857	 * Check if skb_resize is required because of
    858	 * tx_headroom adjustment.
    859	 */
    860	if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts)
    861						+ REDUCED_TX_HEADROOM))) {
    862		if (pskb_expand_head(skb, REDUCED_TX_HEADROOM, 0, GFP_ATOMIC)) {
    863
    864			wiphy_err(priv->hw->wiphy,
    865					"Failed to reallocate TX buffer\n");
    866			return;
    867		}
    868		skb->truesize += REDUCED_TX_HEADROOM;
    869	}
    870
    871	reqd_hdrlen = sizeof(*tr) + head_pad;
    872
    873	if (hdrlen != reqd_hdrlen)
    874		skb_push(skb, reqd_hdrlen - hdrlen);
    875
    876	if (ieee80211_is_data_qos(wh->frame_control))
    877		hdrlen -= IEEE80211_QOS_CTL_LEN;
    878
    879	tr = (struct mwl8k_dma_data *)skb->data;
    880	if (wh != &tr->wh)
    881		memmove(&tr->wh, wh, hdrlen);
    882	if (hdrlen != sizeof(tr->wh))
    883		memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
    884
    885	/*
    886	 * Firmware length is the length of the fully formed "802.11
    887	 * payload".  That is, everything except for the 802.11 header.
    888	 * This includes all crypto material including the MIC.
    889	 */
    890	tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
    891}
    892
    893static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
    894		struct sk_buff *skb)
    895{
    896	struct ieee80211_hdr *wh;
    897	struct ieee80211_tx_info *tx_info;
    898	struct ieee80211_key_conf *key_conf;
    899	int data_pad;
    900	int head_pad = 0;
    901
    902	wh = (struct ieee80211_hdr *)skb->data;
    903
    904	tx_info = IEEE80211_SKB_CB(skb);
    905
    906	key_conf = NULL;
    907	if (ieee80211_is_data(wh->frame_control))
    908		key_conf = tx_info->control.hw_key;
    909
    910	/*
    911	 * Make sure the packet header is in the DMA header format (4-address
    912	 * without QoS), and add head & tail padding when HW crypto is enabled.
    913	 *
    914	 * We have the following trailer padding requirements:
    915	 * - WEP: 4 trailer bytes (ICV)
    916	 * - TKIP: 12 trailer bytes (8 MIC + 4 ICV)
    917	 * - CCMP: 8 trailer bytes (MIC)
    918	 */
    919	data_pad = 0;
    920	if (key_conf != NULL) {
    921		head_pad = key_conf->iv_len;
    922		switch (key_conf->cipher) {
    923		case WLAN_CIPHER_SUITE_WEP40:
    924		case WLAN_CIPHER_SUITE_WEP104:
    925			data_pad = 4;
    926			break;
    927		case WLAN_CIPHER_SUITE_TKIP:
    928			data_pad = 12;
    929			break;
    930		case WLAN_CIPHER_SUITE_CCMP:
    931			data_pad = 8;
    932			break;
    933		}
    934	}
    935	mwl8k_add_dma_header(priv, skb, head_pad, data_pad);
    936}
    937
    938/*
    939 * Packet reception for 88w8366/88w8764 AP firmware.
    940 */
    941struct mwl8k_rxd_ap {
    942	__le16 pkt_len;
    943	__u8 sq2;
    944	__u8 rate;
    945	__le32 pkt_phys_addr;
    946	__le32 next_rxd_phys_addr;
    947	__le16 qos_control;
    948	__le16 htsig2;
    949	__le32 hw_rssi_info;
    950	__le32 hw_noise_floor_info;
    951	__u8 noise_floor;
    952	__u8 pad0[3];
    953	__u8 rssi;
    954	__u8 rx_status;
    955	__u8 channel;
    956	__u8 rx_ctrl;
    957} __packed;
    958
    959#define MWL8K_AP_RATE_INFO_MCS_FORMAT		0x80
    960#define MWL8K_AP_RATE_INFO_40MHZ		0x40
    961#define MWL8K_AP_RATE_INFO_RATEID(x)		((x) & 0x3f)
    962
    963#define MWL8K_AP_RX_CTRL_OWNED_BY_HOST		0x80
    964
    965/* 8366/8764 AP rx_status bits */
    966#define MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK		0x80
    967#define MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR		0xFF
    968#define MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR		0x02
    969#define MWL8K_AP_RXSTAT_WEP_DECRYPT_ICV_ERR		0x04
    970#define MWL8K_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR		0x08
    971
    972static void mwl8k_rxd_ap_init(void *_rxd, dma_addr_t next_dma_addr)
    973{
    974	struct mwl8k_rxd_ap *rxd = _rxd;
    975
    976	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
    977	rxd->rx_ctrl = MWL8K_AP_RX_CTRL_OWNED_BY_HOST;
    978}
    979
    980static void mwl8k_rxd_ap_refill(void *_rxd, dma_addr_t addr, int len)
    981{
    982	struct mwl8k_rxd_ap *rxd = _rxd;
    983
    984	rxd->pkt_len = cpu_to_le16(len);
    985	rxd->pkt_phys_addr = cpu_to_le32(addr);
    986	wmb();
    987	rxd->rx_ctrl = 0;
    988}
    989
    990static int
    991mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status,
    992		     __le16 *qos, s8 *noise)
    993{
    994	struct mwl8k_rxd_ap *rxd = _rxd;
    995
    996	if (!(rxd->rx_ctrl & MWL8K_AP_RX_CTRL_OWNED_BY_HOST))
    997		return -1;
    998	rmb();
    999
   1000	memset(status, 0, sizeof(*status));
   1001
   1002	status->signal = -rxd->rssi;
   1003	*noise = -rxd->noise_floor;
   1004
   1005	if (rxd->rate & MWL8K_AP_RATE_INFO_MCS_FORMAT) {
   1006		status->encoding = RX_ENC_HT;
   1007		if (rxd->rate & MWL8K_AP_RATE_INFO_40MHZ)
   1008			status->bw = RATE_INFO_BW_40;
   1009		status->rate_idx = MWL8K_AP_RATE_INFO_RATEID(rxd->rate);
   1010	} else {
   1011		int i;
   1012
   1013		for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) {
   1014			if (mwl8k_rates_24[i].hw_value == rxd->rate) {
   1015				status->rate_idx = i;
   1016				break;
   1017			}
   1018		}
   1019	}
   1020
   1021	if (rxd->channel > 14) {
   1022		status->band = NL80211_BAND_5GHZ;
   1023		if (!(status->encoding == RX_ENC_HT) &&
   1024		    status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET)
   1025			status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET;
   1026	} else {
   1027		status->band = NL80211_BAND_2GHZ;
   1028	}
   1029	status->freq = ieee80211_channel_to_frequency(rxd->channel,
   1030						      status->band);
   1031
   1032	*qos = rxd->qos_control;
   1033
   1034	if ((rxd->rx_status != MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR) &&
   1035	    (rxd->rx_status & MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK) &&
   1036	    (rxd->rx_status & MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR))
   1037		status->flag |= RX_FLAG_MMIC_ERROR;
   1038
   1039	return le16_to_cpu(rxd->pkt_len);
   1040}
   1041
   1042static struct rxd_ops rxd_ap_ops = {
   1043	.rxd_size	= sizeof(struct mwl8k_rxd_ap),
   1044	.rxd_init	= mwl8k_rxd_ap_init,
   1045	.rxd_refill	= mwl8k_rxd_ap_refill,
   1046	.rxd_process	= mwl8k_rxd_ap_process,
   1047};
   1048
   1049/*
   1050 * Packet reception for STA firmware.
   1051 */
   1052struct mwl8k_rxd_sta {
   1053	__le16 pkt_len;
   1054	__u8 link_quality;
   1055	__u8 noise_level;
   1056	__le32 pkt_phys_addr;
   1057	__le32 next_rxd_phys_addr;
   1058	__le16 qos_control;
   1059	__le16 rate_info;
   1060	__le32 pad0[4];
   1061	__u8 rssi;
   1062	__u8 channel;
   1063	__le16 pad1;
   1064	__u8 rx_ctrl;
   1065	__u8 rx_status;
   1066	__u8 pad2[2];
   1067} __packed;
   1068
   1069#define MWL8K_STA_RATE_INFO_SHORTPRE		0x8000
   1070#define MWL8K_STA_RATE_INFO_ANTSELECT(x)	(((x) >> 11) & 0x3)
   1071#define MWL8K_STA_RATE_INFO_RATEID(x)		(((x) >> 3) & 0x3f)
   1072#define MWL8K_STA_RATE_INFO_40MHZ		0x0004
   1073#define MWL8K_STA_RATE_INFO_SHORTGI		0x0002
   1074#define MWL8K_STA_RATE_INFO_MCS_FORMAT		0x0001
   1075
   1076#define MWL8K_STA_RX_CTRL_OWNED_BY_HOST		0x02
   1077#define MWL8K_STA_RX_CTRL_DECRYPT_ERROR		0x04
   1078/* ICV=0 or MIC=1 */
   1079#define MWL8K_STA_RX_CTRL_DEC_ERR_TYPE		0x08
   1080/* Key is uploaded only in failure case */
   1081#define MWL8K_STA_RX_CTRL_KEY_INDEX			0x30
   1082
   1083static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr)
   1084{
   1085	struct mwl8k_rxd_sta *rxd = _rxd;
   1086
   1087	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
   1088	rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST;
   1089}
   1090
   1091static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
   1092{
   1093	struct mwl8k_rxd_sta *rxd = _rxd;
   1094
   1095	rxd->pkt_len = cpu_to_le16(len);
   1096	rxd->pkt_phys_addr = cpu_to_le32(addr);
   1097	wmb();
   1098	rxd->rx_ctrl = 0;
   1099}
   1100
   1101static int
   1102mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
   1103		       __le16 *qos, s8 *noise)
   1104{
   1105	struct mwl8k_rxd_sta *rxd = _rxd;
   1106	u16 rate_info;
   1107
   1108	if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST))
   1109		return -1;
   1110	rmb();
   1111
   1112	rate_info = le16_to_cpu(rxd->rate_info);
   1113
   1114	memset(status, 0, sizeof(*status));
   1115
   1116	status->signal = -rxd->rssi;
   1117	*noise = -rxd->noise_level;
   1118	status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
   1119	status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
   1120
   1121	if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE)
   1122		status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
   1123	if (rate_info & MWL8K_STA_RATE_INFO_40MHZ)
   1124		status->bw = RATE_INFO_BW_40;
   1125	if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI)
   1126		status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
   1127	if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
   1128		status->encoding = RX_ENC_HT;
   1129
   1130	if (rxd->channel > 14) {
   1131		status->band = NL80211_BAND_5GHZ;
   1132		if (!(status->encoding == RX_ENC_HT) &&
   1133		    status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET)
   1134			status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET;
   1135	} else {
   1136		status->band = NL80211_BAND_2GHZ;
   1137	}
   1138	status->freq = ieee80211_channel_to_frequency(rxd->channel,
   1139						      status->band);
   1140
   1141	*qos = rxd->qos_control;
   1142	if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) &&
   1143	    (rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DEC_ERR_TYPE))
   1144		status->flag |= RX_FLAG_MMIC_ERROR;
   1145
   1146	return le16_to_cpu(rxd->pkt_len);
   1147}
   1148
   1149static struct rxd_ops rxd_sta_ops = {
   1150	.rxd_size	= sizeof(struct mwl8k_rxd_sta),
   1151	.rxd_init	= mwl8k_rxd_sta_init,
   1152	.rxd_refill	= mwl8k_rxd_sta_refill,
   1153	.rxd_process	= mwl8k_rxd_sta_process,
   1154};
   1155
   1156
   1157#define MWL8K_RX_DESCS		256
   1158#define MWL8K_RX_MAXSZ		3800
   1159
   1160static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
   1161{
   1162	struct mwl8k_priv *priv = hw->priv;
   1163	struct mwl8k_rx_queue *rxq = priv->rxq + index;
   1164	int size;
   1165	int i;
   1166
   1167	rxq->rxd_count = 0;
   1168	rxq->head = 0;
   1169	rxq->tail = 0;
   1170
   1171	size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size;
   1172
   1173	rxq->rxd = dma_alloc_coherent(&priv->pdev->dev, size, &rxq->rxd_dma,
   1174				      GFP_KERNEL);
   1175	if (rxq->rxd == NULL) {
   1176		wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n");
   1177		return -ENOMEM;
   1178	}
   1179
   1180	rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL);
   1181	if (rxq->buf == NULL) {
   1182		dma_free_coherent(&priv->pdev->dev, size, rxq->rxd,
   1183				  rxq->rxd_dma);
   1184		return -ENOMEM;
   1185	}
   1186
   1187	for (i = 0; i < MWL8K_RX_DESCS; i++) {
   1188		int desc_size;
   1189		void *rxd;
   1190		int nexti;
   1191		dma_addr_t next_dma_addr;
   1192
   1193		desc_size = priv->rxd_ops->rxd_size;
   1194		rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size);
   1195
   1196		nexti = i + 1;
   1197		if (nexti == MWL8K_RX_DESCS)
   1198			nexti = 0;
   1199		next_dma_addr = rxq->rxd_dma + (nexti * desc_size);
   1200
   1201		priv->rxd_ops->rxd_init(rxd, next_dma_addr);
   1202	}
   1203
   1204	return 0;
   1205}
   1206
   1207static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
   1208{
   1209	struct mwl8k_priv *priv = hw->priv;
   1210	struct mwl8k_rx_queue *rxq = priv->rxq + index;
   1211	int refilled = 0;
   1212
   1213	while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) {
   1214		struct sk_buff *skb;
   1215		dma_addr_t addr;
   1216		int rx;
   1217		void *rxd;
   1218
   1219		skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
   1220		if (skb == NULL)
   1221			break;
   1222
   1223		addr = dma_map_single(&priv->pdev->dev, skb->data,
   1224				      MWL8K_RX_MAXSZ, DMA_FROM_DEVICE);
   1225
   1226		rxq->rxd_count++;
   1227		rx = rxq->tail++;
   1228		if (rxq->tail == MWL8K_RX_DESCS)
   1229			rxq->tail = 0;
   1230		rxq->buf[rx].skb = skb;
   1231		dma_unmap_addr_set(&rxq->buf[rx], dma, addr);
   1232
   1233		rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size);
   1234		priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ);
   1235
   1236		refilled++;
   1237	}
   1238
   1239	return refilled;
   1240}
   1241
   1242/* Must be called only when the card's reception is completely halted */
   1243static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
   1244{
   1245	struct mwl8k_priv *priv = hw->priv;
   1246	struct mwl8k_rx_queue *rxq = priv->rxq + index;
   1247	int i;
   1248
   1249	if (rxq->rxd == NULL)
   1250		return;
   1251
   1252	for (i = 0; i < MWL8K_RX_DESCS; i++) {
   1253		if (rxq->buf[i].skb != NULL) {
   1254			dma_unmap_single(&priv->pdev->dev,
   1255					 dma_unmap_addr(&rxq->buf[i], dma),
   1256					 MWL8K_RX_MAXSZ, DMA_FROM_DEVICE);
   1257			dma_unmap_addr_set(&rxq->buf[i], dma, 0);
   1258
   1259			kfree_skb(rxq->buf[i].skb);
   1260			rxq->buf[i].skb = NULL;
   1261		}
   1262	}
   1263
   1264	kfree(rxq->buf);
   1265	rxq->buf = NULL;
   1266
   1267	dma_free_coherent(&priv->pdev->dev,
   1268			  MWL8K_RX_DESCS * priv->rxd_ops->rxd_size, rxq->rxd,
   1269			  rxq->rxd_dma);
   1270	rxq->rxd = NULL;
   1271}
   1272
   1273
   1274/*
   1275 * Scan a list of BSSIDs to process for finalize join.
   1276 * Allows for extension to process multiple BSSIDs.
   1277 */
   1278static inline int
   1279mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
   1280{
   1281	return priv->capture_beacon &&
   1282		ieee80211_is_beacon(wh->frame_control) &&
   1283		ether_addr_equal_64bits(wh->addr3, priv->capture_bssid);
   1284}
   1285
   1286static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
   1287				     struct sk_buff *skb)
   1288{
   1289	struct mwl8k_priv *priv = hw->priv;
   1290
   1291	priv->capture_beacon = false;
   1292	eth_zero_addr(priv->capture_bssid);
   1293
   1294	/*
   1295	 * Use GFP_ATOMIC as rxq_process is called from
   1296	 * the primary interrupt handler, memory allocation call
   1297	 * must not sleep.
   1298	 */
   1299	priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
   1300	if (priv->beacon_skb != NULL)
   1301		ieee80211_queue_work(hw, &priv->finalize_join_worker);
   1302}
   1303
   1304static inline struct mwl8k_vif *mwl8k_find_vif_bss(struct list_head *vif_list,
   1305						   u8 *bssid)
   1306{
   1307	struct mwl8k_vif *mwl8k_vif;
   1308
   1309	list_for_each_entry(mwl8k_vif,
   1310			    vif_list, list) {
   1311		if (memcmp(bssid, mwl8k_vif->bssid,
   1312			   ETH_ALEN) == 0)
   1313			return mwl8k_vif;
   1314	}
   1315
   1316	return NULL;
   1317}
   1318
   1319static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
   1320{
   1321	struct mwl8k_priv *priv = hw->priv;
   1322	struct mwl8k_vif *mwl8k_vif = NULL;
   1323	struct mwl8k_rx_queue *rxq = priv->rxq + index;
   1324	int processed;
   1325
   1326	processed = 0;
   1327	while (rxq->rxd_count && limit--) {
   1328		struct sk_buff *skb;
   1329		void *rxd;
   1330		int pkt_len;
   1331		struct ieee80211_rx_status status;
   1332		struct ieee80211_hdr *wh;
   1333		__le16 qos;
   1334
   1335		skb = rxq->buf[rxq->head].skb;
   1336		if (skb == NULL)
   1337			break;
   1338
   1339		rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
   1340
   1341		pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos,
   1342							&priv->noise);
   1343		if (pkt_len < 0)
   1344			break;
   1345
   1346		rxq->buf[rxq->head].skb = NULL;
   1347
   1348		dma_unmap_single(&priv->pdev->dev,
   1349				 dma_unmap_addr(&rxq->buf[rxq->head], dma),
   1350				 MWL8K_RX_MAXSZ, DMA_FROM_DEVICE);
   1351		dma_unmap_addr_set(&rxq->buf[rxq->head], dma, 0);
   1352
   1353		rxq->head++;
   1354		if (rxq->head == MWL8K_RX_DESCS)
   1355			rxq->head = 0;
   1356
   1357		rxq->rxd_count--;
   1358
   1359		wh = &((struct mwl8k_dma_data *)skb->data)->wh;
   1360
   1361		/*
   1362		 * Check for a pending join operation.  Save a
   1363		 * copy of the beacon and schedule a tasklet to
   1364		 * send a FINALIZE_JOIN command to the firmware.
   1365		 */
   1366		if (mwl8k_capture_bssid(priv, (void *)skb->data))
   1367			mwl8k_save_beacon(hw, skb);
   1368
   1369		if (ieee80211_has_protected(wh->frame_control)) {
   1370
   1371			/* Check if hw crypto has been enabled for
   1372			 * this bss. If yes, set the status flags
   1373			 * accordingly
   1374			 */
   1375			mwl8k_vif = mwl8k_find_vif_bss(&priv->vif_list,
   1376								wh->addr1);
   1377
   1378			if (mwl8k_vif != NULL &&
   1379			    mwl8k_vif->is_hw_crypto_enabled) {
   1380				/*
   1381				 * When MMIC ERROR is encountered
   1382				 * by the firmware, payload is
   1383				 * dropped and only 32 bytes of
   1384				 * mwl8k Firmware header is sent
   1385				 * to the host.
   1386				 *
   1387				 * We need to add four bytes of
   1388				 * key information.  In it
   1389				 * MAC80211 expects keyidx set to
   1390				 * 0 for triggering Counter
   1391				 * Measure of MMIC failure.
   1392				 */
   1393				if (status.flag & RX_FLAG_MMIC_ERROR) {
   1394					struct mwl8k_dma_data *tr;
   1395					tr = (struct mwl8k_dma_data *)skb->data;
   1396					memset((void *)&(tr->data), 0, 4);
   1397					pkt_len += 4;
   1398				}
   1399
   1400				if (!ieee80211_is_auth(wh->frame_control))
   1401					status.flag |= RX_FLAG_IV_STRIPPED |
   1402						       RX_FLAG_DECRYPTED |
   1403						       RX_FLAG_MMIC_STRIPPED;
   1404			}
   1405		}
   1406
   1407		skb_put(skb, pkt_len);
   1408		mwl8k_remove_dma_header(skb, qos);
   1409		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
   1410		ieee80211_rx_irqsafe(hw, skb);
   1411
   1412		processed++;
   1413	}
   1414
   1415	return processed;
   1416}
   1417
   1418
   1419/*
   1420 * Packet transmission.
   1421 */
   1422
   1423#define MWL8K_TXD_STATUS_OK			0x00000001
   1424#define MWL8K_TXD_STATUS_OK_RETRY		0x00000002
   1425#define MWL8K_TXD_STATUS_OK_MORE_RETRY		0x00000004
   1426#define MWL8K_TXD_STATUS_MULTICAST_TX		0x00000008
   1427#define MWL8K_TXD_STATUS_FW_OWNED		0x80000000
   1428
   1429#define MWL8K_QOS_QLEN_UNSPEC			0xff00
   1430#define MWL8K_QOS_ACK_POLICY_MASK		0x0060
   1431#define MWL8K_QOS_ACK_POLICY_NORMAL		0x0000
   1432#define MWL8K_QOS_ACK_POLICY_BLOCKACK		0x0060
   1433#define MWL8K_QOS_EOSP				0x0010
   1434
   1435struct mwl8k_tx_desc {
   1436	__le32 status;
   1437	__u8 data_rate;
   1438	__u8 tx_priority;
   1439	__le16 qos_control;
   1440	__le32 pkt_phys_addr;
   1441	__le16 pkt_len;
   1442	__u8 dest_MAC_addr[ETH_ALEN];
   1443	__le32 next_txd_phys_addr;
   1444	__le32 timestamp;
   1445	__le16 rate_info;
   1446	__u8 peer_id;
   1447	__u8 tx_frag_cnt;
   1448} __packed;
   1449
   1450#define MWL8K_TX_DESCS		128
   1451
   1452static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
   1453{
   1454	struct mwl8k_priv *priv = hw->priv;
   1455	struct mwl8k_tx_queue *txq = priv->txq + index;
   1456	int size;
   1457	int i;
   1458
   1459	txq->len = 0;
   1460	txq->head = 0;
   1461	txq->tail = 0;
   1462
   1463	size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc);
   1464
   1465	txq->txd = dma_alloc_coherent(&priv->pdev->dev, size, &txq->txd_dma,
   1466				      GFP_KERNEL);
   1467	if (txq->txd == NULL) {
   1468		wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n");
   1469		return -ENOMEM;
   1470	}
   1471
   1472	txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL);
   1473	if (txq->skb == NULL) {
   1474		dma_free_coherent(&priv->pdev->dev, size, txq->txd,
   1475				  txq->txd_dma);
   1476		txq->txd = NULL;
   1477		return -ENOMEM;
   1478	}
   1479
   1480	for (i = 0; i < MWL8K_TX_DESCS; i++) {
   1481		struct mwl8k_tx_desc *tx_desc;
   1482		int nexti;
   1483
   1484		tx_desc = txq->txd + i;
   1485		nexti = (i + 1) % MWL8K_TX_DESCS;
   1486
   1487		tx_desc->status = 0;
   1488		tx_desc->next_txd_phys_addr =
   1489			cpu_to_le32(txq->txd_dma + nexti * sizeof(*tx_desc));
   1490	}
   1491
   1492	return 0;
   1493}
   1494
   1495static inline void mwl8k_tx_start(struct mwl8k_priv *priv)
   1496{
   1497	iowrite32(MWL8K_H2A_INT_PPA_READY,
   1498		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
   1499	iowrite32(MWL8K_H2A_INT_DUMMY,
   1500		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
   1501	ioread32(priv->regs + MWL8K_HIU_INT_CODE);
   1502}
   1503
   1504static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
   1505{
   1506	struct mwl8k_priv *priv = hw->priv;
   1507	int i;
   1508
   1509	for (i = 0; i < mwl8k_tx_queues(priv); i++) {
   1510		struct mwl8k_tx_queue *txq = priv->txq + i;
   1511		int fw_owned = 0;
   1512		int drv_owned = 0;
   1513		int unused = 0;
   1514		int desc;
   1515
   1516		for (desc = 0; desc < MWL8K_TX_DESCS; desc++) {
   1517			struct mwl8k_tx_desc *tx_desc = txq->txd + desc;
   1518			u32 status;
   1519
   1520			status = le32_to_cpu(tx_desc->status);
   1521			if (status & MWL8K_TXD_STATUS_FW_OWNED)
   1522				fw_owned++;
   1523			else
   1524				drv_owned++;
   1525
   1526			if (tx_desc->pkt_len == 0)
   1527				unused++;
   1528		}
   1529
   1530		wiphy_err(hw->wiphy,
   1531			  "txq[%d] len=%d head=%d tail=%d "
   1532			  "fw_owned=%d drv_owned=%d unused=%d\n",
   1533			  i,
   1534			  txq->len, txq->head, txq->tail,
   1535			  fw_owned, drv_owned, unused);
   1536	}
   1537}
   1538
   1539/*
   1540 * Must be called with priv->fw_mutex held and tx queues stopped.
   1541 */
   1542#define MWL8K_TX_WAIT_TIMEOUT_MS	5000
   1543
   1544static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
   1545{
   1546	struct mwl8k_priv *priv = hw->priv;
   1547	DECLARE_COMPLETION_ONSTACK(tx_wait);
   1548	int retry;
   1549	int rc;
   1550
   1551	might_sleep();
   1552
   1553	/* Since fw restart is in progress, allow only the firmware
   1554	 * commands from the restart code and block the other
   1555	 * commands since they are going to fail in any case since
   1556	 * the firmware has crashed
   1557	 */
   1558	if (priv->hw_restart_in_progress) {
   1559		if (priv->hw_restart_owner == current)
   1560			return 0;
   1561		else
   1562			return -EBUSY;
   1563	}
   1564
   1565	if (atomic_read(&priv->watchdog_event_pending))
   1566		return 0;
   1567
   1568	/*
   1569	 * The TX queues are stopped at this point, so this test
   1570	 * doesn't need to take ->tx_lock.
   1571	 */
   1572	if (!priv->pending_tx_pkts)
   1573		return 0;
   1574
   1575	retry = 1;
   1576	rc = 0;
   1577
   1578	spin_lock_bh(&priv->tx_lock);
   1579	priv->tx_wait = &tx_wait;
   1580	while (!rc) {
   1581		int oldcount;
   1582		unsigned long timeout;
   1583
   1584		oldcount = priv->pending_tx_pkts;
   1585
   1586		spin_unlock_bh(&priv->tx_lock);
   1587		timeout = wait_for_completion_timeout(&tx_wait,
   1588			    msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS));
   1589
   1590		if (atomic_read(&priv->watchdog_event_pending)) {
   1591			spin_lock_bh(&priv->tx_lock);
   1592			priv->tx_wait = NULL;
   1593			spin_unlock_bh(&priv->tx_lock);
   1594			return 0;
   1595		}
   1596
   1597		spin_lock_bh(&priv->tx_lock);
   1598
   1599		if (timeout || !priv->pending_tx_pkts) {
   1600			WARN_ON(priv->pending_tx_pkts);
   1601			if (retry)
   1602				wiphy_notice(hw->wiphy, "tx rings drained\n");
   1603			break;
   1604		}
   1605
   1606		if (retry) {
   1607			mwl8k_tx_start(priv);
   1608			retry = 0;
   1609			continue;
   1610		}
   1611
   1612		if (priv->pending_tx_pkts < oldcount) {
   1613			wiphy_notice(hw->wiphy,
   1614				     "waiting for tx rings to drain (%d -> %d pkts)\n",
   1615				     oldcount, priv->pending_tx_pkts);
   1616			retry = 1;
   1617			continue;
   1618		}
   1619
   1620		priv->tx_wait = NULL;
   1621
   1622		wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n",
   1623			  MWL8K_TX_WAIT_TIMEOUT_MS);
   1624		mwl8k_dump_tx_rings(hw);
   1625		priv->hw_restart_in_progress = true;
   1626		ieee80211_queue_work(hw, &priv->fw_reload);
   1627
   1628		rc = -ETIMEDOUT;
   1629	}
   1630	priv->tx_wait = NULL;
   1631	spin_unlock_bh(&priv->tx_lock);
   1632
   1633	return rc;
   1634}
   1635
   1636#define MWL8K_TXD_SUCCESS(status)				\
   1637	((status) & (MWL8K_TXD_STATUS_OK |			\
   1638		     MWL8K_TXD_STATUS_OK_RETRY |		\
   1639		     MWL8K_TXD_STATUS_OK_MORE_RETRY))
   1640
   1641static int mwl8k_tid_queue_mapping(u8 tid)
   1642{
   1643	BUG_ON(tid > 7);
   1644
   1645	switch (tid) {
   1646	case 0:
   1647	case 3:
   1648		return IEEE80211_AC_BE;
   1649	case 1:
   1650	case 2:
   1651		return IEEE80211_AC_BK;
   1652	case 4:
   1653	case 5:
   1654		return IEEE80211_AC_VI;
   1655	case 6:
   1656	case 7:
   1657		return IEEE80211_AC_VO;
   1658	default:
   1659		return -1;
   1660	}
   1661}
   1662
   1663/* The firmware will fill in the rate information
   1664 * for each packet that gets queued in the hardware
   1665 * and these macros will interpret that info.
   1666 */
   1667
   1668#define RI_FORMAT(a)		  (a & 0x0001)
   1669#define RI_RATE_ID_MCS(a)	 ((a & 0x01f8) >> 3)
   1670
   1671static int
   1672mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
   1673{
   1674	struct mwl8k_priv *priv = hw->priv;
   1675	struct mwl8k_tx_queue *txq = priv->txq + index;
   1676	int processed;
   1677
   1678	processed = 0;
   1679	while (txq->len > 0 && limit--) {
   1680		int tx;
   1681		struct mwl8k_tx_desc *tx_desc;
   1682		unsigned long addr;
   1683		int size;
   1684		struct sk_buff *skb;
   1685		struct ieee80211_tx_info *info;
   1686		u32 status;
   1687		struct ieee80211_sta *sta;
   1688		struct mwl8k_sta *sta_info = NULL;
   1689		u16 rate_info;
   1690		struct ieee80211_hdr *wh;
   1691
   1692		tx = txq->head;
   1693		tx_desc = txq->txd + tx;
   1694
   1695		status = le32_to_cpu(tx_desc->status);
   1696
   1697		if (status & MWL8K_TXD_STATUS_FW_OWNED) {
   1698			if (!force)
   1699				break;
   1700			tx_desc->status &=
   1701				~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED);
   1702		}
   1703
   1704		txq->head = (tx + 1) % MWL8K_TX_DESCS;
   1705		BUG_ON(txq->len == 0);
   1706		txq->len--;
   1707		priv->pending_tx_pkts--;
   1708
   1709		addr = le32_to_cpu(tx_desc->pkt_phys_addr);
   1710		size = le16_to_cpu(tx_desc->pkt_len);
   1711		skb = txq->skb[tx];
   1712		txq->skb[tx] = NULL;
   1713
   1714		BUG_ON(skb == NULL);
   1715		dma_unmap_single(&priv->pdev->dev, addr, size, DMA_TO_DEVICE);
   1716
   1717		mwl8k_remove_dma_header(skb, tx_desc->qos_control);
   1718
   1719		wh = (struct ieee80211_hdr *) skb->data;
   1720
   1721		/* Mark descriptor as unused */
   1722		tx_desc->pkt_phys_addr = 0;
   1723		tx_desc->pkt_len = 0;
   1724
   1725		info = IEEE80211_SKB_CB(skb);
   1726		if (ieee80211_is_data(wh->frame_control)) {
   1727			rcu_read_lock();
   1728			sta = ieee80211_find_sta_by_ifaddr(hw, wh->addr1,
   1729							   wh->addr2);
   1730			if (sta) {
   1731				sta_info = MWL8K_STA(sta);
   1732				BUG_ON(sta_info == NULL);
   1733				rate_info = le16_to_cpu(tx_desc->rate_info);
   1734				/* If rate is < 6.5 Mpbs for an ht station
   1735				 * do not form an ampdu. If the station is a
   1736				 * legacy station (format = 0), do not form an
   1737				 * ampdu
   1738				 */
   1739				if (RI_RATE_ID_MCS(rate_info) < 1 ||
   1740				    RI_FORMAT(rate_info) == 0) {
   1741					sta_info->is_ampdu_allowed = false;
   1742				} else {
   1743					sta_info->is_ampdu_allowed = true;
   1744				}
   1745			}
   1746			rcu_read_unlock();
   1747		}
   1748
   1749		ieee80211_tx_info_clear_status(info);
   1750
   1751		/* Rate control is happening in the firmware.
   1752		 * Ensure no tx rate is being reported.
   1753		 */
   1754		info->status.rates[0].idx = -1;
   1755		info->status.rates[0].count = 1;
   1756
   1757		if (MWL8K_TXD_SUCCESS(status))
   1758			info->flags |= IEEE80211_TX_STAT_ACK;
   1759
   1760		ieee80211_tx_status_irqsafe(hw, skb);
   1761
   1762		processed++;
   1763	}
   1764
   1765	return processed;
   1766}
   1767
   1768/* must be called only when the card's transmit is completely halted */
   1769static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
   1770{
   1771	struct mwl8k_priv *priv = hw->priv;
   1772	struct mwl8k_tx_queue *txq = priv->txq + index;
   1773
   1774	if (txq->txd == NULL)
   1775		return;
   1776
   1777	mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
   1778
   1779	kfree(txq->skb);
   1780	txq->skb = NULL;
   1781
   1782	dma_free_coherent(&priv->pdev->dev,
   1783			  MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc),
   1784			  txq->txd, txq->txd_dma);
   1785	txq->txd = NULL;
   1786}
   1787
   1788/* caller must hold priv->stream_lock when calling the stream functions */
   1789static struct mwl8k_ampdu_stream *
   1790mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid)
   1791{
   1792	struct mwl8k_ampdu_stream *stream;
   1793	struct mwl8k_priv *priv = hw->priv;
   1794	int i;
   1795
   1796	for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
   1797		stream = &priv->ampdu[i];
   1798		if (stream->state == AMPDU_NO_STREAM) {
   1799			stream->sta = sta;
   1800			stream->state = AMPDU_STREAM_NEW;
   1801			stream->tid = tid;
   1802			stream->idx = i;
   1803			wiphy_debug(hw->wiphy, "Added a new stream for %pM %d",
   1804				    sta->addr, tid);
   1805			return stream;
   1806		}
   1807	}
   1808	return NULL;
   1809}
   1810
   1811static int
   1812mwl8k_start_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
   1813{
   1814	int ret;
   1815
   1816	/* if the stream has already been started, don't start it again */
   1817	if (stream->state != AMPDU_STREAM_NEW)
   1818		return 0;
   1819	ret = ieee80211_start_tx_ba_session(stream->sta, stream->tid, 0);
   1820	if (ret)
   1821		wiphy_debug(hw->wiphy, "Failed to start stream for %pM %d: "
   1822			    "%d\n", stream->sta->addr, stream->tid, ret);
   1823	else
   1824		wiphy_debug(hw->wiphy, "Started stream for %pM %d\n",
   1825			    stream->sta->addr, stream->tid);
   1826	return ret;
   1827}
   1828
   1829static void
   1830mwl8k_remove_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
   1831{
   1832	wiphy_debug(hw->wiphy, "Remove stream for %pM %d\n", stream->sta->addr,
   1833		    stream->tid);
   1834	memset(stream, 0, sizeof(*stream));
   1835}
   1836
   1837static struct mwl8k_ampdu_stream *
   1838mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid)
   1839{
   1840	struct mwl8k_priv *priv = hw->priv;
   1841	int i;
   1842
   1843	for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
   1844		struct mwl8k_ampdu_stream *stream;
   1845		stream = &priv->ampdu[i];
   1846		if (stream->state == AMPDU_NO_STREAM)
   1847			continue;
   1848		if (!memcmp(stream->sta->addr, addr, ETH_ALEN) &&
   1849		    stream->tid == tid)
   1850			return stream;
   1851	}
   1852	return NULL;
   1853}
   1854
   1855#define MWL8K_AMPDU_PACKET_THRESHOLD 64
   1856static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid)
   1857{
   1858	struct mwl8k_sta *sta_info = MWL8K_STA(sta);
   1859	struct tx_traffic_info *tx_stats;
   1860
   1861	BUG_ON(tid >= MWL8K_MAX_TID);
   1862	tx_stats = &sta_info->tx_stats[tid];
   1863
   1864	return sta_info->is_ampdu_allowed &&
   1865		tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD;
   1866}
   1867
   1868static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
   1869{
   1870	struct mwl8k_sta *sta_info = MWL8K_STA(sta);
   1871	struct tx_traffic_info *tx_stats;
   1872
   1873	BUG_ON(tid >= MWL8K_MAX_TID);
   1874	tx_stats = &sta_info->tx_stats[tid];
   1875
   1876	if (tx_stats->start_time == 0)
   1877		tx_stats->start_time = jiffies;
   1878
   1879	/* reset the packet count after each second elapses.  If the number of
   1880	 * packets ever exceeds the ampdu_min_traffic threshold, we will allow
   1881	 * an ampdu stream to be started.
   1882	 */
   1883	if (jiffies - tx_stats->start_time > HZ) {
   1884		tx_stats->pkts = 0;
   1885		tx_stats->start_time = 0;
   1886	} else
   1887		tx_stats->pkts++;
   1888}
   1889
   1890/* The hardware ampdu queues start from 5.
   1891 * txpriorities for ampdu queues are
   1892 * 5 6 7 0 1 2 3 4 ie., queue 5 is highest
   1893 * and queue 3 is lowest (queue 4 is reserved)
   1894 */
   1895#define BA_QUEUE		5
   1896
   1897static void
   1898mwl8k_txq_xmit(struct ieee80211_hw *hw,
   1899	       int index,
   1900	       struct ieee80211_sta *sta,
   1901	       struct sk_buff *skb)
   1902{
   1903	struct mwl8k_priv *priv = hw->priv;
   1904	struct ieee80211_tx_info *tx_info;
   1905	struct mwl8k_vif *mwl8k_vif;
   1906	struct ieee80211_hdr *wh;
   1907	struct mwl8k_tx_queue *txq;
   1908	struct mwl8k_tx_desc *tx;
   1909	dma_addr_t dma;
   1910	u32 txstatus;
   1911	u8 txdatarate;
   1912	u16 qos;
   1913	int txpriority;
   1914	u8 tid = 0;
   1915	struct mwl8k_ampdu_stream *stream = NULL;
   1916	bool start_ba_session = false;
   1917	bool mgmtframe = false;
   1918	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
   1919	bool eapol_frame = false;
   1920
   1921	wh = (struct ieee80211_hdr *)skb->data;
   1922	if (ieee80211_is_data_qos(wh->frame_control))
   1923		qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
   1924	else
   1925		qos = 0;
   1926
   1927	if (skb->protocol == cpu_to_be16(ETH_P_PAE))
   1928		eapol_frame = true;
   1929
   1930	if (ieee80211_is_mgmt(wh->frame_control))
   1931		mgmtframe = true;
   1932
   1933	if (priv->ap_fw)
   1934		mwl8k_encapsulate_tx_frame(priv, skb);
   1935	else
   1936		mwl8k_add_dma_header(priv, skb, 0, 0);
   1937
   1938	wh = &((struct mwl8k_dma_data *)skb->data)->wh;
   1939
   1940	tx_info = IEEE80211_SKB_CB(skb);
   1941	mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
   1942
   1943	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
   1944		wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
   1945		wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno);
   1946		mwl8k_vif->seqno += 0x10;
   1947	}
   1948
   1949	/* Setup firmware control bit fields for each frame type.  */
   1950	txstatus = 0;
   1951	txdatarate = 0;
   1952	if (ieee80211_is_mgmt(wh->frame_control) ||
   1953	    ieee80211_is_ctl(wh->frame_control)) {
   1954		txdatarate = 0;
   1955		qos |= MWL8K_QOS_QLEN_UNSPEC | MWL8K_QOS_EOSP;
   1956	} else if (ieee80211_is_data(wh->frame_control)) {
   1957		txdatarate = 1;
   1958		if (is_multicast_ether_addr(wh->addr1))
   1959			txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX;
   1960
   1961		qos &= ~MWL8K_QOS_ACK_POLICY_MASK;
   1962		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
   1963			qos |= MWL8K_QOS_ACK_POLICY_BLOCKACK;
   1964		else
   1965			qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
   1966	}
   1967
   1968	/* Queue ADDBA request in the respective data queue.  While setting up
   1969	 * the ampdu stream, mac80211 queues further packets for that
   1970	 * particular ra/tid pair.  However, packets piled up in the hardware
   1971	 * for that ra/tid pair will still go out. ADDBA request and the
   1972	 * related data packets going out from different queues asynchronously
   1973	 * will cause a shift in the receiver window which might result in
   1974	 * ampdu packets getting dropped at the receiver after the stream has
   1975	 * been setup.
   1976	 */
   1977	if (unlikely(ieee80211_is_action(wh->frame_control) &&
   1978	    mgmt->u.action.category == WLAN_CATEGORY_BACK &&
   1979	    mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ &&
   1980	    priv->ap_fw)) {
   1981		u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
   1982		tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
   1983		index = mwl8k_tid_queue_mapping(tid);
   1984	}
   1985
   1986	txpriority = index;
   1987
   1988	if (priv->ap_fw && sta && sta->deflink.ht_cap.ht_supported && !eapol_frame &&
   1989	    ieee80211_is_data_qos(wh->frame_control)) {
   1990		tid = qos & 0xf;
   1991		mwl8k_tx_count_packet(sta, tid);
   1992		spin_lock(&priv->stream_lock);
   1993		stream = mwl8k_lookup_stream(hw, sta->addr, tid);
   1994		if (stream != NULL) {
   1995			if (stream->state == AMPDU_STREAM_ACTIVE) {
   1996				WARN_ON(!(qos & MWL8K_QOS_ACK_POLICY_BLOCKACK));
   1997				txpriority = (BA_QUEUE + stream->idx) %
   1998					     TOTAL_HW_TX_QUEUES;
   1999				if (stream->idx <= 1)
   2000					index = stream->idx +
   2001						MWL8K_TX_WMM_QUEUES;
   2002
   2003			} else if (stream->state == AMPDU_STREAM_NEW) {
   2004				/* We get here if the driver sends us packets
   2005				 * after we've initiated a stream, but before
   2006				 * our ampdu_action routine has been called
   2007				 * with IEEE80211_AMPDU_TX_START to get the SSN
   2008				 * for the ADDBA request.  So this packet can
   2009				 * go out with no risk of sequence number
   2010				 * mismatch.  No special handling is required.
   2011				 */
   2012			} else {
   2013				/* Drop packets that would go out after the
   2014				 * ADDBA request was sent but before the ADDBA
   2015				 * response is received.  If we don't do this,
   2016				 * the recipient would probably receive it
   2017				 * after the ADDBA request with SSN 0.  This
   2018				 * will cause the recipient's BA receive window
   2019				 * to shift, which would cause the subsequent
   2020				 * packets in the BA stream to be discarded.
   2021				 * mac80211 queues our packets for us in this
   2022				 * case, so this is really just a safety check.
   2023				 */
   2024				wiphy_warn(hw->wiphy,
   2025					   "Cannot send packet while ADDBA "
   2026					   "dialog is underway.\n");
   2027				spin_unlock(&priv->stream_lock);
   2028				dev_kfree_skb(skb);
   2029				return;
   2030			}
   2031		} else {
   2032			/* Defer calling mwl8k_start_stream so that the current
   2033			 * skb can go out before the ADDBA request.  This
   2034			 * prevents sequence number mismatch at the recepient
   2035			 * as described above.
   2036			 */
   2037			if (mwl8k_ampdu_allowed(sta, tid)) {
   2038				stream = mwl8k_add_stream(hw, sta, tid);
   2039				if (stream != NULL)
   2040					start_ba_session = true;
   2041			}
   2042		}
   2043		spin_unlock(&priv->stream_lock);
   2044	} else {
   2045		qos &= ~MWL8K_QOS_ACK_POLICY_MASK;
   2046		qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
   2047	}
   2048
   2049	dma = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
   2050			     DMA_TO_DEVICE);
   2051
   2052	if (dma_mapping_error(&priv->pdev->dev, dma)) {
   2053		wiphy_debug(hw->wiphy,
   2054			    "failed to dma map skb, dropping TX frame.\n");
   2055		if (start_ba_session) {
   2056			spin_lock(&priv->stream_lock);
   2057			mwl8k_remove_stream(hw, stream);
   2058			spin_unlock(&priv->stream_lock);
   2059		}
   2060		dev_kfree_skb(skb);
   2061		return;
   2062	}
   2063
   2064	spin_lock_bh(&priv->tx_lock);
   2065
   2066	txq = priv->txq + index;
   2067
   2068	/* Mgmt frames that go out frequently are probe
   2069	 * responses. Other mgmt frames got out relatively
   2070	 * infrequently. Hence reserve 2 buffers so that
   2071	 * other mgmt frames do not get dropped due to an
   2072	 * already queued probe response in one of the
   2073	 * reserved buffers.
   2074	 */
   2075
   2076	if (txq->len >= MWL8K_TX_DESCS - 2) {
   2077		if (!mgmtframe || txq->len == MWL8K_TX_DESCS) {
   2078			if (start_ba_session) {
   2079				spin_lock(&priv->stream_lock);
   2080				mwl8k_remove_stream(hw, stream);
   2081				spin_unlock(&priv->stream_lock);
   2082			}
   2083			mwl8k_tx_start(priv);
   2084			spin_unlock_bh(&priv->tx_lock);
   2085			dma_unmap_single(&priv->pdev->dev, dma, skb->len,
   2086					 DMA_TO_DEVICE);
   2087			dev_kfree_skb(skb);
   2088			return;
   2089		}
   2090	}
   2091
   2092	BUG_ON(txq->skb[txq->tail] != NULL);
   2093	txq->skb[txq->tail] = skb;
   2094
   2095	tx = txq->txd + txq->tail;
   2096	tx->data_rate = txdatarate;
   2097	tx->tx_priority = txpriority;
   2098	tx->qos_control = cpu_to_le16(qos);
   2099	tx->pkt_phys_addr = cpu_to_le32(dma);
   2100	tx->pkt_len = cpu_to_le16(skb->len);
   2101	tx->rate_info = 0;
   2102	if (!priv->ap_fw && sta != NULL)
   2103		tx->peer_id = MWL8K_STA(sta)->peer_id;
   2104	else
   2105		tx->peer_id = 0;
   2106
   2107	if (priv->ap_fw && ieee80211_is_data(wh->frame_control) && !eapol_frame)
   2108		tx->timestamp = cpu_to_le32(ioread32(priv->regs +
   2109						MWL8K_HW_TIMER_REGISTER));
   2110	else
   2111		tx->timestamp = 0;
   2112
   2113	wmb();
   2114	tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
   2115
   2116	txq->len++;
   2117	priv->pending_tx_pkts++;
   2118
   2119	txq->tail++;
   2120	if (txq->tail == MWL8K_TX_DESCS)
   2121		txq->tail = 0;
   2122
   2123	mwl8k_tx_start(priv);
   2124
   2125	spin_unlock_bh(&priv->tx_lock);
   2126
   2127	/* Initiate the ampdu session here */
   2128	if (start_ba_session) {
   2129		spin_lock(&priv->stream_lock);
   2130		if (mwl8k_start_stream(hw, stream))
   2131			mwl8k_remove_stream(hw, stream);
   2132		spin_unlock(&priv->stream_lock);
   2133	}
   2134}
   2135
   2136
   2137/*
   2138 * Firmware access.
   2139 *
   2140 * We have the following requirements for issuing firmware commands:
   2141 * - Some commands require that the packet transmit path is idle when
   2142 *   the command is issued.  (For simplicity, we'll just quiesce the
   2143 *   transmit path for every command.)
   2144 * - There are certain sequences of commands that need to be issued to
   2145 *   the hardware sequentially, with no other intervening commands.
   2146 *
   2147 * This leads to an implementation of a "firmware lock" as a mutex that
   2148 * can be taken recursively, and which is taken by both the low-level
   2149 * command submission function (mwl8k_post_cmd) as well as any users of
   2150 * that function that require issuing of an atomic sequence of commands,
   2151 * and quiesces the transmit path whenever it's taken.
   2152 */
   2153static int mwl8k_fw_lock(struct ieee80211_hw *hw)
   2154{
   2155	struct mwl8k_priv *priv = hw->priv;
   2156
   2157	if (priv->fw_mutex_owner != current) {
   2158		int rc;
   2159
   2160		mutex_lock(&priv->fw_mutex);
   2161		ieee80211_stop_queues(hw);
   2162
   2163		rc = mwl8k_tx_wait_empty(hw);
   2164		if (rc) {
   2165			if (!priv->hw_restart_in_progress)
   2166				ieee80211_wake_queues(hw);
   2167
   2168			mutex_unlock(&priv->fw_mutex);
   2169
   2170			return rc;
   2171		}
   2172
   2173		priv->fw_mutex_owner = current;
   2174	}
   2175
   2176	priv->fw_mutex_depth++;
   2177
   2178	return 0;
   2179}
   2180
   2181static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
   2182{
   2183	struct mwl8k_priv *priv = hw->priv;
   2184
   2185	if (!--priv->fw_mutex_depth) {
   2186		if (!priv->hw_restart_in_progress)
   2187			ieee80211_wake_queues(hw);
   2188
   2189		priv->fw_mutex_owner = NULL;
   2190		mutex_unlock(&priv->fw_mutex);
   2191	}
   2192}
   2193
   2194static void mwl8k_enable_bsses(struct ieee80211_hw *hw, bool enable,
   2195			       u32 bitmap);
   2196
   2197/*
   2198 * Command processing.
   2199 */
   2200
   2201/* Timeout firmware commands after 10s */
   2202#define MWL8K_CMD_TIMEOUT_MS	10000
   2203
   2204static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
   2205{
   2206	DECLARE_COMPLETION_ONSTACK(cmd_wait);
   2207	struct mwl8k_priv *priv = hw->priv;
   2208	void __iomem *regs = priv->regs;
   2209	dma_addr_t dma_addr;
   2210	unsigned int dma_size;
   2211	int rc;
   2212	unsigned long timeout = 0;
   2213	u8 buf[32];
   2214	u32 bitmap = 0;
   2215
   2216	wiphy_dbg(hw->wiphy, "Posting %s [%d]\n",
   2217		  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), cmd->macid);
   2218
   2219	/* Before posting firmware commands that could change the hardware
   2220	 * characteristics, make sure that all BSSes are stopped temporary.
   2221	 * Enable these stopped BSSes after completion of the commands
   2222	 */
   2223
   2224	rc = mwl8k_fw_lock(hw);
   2225	if (rc)
   2226		return rc;
   2227
   2228	if (priv->ap_fw && priv->running_bsses) {
   2229		switch (le16_to_cpu(cmd->code)) {
   2230		case MWL8K_CMD_SET_RF_CHANNEL:
   2231		case MWL8K_CMD_RADIO_CONTROL:
   2232		case MWL8K_CMD_RF_TX_POWER:
   2233		case MWL8K_CMD_TX_POWER:
   2234		case MWL8K_CMD_RF_ANTENNA:
   2235		case MWL8K_CMD_RTS_THRESHOLD:
   2236		case MWL8K_CMD_MIMO_CONFIG:
   2237			bitmap = priv->running_bsses;
   2238			mwl8k_enable_bsses(hw, false, bitmap);
   2239			break;
   2240		}
   2241	}
   2242
   2243	cmd->result = (__force __le16) 0xffff;
   2244	dma_size = le16_to_cpu(cmd->length);
   2245	dma_addr = dma_map_single(&priv->pdev->dev, cmd, dma_size,
   2246				  DMA_BIDIRECTIONAL);
   2247	if (dma_mapping_error(&priv->pdev->dev, dma_addr)) {
   2248		rc = -ENOMEM;
   2249		goto exit;
   2250	}
   2251
   2252	priv->hostcmd_wait = &cmd_wait;
   2253	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
   2254	iowrite32(MWL8K_H2A_INT_DOORBELL,
   2255		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
   2256	iowrite32(MWL8K_H2A_INT_DUMMY,
   2257		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
   2258
   2259	timeout = wait_for_completion_timeout(&cmd_wait,
   2260				msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
   2261
   2262	priv->hostcmd_wait = NULL;
   2263
   2264
   2265	dma_unmap_single(&priv->pdev->dev, dma_addr, dma_size,
   2266			 DMA_BIDIRECTIONAL);
   2267
   2268	if (!timeout) {
   2269		wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n",
   2270			  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
   2271			  MWL8K_CMD_TIMEOUT_MS);
   2272		rc = -ETIMEDOUT;
   2273	} else {
   2274		int ms;
   2275
   2276		ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(timeout);
   2277
   2278		rc = cmd->result ? -EINVAL : 0;
   2279		if (rc)
   2280			wiphy_err(hw->wiphy, "Command %s error 0x%x\n",
   2281				  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
   2282				  le16_to_cpu(cmd->result));
   2283		else if (ms > 2000)
   2284			wiphy_notice(hw->wiphy, "Command %s took %d ms\n",
   2285				     mwl8k_cmd_name(cmd->code,
   2286						    buf, sizeof(buf)),
   2287				     ms);
   2288	}
   2289
   2290exit:
   2291	if (bitmap)
   2292		mwl8k_enable_bsses(hw, true, bitmap);
   2293
   2294	mwl8k_fw_unlock(hw);
   2295
   2296	return rc;
   2297}
   2298
   2299static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw,
   2300				 struct ieee80211_vif *vif,
   2301				 struct mwl8k_cmd_pkt *cmd)
   2302{
   2303	if (vif != NULL)
   2304		cmd->macid = MWL8K_VIF(vif)->macid;
   2305	return mwl8k_post_cmd(hw, cmd);
   2306}
   2307
   2308/*
   2309 * Setup code shared between STA and AP firmware images.
   2310 */
   2311static void mwl8k_setup_2ghz_band(struct ieee80211_hw *hw)
   2312{
   2313	struct mwl8k_priv *priv = hw->priv;
   2314
   2315	BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24));
   2316	memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24));
   2317
   2318	BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24));
   2319	memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24));
   2320
   2321	priv->band_24.band = NL80211_BAND_2GHZ;
   2322	priv->band_24.channels = priv->channels_24;
   2323	priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24);
   2324	priv->band_24.bitrates = priv->rates_24;
   2325	priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24);
   2326
   2327	hw->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band_24;
   2328}
   2329
   2330static void mwl8k_setup_5ghz_band(struct ieee80211_hw *hw)
   2331{
   2332	struct mwl8k_priv *priv = hw->priv;
   2333
   2334	BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50));
   2335	memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50));
   2336
   2337	BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50));
   2338	memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50));
   2339
   2340	priv->band_50.band = NL80211_BAND_5GHZ;
   2341	priv->band_50.channels = priv->channels_50;
   2342	priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50);
   2343	priv->band_50.bitrates = priv->rates_50;
   2344	priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50);
   2345
   2346	hw->wiphy->bands[NL80211_BAND_5GHZ] = &priv->band_50;
   2347}
   2348
   2349/*
   2350 * CMD_GET_HW_SPEC (STA version).
   2351 */
   2352struct mwl8k_cmd_get_hw_spec_sta {
   2353	struct mwl8k_cmd_pkt header;
   2354	__u8 hw_rev;
   2355	__u8 host_interface;
   2356	__le16 num_mcaddrs;
   2357	__u8 perm_addr[ETH_ALEN];
   2358	__le16 region_code;
   2359	__le32 fw_rev;
   2360	__le32 ps_cookie;
   2361	__le32 caps;
   2362	__u8 mcs_bitmap[16];
   2363	__le32 rx_queue_ptr;
   2364	__le32 num_tx_queues;
   2365	__le32 tx_queue_ptrs[MWL8K_TX_WMM_QUEUES];
   2366	__le32 caps2;
   2367	__le32 num_tx_desc_per_queue;
   2368	__le32 total_rxd;
   2369} __packed;
   2370
   2371#define MWL8K_CAP_MAX_AMSDU		0x20000000
   2372#define MWL8K_CAP_GREENFIELD		0x08000000
   2373#define MWL8K_CAP_AMPDU			0x04000000
   2374#define MWL8K_CAP_RX_STBC		0x01000000
   2375#define MWL8K_CAP_TX_STBC		0x00800000
   2376#define MWL8K_CAP_SHORTGI_40MHZ		0x00400000
   2377#define MWL8K_CAP_SHORTGI_20MHZ		0x00200000
   2378#define MWL8K_CAP_RX_ANTENNA_MASK	0x000e0000
   2379#define MWL8K_CAP_TX_ANTENNA_MASK	0x0001c000
   2380#define MWL8K_CAP_DELAY_BA		0x00003000
   2381#define MWL8K_CAP_MIMO			0x00000200
   2382#define MWL8K_CAP_40MHZ			0x00000100
   2383#define MWL8K_CAP_BAND_MASK		0x00000007
   2384#define MWL8K_CAP_5GHZ			0x00000004
   2385#define MWL8K_CAP_2GHZ4			0x00000001
   2386
   2387static void
   2388mwl8k_set_ht_caps(struct ieee80211_hw *hw,
   2389		  struct ieee80211_supported_band *band, u32 cap)
   2390{
   2391	int rx_streams;
   2392	int tx_streams;
   2393
   2394	band->ht_cap.ht_supported = 1;
   2395
   2396	if (cap & MWL8K_CAP_MAX_AMSDU)
   2397		band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
   2398	if (cap & MWL8K_CAP_GREENFIELD)
   2399		band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD;
   2400	if (cap & MWL8K_CAP_AMPDU) {
   2401		ieee80211_hw_set(hw, AMPDU_AGGREGATION);
   2402		band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
   2403		band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
   2404	}
   2405	if (cap & MWL8K_CAP_RX_STBC)
   2406		band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC;
   2407	if (cap & MWL8K_CAP_TX_STBC)
   2408		band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
   2409	if (cap & MWL8K_CAP_SHORTGI_40MHZ)
   2410		band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
   2411	if (cap & MWL8K_CAP_SHORTGI_20MHZ)
   2412		band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
   2413	if (cap & MWL8K_CAP_DELAY_BA)
   2414		band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA;
   2415	if (cap & MWL8K_CAP_40MHZ)
   2416		band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
   2417
   2418	rx_streams = hweight32(cap & MWL8K_CAP_RX_ANTENNA_MASK);
   2419	tx_streams = hweight32(cap & MWL8K_CAP_TX_ANTENNA_MASK);
   2420
   2421	band->ht_cap.mcs.rx_mask[0] = 0xff;
   2422	if (rx_streams >= 2)
   2423		band->ht_cap.mcs.rx_mask[1] = 0xff;
   2424	if (rx_streams >= 3)
   2425		band->ht_cap.mcs.rx_mask[2] = 0xff;
   2426	band->ht_cap.mcs.rx_mask[4] = 0x01;
   2427	band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
   2428
   2429	if (rx_streams != tx_streams) {
   2430		band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
   2431		band->ht_cap.mcs.tx_params |= (tx_streams - 1) <<
   2432				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
   2433	}
   2434}
   2435
   2436static void
   2437mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps)
   2438{
   2439	struct mwl8k_priv *priv = hw->priv;
   2440
   2441	if (priv->caps)
   2442		return;
   2443
   2444	if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
   2445		mwl8k_setup_2ghz_band(hw);
   2446		if (caps & MWL8K_CAP_MIMO)
   2447			mwl8k_set_ht_caps(hw, &priv->band_24, caps);
   2448	}
   2449
   2450	if (caps & MWL8K_CAP_5GHZ) {
   2451		mwl8k_setup_5ghz_band(hw);
   2452		if (caps & MWL8K_CAP_MIMO)
   2453			mwl8k_set_ht_caps(hw, &priv->band_50, caps);
   2454	}
   2455
   2456	priv->caps = caps;
   2457}
   2458
   2459static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
   2460{
   2461	struct mwl8k_priv *priv = hw->priv;
   2462	struct mwl8k_cmd_get_hw_spec_sta *cmd;
   2463	int rc;
   2464	int i;
   2465
   2466	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   2467	if (cmd == NULL)
   2468		return -ENOMEM;
   2469
   2470	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
   2471	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   2472
   2473	memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
   2474	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
   2475	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
   2476	cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
   2477	for (i = 0; i < mwl8k_tx_queues(priv); i++)
   2478		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
   2479	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
   2480	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
   2481
   2482	rc = mwl8k_post_cmd(hw, &cmd->header);
   2483
   2484	if (!rc) {
   2485		SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
   2486		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
   2487		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
   2488		priv->hw_rev = cmd->hw_rev;
   2489		mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
   2490		priv->ap_macids_supported = 0x00000000;
   2491		priv->sta_macids_supported = 0x00000001;
   2492	}
   2493
   2494	kfree(cmd);
   2495	return rc;
   2496}
   2497
   2498/*
   2499 * CMD_GET_HW_SPEC (AP version).
   2500 */
   2501struct mwl8k_cmd_get_hw_spec_ap {
   2502	struct mwl8k_cmd_pkt header;
   2503	__u8 hw_rev;
   2504	__u8 host_interface;
   2505	__le16 num_wcb;
   2506	__le16 num_mcaddrs;
   2507	__u8 perm_addr[ETH_ALEN];
   2508	__le16 region_code;
   2509	__le16 num_antenna;
   2510	__le32 fw_rev;
   2511	__le32 wcbbase0;
   2512	__le32 rxwrptr;
   2513	__le32 rxrdptr;
   2514	__le32 ps_cookie;
   2515	__le32 wcbbase1;
   2516	__le32 wcbbase2;
   2517	__le32 wcbbase3;
   2518	__le32 fw_api_version;
   2519	__le32 caps;
   2520	__le32 num_of_ampdu_queues;
   2521	__le32 wcbbase_ampdu[MWL8K_MAX_AMPDU_QUEUES];
   2522} __packed;
   2523
   2524static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
   2525{
   2526	struct mwl8k_priv *priv = hw->priv;
   2527	struct mwl8k_cmd_get_hw_spec_ap *cmd;
   2528	int rc, i;
   2529	u32 api_version;
   2530
   2531	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   2532	if (cmd == NULL)
   2533		return -ENOMEM;
   2534
   2535	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
   2536	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   2537
   2538	memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
   2539	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
   2540
   2541	rc = mwl8k_post_cmd(hw, &cmd->header);
   2542
   2543	if (!rc) {
   2544		int off;
   2545
   2546		api_version = le32_to_cpu(cmd->fw_api_version);
   2547		if (priv->device_info->fw_api_ap != api_version) {
   2548			printk(KERN_ERR "%s: Unsupported fw API version for %s."
   2549			       "  Expected %d got %d.\n", MWL8K_NAME,
   2550			       priv->device_info->part_name,
   2551			       priv->device_info->fw_api_ap,
   2552			       api_version);
   2553			rc = -EINVAL;
   2554			goto done;
   2555		}
   2556		SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
   2557		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
   2558		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
   2559		priv->hw_rev = cmd->hw_rev;
   2560		mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
   2561		priv->ap_macids_supported = 0x000000ff;
   2562		priv->sta_macids_supported = 0x00000100;
   2563		priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues);
   2564		if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) {
   2565			wiphy_warn(hw->wiphy, "fw reported %d ampdu queues"
   2566				   " but we only support %d.\n",
   2567				   priv->num_ampdu_queues,
   2568				   MWL8K_MAX_AMPDU_QUEUES);
   2569			priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES;
   2570		}
   2571		off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
   2572		iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
   2573
   2574		off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
   2575		iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
   2576
   2577		priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff;
   2578		priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff;
   2579		priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff;
   2580		priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff;
   2581
   2582		for (i = 0; i < priv->num_ampdu_queues; i++)
   2583			priv->txq_offset[i + MWL8K_TX_WMM_QUEUES] =
   2584				le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff;
   2585	}
   2586
   2587done:
   2588	kfree(cmd);
   2589	return rc;
   2590}
   2591
   2592/*
   2593 * CMD_SET_HW_SPEC.
   2594 */
   2595struct mwl8k_cmd_set_hw_spec {
   2596	struct mwl8k_cmd_pkt header;
   2597	__u8 hw_rev;
   2598	__u8 host_interface;
   2599	__le16 num_mcaddrs;
   2600	__u8 perm_addr[ETH_ALEN];
   2601	__le16 region_code;
   2602	__le32 fw_rev;
   2603	__le32 ps_cookie;
   2604	__le32 caps;
   2605	__le32 rx_queue_ptr;
   2606	__le32 num_tx_queues;
   2607	__le32 tx_queue_ptrs[MWL8K_MAX_TX_QUEUES];
   2608	__le32 flags;
   2609	__le32 num_tx_desc_per_queue;
   2610	__le32 total_rxd;
   2611} __packed;
   2612
   2613/* If enabled, MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY will cause
   2614 * packets to expire 500 ms after the timestamp in the tx descriptor.  That is,
   2615 * the packets that are queued for more than 500ms, will be dropped in the
   2616 * hardware. This helps minimizing the issues caused due to head-of-line
   2617 * blocking where a slow client can hog the bandwidth and affect traffic to a
   2618 * faster client.
   2619 */
   2620#define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY	0x00000400
   2621#define MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR	0x00000200
   2622#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT		0x00000080
   2623#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP	0x00000020
   2624#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON		0x00000010
   2625
   2626static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
   2627{
   2628	struct mwl8k_priv *priv = hw->priv;
   2629	struct mwl8k_cmd_set_hw_spec *cmd;
   2630	int rc;
   2631	int i;
   2632
   2633	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   2634	if (cmd == NULL)
   2635		return -ENOMEM;
   2636
   2637	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC);
   2638	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   2639
   2640	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
   2641	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
   2642	cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
   2643
   2644	/*
   2645	 * Mac80211 stack has Q0 as highest priority and Q3 as lowest in
   2646	 * that order. Firmware has Q3 as highest priority and Q0 as lowest
   2647	 * in that order. Map Q3 of mac80211 to Q0 of firmware so that the
   2648	 * priority is interpreted the right way in firmware.
   2649	 */
   2650	for (i = 0; i < mwl8k_tx_queues(priv); i++) {
   2651		int j = mwl8k_tx_queues(priv) - 1 - i;
   2652		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma);
   2653	}
   2654
   2655	cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
   2656				 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
   2657				 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON |
   2658				 MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY |
   2659				 MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR);
   2660	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
   2661	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
   2662
   2663	rc = mwl8k_post_cmd(hw, &cmd->header);
   2664	kfree(cmd);
   2665
   2666	return rc;
   2667}
   2668
   2669/*
   2670 * CMD_MAC_MULTICAST_ADR.
   2671 */
   2672struct mwl8k_cmd_mac_multicast_adr {
   2673	struct mwl8k_cmd_pkt header;
   2674	__le16 action;
   2675	__le16 numaddr;
   2676	__u8 addr[][ETH_ALEN];
   2677};
   2678
   2679#define MWL8K_ENABLE_RX_DIRECTED	0x0001
   2680#define MWL8K_ENABLE_RX_MULTICAST	0x0002
   2681#define MWL8K_ENABLE_RX_ALL_MULTICAST	0x0004
   2682#define MWL8K_ENABLE_RX_BROADCAST	0x0008
   2683
   2684static struct mwl8k_cmd_pkt *
   2685__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
   2686			      struct netdev_hw_addr_list *mc_list)
   2687{
   2688	struct mwl8k_priv *priv = hw->priv;
   2689	struct mwl8k_cmd_mac_multicast_adr *cmd;
   2690	int size;
   2691	int mc_count = 0;
   2692
   2693	if (mc_list)
   2694		mc_count = netdev_hw_addr_list_count(mc_list);
   2695
   2696	if (allmulti || mc_count > priv->num_mcaddrs) {
   2697		allmulti = 1;
   2698		mc_count = 0;
   2699	}
   2700
   2701	size = sizeof(*cmd) + mc_count * ETH_ALEN;
   2702
   2703	cmd = kzalloc(size, GFP_ATOMIC);
   2704	if (cmd == NULL)
   2705		return NULL;
   2706
   2707	cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
   2708	cmd->header.length = cpu_to_le16(size);
   2709	cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_DIRECTED |
   2710				  MWL8K_ENABLE_RX_BROADCAST);
   2711
   2712	if (allmulti) {
   2713		cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST);
   2714	} else if (mc_count) {
   2715		struct netdev_hw_addr *ha;
   2716		int i = 0;
   2717
   2718		cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
   2719		cmd->numaddr = cpu_to_le16(mc_count);
   2720		netdev_hw_addr_list_for_each(ha, mc_list) {
   2721			memcpy(cmd->addr[i], ha->addr, ETH_ALEN);
   2722		}
   2723	}
   2724
   2725	return &cmd->header;
   2726}
   2727
   2728/*
   2729 * CMD_GET_STAT.
   2730 */
   2731struct mwl8k_cmd_get_stat {
   2732	struct mwl8k_cmd_pkt header;
   2733	__le32 stats[64];
   2734} __packed;
   2735
   2736#define MWL8K_STAT_ACK_FAILURE	9
   2737#define MWL8K_STAT_RTS_FAILURE	12
   2738#define MWL8K_STAT_FCS_ERROR	24
   2739#define MWL8K_STAT_RTS_SUCCESS	11
   2740
   2741static int mwl8k_cmd_get_stat(struct ieee80211_hw *hw,
   2742			      struct ieee80211_low_level_stats *stats)
   2743{
   2744	struct mwl8k_cmd_get_stat *cmd;
   2745	int rc;
   2746
   2747	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   2748	if (cmd == NULL)
   2749		return -ENOMEM;
   2750
   2751	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT);
   2752	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   2753
   2754	rc = mwl8k_post_cmd(hw, &cmd->header);
   2755	if (!rc) {
   2756		stats->dot11ACKFailureCount =
   2757			le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]);
   2758		stats->dot11RTSFailureCount =
   2759			le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]);
   2760		stats->dot11FCSErrorCount =
   2761			le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]);
   2762		stats->dot11RTSSuccessCount =
   2763			le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]);
   2764	}
   2765	kfree(cmd);
   2766
   2767	return rc;
   2768}
   2769
   2770/*
   2771 * CMD_RADIO_CONTROL.
   2772 */
   2773struct mwl8k_cmd_radio_control {
   2774	struct mwl8k_cmd_pkt header;
   2775	__le16 action;
   2776	__le16 control;
   2777	__le16 radio_on;
   2778} __packed;
   2779
   2780static int
   2781mwl8k_cmd_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
   2782{
   2783	struct mwl8k_priv *priv = hw->priv;
   2784	struct mwl8k_cmd_radio_control *cmd;
   2785	int rc;
   2786
   2787	if (enable == priv->radio_on && !force)
   2788		return 0;
   2789
   2790	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   2791	if (cmd == NULL)
   2792		return -ENOMEM;
   2793
   2794	cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL);
   2795	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   2796	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
   2797	cmd->control = cpu_to_le16(priv->radio_short_preamble ? 3 : 1);
   2798	cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000);
   2799
   2800	rc = mwl8k_post_cmd(hw, &cmd->header);
   2801	kfree(cmd);
   2802
   2803	if (!rc)
   2804		priv->radio_on = enable;
   2805
   2806	return rc;
   2807}
   2808
   2809static int mwl8k_cmd_radio_disable(struct ieee80211_hw *hw)
   2810{
   2811	return mwl8k_cmd_radio_control(hw, 0, 0);
   2812}
   2813
   2814static int mwl8k_cmd_radio_enable(struct ieee80211_hw *hw)
   2815{
   2816	return mwl8k_cmd_radio_control(hw, 1, 0);
   2817}
   2818
   2819static int
   2820mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
   2821{
   2822	struct mwl8k_priv *priv = hw->priv;
   2823
   2824	priv->radio_short_preamble = short_preamble;
   2825
   2826	return mwl8k_cmd_radio_control(hw, 1, 1);
   2827}
   2828
   2829/*
   2830 * CMD_RF_TX_POWER.
   2831 */
   2832#define MWL8K_RF_TX_POWER_LEVEL_TOTAL	8
   2833
   2834struct mwl8k_cmd_rf_tx_power {
   2835	struct mwl8k_cmd_pkt header;
   2836	__le16 action;
   2837	__le16 support_level;
   2838	__le16 current_level;
   2839	__le16 reserved;
   2840	__le16 power_level_list[MWL8K_RF_TX_POWER_LEVEL_TOTAL];
   2841} __packed;
   2842
   2843static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
   2844{
   2845	struct mwl8k_cmd_rf_tx_power *cmd;
   2846	int rc;
   2847
   2848	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   2849	if (cmd == NULL)
   2850		return -ENOMEM;
   2851
   2852	cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER);
   2853	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   2854	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
   2855	cmd->support_level = cpu_to_le16(dBm);
   2856
   2857	rc = mwl8k_post_cmd(hw, &cmd->header);
   2858	kfree(cmd);
   2859
   2860	return rc;
   2861}
   2862
   2863/*
   2864 * CMD_TX_POWER.
   2865 */
   2866#define MWL8K_TX_POWER_LEVEL_TOTAL      12
   2867
   2868struct mwl8k_cmd_tx_power {
   2869	struct mwl8k_cmd_pkt header;
   2870	__le16 action;
   2871	__le16 band;
   2872	__le16 channel;
   2873	__le16 bw;
   2874	__le16 sub_ch;
   2875	__le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
   2876} __packed;
   2877
   2878static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
   2879				     struct ieee80211_conf *conf,
   2880				     unsigned short pwr)
   2881{
   2882	struct ieee80211_channel *channel = conf->chandef.chan;
   2883	enum nl80211_channel_type channel_type =
   2884		cfg80211_get_chandef_type(&conf->chandef);
   2885	struct mwl8k_cmd_tx_power *cmd;
   2886	int rc;
   2887	int i;
   2888
   2889	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   2890	if (cmd == NULL)
   2891		return -ENOMEM;
   2892
   2893	cmd->header.code = cpu_to_le16(MWL8K_CMD_TX_POWER);
   2894	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   2895	cmd->action = cpu_to_le16(MWL8K_CMD_SET_LIST);
   2896
   2897	if (channel->band == NL80211_BAND_2GHZ)
   2898		cmd->band = cpu_to_le16(0x1);
   2899	else if (channel->band == NL80211_BAND_5GHZ)
   2900		cmd->band = cpu_to_le16(0x4);
   2901
   2902	cmd->channel = cpu_to_le16(channel->hw_value);
   2903
   2904	if (channel_type == NL80211_CHAN_NO_HT ||
   2905	    channel_type == NL80211_CHAN_HT20) {
   2906		cmd->bw = cpu_to_le16(0x2);
   2907	} else {
   2908		cmd->bw = cpu_to_le16(0x4);
   2909		if (channel_type == NL80211_CHAN_HT40MINUS)
   2910			cmd->sub_ch = cpu_to_le16(0x3);
   2911		else if (channel_type == NL80211_CHAN_HT40PLUS)
   2912			cmd->sub_ch = cpu_to_le16(0x1);
   2913	}
   2914
   2915	for (i = 0; i < MWL8K_TX_POWER_LEVEL_TOTAL; i++)
   2916		cmd->power_level_list[i] = cpu_to_le16(pwr);
   2917
   2918	rc = mwl8k_post_cmd(hw, &cmd->header);
   2919	kfree(cmd);
   2920
   2921	return rc;
   2922}
   2923
   2924/*
   2925 * CMD_RF_ANTENNA.
   2926 */
   2927struct mwl8k_cmd_rf_antenna {
   2928	struct mwl8k_cmd_pkt header;
   2929	__le16 antenna;
   2930	__le16 mode;
   2931} __packed;
   2932
   2933#define MWL8K_RF_ANTENNA_RX		1
   2934#define MWL8K_RF_ANTENNA_TX		2
   2935
   2936static int
   2937mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask)
   2938{
   2939	struct mwl8k_cmd_rf_antenna *cmd;
   2940	int rc;
   2941
   2942	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   2943	if (cmd == NULL)
   2944		return -ENOMEM;
   2945
   2946	cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_ANTENNA);
   2947	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   2948	cmd->antenna = cpu_to_le16(antenna);
   2949	cmd->mode = cpu_to_le16(mask);
   2950
   2951	rc = mwl8k_post_cmd(hw, &cmd->header);
   2952	kfree(cmd);
   2953
   2954	return rc;
   2955}
   2956
   2957/*
   2958 * CMD_SET_BEACON.
   2959 */
   2960struct mwl8k_cmd_set_beacon {
   2961	struct mwl8k_cmd_pkt header;
   2962	__le16 beacon_len;
   2963	__u8 beacon[];
   2964};
   2965
   2966static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw,
   2967				struct ieee80211_vif *vif, u8 *beacon, int len)
   2968{
   2969	struct mwl8k_cmd_set_beacon *cmd;
   2970	int rc;
   2971
   2972	cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL);
   2973	if (cmd == NULL)
   2974		return -ENOMEM;
   2975
   2976	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON);
   2977	cmd->header.length = cpu_to_le16(sizeof(*cmd) + len);
   2978	cmd->beacon_len = cpu_to_le16(len);
   2979	memcpy(cmd->beacon, beacon, len);
   2980
   2981	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   2982	kfree(cmd);
   2983
   2984	return rc;
   2985}
   2986
   2987/*
   2988 * CMD_SET_PRE_SCAN.
   2989 */
   2990struct mwl8k_cmd_set_pre_scan {
   2991	struct mwl8k_cmd_pkt header;
   2992} __packed;
   2993
   2994static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
   2995{
   2996	struct mwl8k_cmd_set_pre_scan *cmd;
   2997	int rc;
   2998
   2999	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3000	if (cmd == NULL)
   3001		return -ENOMEM;
   3002
   3003	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN);
   3004	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3005
   3006	rc = mwl8k_post_cmd(hw, &cmd->header);
   3007	kfree(cmd);
   3008
   3009	return rc;
   3010}
   3011
   3012/*
   3013 * CMD_BBP_REG_ACCESS.
   3014 */
   3015struct mwl8k_cmd_bbp_reg_access {
   3016	struct mwl8k_cmd_pkt header;
   3017	__le16 action;
   3018	__le16 offset;
   3019	u8 value;
   3020	u8 rsrv[3];
   3021} __packed;
   3022
   3023static int
   3024mwl8k_cmd_bbp_reg_access(struct ieee80211_hw *hw,
   3025			 u16 action,
   3026			 u16 offset,
   3027			 u8 *value)
   3028{
   3029	struct mwl8k_cmd_bbp_reg_access *cmd;
   3030	int rc;
   3031
   3032	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3033	if (cmd == NULL)
   3034		return -ENOMEM;
   3035
   3036	cmd->header.code = cpu_to_le16(MWL8K_CMD_BBP_REG_ACCESS);
   3037	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3038	cmd->action = cpu_to_le16(action);
   3039	cmd->offset = cpu_to_le16(offset);
   3040
   3041	rc = mwl8k_post_cmd(hw, &cmd->header);
   3042
   3043	if (!rc)
   3044		*value = cmd->value;
   3045	else
   3046		*value = 0;
   3047
   3048	kfree(cmd);
   3049
   3050	return rc;
   3051}
   3052
   3053/*
   3054 * CMD_SET_POST_SCAN.
   3055 */
   3056struct mwl8k_cmd_set_post_scan {
   3057	struct mwl8k_cmd_pkt header;
   3058	__le32 isibss;
   3059	__u8 bssid[ETH_ALEN];
   3060} __packed;
   3061
   3062static int
   3063mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac)
   3064{
   3065	struct mwl8k_cmd_set_post_scan *cmd;
   3066	int rc;
   3067
   3068	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3069	if (cmd == NULL)
   3070		return -ENOMEM;
   3071
   3072	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN);
   3073	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3074	cmd->isibss = 0;
   3075	memcpy(cmd->bssid, mac, ETH_ALEN);
   3076
   3077	rc = mwl8k_post_cmd(hw, &cmd->header);
   3078	kfree(cmd);
   3079
   3080	return rc;
   3081}
   3082
   3083static int freq_to_idx(struct mwl8k_priv *priv, int freq)
   3084{
   3085	struct ieee80211_supported_band *sband;
   3086	int band, ch, idx = 0;
   3087
   3088	for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) {
   3089		sband = priv->hw->wiphy->bands[band];
   3090		if (!sband)
   3091			continue;
   3092
   3093		for (ch = 0; ch < sband->n_channels; ch++, idx++)
   3094			if (sband->channels[ch].center_freq == freq)
   3095				goto exit;
   3096	}
   3097
   3098exit:
   3099	return idx;
   3100}
   3101
   3102static void mwl8k_update_survey(struct mwl8k_priv *priv,
   3103				struct ieee80211_channel *channel)
   3104{
   3105	u32 cca_cnt, rx_rdy;
   3106	s8 nf = 0, idx;
   3107	struct survey_info *survey;
   3108
   3109	idx = freq_to_idx(priv, priv->acs_chan->center_freq);
   3110	if (idx >= MWL8K_NUM_CHANS) {
   3111		wiphy_err(priv->hw->wiphy, "Failed to update survey\n");
   3112		return;
   3113	}
   3114
   3115	survey = &priv->survey[idx];
   3116
   3117	cca_cnt = ioread32(priv->regs + NOK_CCA_CNT_REG);
   3118	cca_cnt /= 1000; /* uSecs to mSecs */
   3119	survey->time_busy = (u64) cca_cnt;
   3120
   3121	rx_rdy = ioread32(priv->regs + BBU_RXRDY_CNT_REG);
   3122	rx_rdy /= 1000; /* uSecs to mSecs */
   3123	survey->time_rx = (u64) rx_rdy;
   3124
   3125	priv->channel_time = jiffies - priv->channel_time;
   3126	survey->time = jiffies_to_msecs(priv->channel_time);
   3127
   3128	survey->channel = channel;
   3129
   3130	mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &nf);
   3131
   3132	/* Make sure sign is negative else ACS  at hostapd fails */
   3133	survey->noise = nf * -1;
   3134
   3135	survey->filled = SURVEY_INFO_NOISE_DBM |
   3136			 SURVEY_INFO_TIME |
   3137			 SURVEY_INFO_TIME_BUSY |
   3138			 SURVEY_INFO_TIME_RX;
   3139}
   3140
   3141/*
   3142 * CMD_SET_RF_CHANNEL.
   3143 */
   3144struct mwl8k_cmd_set_rf_channel {
   3145	struct mwl8k_cmd_pkt header;
   3146	__le16 action;
   3147	__u8 current_channel;
   3148	__le32 channel_flags;
   3149} __packed;
   3150
   3151static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
   3152				    struct ieee80211_conf *conf)
   3153{
   3154	struct ieee80211_channel *channel = conf->chandef.chan;
   3155	enum nl80211_channel_type channel_type =
   3156		cfg80211_get_chandef_type(&conf->chandef);
   3157	struct mwl8k_cmd_set_rf_channel *cmd;
   3158	struct mwl8k_priv *priv = hw->priv;
   3159	int rc;
   3160
   3161	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3162	if (cmd == NULL)
   3163		return -ENOMEM;
   3164
   3165	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL);
   3166	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3167	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
   3168	cmd->current_channel = channel->hw_value;
   3169
   3170	if (channel->band == NL80211_BAND_2GHZ)
   3171		cmd->channel_flags |= cpu_to_le32(0x00000001);
   3172	else if (channel->band == NL80211_BAND_5GHZ)
   3173		cmd->channel_flags |= cpu_to_le32(0x00000004);
   3174
   3175	if (!priv->sw_scan_start) {
   3176		if (channel_type == NL80211_CHAN_NO_HT ||
   3177		    channel_type == NL80211_CHAN_HT20)
   3178			cmd->channel_flags |= cpu_to_le32(0x00000080);
   3179		else if (channel_type == NL80211_CHAN_HT40MINUS)
   3180			cmd->channel_flags |= cpu_to_le32(0x000001900);
   3181		else if (channel_type == NL80211_CHAN_HT40PLUS)
   3182			cmd->channel_flags |= cpu_to_le32(0x000000900);
   3183	} else {
   3184		cmd->channel_flags |= cpu_to_le32(0x00000080);
   3185	}
   3186
   3187	if (priv->sw_scan_start) {
   3188		/* Store current channel stats
   3189		 * before switching to newer one.
   3190		 * This will be processed only for AP fw.
   3191		 */
   3192		if (priv->channel_time != 0)
   3193			mwl8k_update_survey(priv, priv->acs_chan);
   3194
   3195		priv->channel_time = jiffies;
   3196		priv->acs_chan =  channel;
   3197	}
   3198
   3199	rc = mwl8k_post_cmd(hw, &cmd->header);
   3200	kfree(cmd);
   3201
   3202	return rc;
   3203}
   3204
   3205/*
   3206 * CMD_SET_AID.
   3207 */
   3208#define MWL8K_FRAME_PROT_DISABLED			0x00
   3209#define MWL8K_FRAME_PROT_11G				0x07
   3210#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY		0x02
   3211#define MWL8K_FRAME_PROT_11N_HT_ALL			0x06
   3212
   3213struct mwl8k_cmd_update_set_aid {
   3214	struct	mwl8k_cmd_pkt header;
   3215	__le16	aid;
   3216
   3217	 /* AP's MAC address (BSSID) */
   3218	__u8	bssid[ETH_ALEN];
   3219	__le16	protection_mode;
   3220	__u8	supp_rates[14];
   3221} __packed;
   3222
   3223static void legacy_rate_mask_to_array(u8 *rates, u32 mask)
   3224{
   3225	int i;
   3226	int j;
   3227
   3228	/*
   3229	 * Clear nonstandard rate 4.
   3230	 */
   3231	mask &= 0x1fef;
   3232
   3233	for (i = 0, j = 0; i < 13; i++) {
   3234		if (mask & (1 << i))
   3235			rates[j++] = mwl8k_rates_24[i].hw_value;
   3236	}
   3237}
   3238
   3239static int
   3240mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
   3241		  struct ieee80211_vif *vif, u32 legacy_rate_mask)
   3242{
   3243	struct mwl8k_cmd_update_set_aid *cmd;
   3244	u16 prot_mode;
   3245	int rc;
   3246
   3247	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3248	if (cmd == NULL)
   3249		return -ENOMEM;
   3250
   3251	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
   3252	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3253	cmd->aid = cpu_to_le16(vif->bss_conf.aid);
   3254	memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
   3255
   3256	if (vif->bss_conf.use_cts_prot) {
   3257		prot_mode = MWL8K_FRAME_PROT_11G;
   3258	} else {
   3259		switch (vif->bss_conf.ht_operation_mode &
   3260			IEEE80211_HT_OP_MODE_PROTECTION) {
   3261		case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
   3262			prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
   3263			break;
   3264		case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
   3265			prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
   3266			break;
   3267		default:
   3268			prot_mode = MWL8K_FRAME_PROT_DISABLED;
   3269			break;
   3270		}
   3271	}
   3272	cmd->protection_mode = cpu_to_le16(prot_mode);
   3273
   3274	legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask);
   3275
   3276	rc = mwl8k_post_cmd(hw, &cmd->header);
   3277	kfree(cmd);
   3278
   3279	return rc;
   3280}
   3281
   3282/*
   3283 * CMD_SET_RATE.
   3284 */
   3285struct mwl8k_cmd_set_rate {
   3286	struct	mwl8k_cmd_pkt header;
   3287	__u8	legacy_rates[14];
   3288
   3289	/* Bitmap for supported MCS codes.  */
   3290	__u8	mcs_set[16];
   3291	__u8	reserved[16];
   3292} __packed;
   3293
   3294static int
   3295mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
   3296		   u32 legacy_rate_mask, u8 *mcs_rates)
   3297{
   3298	struct mwl8k_cmd_set_rate *cmd;
   3299	int rc;
   3300
   3301	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3302	if (cmd == NULL)
   3303		return -ENOMEM;
   3304
   3305	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
   3306	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3307	legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask);
   3308	memcpy(cmd->mcs_set, mcs_rates, 16);
   3309
   3310	rc = mwl8k_post_cmd(hw, &cmd->header);
   3311	kfree(cmd);
   3312
   3313	return rc;
   3314}
   3315
   3316/*
   3317 * CMD_FINALIZE_JOIN.
   3318 */
   3319#define MWL8K_FJ_BEACON_MAXLEN	128
   3320
   3321struct mwl8k_cmd_finalize_join {
   3322	struct mwl8k_cmd_pkt header;
   3323	__le32 sleep_interval;	/* Number of beacon periods to sleep */
   3324	__u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
   3325} __packed;
   3326
   3327static int mwl8k_cmd_finalize_join(struct ieee80211_hw *hw, void *frame,
   3328				   int framelen, int dtim)
   3329{
   3330	struct mwl8k_cmd_finalize_join *cmd;
   3331	struct ieee80211_mgmt *payload = frame;
   3332	int payload_len;
   3333	int rc;
   3334
   3335	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3336	if (cmd == NULL)
   3337		return -ENOMEM;
   3338
   3339	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
   3340	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3341	cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
   3342
   3343	payload_len = framelen - ieee80211_hdrlen(payload->frame_control);
   3344	if (payload_len < 0)
   3345		payload_len = 0;
   3346	else if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
   3347		payload_len = MWL8K_FJ_BEACON_MAXLEN;
   3348
   3349	memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
   3350
   3351	rc = mwl8k_post_cmd(hw, &cmd->header);
   3352	kfree(cmd);
   3353
   3354	return rc;
   3355}
   3356
   3357/*
   3358 * CMD_SET_RTS_THRESHOLD.
   3359 */
   3360struct mwl8k_cmd_set_rts_threshold {
   3361	struct mwl8k_cmd_pkt header;
   3362	__le16 action;
   3363	__le16 threshold;
   3364} __packed;
   3365
   3366static int
   3367mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh)
   3368{
   3369	struct mwl8k_cmd_set_rts_threshold *cmd;
   3370	int rc;
   3371
   3372	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3373	if (cmd == NULL)
   3374		return -ENOMEM;
   3375
   3376	cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
   3377	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3378	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
   3379	cmd->threshold = cpu_to_le16(rts_thresh);
   3380
   3381	rc = mwl8k_post_cmd(hw, &cmd->header);
   3382	kfree(cmd);
   3383
   3384	return rc;
   3385}
   3386
   3387/*
   3388 * CMD_SET_SLOT.
   3389 */
   3390struct mwl8k_cmd_set_slot {
   3391	struct mwl8k_cmd_pkt header;
   3392	__le16 action;
   3393	__u8 short_slot;
   3394} __packed;
   3395
   3396static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
   3397{
   3398	struct mwl8k_cmd_set_slot *cmd;
   3399	int rc;
   3400
   3401	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3402	if (cmd == NULL)
   3403		return -ENOMEM;
   3404
   3405	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
   3406	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3407	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
   3408	cmd->short_slot = short_slot_time;
   3409
   3410	rc = mwl8k_post_cmd(hw, &cmd->header);
   3411	kfree(cmd);
   3412
   3413	return rc;
   3414}
   3415
   3416/*
   3417 * CMD_SET_EDCA_PARAMS.
   3418 */
   3419struct mwl8k_cmd_set_edca_params {
   3420	struct mwl8k_cmd_pkt header;
   3421
   3422	/* See MWL8K_SET_EDCA_XXX below */
   3423	__le16 action;
   3424
   3425	/* TX opportunity in units of 32 us */
   3426	__le16 txop;
   3427
   3428	union {
   3429		struct {
   3430			/* Log exponent of max contention period: 0...15 */
   3431			__le32 log_cw_max;
   3432
   3433			/* Log exponent of min contention period: 0...15 */
   3434			__le32 log_cw_min;
   3435
   3436			/* Adaptive interframe spacing in units of 32us */
   3437			__u8 aifs;
   3438
   3439			/* TX queue to configure */
   3440			__u8 txq;
   3441		} ap;
   3442		struct {
   3443			/* Log exponent of max contention period: 0...15 */
   3444			__u8 log_cw_max;
   3445
   3446			/* Log exponent of min contention period: 0...15 */
   3447			__u8 log_cw_min;
   3448
   3449			/* Adaptive interframe spacing in units of 32us */
   3450			__u8 aifs;
   3451
   3452			/* TX queue to configure */
   3453			__u8 txq;
   3454		} sta;
   3455	};
   3456} __packed;
   3457
   3458#define MWL8K_SET_EDCA_CW	0x01
   3459#define MWL8K_SET_EDCA_TXOP	0x02
   3460#define MWL8K_SET_EDCA_AIFS	0x04
   3461
   3462#define MWL8K_SET_EDCA_ALL	(MWL8K_SET_EDCA_CW | \
   3463				 MWL8K_SET_EDCA_TXOP | \
   3464				 MWL8K_SET_EDCA_AIFS)
   3465
   3466static int
   3467mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
   3468			  __u16 cw_min, __u16 cw_max,
   3469			  __u8 aifs, __u16 txop)
   3470{
   3471	struct mwl8k_priv *priv = hw->priv;
   3472	struct mwl8k_cmd_set_edca_params *cmd;
   3473	int rc;
   3474
   3475	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3476	if (cmd == NULL)
   3477		return -ENOMEM;
   3478
   3479	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
   3480	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3481	cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
   3482	cmd->txop = cpu_to_le16(txop);
   3483	if (priv->ap_fw) {
   3484		cmd->ap.log_cw_max = cpu_to_le32(ilog2(cw_max + 1));
   3485		cmd->ap.log_cw_min = cpu_to_le32(ilog2(cw_min + 1));
   3486		cmd->ap.aifs = aifs;
   3487		cmd->ap.txq = qnum;
   3488	} else {
   3489		cmd->sta.log_cw_max = (u8)ilog2(cw_max + 1);
   3490		cmd->sta.log_cw_min = (u8)ilog2(cw_min + 1);
   3491		cmd->sta.aifs = aifs;
   3492		cmd->sta.txq = qnum;
   3493	}
   3494
   3495	rc = mwl8k_post_cmd(hw, &cmd->header);
   3496	kfree(cmd);
   3497
   3498	return rc;
   3499}
   3500
   3501/*
   3502 * CMD_SET_WMM_MODE.
   3503 */
   3504struct mwl8k_cmd_set_wmm_mode {
   3505	struct mwl8k_cmd_pkt header;
   3506	__le16 action;
   3507} __packed;
   3508
   3509static int mwl8k_cmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable)
   3510{
   3511	struct mwl8k_priv *priv = hw->priv;
   3512	struct mwl8k_cmd_set_wmm_mode *cmd;
   3513	int rc;
   3514
   3515	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3516	if (cmd == NULL)
   3517		return -ENOMEM;
   3518
   3519	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
   3520	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3521	cmd->action = cpu_to_le16(!!enable);
   3522
   3523	rc = mwl8k_post_cmd(hw, &cmd->header);
   3524	kfree(cmd);
   3525
   3526	if (!rc)
   3527		priv->wmm_enabled = enable;
   3528
   3529	return rc;
   3530}
   3531
   3532/*
   3533 * CMD_MIMO_CONFIG.
   3534 */
   3535struct mwl8k_cmd_mimo_config {
   3536	struct mwl8k_cmd_pkt header;
   3537	__le32 action;
   3538	__u8 rx_antenna_map;
   3539	__u8 tx_antenna_map;
   3540} __packed;
   3541
   3542static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
   3543{
   3544	struct mwl8k_cmd_mimo_config *cmd;
   3545	int rc;
   3546
   3547	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3548	if (cmd == NULL)
   3549		return -ENOMEM;
   3550
   3551	cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
   3552	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3553	cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
   3554	cmd->rx_antenna_map = rx;
   3555	cmd->tx_antenna_map = tx;
   3556
   3557	rc = mwl8k_post_cmd(hw, &cmd->header);
   3558	kfree(cmd);
   3559
   3560	return rc;
   3561}
   3562
   3563/*
   3564 * CMD_USE_FIXED_RATE (STA version).
   3565 */
   3566struct mwl8k_cmd_use_fixed_rate_sta {
   3567	struct mwl8k_cmd_pkt header;
   3568	__le32 action;
   3569	__le32 allow_rate_drop;
   3570	__le32 num_rates;
   3571	struct {
   3572		__le32 is_ht_rate;
   3573		__le32 enable_retry;
   3574		__le32 rate;
   3575		__le32 retry_count;
   3576	} rate_entry[8];
   3577	__le32 rate_type;
   3578	__le32 reserved1;
   3579	__le32 reserved2;
   3580} __packed;
   3581
   3582#define MWL8K_USE_AUTO_RATE	0x0002
   3583#define MWL8K_UCAST_RATE	0
   3584
   3585static int mwl8k_cmd_use_fixed_rate_sta(struct ieee80211_hw *hw)
   3586{
   3587	struct mwl8k_cmd_use_fixed_rate_sta *cmd;
   3588	int rc;
   3589
   3590	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3591	if (cmd == NULL)
   3592		return -ENOMEM;
   3593
   3594	cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
   3595	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3596	cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
   3597	cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE);
   3598
   3599	rc = mwl8k_post_cmd(hw, &cmd->header);
   3600	kfree(cmd);
   3601
   3602	return rc;
   3603}
   3604
   3605/*
   3606 * CMD_USE_FIXED_RATE (AP version).
   3607 */
   3608struct mwl8k_cmd_use_fixed_rate_ap {
   3609	struct mwl8k_cmd_pkt header;
   3610	__le32 action;
   3611	__le32 allow_rate_drop;
   3612	__le32 num_rates;
   3613	struct mwl8k_rate_entry_ap {
   3614		__le32 is_ht_rate;
   3615		__le32 enable_retry;
   3616		__le32 rate;
   3617		__le32 retry_count;
   3618	} rate_entry[4];
   3619	u8 multicast_rate;
   3620	u8 multicast_rate_type;
   3621	u8 management_rate;
   3622} __packed;
   3623
   3624static int
   3625mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt)
   3626{
   3627	struct mwl8k_cmd_use_fixed_rate_ap *cmd;
   3628	int rc;
   3629
   3630	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3631	if (cmd == NULL)
   3632		return -ENOMEM;
   3633
   3634	cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
   3635	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3636	cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
   3637	cmd->multicast_rate = mcast;
   3638	cmd->management_rate = mgmt;
   3639
   3640	rc = mwl8k_post_cmd(hw, &cmd->header);
   3641	kfree(cmd);
   3642
   3643	return rc;
   3644}
   3645
   3646/*
   3647 * CMD_ENABLE_SNIFFER.
   3648 */
   3649struct mwl8k_cmd_enable_sniffer {
   3650	struct mwl8k_cmd_pkt header;
   3651	__le32 action;
   3652} __packed;
   3653
   3654static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable)
   3655{
   3656	struct mwl8k_cmd_enable_sniffer *cmd;
   3657	int rc;
   3658
   3659	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3660	if (cmd == NULL)
   3661		return -ENOMEM;
   3662
   3663	cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
   3664	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3665	cmd->action = cpu_to_le32(!!enable);
   3666
   3667	rc = mwl8k_post_cmd(hw, &cmd->header);
   3668	kfree(cmd);
   3669
   3670	return rc;
   3671}
   3672
   3673struct mwl8k_cmd_update_mac_addr {
   3674	struct mwl8k_cmd_pkt header;
   3675	union {
   3676		struct {
   3677			__le16 mac_type;
   3678			__u8 mac_addr[ETH_ALEN];
   3679		} mbss;
   3680		__u8 mac_addr[ETH_ALEN];
   3681	};
   3682} __packed;
   3683
   3684#define MWL8K_MAC_TYPE_PRIMARY_CLIENT		0
   3685#define MWL8K_MAC_TYPE_SECONDARY_CLIENT		1
   3686#define MWL8K_MAC_TYPE_PRIMARY_AP		2
   3687#define MWL8K_MAC_TYPE_SECONDARY_AP		3
   3688
   3689static int mwl8k_cmd_update_mac_addr(struct ieee80211_hw *hw,
   3690				  struct ieee80211_vif *vif, u8 *mac, bool set)
   3691{
   3692	struct mwl8k_priv *priv = hw->priv;
   3693	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
   3694	struct mwl8k_cmd_update_mac_addr *cmd;
   3695	int mac_type;
   3696	int rc;
   3697
   3698	mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
   3699	if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) {
   3700		if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported))
   3701			if (priv->ap_fw)
   3702				mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
   3703			else
   3704				mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT;
   3705		else
   3706			mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
   3707	} else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) {
   3708		if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported))
   3709			mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
   3710		else
   3711			mac_type = MWL8K_MAC_TYPE_SECONDARY_AP;
   3712	}
   3713
   3714	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3715	if (cmd == NULL)
   3716		return -ENOMEM;
   3717
   3718	if (set)
   3719		cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
   3720	else
   3721		cmd->header.code = cpu_to_le16(MWL8K_CMD_DEL_MAC_ADDR);
   3722
   3723	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3724	if (priv->ap_fw) {
   3725		cmd->mbss.mac_type = cpu_to_le16(mac_type);
   3726		memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
   3727	} else {
   3728		memcpy(cmd->mac_addr, mac, ETH_ALEN);
   3729	}
   3730
   3731	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   3732	kfree(cmd);
   3733
   3734	return rc;
   3735}
   3736
   3737/*
   3738 * MWL8K_CMD_SET_MAC_ADDR.
   3739 */
   3740static inline int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
   3741				  struct ieee80211_vif *vif, u8 *mac)
   3742{
   3743	return mwl8k_cmd_update_mac_addr(hw, vif, mac, true);
   3744}
   3745
   3746/*
   3747 * MWL8K_CMD_DEL_MAC_ADDR.
   3748 */
   3749static inline int mwl8k_cmd_del_mac_addr(struct ieee80211_hw *hw,
   3750				  struct ieee80211_vif *vif, u8 *mac)
   3751{
   3752	return mwl8k_cmd_update_mac_addr(hw, vif, mac, false);
   3753}
   3754
   3755/*
   3756 * CMD_SET_RATEADAPT_MODE.
   3757 */
   3758struct mwl8k_cmd_set_rate_adapt_mode {
   3759	struct mwl8k_cmd_pkt header;
   3760	__le16 action;
   3761	__le16 mode;
   3762} __packed;
   3763
   3764static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode)
   3765{
   3766	struct mwl8k_cmd_set_rate_adapt_mode *cmd;
   3767	int rc;
   3768
   3769	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3770	if (cmd == NULL)
   3771		return -ENOMEM;
   3772
   3773	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE);
   3774	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3775	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
   3776	cmd->mode = cpu_to_le16(mode);
   3777
   3778	rc = mwl8k_post_cmd(hw, &cmd->header);
   3779	kfree(cmd);
   3780
   3781	return rc;
   3782}
   3783
   3784/*
   3785 * CMD_GET_WATCHDOG_BITMAP.
   3786 */
   3787struct mwl8k_cmd_get_watchdog_bitmap {
   3788	struct mwl8k_cmd_pkt header;
   3789	u8	bitmap;
   3790} __packed;
   3791
   3792static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap)
   3793{
   3794	struct mwl8k_cmd_get_watchdog_bitmap *cmd;
   3795	int rc;
   3796
   3797	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3798	if (cmd == NULL)
   3799		return -ENOMEM;
   3800
   3801	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_WATCHDOG_BITMAP);
   3802	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3803
   3804	rc = mwl8k_post_cmd(hw, &cmd->header);
   3805	if (!rc)
   3806		*bitmap = cmd->bitmap;
   3807
   3808	kfree(cmd);
   3809
   3810	return rc;
   3811}
   3812
   3813#define MWL8K_WMM_QUEUE_NUMBER	3
   3814
   3815static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
   3816			     u8 idx);
   3817
   3818static void mwl8k_watchdog_ba_events(struct work_struct *work)
   3819{
   3820	int rc;
   3821	u8 bitmap = 0, stream_index;
   3822	struct mwl8k_ampdu_stream *streams;
   3823	struct mwl8k_priv *priv =
   3824		container_of(work, struct mwl8k_priv, watchdog_ba_handle);
   3825	struct ieee80211_hw *hw = priv->hw;
   3826	int i;
   3827	u32 status = 0;
   3828
   3829	mwl8k_fw_lock(hw);
   3830
   3831	rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap);
   3832	if (rc)
   3833		goto done;
   3834
   3835	spin_lock(&priv->stream_lock);
   3836
   3837	/* the bitmap is the hw queue number.  Map it to the ampdu queue. */
   3838	for (i = 0; i < TOTAL_HW_TX_QUEUES; i++) {
   3839		if (bitmap & (1 << i)) {
   3840			stream_index = (i + MWL8K_WMM_QUEUE_NUMBER) %
   3841				       TOTAL_HW_TX_QUEUES;
   3842			streams = &priv->ampdu[stream_index];
   3843			if (streams->state == AMPDU_STREAM_ACTIVE) {
   3844				ieee80211_stop_tx_ba_session(streams->sta,
   3845							     streams->tid);
   3846				spin_unlock(&priv->stream_lock);
   3847				mwl8k_destroy_ba(hw, stream_index);
   3848				spin_lock(&priv->stream_lock);
   3849			}
   3850		}
   3851	}
   3852
   3853	spin_unlock(&priv->stream_lock);
   3854done:
   3855	atomic_dec(&priv->watchdog_event_pending);
   3856	status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
   3857	iowrite32((status | MWL8K_A2H_INT_BA_WATCHDOG),
   3858		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
   3859	mwl8k_fw_unlock(hw);
   3860	return;
   3861}
   3862
   3863
   3864/*
   3865 * CMD_BSS_START.
   3866 */
   3867struct mwl8k_cmd_bss_start {
   3868	struct mwl8k_cmd_pkt header;
   3869	__le32 enable;
   3870} __packed;
   3871
   3872static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
   3873			       struct ieee80211_vif *vif, int enable)
   3874{
   3875	struct mwl8k_cmd_bss_start *cmd;
   3876	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
   3877	struct mwl8k_priv *priv = hw->priv;
   3878	int rc;
   3879
   3880	if (enable && (priv->running_bsses & (1 << mwl8k_vif->macid)))
   3881		return 0;
   3882
   3883	if (!enable && !(priv->running_bsses & (1 << mwl8k_vif->macid)))
   3884		return 0;
   3885
   3886	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3887	if (cmd == NULL)
   3888		return -ENOMEM;
   3889
   3890	cmd->header.code = cpu_to_le16(MWL8K_CMD_BSS_START);
   3891	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3892	cmd->enable = cpu_to_le32(enable);
   3893
   3894	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   3895	kfree(cmd);
   3896
   3897	if (!rc) {
   3898		if (enable)
   3899			priv->running_bsses |= (1 << mwl8k_vif->macid);
   3900		else
   3901			priv->running_bsses &= ~(1 << mwl8k_vif->macid);
   3902	}
   3903	return rc;
   3904}
   3905
   3906static void mwl8k_enable_bsses(struct ieee80211_hw *hw, bool enable, u32 bitmap)
   3907{
   3908	struct mwl8k_priv *priv = hw->priv;
   3909	struct mwl8k_vif *mwl8k_vif, *tmp_vif;
   3910	struct ieee80211_vif *vif;
   3911
   3912	list_for_each_entry_safe(mwl8k_vif, tmp_vif, &priv->vif_list, list) {
   3913		vif = mwl8k_vif->vif;
   3914
   3915		if (!(bitmap & (1 << mwl8k_vif->macid)))
   3916			continue;
   3917
   3918		if (vif->type == NL80211_IFTYPE_AP)
   3919			mwl8k_cmd_bss_start(hw, vif, enable);
   3920	}
   3921}
   3922/*
   3923 * CMD_BASTREAM.
   3924 */
   3925
   3926/*
   3927 * UPSTREAM is tx direction
   3928 */
   3929#define BASTREAM_FLAG_DIRECTION_UPSTREAM	0x00
   3930#define BASTREAM_FLAG_IMMEDIATE_TYPE		0x01
   3931
   3932enum ba_stream_action_type {
   3933	MWL8K_BA_CREATE,
   3934	MWL8K_BA_UPDATE,
   3935	MWL8K_BA_DESTROY,
   3936	MWL8K_BA_FLUSH,
   3937	MWL8K_BA_CHECK,
   3938};
   3939
   3940
   3941struct mwl8k_create_ba_stream {
   3942	__le32	flags;
   3943	__le32	idle_thrs;
   3944	__le32	bar_thrs;
   3945	__le32	window_size;
   3946	u8	peer_mac_addr[6];
   3947	u8	dialog_token;
   3948	u8	tid;
   3949	u8	queue_id;
   3950	u8	param_info;
   3951	__le32	ba_context;
   3952	u8	reset_seq_no_flag;
   3953	__le16	curr_seq_no;
   3954	u8	sta_src_mac_addr[6];
   3955} __packed;
   3956
   3957struct mwl8k_destroy_ba_stream {
   3958	__le32	flags;
   3959	__le32	ba_context;
   3960} __packed;
   3961
   3962struct mwl8k_cmd_bastream {
   3963	struct mwl8k_cmd_pkt	header;
   3964	__le32	action;
   3965	union {
   3966		struct mwl8k_create_ba_stream	create_params;
   3967		struct mwl8k_destroy_ba_stream	destroy_params;
   3968	};
   3969} __packed;
   3970
   3971static int
   3972mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
   3973	       struct ieee80211_vif *vif)
   3974{
   3975	struct mwl8k_cmd_bastream *cmd;
   3976	int rc;
   3977
   3978	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   3979	if (cmd == NULL)
   3980		return -ENOMEM;
   3981
   3982	cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
   3983	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   3984
   3985	cmd->action = cpu_to_le32(MWL8K_BA_CHECK);
   3986
   3987	cmd->create_params.queue_id = stream->idx;
   3988	memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr,
   3989	       ETH_ALEN);
   3990	cmd->create_params.tid = stream->tid;
   3991
   3992	cmd->create_params.flags =
   3993		cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) |
   3994		cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM);
   3995
   3996	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   3997
   3998	kfree(cmd);
   3999
   4000	return rc;
   4001}
   4002
   4003static int
   4004mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
   4005		u8 buf_size, struct ieee80211_vif *vif)
   4006{
   4007	struct mwl8k_cmd_bastream *cmd;
   4008	int rc;
   4009
   4010	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4011	if (cmd == NULL)
   4012		return -ENOMEM;
   4013
   4014
   4015	cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
   4016	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4017
   4018	cmd->action = cpu_to_le32(MWL8K_BA_CREATE);
   4019
   4020	cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size);
   4021	cmd->create_params.window_size = cpu_to_le32((u32)buf_size);
   4022	cmd->create_params.queue_id = stream->idx;
   4023
   4024	memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN);
   4025	cmd->create_params.tid = stream->tid;
   4026	cmd->create_params.curr_seq_no = cpu_to_le16(0);
   4027	cmd->create_params.reset_seq_no_flag = 1;
   4028
   4029	cmd->create_params.param_info =
   4030		(stream->sta->deflink.ht_cap.ampdu_factor &
   4031		 IEEE80211_HT_AMPDU_PARM_FACTOR) |
   4032		((stream->sta->deflink.ht_cap.ampdu_density << 2) &
   4033		 IEEE80211_HT_AMPDU_PARM_DENSITY);
   4034
   4035	cmd->create_params.flags =
   4036		cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE |
   4037					BASTREAM_FLAG_DIRECTION_UPSTREAM);
   4038
   4039	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   4040
   4041	wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n",
   4042		stream->sta->addr, stream->tid);
   4043	kfree(cmd);
   4044
   4045	return rc;
   4046}
   4047
   4048static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
   4049			     u8 idx)
   4050{
   4051	struct mwl8k_cmd_bastream *cmd;
   4052
   4053	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4054	if (cmd == NULL)
   4055		return;
   4056
   4057	cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
   4058	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4059	cmd->action = cpu_to_le32(MWL8K_BA_DESTROY);
   4060
   4061	cmd->destroy_params.ba_context = cpu_to_le32(idx);
   4062	mwl8k_post_cmd(hw, &cmd->header);
   4063
   4064	wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", idx);
   4065
   4066	kfree(cmd);
   4067}
   4068
   4069/*
   4070 * CMD_SET_NEW_STN.
   4071 */
   4072struct mwl8k_cmd_set_new_stn {
   4073	struct mwl8k_cmd_pkt header;
   4074	__le16 aid;
   4075	__u8 mac_addr[6];
   4076	__le16 stn_id;
   4077	__le16 action;
   4078	__le16 rsvd;
   4079	__le32 legacy_rates;
   4080	__u8 ht_rates[4];
   4081	__le16 cap_info;
   4082	__le16 ht_capabilities_info;
   4083	__u8 mac_ht_param_info;
   4084	__u8 rev;
   4085	__u8 control_channel;
   4086	__u8 add_channel;
   4087	__le16 op_mode;
   4088	__le16 stbc;
   4089	__u8 add_qos_info;
   4090	__u8 is_qos_sta;
   4091	__le32 fw_sta_ptr;
   4092} __packed;
   4093
   4094#define MWL8K_STA_ACTION_ADD		0
   4095#define MWL8K_STA_ACTION_REMOVE		2
   4096
   4097static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
   4098				     struct ieee80211_vif *vif,
   4099				     struct ieee80211_sta *sta)
   4100{
   4101	struct mwl8k_cmd_set_new_stn *cmd;
   4102	u32 rates;
   4103	int rc;
   4104
   4105	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4106	if (cmd == NULL)
   4107		return -ENOMEM;
   4108
   4109	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
   4110	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4111	cmd->aid = cpu_to_le16(sta->aid);
   4112	memcpy(cmd->mac_addr, sta->addr, ETH_ALEN);
   4113	cmd->stn_id = cpu_to_le16(sta->aid);
   4114	cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
   4115	if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ)
   4116		rates = sta->deflink.supp_rates[NL80211_BAND_2GHZ];
   4117	else
   4118		rates = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 5;
   4119	cmd->legacy_rates = cpu_to_le32(rates);
   4120	if (sta->deflink.ht_cap.ht_supported) {
   4121		cmd->ht_rates[0] = sta->deflink.ht_cap.mcs.rx_mask[0];
   4122		cmd->ht_rates[1] = sta->deflink.ht_cap.mcs.rx_mask[1];
   4123		cmd->ht_rates[2] = sta->deflink.ht_cap.mcs.rx_mask[2];
   4124		cmd->ht_rates[3] = sta->deflink.ht_cap.mcs.rx_mask[3];
   4125		cmd->ht_capabilities_info = cpu_to_le16(sta->deflink.ht_cap.cap);
   4126		cmd->mac_ht_param_info = (sta->deflink.ht_cap.ampdu_factor & 3) |
   4127			((sta->deflink.ht_cap.ampdu_density & 7) << 2);
   4128		cmd->is_qos_sta = 1;
   4129	}
   4130
   4131	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   4132	kfree(cmd);
   4133
   4134	return rc;
   4135}
   4136
   4137static int mwl8k_cmd_set_new_stn_add_self(struct ieee80211_hw *hw,
   4138					  struct ieee80211_vif *vif)
   4139{
   4140	struct mwl8k_cmd_set_new_stn *cmd;
   4141	int rc;
   4142
   4143	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4144	if (cmd == NULL)
   4145		return -ENOMEM;
   4146
   4147	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
   4148	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4149	memcpy(cmd->mac_addr, vif->addr, ETH_ALEN);
   4150
   4151	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   4152	kfree(cmd);
   4153
   4154	return rc;
   4155}
   4156
   4157static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw,
   4158				     struct ieee80211_vif *vif, u8 *addr)
   4159{
   4160	struct mwl8k_cmd_set_new_stn *cmd;
   4161	struct mwl8k_priv *priv = hw->priv;
   4162	int rc, i;
   4163	u8 idx;
   4164
   4165	spin_lock(&priv->stream_lock);
   4166	/* Destroy any active ampdu streams for this sta */
   4167	for (i = 0; i < MWL8K_NUM_AMPDU_STREAMS; i++) {
   4168		struct mwl8k_ampdu_stream *s;
   4169		s = &priv->ampdu[i];
   4170		if (s->state != AMPDU_NO_STREAM) {
   4171			if (memcmp(s->sta->addr, addr, ETH_ALEN) == 0) {
   4172				if (s->state == AMPDU_STREAM_ACTIVE) {
   4173					idx = s->idx;
   4174					spin_unlock(&priv->stream_lock);
   4175					mwl8k_destroy_ba(hw, idx);
   4176					spin_lock(&priv->stream_lock);
   4177				} else if (s->state == AMPDU_STREAM_NEW) {
   4178					mwl8k_remove_stream(hw, s);
   4179				}
   4180			}
   4181		}
   4182	}
   4183
   4184	spin_unlock(&priv->stream_lock);
   4185
   4186	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4187	if (cmd == NULL)
   4188		return -ENOMEM;
   4189
   4190	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
   4191	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4192	memcpy(cmd->mac_addr, addr, ETH_ALEN);
   4193	cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE);
   4194
   4195	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   4196	kfree(cmd);
   4197
   4198	return rc;
   4199}
   4200
   4201/*
   4202 * CMD_UPDATE_ENCRYPTION.
   4203 */
   4204
   4205#define MAX_ENCR_KEY_LENGTH	16
   4206#define MIC_KEY_LENGTH		8
   4207
   4208struct mwl8k_cmd_update_encryption {
   4209	struct mwl8k_cmd_pkt header;
   4210
   4211	__le32 action;
   4212	__le32 reserved;
   4213	__u8 mac_addr[6];
   4214	__u8 encr_type;
   4215
   4216} __packed;
   4217
   4218struct mwl8k_cmd_set_key {
   4219	struct mwl8k_cmd_pkt header;
   4220
   4221	__le32 action;
   4222	__le32 reserved;
   4223	__le16 length;
   4224	__le16 key_type_id;
   4225	__le32 key_info;
   4226	__le32 key_id;
   4227	__le16 key_len;
   4228	struct {
   4229		__u8 key_material[MAX_ENCR_KEY_LENGTH];
   4230		__u8 tkip_tx_mic_key[MIC_KEY_LENGTH];
   4231		__u8 tkip_rx_mic_key[MIC_KEY_LENGTH];
   4232	} tkip;
   4233	__le16 tkip_rsc_low;
   4234	__le32 tkip_rsc_high;
   4235	__le16 tkip_tsc_low;
   4236	__le32 tkip_tsc_high;
   4237	__u8 mac_addr[6];
   4238} __packed;
   4239
   4240enum {
   4241	MWL8K_ENCR_ENABLE,
   4242	MWL8K_ENCR_SET_KEY,
   4243	MWL8K_ENCR_REMOVE_KEY,
   4244	MWL8K_ENCR_SET_GROUP_KEY,
   4245};
   4246
   4247#define MWL8K_UPDATE_ENCRYPTION_TYPE_WEP	0
   4248#define MWL8K_UPDATE_ENCRYPTION_TYPE_DISABLE	1
   4249#define MWL8K_UPDATE_ENCRYPTION_TYPE_TKIP	4
   4250#define MWL8K_UPDATE_ENCRYPTION_TYPE_MIXED	7
   4251#define MWL8K_UPDATE_ENCRYPTION_TYPE_AES	8
   4252
   4253enum {
   4254	MWL8K_ALG_WEP,
   4255	MWL8K_ALG_TKIP,
   4256	MWL8K_ALG_CCMP,
   4257};
   4258
   4259#define MWL8K_KEY_FLAG_TXGROUPKEY	0x00000004
   4260#define MWL8K_KEY_FLAG_PAIRWISE		0x00000008
   4261#define MWL8K_KEY_FLAG_TSC_VALID	0x00000040
   4262#define MWL8K_KEY_FLAG_WEP_TXKEY	0x01000000
   4263#define MWL8K_KEY_FLAG_MICKEY_VALID	0x02000000
   4264
   4265static int mwl8k_cmd_update_encryption_enable(struct ieee80211_hw *hw,
   4266					      struct ieee80211_vif *vif,
   4267					      u8 *addr,
   4268					      u8 encr_type)
   4269{
   4270	struct mwl8k_cmd_update_encryption *cmd;
   4271	int rc;
   4272
   4273	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4274	if (cmd == NULL)
   4275		return -ENOMEM;
   4276
   4277	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION);
   4278	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4279	cmd->action = cpu_to_le32(MWL8K_ENCR_ENABLE);
   4280	memcpy(cmd->mac_addr, addr, ETH_ALEN);
   4281	cmd->encr_type = encr_type;
   4282
   4283	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   4284	kfree(cmd);
   4285
   4286	return rc;
   4287}
   4288
   4289static int mwl8k_encryption_set_cmd_info(struct mwl8k_cmd_set_key *cmd,
   4290						u8 *addr,
   4291						struct ieee80211_key_conf *key)
   4292{
   4293	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION);
   4294	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4295	cmd->length = cpu_to_le16(sizeof(*cmd) -
   4296				offsetof(struct mwl8k_cmd_set_key, length));
   4297	cmd->key_id = cpu_to_le32(key->keyidx);
   4298	cmd->key_len = cpu_to_le16(key->keylen);
   4299	memcpy(cmd->mac_addr, addr, ETH_ALEN);
   4300
   4301	switch (key->cipher) {
   4302	case WLAN_CIPHER_SUITE_WEP40:
   4303	case WLAN_CIPHER_SUITE_WEP104:
   4304		cmd->key_type_id = cpu_to_le16(MWL8K_ALG_WEP);
   4305		if (key->keyidx == 0)
   4306			cmd->key_info =	cpu_to_le32(MWL8K_KEY_FLAG_WEP_TXKEY);
   4307
   4308		break;
   4309	case WLAN_CIPHER_SUITE_TKIP:
   4310		cmd->key_type_id = cpu_to_le16(MWL8K_ALG_TKIP);
   4311		cmd->key_info =	(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
   4312			? cpu_to_le32(MWL8K_KEY_FLAG_PAIRWISE)
   4313			: cpu_to_le32(MWL8K_KEY_FLAG_TXGROUPKEY);
   4314		cmd->key_info |= cpu_to_le32(MWL8K_KEY_FLAG_MICKEY_VALID
   4315						| MWL8K_KEY_FLAG_TSC_VALID);
   4316		break;
   4317	case WLAN_CIPHER_SUITE_CCMP:
   4318		cmd->key_type_id = cpu_to_le16(MWL8K_ALG_CCMP);
   4319		cmd->key_info =	(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
   4320			? cpu_to_le32(MWL8K_KEY_FLAG_PAIRWISE)
   4321			: cpu_to_le32(MWL8K_KEY_FLAG_TXGROUPKEY);
   4322		break;
   4323	default:
   4324		return -ENOTSUPP;
   4325	}
   4326
   4327	return 0;
   4328}
   4329
   4330static int mwl8k_cmd_encryption_set_key(struct ieee80211_hw *hw,
   4331						struct ieee80211_vif *vif,
   4332						u8 *addr,
   4333						struct ieee80211_key_conf *key)
   4334{
   4335	struct mwl8k_cmd_set_key *cmd;
   4336	int rc;
   4337	int keymlen;
   4338	u32 action;
   4339	u8 idx;
   4340	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
   4341
   4342	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4343	if (cmd == NULL)
   4344		return -ENOMEM;
   4345
   4346	rc = mwl8k_encryption_set_cmd_info(cmd, addr, key);
   4347	if (rc < 0)
   4348		goto done;
   4349
   4350	idx = key->keyidx;
   4351
   4352	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
   4353		action = MWL8K_ENCR_SET_KEY;
   4354	else
   4355		action = MWL8K_ENCR_SET_GROUP_KEY;
   4356
   4357	switch (key->cipher) {
   4358	case WLAN_CIPHER_SUITE_WEP40:
   4359	case WLAN_CIPHER_SUITE_WEP104:
   4360		if (!mwl8k_vif->wep_key_conf[idx].enabled) {
   4361			memcpy(mwl8k_vif->wep_key_conf[idx].key, key,
   4362						sizeof(*key) + key->keylen);
   4363			mwl8k_vif->wep_key_conf[idx].enabled = 1;
   4364		}
   4365
   4366		keymlen = key->keylen;
   4367		action = MWL8K_ENCR_SET_KEY;
   4368		break;
   4369	case WLAN_CIPHER_SUITE_TKIP:
   4370		keymlen = MAX_ENCR_KEY_LENGTH + 2 * MIC_KEY_LENGTH;
   4371		break;
   4372	case WLAN_CIPHER_SUITE_CCMP:
   4373		keymlen = key->keylen;
   4374		break;
   4375	default:
   4376		rc = -ENOTSUPP;
   4377		goto done;
   4378	}
   4379
   4380	memcpy(&cmd->tkip, key->key, keymlen);
   4381	cmd->action = cpu_to_le32(action);
   4382
   4383	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   4384done:
   4385	kfree(cmd);
   4386
   4387	return rc;
   4388}
   4389
   4390static int mwl8k_cmd_encryption_remove_key(struct ieee80211_hw *hw,
   4391						struct ieee80211_vif *vif,
   4392						u8 *addr,
   4393						struct ieee80211_key_conf *key)
   4394{
   4395	struct mwl8k_cmd_set_key *cmd;
   4396	int rc;
   4397	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
   4398
   4399	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4400	if (cmd == NULL)
   4401		return -ENOMEM;
   4402
   4403	rc = mwl8k_encryption_set_cmd_info(cmd, addr, key);
   4404	if (rc < 0)
   4405		goto done;
   4406
   4407	if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
   4408			key->cipher == WLAN_CIPHER_SUITE_WEP104)
   4409		mwl8k_vif->wep_key_conf[key->keyidx].enabled = 0;
   4410
   4411	cmd->action = cpu_to_le32(MWL8K_ENCR_REMOVE_KEY);
   4412
   4413	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
   4414done:
   4415	kfree(cmd);
   4416
   4417	return rc;
   4418}
   4419
   4420static int mwl8k_set_key(struct ieee80211_hw *hw,
   4421			 enum set_key_cmd cmd_param,
   4422			 struct ieee80211_vif *vif,
   4423			 struct ieee80211_sta *sta,
   4424			 struct ieee80211_key_conf *key)
   4425{
   4426	int rc = 0;
   4427	u8 encr_type;
   4428	u8 *addr;
   4429	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
   4430	struct mwl8k_priv *priv = hw->priv;
   4431
   4432	if (vif->type == NL80211_IFTYPE_STATION && !priv->ap_fw)
   4433		return -EOPNOTSUPP;
   4434
   4435	if (sta == NULL)
   4436		addr = vif->addr;
   4437	else
   4438		addr = sta->addr;
   4439
   4440	if (cmd_param == SET_KEY) {
   4441		rc = mwl8k_cmd_encryption_set_key(hw, vif, addr, key);
   4442		if (rc)
   4443			goto out;
   4444
   4445		if ((key->cipher == WLAN_CIPHER_SUITE_WEP40)
   4446				|| (key->cipher == WLAN_CIPHER_SUITE_WEP104))
   4447			encr_type = MWL8K_UPDATE_ENCRYPTION_TYPE_WEP;
   4448		else
   4449			encr_type = MWL8K_UPDATE_ENCRYPTION_TYPE_MIXED;
   4450
   4451		rc = mwl8k_cmd_update_encryption_enable(hw, vif, addr,
   4452								encr_type);
   4453		if (rc)
   4454			goto out;
   4455
   4456		mwl8k_vif->is_hw_crypto_enabled = true;
   4457
   4458	} else {
   4459		rc = mwl8k_cmd_encryption_remove_key(hw, vif, addr, key);
   4460
   4461		if (rc)
   4462			goto out;
   4463	}
   4464out:
   4465	return rc;
   4466}
   4467
   4468/*
   4469 * CMD_UPDATE_STADB.
   4470 */
   4471struct ewc_ht_info {
   4472	__le16	control1;
   4473	__le16	control2;
   4474	__le16	control3;
   4475} __packed;
   4476
   4477struct peer_capability_info {
   4478	/* Peer type - AP vs. STA.  */
   4479	__u8	peer_type;
   4480
   4481	/* Basic 802.11 capabilities from assoc resp.  */
   4482	__le16	basic_caps;
   4483
   4484	/* Set if peer supports 802.11n high throughput (HT).  */
   4485	__u8	ht_support;
   4486
   4487	/* Valid if HT is supported.  */
   4488	__le16	ht_caps;
   4489	__u8	extended_ht_caps;
   4490	struct ewc_ht_info	ewc_info;
   4491
   4492	/* Legacy rate table. Intersection of our rates and peer rates.  */
   4493	__u8	legacy_rates[12];
   4494
   4495	/* HT rate table. Intersection of our rates and peer rates.  */
   4496	__u8	ht_rates[16];
   4497	__u8	pad[16];
   4498
   4499	/* If set, interoperability mode, no proprietary extensions.  */
   4500	__u8	interop;
   4501	__u8	pad2;
   4502	__u8	station_id;
   4503	__le16	amsdu_enabled;
   4504} __packed;
   4505
   4506struct mwl8k_cmd_update_stadb {
   4507	struct mwl8k_cmd_pkt header;
   4508
   4509	/* See STADB_ACTION_TYPE */
   4510	__le32	action;
   4511
   4512	/* Peer MAC address */
   4513	__u8	peer_addr[ETH_ALEN];
   4514
   4515	__le32	reserved;
   4516
   4517	/* Peer info - valid during add/update.  */
   4518	struct peer_capability_info	peer_info;
   4519} __packed;
   4520
   4521#define MWL8K_STA_DB_MODIFY_ENTRY	1
   4522#define MWL8K_STA_DB_DEL_ENTRY		2
   4523
   4524/* Peer Entry flags - used to define the type of the peer node */
   4525#define MWL8K_PEER_TYPE_ACCESSPOINT	2
   4526
   4527static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
   4528				      struct ieee80211_vif *vif,
   4529				      struct ieee80211_sta *sta)
   4530{
   4531	struct mwl8k_cmd_update_stadb *cmd;
   4532	struct peer_capability_info *p;
   4533	u32 rates;
   4534	int rc;
   4535
   4536	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4537	if (cmd == NULL)
   4538		return -ENOMEM;
   4539
   4540	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
   4541	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4542	cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY);
   4543	memcpy(cmd->peer_addr, sta->addr, ETH_ALEN);
   4544
   4545	p = &cmd->peer_info;
   4546	p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
   4547	p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability);
   4548	p->ht_support = sta->deflink.ht_cap.ht_supported;
   4549	p->ht_caps = cpu_to_le16(sta->deflink.ht_cap.cap);
   4550	p->extended_ht_caps = (sta->deflink.ht_cap.ampdu_factor & 3) |
   4551		((sta->deflink.ht_cap.ampdu_density & 7) << 2);
   4552	if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ)
   4553		rates = sta->deflink.supp_rates[NL80211_BAND_2GHZ];
   4554	else
   4555		rates = sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 5;
   4556	legacy_rate_mask_to_array(p->legacy_rates, rates);
   4557	memcpy(p->ht_rates, &sta->deflink.ht_cap.mcs, 16);
   4558	p->interop = 1;
   4559	p->amsdu_enabled = 0;
   4560
   4561	rc = mwl8k_post_cmd(hw, &cmd->header);
   4562	if (!rc)
   4563		rc = p->station_id;
   4564	kfree(cmd);
   4565
   4566	return rc;
   4567}
   4568
   4569static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw,
   4570				      struct ieee80211_vif *vif, u8 *addr)
   4571{
   4572	struct mwl8k_cmd_update_stadb *cmd;
   4573	int rc;
   4574
   4575	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
   4576	if (cmd == NULL)
   4577		return -ENOMEM;
   4578
   4579	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
   4580	cmd->header.length = cpu_to_le16(sizeof(*cmd));
   4581	cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY);
   4582	memcpy(cmd->peer_addr, addr, ETH_ALEN);
   4583
   4584	rc = mwl8k_post_cmd(hw, &cmd->header);
   4585	kfree(cmd);
   4586
   4587	return rc;
   4588}
   4589
   4590
   4591/*
   4592 * Interrupt handling.
   4593 */
   4594static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
   4595{
   4596	struct ieee80211_hw *hw = dev_id;
   4597	struct mwl8k_priv *priv = hw->priv;
   4598	u32 status;
   4599
   4600	status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
   4601	if (!status)
   4602		return IRQ_NONE;
   4603
   4604	if (status & MWL8K_A2H_INT_TX_DONE) {
   4605		status &= ~MWL8K_A2H_INT_TX_DONE;
   4606		tasklet_schedule(&priv->poll_tx_task);
   4607	}
   4608
   4609	if (status & MWL8K_A2H_INT_RX_READY) {
   4610		status &= ~MWL8K_A2H_INT_RX_READY;
   4611		tasklet_schedule(&priv->poll_rx_task);
   4612	}
   4613
   4614	if (status & MWL8K_A2H_INT_BA_WATCHDOG) {
   4615		iowrite32(~MWL8K_A2H_INT_BA_WATCHDOG,
   4616			  priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
   4617
   4618		atomic_inc(&priv->watchdog_event_pending);
   4619		status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
   4620		ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
   4621	}
   4622
   4623	if (status)
   4624		iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
   4625
   4626	if (status & MWL8K_A2H_INT_OPC_DONE) {
   4627		if (priv->hostcmd_wait != NULL)
   4628			complete(priv->hostcmd_wait);
   4629	}
   4630
   4631	if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
   4632		if (!mutex_is_locked(&priv->fw_mutex) &&
   4633		    priv->radio_on && priv->pending_tx_pkts)
   4634			mwl8k_tx_start(priv);
   4635	}
   4636
   4637	return IRQ_HANDLED;
   4638}
   4639
   4640static void mwl8k_tx_poll(struct tasklet_struct *t)
   4641{
   4642	struct mwl8k_priv *priv = from_tasklet(priv, t, poll_tx_task);
   4643	struct ieee80211_hw *hw = pci_get_drvdata(priv->pdev);
   4644	int limit;
   4645	int i;
   4646
   4647	limit = 32;
   4648
   4649	spin_lock(&priv->tx_lock);
   4650
   4651	for (i = 0; i < mwl8k_tx_queues(priv); i++)
   4652		limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
   4653
   4654	if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
   4655		complete(priv->tx_wait);
   4656		priv->tx_wait = NULL;
   4657	}
   4658
   4659	spin_unlock(&priv->tx_lock);
   4660
   4661	if (limit) {
   4662		writel(~MWL8K_A2H_INT_TX_DONE,
   4663		       priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
   4664	} else {
   4665		tasklet_schedule(&priv->poll_tx_task);
   4666	}
   4667}
   4668
   4669static void mwl8k_rx_poll(struct tasklet_struct *t)
   4670{
   4671	struct mwl8k_priv *priv = from_tasklet(priv, t, poll_rx_task);
   4672	struct ieee80211_hw *hw = pci_get_drvdata(priv->pdev);
   4673	int limit;
   4674
   4675	limit = 32;
   4676	limit -= rxq_process(hw, 0, limit);
   4677	limit -= rxq_refill(hw, 0, limit);
   4678
   4679	if (limit) {
   4680		writel(~MWL8K_A2H_INT_RX_READY,
   4681		       priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
   4682	} else {
   4683		tasklet_schedule(&priv->poll_rx_task);
   4684	}
   4685}
   4686
   4687
   4688/*
   4689 * Core driver operations.
   4690 */
   4691static void mwl8k_tx(struct ieee80211_hw *hw,
   4692		     struct ieee80211_tx_control *control,
   4693		     struct sk_buff *skb)
   4694{
   4695	struct mwl8k_priv *priv = hw->priv;
   4696	int index = skb_get_queue_mapping(skb);
   4697
   4698	if (!priv->radio_on) {
   4699		wiphy_debug(hw->wiphy,
   4700			    "dropped TX frame since radio disabled\n");
   4701		dev_kfree_skb(skb);
   4702		return;
   4703	}
   4704
   4705	mwl8k_txq_xmit(hw, index, control->sta, skb);
   4706}
   4707
   4708static int mwl8k_start(struct ieee80211_hw *hw)
   4709{
   4710	struct mwl8k_priv *priv = hw->priv;
   4711	int rc;
   4712
   4713	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
   4714			 IRQF_SHARED, MWL8K_NAME, hw);
   4715	if (rc) {
   4716		priv->irq = -1;
   4717		wiphy_err(hw->wiphy, "failed to register IRQ handler\n");
   4718		return -EIO;
   4719	}
   4720	priv->irq = priv->pdev->irq;
   4721
   4722	/* Enable TX reclaim and RX tasklets.  */
   4723	tasklet_enable(&priv->poll_tx_task);
   4724	tasklet_enable(&priv->poll_rx_task);
   4725
   4726	/* Enable interrupts */
   4727	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
   4728	iowrite32(MWL8K_A2H_EVENTS,
   4729		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
   4730
   4731	rc = mwl8k_fw_lock(hw);
   4732	if (!rc) {
   4733		rc = mwl8k_cmd_radio_enable(hw);
   4734
   4735		if (!priv->ap_fw) {
   4736			if (!rc)
   4737				rc = mwl8k_cmd_enable_sniffer(hw, 0);
   4738
   4739			if (!rc)
   4740				rc = mwl8k_cmd_set_pre_scan(hw);
   4741
   4742			if (!rc)
   4743				rc = mwl8k_cmd_set_post_scan(hw,
   4744						"\x00\x00\x00\x00\x00\x00");
   4745		}
   4746
   4747		if (!rc)
   4748			rc = mwl8k_cmd_set_rateadapt_mode(hw, 0);
   4749
   4750		if (!rc)
   4751			rc = mwl8k_cmd_set_wmm_mode(hw, 0);
   4752
   4753		mwl8k_fw_unlock(hw);
   4754	}
   4755
   4756	if (rc) {
   4757		iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
   4758		free_irq(priv->pdev->irq, hw);
   4759		priv->irq = -1;
   4760		tasklet_disable(&priv->poll_tx_task);
   4761		tasklet_disable(&priv->poll_rx_task);
   4762	} else {
   4763		ieee80211_wake_queues(hw);
   4764	}
   4765
   4766	return rc;
   4767}
   4768
   4769static void mwl8k_stop(struct ieee80211_hw *hw)
   4770{
   4771	struct mwl8k_priv *priv = hw->priv;
   4772	int i;
   4773
   4774	if (!priv->hw_restart_in_progress)
   4775		mwl8k_cmd_radio_disable(hw);
   4776
   4777	ieee80211_stop_queues(hw);
   4778
   4779	/* Disable interrupts */
   4780	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
   4781	if (priv->irq != -1) {
   4782		free_irq(priv->pdev->irq, hw);
   4783		priv->irq = -1;
   4784	}
   4785
   4786	/* Stop finalize join worker */
   4787	cancel_work_sync(&priv->finalize_join_worker);
   4788	cancel_work_sync(&priv->watchdog_ba_handle);
   4789	if (priv->beacon_skb != NULL)
   4790		dev_kfree_skb(priv->beacon_skb);
   4791
   4792	/* Stop TX reclaim and RX tasklets.  */
   4793	tasklet_disable(&priv->poll_tx_task);
   4794	tasklet_disable(&priv->poll_rx_task);
   4795
   4796	/* Return all skbs to mac80211 */
   4797	for (i = 0; i < mwl8k_tx_queues(priv); i++)
   4798		mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
   4799}
   4800
   4801static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image);
   4802
   4803static int mwl8k_add_interface(struct ieee80211_hw *hw,
   4804			       struct ieee80211_vif *vif)
   4805{
   4806	struct mwl8k_priv *priv = hw->priv;
   4807	struct mwl8k_vif *mwl8k_vif;
   4808	u32 macids_supported;
   4809	int macid, rc;
   4810	struct mwl8k_device_info *di;
   4811
   4812	/*
   4813	 * Reject interface creation if sniffer mode is active, as
   4814	 * STA operation is mutually exclusive with hardware sniffer
   4815	 * mode.  (Sniffer mode is only used on STA firmware.)
   4816	 */
   4817	if (priv->sniffer_enabled) {
   4818		wiphy_info(hw->wiphy,
   4819			   "unable to create STA interface because sniffer mode is enabled\n");
   4820		return -EINVAL;
   4821	}
   4822
   4823	di = priv->device_info;
   4824	switch (vif->type) {
   4825	case NL80211_IFTYPE_AP:
   4826		if (!priv->ap_fw && di->fw_image_ap) {
   4827			/* we must load the ap fw to meet this request */
   4828			if (!list_empty(&priv->vif_list))
   4829				return -EBUSY;
   4830			rc = mwl8k_reload_firmware(hw, di->fw_image_ap);
   4831			if (rc)
   4832				return rc;
   4833		}
   4834		macids_supported = priv->ap_macids_supported;
   4835		break;
   4836	case NL80211_IFTYPE_STATION:
   4837		if (priv->ap_fw && di->fw_image_sta) {
   4838			if (!list_empty(&priv->vif_list)) {
   4839				wiphy_warn(hw->wiphy, "AP interface is running.\n"
   4840					   "Adding STA interface for WDS");
   4841			} else {
   4842				/* we must load the sta fw to
   4843				 * meet this request.
   4844				 */
   4845				rc = mwl8k_reload_firmware(hw,
   4846							   di->fw_image_sta);
   4847				if (rc)
   4848					return rc;
   4849			}
   4850		}
   4851		macids_supported = priv->sta_macids_supported;
   4852		break;
   4853	default:
   4854		return -EINVAL;
   4855	}
   4856
   4857	macid = ffs(macids_supported & ~priv->macids_used);
   4858	if (!macid--)
   4859		return -EBUSY;
   4860
   4861	/* Setup driver private area. */
   4862	mwl8k_vif = MWL8K_VIF(vif);
   4863	memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
   4864	mwl8k_vif->vif = vif;
   4865	mwl8k_vif->macid = macid;
   4866	mwl8k_vif->seqno = 0;
   4867	memcpy(mwl8k_vif->bssid, vif->addr, ETH_ALEN);
   4868	mwl8k_vif->is_hw_crypto_enabled = false;
   4869
   4870	/* Set the mac address.  */
   4871	mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
   4872
   4873	if (vif->type == NL80211_IFTYPE_AP)
   4874		mwl8k_cmd_set_new_stn_add_self(hw, vif);
   4875
   4876	priv->macids_used |= 1 << mwl8k_vif->macid;
   4877	list_add_tail(&mwl8k_vif->list, &priv->vif_list);
   4878
   4879	return 0;
   4880}
   4881
   4882static void mwl8k_remove_vif(struct mwl8k_priv *priv, struct mwl8k_vif *vif)
   4883{
   4884	/* Has ieee80211_restart_hw re-added the removed interfaces? */
   4885	if (!priv->macids_used)
   4886		return;
   4887
   4888	priv->macids_used &= ~(1 << vif->macid);
   4889	list_del(&vif->list);
   4890}
   4891
   4892static void mwl8k_remove_interface(struct ieee80211_hw *hw,
   4893				   struct ieee80211_vif *vif)
   4894{
   4895	struct mwl8k_priv *priv = hw->priv;
   4896	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
   4897
   4898	if (vif->type == NL80211_IFTYPE_AP)
   4899		mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
   4900
   4901	mwl8k_cmd_del_mac_addr(hw, vif, vif->addr);
   4902
   4903	mwl8k_remove_vif(priv, mwl8k_vif);
   4904}
   4905
   4906static void mwl8k_hw_restart_work(struct work_struct *work)
   4907{
   4908	struct mwl8k_priv *priv =
   4909		container_of(work, struct mwl8k_priv, fw_reload);
   4910	struct ieee80211_hw *hw = priv->hw;
   4911	struct mwl8k_device_info *di;
   4912	int rc;
   4913
   4914	/* If some command is waiting for a response, clear it */
   4915	if (priv->hostcmd_wait != NULL) {
   4916		complete(priv->hostcmd_wait);
   4917		priv->hostcmd_wait = NULL;
   4918	}
   4919
   4920	priv->hw_restart_owner = current;
   4921	di = priv->device_info;
   4922	mwl8k_fw_lock(hw);
   4923
   4924	if (priv->ap_fw)
   4925		rc = mwl8k_reload_firmware(hw, di->fw_image_ap);
   4926	else
   4927		rc = mwl8k_reload_firmware(hw, di->fw_image_sta);
   4928
   4929	if (rc)
   4930		goto fail;
   4931
   4932	priv->hw_restart_owner = NULL;
   4933	priv->hw_restart_in_progress = false;
   4934
   4935	/*
   4936	 * This unlock will wake up the queues and
   4937	 * also opens the command path for other
   4938	 * commands
   4939	 */
   4940	mwl8k_fw_unlock(hw);
   4941
   4942	ieee80211_restart_hw(hw);
   4943
   4944	wiphy_err(hw->wiphy, "Firmware restarted successfully\n");
   4945
   4946	return;
   4947fail:
   4948	mwl8k_fw_unlock(hw);
   4949
   4950	wiphy_err(hw->wiphy, "Firmware restart failed\n");
   4951}
   4952
   4953static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
   4954{
   4955	struct ieee80211_conf *conf = &hw->conf;
   4956	struct mwl8k_priv *priv = hw->priv;
   4957	int rc;
   4958
   4959	rc = mwl8k_fw_lock(hw);
   4960	if (rc)
   4961		return rc;
   4962
   4963	if (conf->flags & IEEE80211_CONF_IDLE)
   4964		rc = mwl8k_cmd_radio_disable(hw);
   4965	else
   4966		rc = mwl8k_cmd_radio_enable(hw);
   4967	if (rc)
   4968		goto out;
   4969
   4970	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
   4971		rc = mwl8k_cmd_set_rf_channel(hw, conf);
   4972		if (rc)
   4973			goto out;
   4974	}
   4975
   4976	if (conf->power_level > 18)
   4977		conf->power_level = 18;
   4978
   4979	if (priv->ap_fw) {
   4980
   4981		if (conf->flags & IEEE80211_CONF_CHANGE_POWER) {
   4982			rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
   4983			if (rc)
   4984				goto out;
   4985		}
   4986
   4987
   4988	} else {
   4989		rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
   4990		if (rc)
   4991			goto out;
   4992		rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7);
   4993	}
   4994
   4995out:
   4996	mwl8k_fw_unlock(hw);
   4997
   4998	return rc;
   4999}
   5000
   5001static void
   5002mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
   5003			   struct ieee80211_bss_conf *info, u32 changed)
   5004{
   5005	struct mwl8k_priv *priv = hw->priv;
   5006	u32 ap_legacy_rates = 0;
   5007	u8 ap_mcs_rates[16];
   5008	int rc;
   5009
   5010	if (mwl8k_fw_lock(hw))
   5011		return;
   5012
   5013	/*
   5014	 * No need to capture a beacon if we're no longer associated.
   5015	 */
   5016	if ((changed & BSS_CHANGED_ASSOC) && !vif->bss_conf.assoc)
   5017		priv->capture_beacon = false;
   5018
   5019	/*
   5020	 * Get the AP's legacy and MCS rates.
   5021	 */
   5022	if (vif->bss_conf.assoc) {
   5023		struct ieee80211_sta *ap;
   5024
   5025		rcu_read_lock();
   5026
   5027		ap = ieee80211_find_sta(vif, vif->bss_conf.bssid);
   5028		if (ap == NULL) {
   5029			rcu_read_unlock();
   5030			goto out;
   5031		}
   5032
   5033		if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) {
   5034			ap_legacy_rates = ap->deflink.supp_rates[NL80211_BAND_2GHZ];
   5035		} else {
   5036			ap_legacy_rates =
   5037				ap->deflink.supp_rates[NL80211_BAND_5GHZ] << 5;
   5038		}
   5039		memcpy(ap_mcs_rates, &ap->deflink.ht_cap.mcs, 16);
   5040
   5041		rcu_read_unlock();
   5042
   5043		if (changed & BSS_CHANGED_ASSOC) {
   5044			if (!priv->ap_fw) {
   5045				rc = mwl8k_cmd_set_rate(hw, vif,
   5046							ap_legacy_rates,
   5047							ap_mcs_rates);
   5048				if (rc)
   5049					goto out;
   5050
   5051				rc = mwl8k_cmd_use_fixed_rate_sta(hw);
   5052				if (rc)
   5053					goto out;
   5054			} else {
   5055				int idx;
   5056				int rate;
   5057
   5058				/* Use AP firmware specific rate command.
   5059				 */
   5060				idx = ffs(vif->bss_conf.basic_rates);
   5061				if (idx)
   5062					idx--;
   5063
   5064				if (hw->conf.chandef.chan->band ==
   5065				    NL80211_BAND_2GHZ)
   5066					rate = mwl8k_rates_24[idx].hw_value;
   5067				else
   5068					rate = mwl8k_rates_50[idx].hw_value;
   5069
   5070				mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
   5071			}
   5072		}
   5073	}
   5074
   5075	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
   5076		rc = mwl8k_set_radio_preamble(hw,
   5077				vif->bss_conf.use_short_preamble);
   5078		if (rc)
   5079			goto out;
   5080	}
   5081
   5082	if ((changed & BSS_CHANGED_ERP_SLOT) && !priv->ap_fw)  {
   5083		rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot);
   5084		if (rc)
   5085			goto out;
   5086	}
   5087
   5088	if (vif->bss_conf.assoc && !priv->ap_fw &&
   5089	    (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT |
   5090			BSS_CHANGED_HT))) {
   5091		rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
   5092		if (rc)
   5093			goto out;
   5094	}
   5095
   5096	if (vif->bss_conf.assoc &&
   5097	    (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INT))) {
   5098		/*
   5099		 * Finalize the join.  Tell rx handler to process
   5100		 * next beacon from our BSSID.
   5101		 */
   5102		memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN);
   5103		priv->capture_beacon = true;
   5104	}
   5105
   5106out:
   5107	mwl8k_fw_unlock(hw);
   5108}
   5109
   5110static void
   5111mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
   5112			  struct ieee80211_bss_conf *info, u32 changed)
   5113{
   5114	int rc;
   5115
   5116	if (mwl8k_fw_lock(hw))
   5117		return;
   5118
   5119	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
   5120		rc = mwl8k_set_radio_preamble(hw,
   5121				vif->bss_conf.use_short_preamble);
   5122		if (rc)
   5123			goto out;
   5124	}
   5125
   5126	if (changed & BSS_CHANGED_BASIC_RATES) {
   5127		int idx;
   5128		int rate;
   5129
   5130		/*
   5131		 * Use lowest supported basic rate for multicasts
   5132		 * and management frames (such as probe responses --
   5133		 * beacons will always go out at 1 Mb/s).
   5134		 */
   5135		idx = ffs(vif->bss_conf.basic_rates);
   5136		if (idx)
   5137			idx--;
   5138
   5139		if (hw->conf.chandef.chan->band == NL80211_BAND_2GHZ)
   5140			rate = mwl8k_rates_24[idx].hw_value;
   5141		else
   5142			rate = mwl8k_rates_50[idx].hw_value;
   5143
   5144		mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
   5145	}
   5146
   5147	if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
   5148		struct sk_buff *skb;
   5149
   5150		skb = ieee80211_beacon_get(hw, vif);
   5151		if (skb != NULL) {
   5152			mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len);
   5153			kfree_skb(skb);
   5154		}
   5155	}
   5156
   5157	if (changed & BSS_CHANGED_BEACON_ENABLED)
   5158		mwl8k_cmd_bss_start(hw, vif, info->enable_beacon);
   5159
   5160out:
   5161	mwl8k_fw_unlock(hw);
   5162}
   5163
   5164static void
   5165mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
   5166		       struct ieee80211_bss_conf *info, u32 changed)
   5167{
   5168	if (vif->type == NL80211_IFTYPE_STATION)
   5169		mwl8k_bss_info_changed_sta(hw, vif, info, changed);
   5170	if (vif->type == NL80211_IFTYPE_AP)
   5171		mwl8k_bss_info_changed_ap(hw, vif, info, changed);
   5172}
   5173
   5174static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
   5175				   struct netdev_hw_addr_list *mc_list)
   5176{
   5177	struct mwl8k_cmd_pkt *cmd;
   5178
   5179	/*
   5180	 * Synthesize and return a command packet that programs the
   5181	 * hardware multicast address filter.  At this point we don't
   5182	 * know whether FIF_ALLMULTI is being requested, but if it is,
   5183	 * we'll end up throwing this packet away and creating a new
   5184	 * one in mwl8k_configure_filter().
   5185	 */
   5186	cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_list);
   5187
   5188	return (unsigned long)cmd;
   5189}
   5190
   5191static int
   5192mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
   5193			       unsigned int changed_flags,
   5194			       unsigned int *total_flags)
   5195{
   5196	struct mwl8k_priv *priv = hw->priv;
   5197
   5198	/*
   5199	 * Hardware sniffer mode is mutually exclusive with STA
   5200	 * operation, so refuse to enable sniffer mode if a STA
   5201	 * interface is active.
   5202	 */
   5203	if (!list_empty(&priv->vif_list)) {
   5204		if (net_ratelimit())
   5205			wiphy_info(hw->wiphy,
   5206				   "not enabling sniffer mode because STA interface is active\n");
   5207		return 0;
   5208	}
   5209
   5210	if (!priv->sniffer_enabled) {
   5211		if (mwl8k_cmd_enable_sniffer(hw, 1))
   5212			return 0;
   5213		priv->sniffer_enabled = true;
   5214	}
   5215
   5216	*total_flags &=	FIF_ALLMULTI |
   5217			FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL |
   5218			FIF_OTHER_BSS;
   5219
   5220	return 1;
   5221}
   5222
   5223static struct mwl8k_vif *mwl8k_first_vif(struct mwl8k_priv *priv)
   5224{
   5225	if (!list_empty(&priv->vif_list))
   5226		return list_entry(priv->vif_list.next, struct mwl8k_vif, list);
   5227
   5228	return NULL;
   5229}
   5230
   5231static void mwl8k_configure_filter(struct ieee80211_hw *hw,
   5232				   unsigned int changed_flags,
   5233				   unsigned int *total_flags,
   5234				   u64 multicast)
   5235{
   5236	struct mwl8k_priv *priv = hw->priv;
   5237	struct mwl8k_cmd_pkt *cmd = (void *)(unsigned long)multicast;
   5238
   5239	/*
   5240	 * AP firmware doesn't allow fine-grained control over
   5241	 * the receive filter.
   5242	 */
   5243	if (priv->ap_fw) {
   5244		*total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
   5245		kfree(cmd);
   5246		return;
   5247	}
   5248
   5249	/*
   5250	 * Enable hardware sniffer mode if FIF_CONTROL or
   5251	 * FIF_OTHER_BSS is requested.
   5252	 */
   5253	if (*total_flags & (FIF_CONTROL | FIF_OTHER_BSS) &&
   5254	    mwl8k_configure_filter_sniffer(hw, changed_flags, total_flags)) {
   5255		kfree(cmd);
   5256		return;
   5257	}
   5258
   5259	/* Clear unsupported feature flags */
   5260	*total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
   5261
   5262	if (mwl8k_fw_lock(hw)) {
   5263		kfree(cmd);
   5264		return;
   5265	}
   5266
   5267	if (priv->sniffer_enabled) {
   5268		mwl8k_cmd_enable_sniffer(hw, 0);
   5269		priv->sniffer_enabled = false;
   5270	}
   5271
   5272	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
   5273		if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
   5274			/*
   5275			 * Disable the BSS filter.
   5276			 */
   5277			mwl8k_cmd_set_pre_scan(hw);
   5278		} else {
   5279			struct mwl8k_vif *mwl8k_vif;
   5280			const u8 *bssid;
   5281
   5282			/*
   5283			 * Enable the BSS filter.
   5284			 *
   5285			 * If there is an active STA interface, use that
   5286			 * interface's BSSID, otherwise use a dummy one
   5287			 * (where the OUI part needs to be nonzero for
   5288			 * the BSSID to be accepted by POST_SCAN).
   5289			 */
   5290			mwl8k_vif = mwl8k_first_vif(priv);
   5291			if (mwl8k_vif != NULL)
   5292				bssid = mwl8k_vif->vif->bss_conf.bssid;
   5293			else
   5294				bssid = "\x01\x00\x00\x00\x00\x00";
   5295
   5296			mwl8k_cmd_set_post_scan(hw, bssid);
   5297		}
   5298	}
   5299
   5300	/*
   5301	 * If FIF_ALLMULTI is being requested, throw away the command
   5302	 * packet that ->prepare_multicast() built and replace it with
   5303	 * a command packet that enables reception of all multicast
   5304	 * packets.
   5305	 */
   5306	if (*total_flags & FIF_ALLMULTI) {
   5307		kfree(cmd);
   5308		cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, NULL);
   5309	}
   5310
   5311	if (cmd != NULL) {
   5312		mwl8k_post_cmd(hw, cmd);
   5313		kfree(cmd);
   5314	}
   5315
   5316	mwl8k_fw_unlock(hw);
   5317}
   5318
   5319static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
   5320{
   5321	return mwl8k_cmd_set_rts_threshold(hw, value);
   5322}
   5323
   5324static int mwl8k_sta_remove(struct ieee80211_hw *hw,
   5325			    struct ieee80211_vif *vif,
   5326			    struct ieee80211_sta *sta)
   5327{
   5328	struct mwl8k_priv *priv = hw->priv;
   5329
   5330	if (priv->ap_fw)
   5331		return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr);
   5332	else
   5333		return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr);
   5334}
   5335
   5336static int mwl8k_sta_add(struct ieee80211_hw *hw,
   5337			 struct ieee80211_vif *vif,
   5338			 struct ieee80211_sta *sta)
   5339{
   5340	struct mwl8k_priv *priv = hw->priv;
   5341	int ret;
   5342	int i;
   5343	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
   5344	struct ieee80211_key_conf *key;
   5345
   5346	if (!priv->ap_fw) {
   5347		ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
   5348		if (ret >= 0) {
   5349			MWL8K_STA(sta)->peer_id = ret;
   5350			if (sta->deflink.ht_cap.ht_supported)
   5351				MWL8K_STA(sta)->is_ampdu_allowed = true;
   5352			ret = 0;
   5353		}
   5354
   5355	} else {
   5356		ret = mwl8k_cmd_set_new_stn_add(hw, vif, sta);
   5357	}
   5358
   5359	for (i = 0; i < NUM_WEP_KEYS; i++) {
   5360		key = IEEE80211_KEY_CONF(mwl8k_vif->wep_key_conf[i].key);
   5361		if (mwl8k_vif->wep_key_conf[i].enabled)
   5362			mwl8k_set_key(hw, SET_KEY, vif, sta, key);
   5363	}
   5364	return ret;
   5365}
   5366
   5367static int mwl8k_conf_tx(struct ieee80211_hw *hw,
   5368			 struct ieee80211_vif *vif, u16 queue,
   5369			 const struct ieee80211_tx_queue_params *params)
   5370{
   5371	struct mwl8k_priv *priv = hw->priv;
   5372	int rc;
   5373
   5374	rc = mwl8k_fw_lock(hw);
   5375	if (!rc) {
   5376		BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1);
   5377		memcpy(&priv->wmm_params[queue], params, sizeof(*params));
   5378
   5379		if (!priv->wmm_enabled)
   5380			rc = mwl8k_cmd_set_wmm_mode(hw, 1);
   5381
   5382		if (!rc) {
   5383			int q = MWL8K_TX_WMM_QUEUES - 1 - queue;
   5384			rc = mwl8k_cmd_set_edca_params(hw, q,
   5385						       params->cw_min,
   5386						       params->cw_max,
   5387						       params->aifs,
   5388						       params->txop);
   5389		}
   5390
   5391		mwl8k_fw_unlock(hw);
   5392	}
   5393
   5394	return rc;
   5395}
   5396
   5397static int mwl8k_get_stats(struct ieee80211_hw *hw,
   5398			   struct ieee80211_low_level_stats *stats)
   5399{
   5400	return mwl8k_cmd_get_stat(hw, stats);
   5401}
   5402
   5403static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
   5404				struct survey_info *survey)
   5405{
   5406	struct mwl8k_priv *priv = hw->priv;
   5407	struct ieee80211_conf *conf = &hw->conf;
   5408	struct ieee80211_supported_band *sband;
   5409
   5410	if (priv->ap_fw) {
   5411		sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
   5412
   5413		if (sband && idx >= sband->n_channels) {
   5414			idx -= sband->n_channels;
   5415			sband = NULL;
   5416		}
   5417
   5418		if (!sband)
   5419			sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
   5420
   5421		if (!sband || idx >= sband->n_channels)
   5422			return -ENOENT;
   5423
   5424		memcpy(survey, &priv->survey[idx], sizeof(*survey));
   5425		survey->channel = &sband->channels[idx];
   5426
   5427		return 0;
   5428	}
   5429
   5430	if (idx != 0)
   5431		return -ENOENT;
   5432
   5433	survey->channel = conf->chandef.chan;
   5434	survey->filled = SURVEY_INFO_NOISE_DBM;
   5435	survey->noise = priv->noise;
   5436
   5437	return 0;
   5438}
   5439
   5440#define MAX_AMPDU_ATTEMPTS 5
   5441
   5442static int
   5443mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
   5444		   struct ieee80211_ampdu_params *params)
   5445{
   5446	struct ieee80211_sta *sta = params->sta;
   5447	enum ieee80211_ampdu_mlme_action action = params->action;
   5448	u16 tid = params->tid;
   5449	u16 *ssn = &params->ssn;
   5450	u8 buf_size = params->buf_size;
   5451	int i, rc = 0;
   5452	struct mwl8k_priv *priv = hw->priv;
   5453	struct mwl8k_ampdu_stream *stream;
   5454	u8 *addr = sta->addr, idx;
   5455	struct mwl8k_sta *sta_info = MWL8K_STA(sta);
   5456
   5457	if (!ieee80211_hw_check(hw, AMPDU_AGGREGATION))
   5458		return -ENOTSUPP;
   5459
   5460	spin_lock(&priv->stream_lock);
   5461	stream = mwl8k_lookup_stream(hw, addr, tid);
   5462
   5463	switch (action) {
   5464	case IEEE80211_AMPDU_RX_START:
   5465	case IEEE80211_AMPDU_RX_STOP:
   5466		break;
   5467	case IEEE80211_AMPDU_TX_START:
   5468		/* By the time we get here the hw queues may contain outgoing
   5469		 * packets for this RA/TID that are not part of this BA
   5470		 * session.  The hw will assign sequence numbers to these
   5471		 * packets as they go out.  So if we query the hw for its next
   5472		 * sequence number and use that for the SSN here, it may end up
   5473		 * being wrong, which will lead to sequence number mismatch at
   5474		 * the recipient.  To avoid this, we reset the sequence number
   5475		 * to O for the first MPDU in this BA stream.
   5476		 */
   5477		*ssn = 0;
   5478		if (stream == NULL) {
   5479			/* This means that somebody outside this driver called
   5480			 * ieee80211_start_tx_ba_session.  This is unexpected
   5481			 * because we do our own rate control.  Just warn and
   5482			 * move on.
   5483			 */
   5484			wiphy_warn(hw->wiphy, "Unexpected call to %s.  "
   5485				   "Proceeding anyway.\n", __func__);
   5486			stream = mwl8k_add_stream(hw, sta, tid);
   5487		}
   5488		if (stream == NULL) {
   5489			wiphy_debug(hw->wiphy, "no free AMPDU streams\n");
   5490			rc = -EBUSY;
   5491			break;
   5492		}
   5493		stream->state = AMPDU_STREAM_IN_PROGRESS;
   5494
   5495		/* Release the lock before we do the time consuming stuff */
   5496		spin_unlock(&priv->stream_lock);
   5497		for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
   5498
   5499			/* Check if link is still valid */
   5500			if (!sta_info->is_ampdu_allowed) {
   5501				spin_lock(&priv->stream_lock);
   5502				mwl8k_remove_stream(hw, stream);
   5503				spin_unlock(&priv->stream_lock);
   5504				return -EBUSY;
   5505			}
   5506
   5507			rc = mwl8k_check_ba(hw, stream, vif);
   5508
   5509			/* If HW restart is in progress mwl8k_post_cmd will
   5510			 * return -EBUSY. Avoid retrying mwl8k_check_ba in
   5511			 * such cases
   5512			 */
   5513			if (!rc || rc == -EBUSY)
   5514				break;
   5515			/*
   5516			 * HW queues take time to be flushed, give them
   5517			 * sufficient time
   5518			 */
   5519
   5520			msleep(1000);
   5521		}
   5522		spin_lock(&priv->stream_lock);
   5523		if (rc) {
   5524			wiphy_err(hw->wiphy, "Stream for tid %d busy after %d"
   5525				" attempts\n", tid, MAX_AMPDU_ATTEMPTS);
   5526			mwl8k_remove_stream(hw, stream);
   5527			rc = -EBUSY;
   5528			break;
   5529		}
   5530		rc = IEEE80211_AMPDU_TX_START_IMMEDIATE;
   5531		break;
   5532	case IEEE80211_AMPDU_TX_STOP_CONT:
   5533	case IEEE80211_AMPDU_TX_STOP_FLUSH:
   5534	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
   5535		if (stream) {
   5536			if (stream->state == AMPDU_STREAM_ACTIVE) {
   5537				idx = stream->idx;
   5538				spin_unlock(&priv->stream_lock);
   5539				mwl8k_destroy_ba(hw, idx);
   5540				spin_lock(&priv->stream_lock);
   5541			}
   5542			mwl8k_remove_stream(hw, stream);
   5543		}
   5544		ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
   5545		break;
   5546	case IEEE80211_AMPDU_TX_OPERATIONAL:
   5547		BUG_ON(stream == NULL);
   5548		BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS);
   5549		spin_unlock(&priv->stream_lock);
   5550		rc = mwl8k_create_ba(hw, stream, buf_size, vif);
   5551		spin_lock(&priv->stream_lock);
   5552		if (!rc)
   5553			stream->state = AMPDU_STREAM_ACTIVE;
   5554		else {
   5555			idx = stream->idx;
   5556			spin_unlock(&priv->stream_lock);
   5557			mwl8k_destroy_ba(hw, idx);
   5558			spin_lock(&priv->stream_lock);
   5559			wiphy_debug(hw->wiphy,
   5560				"Failed adding stream for sta %pM tid %d\n",
   5561				addr, tid);
   5562			mwl8k_remove_stream(hw, stream);
   5563		}
   5564		break;
   5565
   5566	default:
   5567		rc = -ENOTSUPP;
   5568	}
   5569
   5570	spin_unlock(&priv->stream_lock);
   5571	return rc;
   5572}
   5573
   5574static void mwl8k_sw_scan_start(struct ieee80211_hw *hw,
   5575				struct ieee80211_vif *vif,
   5576				const u8 *mac_addr)
   5577{
   5578	struct mwl8k_priv *priv = hw->priv;
   5579	u8 tmp;
   5580
   5581	if (!priv->ap_fw)
   5582		return;
   5583
   5584	/* clear all stats */
   5585	priv->channel_time = 0;
   5586	ioread32(priv->regs + BBU_RXRDY_CNT_REG);
   5587	ioread32(priv->regs + NOK_CCA_CNT_REG);
   5588	mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp);
   5589
   5590	priv->sw_scan_start = true;
   5591}
   5592
   5593static void mwl8k_sw_scan_complete(struct ieee80211_hw *hw,
   5594				   struct ieee80211_vif *vif)
   5595{
   5596	struct mwl8k_priv *priv = hw->priv;
   5597	u8 tmp;
   5598
   5599	if (!priv->ap_fw)
   5600		return;
   5601
   5602	priv->sw_scan_start = false;
   5603
   5604	/* clear all stats */
   5605	priv->channel_time = 0;
   5606	ioread32(priv->regs + BBU_RXRDY_CNT_REG);
   5607	ioread32(priv->regs + NOK_CCA_CNT_REG);
   5608	mwl8k_cmd_bbp_reg_access(priv->hw, 0, BBU_AVG_NOISE_VAL, &tmp);
   5609}
   5610
   5611static const struct ieee80211_ops mwl8k_ops = {
   5612	.tx			= mwl8k_tx,
   5613	.start			= mwl8k_start,
   5614	.stop			= mwl8k_stop,
   5615	.add_interface		= mwl8k_add_interface,
   5616	.remove_interface	= mwl8k_remove_interface,
   5617	.config			= mwl8k_config,
   5618	.bss_info_changed	= mwl8k_bss_info_changed,
   5619	.prepare_multicast	= mwl8k_prepare_multicast,
   5620	.configure_filter	= mwl8k_configure_filter,
   5621	.set_key                = mwl8k_set_key,
   5622	.set_rts_threshold	= mwl8k_set_rts_threshold,
   5623	.sta_add		= mwl8k_sta_add,
   5624	.sta_remove		= mwl8k_sta_remove,
   5625	.conf_tx		= mwl8k_conf_tx,
   5626	.get_stats		= mwl8k_get_stats,
   5627	.get_survey		= mwl8k_get_survey,
   5628	.ampdu_action		= mwl8k_ampdu_action,
   5629	.sw_scan_start		= mwl8k_sw_scan_start,
   5630	.sw_scan_complete	= mwl8k_sw_scan_complete,
   5631};
   5632
   5633static void mwl8k_finalize_join_worker(struct work_struct *work)
   5634{
   5635	struct mwl8k_priv *priv =
   5636		container_of(work, struct mwl8k_priv, finalize_join_worker);
   5637	struct sk_buff *skb = priv->beacon_skb;
   5638	struct ieee80211_mgmt *mgmt = (void *)skb->data;
   5639	int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
   5640	const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
   5641					 mgmt->u.beacon.variable, len);
   5642	int dtim_period = 1;
   5643
   5644	if (tim && tim[1] >= 2)
   5645		dtim_period = tim[3];
   5646
   5647	mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
   5648
   5649	dev_kfree_skb(skb);
   5650	priv->beacon_skb = NULL;
   5651}
   5652
   5653enum {
   5654	MWL8363 = 0,
   5655	MWL8687,
   5656	MWL8366,
   5657	MWL8764,
   5658};
   5659
   5660#define MWL8K_8366_AP_FW_API 3
   5661#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
   5662#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
   5663
   5664#define MWL8K_8764_AP_FW_API 1
   5665#define _MWL8K_8764_AP_FW(api) "mwl8k/fmimage_8764_ap-" #api ".fw"
   5666#define MWL8K_8764_AP_FW(api) _MWL8K_8764_AP_FW(api)
   5667
   5668static struct mwl8k_device_info mwl8k_info_tbl[] = {
   5669	[MWL8363] = {
   5670		.part_name	= "88w8363",
   5671		.helper_image	= "mwl8k/helper_8363.fw",
   5672		.fw_image_sta	= "mwl8k/fmimage_8363.fw",
   5673	},
   5674	[MWL8687] = {
   5675		.part_name	= "88w8687",
   5676		.helper_image	= "mwl8k/helper_8687.fw",
   5677		.fw_image_sta	= "mwl8k/fmimage_8687.fw",
   5678	},
   5679	[MWL8366] = {
   5680		.part_name	= "88w8366",
   5681		.helper_image	= "mwl8k/helper_8366.fw",
   5682		.fw_image_sta	= "mwl8k/fmimage_8366.fw",
   5683		.fw_image_ap	= MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API),
   5684		.fw_api_ap	= MWL8K_8366_AP_FW_API,
   5685		.ap_rxd_ops	= &rxd_ap_ops,
   5686	},
   5687	[MWL8764] = {
   5688		.part_name	= "88w8764",
   5689		.fw_image_ap	= MWL8K_8764_AP_FW(MWL8K_8764_AP_FW_API),
   5690		.fw_api_ap	= MWL8K_8764_AP_FW_API,
   5691		.ap_rxd_ops	= &rxd_ap_ops,
   5692	},
   5693};
   5694
   5695MODULE_FIRMWARE("mwl8k/helper_8363.fw");
   5696MODULE_FIRMWARE("mwl8k/fmimage_8363.fw");
   5697MODULE_FIRMWARE("mwl8k/helper_8687.fw");
   5698MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
   5699MODULE_FIRMWARE("mwl8k/helper_8366.fw");
   5700MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
   5701MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
   5702
   5703static const struct pci_device_id mwl8k_pci_id_table[] = {
   5704	{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
   5705	{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
   5706	{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
   5707	{ PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
   5708	{ PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
   5709	{ PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
   5710	{ PCI_VDEVICE(MARVELL, 0x2a41), .driver_data = MWL8366, },
   5711	{ PCI_VDEVICE(MARVELL, 0x2a42), .driver_data = MWL8366, },
   5712	{ PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, },
   5713	{ PCI_VDEVICE(MARVELL, 0x2b36), .driver_data = MWL8764, },
   5714	{ },
   5715};
   5716MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
   5717
   5718static int mwl8k_request_alt_fw(struct mwl8k_priv *priv)
   5719{
   5720	int rc;
   5721	printk(KERN_ERR "%s: Error requesting preferred fw %s.\n"
   5722	       "Trying alternative firmware %s\n", pci_name(priv->pdev),
   5723	       priv->fw_pref, priv->fw_alt);
   5724	rc = mwl8k_request_fw(priv, priv->fw_alt, &priv->fw_ucode, true);
   5725	if (rc) {
   5726		printk(KERN_ERR "%s: Error requesting alt fw %s\n",
   5727		       pci_name(priv->pdev), priv->fw_alt);
   5728		return rc;
   5729	}
   5730	return 0;
   5731}
   5732
   5733static int mwl8k_firmware_load_success(struct mwl8k_priv *priv);
   5734static void mwl8k_fw_state_machine(const struct firmware *fw, void *context)
   5735{
   5736	struct mwl8k_priv *priv = context;
   5737	struct mwl8k_device_info *di = priv->device_info;
   5738	int rc;
   5739
   5740	switch (priv->fw_state) {
   5741	case FW_STATE_INIT:
   5742		if (!fw) {
   5743			printk(KERN_ERR "%s: Error requesting helper fw %s\n",
   5744			       pci_name(priv->pdev), di->helper_image);
   5745			goto fail;
   5746		}
   5747		priv->fw_helper = fw;
   5748		rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode,
   5749				      true);
   5750		if (rc && priv->fw_alt) {
   5751			rc = mwl8k_request_alt_fw(priv);
   5752			if (rc)
   5753				goto fail;
   5754			priv->fw_state = FW_STATE_LOADING_ALT;
   5755		} else if (rc)
   5756			goto fail;
   5757		else
   5758			priv->fw_state = FW_STATE_LOADING_PREF;
   5759		break;
   5760
   5761	case FW_STATE_LOADING_PREF:
   5762		if (!fw) {
   5763			if (priv->fw_alt) {
   5764				rc = mwl8k_request_alt_fw(priv);
   5765				if (rc)
   5766					goto fail;
   5767				priv->fw_state = FW_STATE_LOADING_ALT;
   5768			} else
   5769				goto fail;
   5770		} else {
   5771			priv->fw_ucode = fw;
   5772			rc = mwl8k_firmware_load_success(priv);
   5773			if (rc)
   5774				goto fail;
   5775			else
   5776				complete(&priv->firmware_loading_complete);
   5777		}
   5778		break;
   5779
   5780	case FW_STATE_LOADING_ALT:
   5781		if (!fw) {
   5782			printk(KERN_ERR "%s: Error requesting alt fw %s\n",
   5783			       pci_name(priv->pdev), di->helper_image);
   5784			goto fail;
   5785		}
   5786		priv->fw_ucode = fw;
   5787		rc = mwl8k_firmware_load_success(priv);
   5788		if (rc)
   5789			goto fail;
   5790		else
   5791			complete(&priv->firmware_loading_complete);
   5792		break;
   5793
   5794	default:
   5795		printk(KERN_ERR "%s: Unexpected firmware loading state: %d\n",
   5796		       MWL8K_NAME, priv->fw_state);
   5797		BUG_ON(1);
   5798	}
   5799
   5800	return;
   5801
   5802fail:
   5803	priv->fw_state = FW_STATE_ERROR;
   5804	complete(&priv->firmware_loading_complete);
   5805	mwl8k_release_firmware(priv);
   5806	device_release_driver(&priv->pdev->dev);
   5807}
   5808
   5809#define MAX_RESTART_ATTEMPTS 1
   5810static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
   5811			       bool nowait)
   5812{
   5813	struct mwl8k_priv *priv = hw->priv;
   5814	int rc;
   5815	int count = MAX_RESTART_ATTEMPTS;
   5816
   5817retry:
   5818	/* Reset firmware and hardware */
   5819	mwl8k_hw_reset(priv);
   5820
   5821	/* Ask userland hotplug daemon for the device firmware */
   5822	rc = mwl8k_request_firmware(priv, fw_image, nowait);
   5823	if (rc) {
   5824		wiphy_err(hw->wiphy, "Firmware files not found\n");
   5825		return rc;
   5826	}
   5827
   5828	if (nowait)
   5829		return rc;
   5830
   5831	/* Load firmware into hardware */
   5832	rc = mwl8k_load_firmware(hw);
   5833	if (rc)
   5834		wiphy_err(hw->wiphy, "Cannot start firmware\n");
   5835
   5836	/* Reclaim memory once firmware is successfully loaded */
   5837	mwl8k_release_firmware(priv);
   5838
   5839	if (rc && count) {
   5840		/* FW did not start successfully;
   5841		 * lets try one more time
   5842		 */
   5843		count--;
   5844		wiphy_err(hw->wiphy, "Trying to reload the firmware again\n");
   5845		msleep(20);
   5846		goto retry;
   5847	}
   5848
   5849	return rc;
   5850}
   5851
   5852static int mwl8k_init_txqs(struct ieee80211_hw *hw)
   5853{
   5854	struct mwl8k_priv *priv = hw->priv;
   5855	int rc = 0;
   5856	int i;
   5857
   5858	for (i = 0; i < mwl8k_tx_queues(priv); i++) {
   5859		rc = mwl8k_txq_init(hw, i);
   5860		if (rc)
   5861			break;
   5862		if (priv->ap_fw)
   5863			iowrite32(priv->txq[i].txd_dma,
   5864				  priv->sram + priv->txq_offset[i]);
   5865	}
   5866	return rc;
   5867}
   5868
   5869/* initialize hw after successfully loading a firmware image */
   5870static int mwl8k_probe_hw(struct ieee80211_hw *hw)
   5871{
   5872	struct mwl8k_priv *priv = hw->priv;
   5873	int rc = 0;
   5874	int i;
   5875
   5876	if (priv->ap_fw) {
   5877		priv->rxd_ops = priv->device_info->ap_rxd_ops;
   5878		if (priv->rxd_ops == NULL) {
   5879			wiphy_err(hw->wiphy,
   5880				  "Driver does not have AP firmware image support for this hardware\n");
   5881			rc = -ENOENT;
   5882			goto err_stop_firmware;
   5883		}
   5884	} else {
   5885		priv->rxd_ops = &rxd_sta_ops;
   5886	}
   5887
   5888	priv->sniffer_enabled = false;
   5889	priv->wmm_enabled = false;
   5890	priv->pending_tx_pkts = 0;
   5891	atomic_set(&priv->watchdog_event_pending, 0);
   5892
   5893	rc = mwl8k_rxq_init(hw, 0);
   5894	if (rc)
   5895		goto err_stop_firmware;
   5896	rxq_refill(hw, 0, INT_MAX);
   5897
   5898	/* For the sta firmware, we need to know the dma addresses of tx queues
   5899	 * before sending MWL8K_CMD_GET_HW_SPEC.  So we must initialize them
   5900	 * prior to issuing this command.  But for the AP case, we learn the
   5901	 * total number of queues from the result CMD_GET_HW_SPEC, so for this
   5902	 * case we must initialize the tx queues after.
   5903	 */
   5904	priv->num_ampdu_queues = 0;
   5905	if (!priv->ap_fw) {
   5906		rc = mwl8k_init_txqs(hw);
   5907		if (rc)
   5908			goto err_free_queues;
   5909	}
   5910
   5911	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
   5912	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
   5913	iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY|
   5914		  MWL8K_A2H_INT_BA_WATCHDOG,
   5915		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
   5916	iowrite32(MWL8K_A2H_INT_OPC_DONE,
   5917		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
   5918
   5919	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
   5920			 IRQF_SHARED, MWL8K_NAME, hw);
   5921	if (rc) {
   5922		wiphy_err(hw->wiphy, "failed to register IRQ handler\n");
   5923		goto err_free_queues;
   5924	}
   5925
   5926	/*
   5927	 * When hw restart is requested,
   5928	 * mac80211 will take care of clearing
   5929	 * the ampdu streams, so do not clear
   5930	 * the ampdu state here
   5931	 */
   5932	if (!priv->hw_restart_in_progress)
   5933		memset(priv->ampdu, 0, sizeof(priv->ampdu));
   5934
   5935	/*
   5936	 * Temporarily enable interrupts.  Initial firmware host
   5937	 * commands use interrupts and avoid polling.  Disable
   5938	 * interrupts when done.
   5939	 */
   5940	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
   5941
   5942	/* Get config data, mac addrs etc */
   5943	if (priv->ap_fw) {
   5944		rc = mwl8k_cmd_get_hw_spec_ap(hw);
   5945		if (!rc)
   5946			rc = mwl8k_init_txqs(hw);
   5947		if (!rc)
   5948			rc = mwl8k_cmd_set_hw_spec(hw);
   5949	} else {
   5950		rc = mwl8k_cmd_get_hw_spec_sta(hw);
   5951	}
   5952	if (rc) {
   5953		wiphy_err(hw->wiphy, "Cannot initialise firmware\n");
   5954		goto err_free_irq;
   5955	}
   5956
   5957	/* Turn radio off */
   5958	rc = mwl8k_cmd_radio_disable(hw);
   5959	if (rc) {
   5960		wiphy_err(hw->wiphy, "Cannot disable\n");
   5961		goto err_free_irq;
   5962	}
   5963
   5964	/* Clear MAC address */
   5965	rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
   5966	if (rc) {
   5967		wiphy_err(hw->wiphy, "Cannot clear MAC address\n");
   5968		goto err_free_irq;
   5969	}
   5970
   5971	/* Configure Antennas */
   5972	rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3);
   5973	if (rc)
   5974		wiphy_warn(hw->wiphy, "failed to set # of RX antennas");
   5975	rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
   5976	if (rc)
   5977		wiphy_warn(hw->wiphy, "failed to set # of TX antennas");
   5978
   5979
   5980	/* Disable interrupts */
   5981	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
   5982	free_irq(priv->pdev->irq, hw);
   5983
   5984	wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n",
   5985		   priv->device_info->part_name,
   5986		   priv->hw_rev, hw->wiphy->perm_addr,
   5987		   priv->ap_fw ? "AP" : "STA",
   5988		   (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
   5989		   (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
   5990
   5991	return 0;
   5992
   5993err_free_irq:
   5994	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
   5995	free_irq(priv->pdev->irq, hw);
   5996
   5997err_free_queues:
   5998	for (i = 0; i < mwl8k_tx_queues(priv); i++)
   5999		mwl8k_txq_deinit(hw, i);
   6000	mwl8k_rxq_deinit(hw, 0);
   6001
   6002err_stop_firmware:
   6003	mwl8k_hw_reset(priv);
   6004
   6005	return rc;
   6006}
   6007
   6008/*
   6009 * invoke mwl8k_reload_firmware to change the firmware image after the device
   6010 * has already been registered
   6011 */
   6012static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
   6013{
   6014	int i, rc = 0;
   6015	struct mwl8k_priv *priv = hw->priv;
   6016	struct mwl8k_vif *vif, *tmp_vif;
   6017
   6018	mwl8k_stop(hw);
   6019	mwl8k_rxq_deinit(hw, 0);
   6020
   6021	/*
   6022	 * All the existing interfaces are re-added by the ieee80211_reconfig;
   6023	 * which means driver should remove existing interfaces before calling
   6024	 * ieee80211_restart_hw
   6025	 */
   6026	if (priv->hw_restart_in_progress)
   6027		list_for_each_entry_safe(vif, tmp_vif, &priv->vif_list, list)
   6028			mwl8k_remove_vif(priv, vif);
   6029
   6030	for (i = 0; i < mwl8k_tx_queues(priv); i++)
   6031		mwl8k_txq_deinit(hw, i);
   6032
   6033	rc = mwl8k_init_firmware(hw, fw_image, false);
   6034	if (rc)
   6035		goto fail;
   6036
   6037	rc = mwl8k_probe_hw(hw);
   6038	if (rc)
   6039		goto fail;
   6040
   6041	if (priv->hw_restart_in_progress)
   6042		return rc;
   6043
   6044	rc = mwl8k_start(hw);
   6045	if (rc)
   6046		goto fail;
   6047
   6048	rc = mwl8k_config(hw, ~0);
   6049	if (rc)
   6050		goto fail;
   6051
   6052	for (i = 0; i < MWL8K_TX_WMM_QUEUES; i++) {
   6053		rc = mwl8k_conf_tx(hw, NULL, i, &priv->wmm_params[i]);
   6054		if (rc)
   6055			goto fail;
   6056	}
   6057
   6058	return rc;
   6059
   6060fail:
   6061	printk(KERN_WARNING "mwl8k: Failed to reload firmware image.\n");
   6062	return rc;
   6063}
   6064
   6065static const struct ieee80211_iface_limit ap_if_limits[] = {
   6066	{ .max = 8,	.types = BIT(NL80211_IFTYPE_AP) },
   6067	{ .max = 1,	.types = BIT(NL80211_IFTYPE_STATION) },
   6068};
   6069
   6070static const struct ieee80211_iface_combination ap_if_comb = {
   6071	.limits = ap_if_limits,
   6072	.n_limits = ARRAY_SIZE(ap_if_limits),
   6073	.max_interfaces = 8,
   6074	.num_different_channels = 1,
   6075};
   6076
   6077
   6078static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
   6079{
   6080	struct ieee80211_hw *hw = priv->hw;
   6081	int i, rc;
   6082
   6083	rc = mwl8k_load_firmware(hw);
   6084	mwl8k_release_firmware(priv);
   6085	if (rc) {
   6086		wiphy_err(hw->wiphy, "Cannot start firmware\n");
   6087		return rc;
   6088	}
   6089
   6090	/*
   6091	 * Extra headroom is the size of the required DMA header
   6092	 * minus the size of the smallest 802.11 frame (CTS frame).
   6093	 */
   6094	hw->extra_tx_headroom =
   6095		sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
   6096
   6097	hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0;
   6098
   6099	hw->queues = MWL8K_TX_WMM_QUEUES;
   6100
   6101	/* Set rssi values to dBm */
   6102	ieee80211_hw_set(hw, SIGNAL_DBM);
   6103	ieee80211_hw_set(hw, HAS_RATE_CONTROL);
   6104
   6105	/*
   6106	 * Ask mac80211 to not to trigger PS mode
   6107	 * based on PM bit of incoming frames.
   6108	 */
   6109	if (priv->ap_fw)
   6110		ieee80211_hw_set(hw, AP_LINK_PS);
   6111
   6112	hw->vif_data_size = sizeof(struct mwl8k_vif);
   6113	hw->sta_data_size = sizeof(struct mwl8k_sta);
   6114
   6115	priv->macids_used = 0;
   6116	INIT_LIST_HEAD(&priv->vif_list);
   6117
   6118	/* Set default radio state and preamble */
   6119	priv->radio_on = false;
   6120	priv->radio_short_preamble = false;
   6121
   6122	/* Finalize join worker */
   6123	INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
   6124	/* Handle watchdog ba events */
   6125	INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events);
   6126	/* To reload the firmware if it crashes */
   6127	INIT_WORK(&priv->fw_reload, mwl8k_hw_restart_work);
   6128
   6129	/* TX reclaim and RX tasklets.  */
   6130	tasklet_setup(&priv->poll_tx_task, mwl8k_tx_poll);
   6131	tasklet_disable(&priv->poll_tx_task);
   6132	tasklet_setup(&priv->poll_rx_task, mwl8k_rx_poll);
   6133	tasklet_disable(&priv->poll_rx_task);
   6134
   6135	/* Power management cookie */
   6136	priv->cookie = dma_alloc_coherent(&priv->pdev->dev, 4,
   6137					  &priv->cookie_dma, GFP_KERNEL);
   6138	if (priv->cookie == NULL)
   6139		return -ENOMEM;
   6140
   6141	mutex_init(&priv->fw_mutex);
   6142	priv->fw_mutex_owner = NULL;
   6143	priv->fw_mutex_depth = 0;
   6144	priv->hostcmd_wait = NULL;
   6145
   6146	spin_lock_init(&priv->tx_lock);
   6147
   6148	spin_lock_init(&priv->stream_lock);
   6149
   6150	priv->tx_wait = NULL;
   6151
   6152	rc = mwl8k_probe_hw(hw);
   6153	if (rc)
   6154		goto err_free_cookie;
   6155
   6156	hw->wiphy->interface_modes = 0;
   6157
   6158	if (priv->ap_macids_supported || priv->device_info->fw_image_ap) {
   6159		hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
   6160		hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
   6161		hw->wiphy->iface_combinations = &ap_if_comb;
   6162		hw->wiphy->n_iface_combinations = 1;
   6163	}
   6164
   6165	if (priv->sta_macids_supported || priv->device_info->fw_image_sta)
   6166		hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
   6167
   6168	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
   6169
   6170	rc = ieee80211_register_hw(hw);
   6171	if (rc) {
   6172		wiphy_err(hw->wiphy, "Cannot register device\n");
   6173		goto err_unprobe_hw;
   6174	}
   6175
   6176	return 0;
   6177
   6178err_unprobe_hw:
   6179	for (i = 0; i < mwl8k_tx_queues(priv); i++)
   6180		mwl8k_txq_deinit(hw, i);
   6181	mwl8k_rxq_deinit(hw, 0);
   6182
   6183err_free_cookie:
   6184	if (priv->cookie != NULL)
   6185		dma_free_coherent(&priv->pdev->dev, 4, priv->cookie,
   6186				  priv->cookie_dma);
   6187
   6188	return rc;
   6189}
   6190static int mwl8k_probe(struct pci_dev *pdev,
   6191				 const struct pci_device_id *id)
   6192{
   6193	static int printed_version;
   6194	struct ieee80211_hw *hw;
   6195	struct mwl8k_priv *priv;
   6196	struct mwl8k_device_info *di;
   6197	int rc;
   6198
   6199	if (!printed_version) {
   6200		printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
   6201		printed_version = 1;
   6202	}
   6203
   6204
   6205	rc = pci_enable_device(pdev);
   6206	if (rc) {
   6207		printk(KERN_ERR "%s: Cannot enable new PCI device\n",
   6208		       MWL8K_NAME);
   6209		return rc;
   6210	}
   6211
   6212	rc = pci_request_regions(pdev, MWL8K_NAME);
   6213	if (rc) {
   6214		printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
   6215		       MWL8K_NAME);
   6216		goto err_disable_device;
   6217	}
   6218
   6219	pci_set_master(pdev);
   6220
   6221
   6222	hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
   6223	if (hw == NULL) {
   6224		printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
   6225		rc = -ENOMEM;
   6226		goto err_free_reg;
   6227	}
   6228
   6229	SET_IEEE80211_DEV(hw, &pdev->dev);
   6230	pci_set_drvdata(pdev, hw);
   6231
   6232	priv = hw->priv;
   6233	priv->hw = hw;
   6234	priv->pdev = pdev;
   6235	priv->device_info = &mwl8k_info_tbl[id->driver_data];
   6236
   6237	if (id->driver_data == MWL8764)
   6238		priv->is_8764 = true;
   6239
   6240	priv->sram = pci_iomap(pdev, 0, 0x10000);
   6241	if (priv->sram == NULL) {
   6242		wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
   6243		rc = -EIO;
   6244		goto err_iounmap;
   6245	}
   6246
   6247	/*
   6248	 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
   6249	 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
   6250	 */
   6251	priv->regs = pci_iomap(pdev, 1, 0x10000);
   6252	if (priv->regs == NULL) {
   6253		priv->regs = pci_iomap(pdev, 2, 0x10000);
   6254		if (priv->regs == NULL) {
   6255			wiphy_err(hw->wiphy, "Cannot map device registers\n");
   6256			rc = -EIO;
   6257			goto err_iounmap;
   6258		}
   6259	}
   6260
   6261	/*
   6262	 * Choose the initial fw image depending on user input.  If a second
   6263	 * image is available, make it the alternative image that will be
   6264	 * loaded if the first one fails.
   6265	 */
   6266	init_completion(&priv->firmware_loading_complete);
   6267	di = priv->device_info;
   6268	if (ap_mode_default && di->fw_image_ap) {
   6269		priv->fw_pref = di->fw_image_ap;
   6270		priv->fw_alt = di->fw_image_sta;
   6271	} else if (!ap_mode_default && di->fw_image_sta) {
   6272		priv->fw_pref = di->fw_image_sta;
   6273		priv->fw_alt = di->fw_image_ap;
   6274	} else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) {
   6275		printk(KERN_WARNING "AP fw is unavailable.  Using STA fw.");
   6276		priv->fw_pref = di->fw_image_sta;
   6277	} else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) {
   6278		printk(KERN_WARNING "STA fw is unavailable.  Using AP fw.");
   6279		priv->fw_pref = di->fw_image_ap;
   6280	}
   6281	rc = mwl8k_init_firmware(hw, priv->fw_pref, true);
   6282	if (rc)
   6283		goto err_stop_firmware;
   6284
   6285	priv->hw_restart_in_progress = false;
   6286
   6287	priv->running_bsses = 0;
   6288
   6289	return rc;
   6290
   6291err_stop_firmware:
   6292	mwl8k_hw_reset(priv);
   6293
   6294err_iounmap:
   6295	if (priv->regs != NULL)
   6296		pci_iounmap(pdev, priv->regs);
   6297
   6298	if (priv->sram != NULL)
   6299		pci_iounmap(pdev, priv->sram);
   6300
   6301	ieee80211_free_hw(hw);
   6302
   6303err_free_reg:
   6304	pci_release_regions(pdev);
   6305
   6306err_disable_device:
   6307	pci_disable_device(pdev);
   6308
   6309	return rc;
   6310}
   6311
   6312static void mwl8k_remove(struct pci_dev *pdev)
   6313{
   6314	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
   6315	struct mwl8k_priv *priv;
   6316	int i;
   6317
   6318	if (hw == NULL)
   6319		return;
   6320	priv = hw->priv;
   6321
   6322	wait_for_completion(&priv->firmware_loading_complete);
   6323
   6324	if (priv->fw_state == FW_STATE_ERROR) {
   6325		mwl8k_hw_reset(priv);
   6326		goto unmap;
   6327	}
   6328
   6329	ieee80211_stop_queues(hw);
   6330
   6331	ieee80211_unregister_hw(hw);
   6332
   6333	/* Remove TX reclaim and RX tasklets.  */
   6334	tasklet_kill(&priv->poll_tx_task);
   6335	tasklet_kill(&priv->poll_rx_task);
   6336
   6337	/* Stop hardware */
   6338	mwl8k_hw_reset(priv);
   6339
   6340	/* Return all skbs to mac80211 */
   6341	for (i = 0; i < mwl8k_tx_queues(priv); i++)
   6342		mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
   6343
   6344	for (i = 0; i < mwl8k_tx_queues(priv); i++)
   6345		mwl8k_txq_deinit(hw, i);
   6346
   6347	mwl8k_rxq_deinit(hw, 0);
   6348
   6349	dma_free_coherent(&priv->pdev->dev, 4, priv->cookie, priv->cookie_dma);
   6350
   6351unmap:
   6352	pci_iounmap(pdev, priv->regs);
   6353	pci_iounmap(pdev, priv->sram);
   6354	ieee80211_free_hw(hw);
   6355	pci_release_regions(pdev);
   6356	pci_disable_device(pdev);
   6357}
   6358
   6359static struct pci_driver mwl8k_driver = {
   6360	.name		= MWL8K_NAME,
   6361	.id_table	= mwl8k_pci_id_table,
   6362	.probe		= mwl8k_probe,
   6363	.remove		= mwl8k_remove,
   6364};
   6365
   6366module_pci_driver(mwl8k_driver);
   6367
   6368MODULE_DESCRIPTION(MWL8K_DESC);
   6369MODULE_VERSION(MWL8K_VERSION);
   6370MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
   6371MODULE_LICENSE("GPL");